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

Commit1bb619d

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 parent4caa9e3 commit1bb619d

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
@@ -3104,6 +3104,7 @@ mblen_converter
31043104
mbverifier
31053105
md5_ctxt
31063106
metastring
3107+
missing_cache_key
31073108
mix_data_t
31083109
mixedStruct
31093110
mode_t

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp