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

Commit01993ac

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 parent01bc426 commit01993ac

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

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

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,11 @@
6161
#include"access/tupdesc_details.h"
6262
#include"access/tuptoaster.h"
6363
#include"executor/tuptable.h"
64+
#include"utils/datum.h"
6465
#include"utils/expandeddatum.h"
66+
#include"utils/hashutils.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,58 @@
7175
#defineVARLENA_ATT_IS_PACKABLE(att) \
7276
((att)->attstorage != 'p')
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+
returnDatumGetUInt32(
97+
hash_any((constunsignedchar*)entry->value,entry->len));
98+
}
99+
100+
staticint
101+
missing_match(constvoid*key1,constvoid*key2,Sizekeysize)
102+
{
103+
constmissing_cache_key*entry1= (missing_cache_key*)key1;
104+
constmissing_cache_key*entry2= (missing_cache_key*)key2;
105+
106+
if (entry1->len!=entry2->len)
107+
returnentry1->len>entry2->len ?1 :-1;
108+
109+
returnmemcmp(DatumGetPointer(entry1->value),
110+
DatumGetPointer(entry2->value),
111+
entry1->len);
112+
}
113+
114+
staticvoid
115+
init_missing_cache()
116+
{
117+
HASHCTLhash_ctl;
118+
119+
hash_ctl.keysize=sizeof(missing_cache_key);
120+
hash_ctl.entrysize=sizeof(missing_cache_key);
121+
hash_ctl.hcxt=TopMemoryContext;
122+
hash_ctl.hash=missing_hash;
123+
hash_ctl.match=missing_match;
124+
missing_cache=
125+
hash_create("Missing Values Cache",
126+
32,
127+
&hash_ctl,
128+
HASH_ELEM |HASH_CONTEXT |HASH_FUNCTION |HASH_COMPARE);
129+
}
74130

75131
/* ----------------------------------------------------------------
76132
*misc support routines
@@ -102,8 +158,41 @@ getmissingattr(TupleDesc tupleDesc,
102158

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

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,6 +3011,7 @@ mblen_converter
30113011
mbverifier
30123012
md5_ctxt
30133013
metastring
3014+
missing_cache_key
30143015
mix_data_t
30153016
mixedStruct
30163017
mode_t

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp