Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita684581

Browse files
committed
Cache by-reference missing values in a long lived context
Attribute missing values might be needed past the lifetime of the tupledescriptors from which they are extracted. To avoid possibly usingpointers for by-reference values which might thus be left dangling, wecache a datumCopy'd version of the datum in the TopMemoryContext. Sincewe first search for the value this only needs to be done once persession for any such value.Original complaint from Tom Lane, idea for mitigation by Andrew Dunstan,tweaked by Tom Lane.Backpatch to version 11 where missing values were introduced.Discussion:https://postgr.es/m/1306569.1687978174@sss.pgh.pa.us
1 parent757fa45 commita684581

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

‎src/backend/access/common/heaptuple.c

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,12 @@
6060
#include"access/heaptoast.h"
6161
#include"access/sysattr.h"
6262
#include"access/tupdesc_details.h"
63+
#include"common/hashfn.h"
6364
#include"executor/tuptable.h"
65+
#include"utils/datum.h"
6466
#include"utils/expandeddatum.h"
67+
#include"utils/hsearch.h"
68+
#include"utils/memutils.h"
6569

6670

6771
/* Does att's datatype allow packing into the 1-byte-header varlena format? */
@@ -71,6 +75,57 @@
7175
#defineVARLENA_ATT_IS_PACKABLE(att) \
7276
((att)->attstorage != TYPSTORAGE_PLAIN)
7377

78+
/*
79+
* Setup for cacheing pass-by-ref missing attributes in a way that survives
80+
* tupleDesc destruction.
81+
*/
82+
83+
typedefstruct
84+
{
85+
intlen;
86+
Datumvalue;
87+
}missing_cache_key;
88+
89+
staticHTAB*missing_cache=NULL;
90+
91+
staticuint32
92+
missing_hash(constvoid*key,Sizekeysize)
93+
{
94+
constmissing_cache_key*entry= (missing_cache_key*)key;
95+
96+
returnhash_bytes((constunsignedchar*)entry->value,entry->len);
97+
}
98+
99+
staticint
100+
missing_match(constvoid*key1,constvoid*key2,Sizekeysize)
101+
{
102+
constmissing_cache_key*entry1= (missing_cache_key*)key1;
103+
constmissing_cache_key*entry2= (missing_cache_key*)key2;
104+
105+
if (entry1->len!=entry2->len)
106+
returnentry1->len>entry2->len ?1 :-1;
107+
108+
returnmemcmp(DatumGetPointer(entry1->value),
109+
DatumGetPointer(entry2->value),
110+
entry1->len);
111+
}
112+
113+
staticvoid
114+
init_missing_cache()
115+
{
116+
HASHCTLhash_ctl;
117+
118+
hash_ctl.keysize=sizeof(missing_cache_key);
119+
hash_ctl.entrysize=sizeof(missing_cache_key);
120+
hash_ctl.hcxt=TopMemoryContext;
121+
hash_ctl.hash=missing_hash;
122+
hash_ctl.match=missing_match;
123+
missing_cache=
124+
hash_create("Missing Values Cache",
125+
32,
126+
&hash_ctl,
127+
HASH_ELEM |HASH_CONTEXT |HASH_FUNCTION |HASH_COMPARE);
128+
}
74129

75130
/* ----------------------------------------------------------------
76131
*misc support routines
@@ -102,8 +157,41 @@ getmissingattr(TupleDesc tupleDesc,
102157

103158
if (attrmiss->am_present)
104159
{
160+
missing_cache_keykey;
161+
missing_cache_key*entry;
162+
boolfound;
163+
MemoryContextoldctx;
164+
105165
*isnull= false;
106-
returnattrmiss->am_value;
166+
167+
/* no need to cache by-value attributes */
168+
if (att->attbyval)
169+
returnattrmiss->am_value;
170+
171+
/* set up cache if required */
172+
if (missing_cache==NULL)
173+
init_missing_cache();
174+
175+
/* check if there's a cache entry */
176+
Assert(att->attlen>0||att->attlen==-1);
177+
if (att->attlen>0)
178+
key.len=att->attlen;
179+
else
180+
key.len=VARSIZE_ANY(attrmiss->am_value);
181+
key.value=attrmiss->am_value;
182+
183+
entry=hash_search(missing_cache,&key,HASH_ENTER,&found);
184+
185+
if (!found)
186+
{
187+
/* cache miss, so we need a non-transient copy of the datum */
188+
oldctx=MemoryContextSwitchTo(TopMemoryContext);
189+
entry->value=
190+
datumCopy(attrmiss->am_value, false,att->attlen);
191+
MemoryContextSwitchTo(oldctx);
192+
}
193+
194+
returnentry->value;
107195
}
108196
}
109197

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3479,6 +3479,7 @@ mbstr_verifier
34793479
memoize_hash
34803480
memoize_iterator
34813481
metastring
3482+
missing_cache_key
34823483
mix_data_t
34833484
mixedStruct
34843485
mode_t

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp