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

Commit012b80a

Browse files
committed
Fix exception safety bug in typcache.c.
If an out-of-memory error was thrown at an unfortunate time,ensure_record_cache_typmod_slot_exists() could leak memory and leavebehind a global state that produced an infinite loop on the next call.Fix by merging RecordCacheArray and RecordIdentifierArray into a singlearray. With only one allocation or re-allocation, there is nointermediate state.Back-patch to all supported releases.Reported-by: "James Pang (chaolpan)" <chaolpan@cisco.com>Reviewed-by: Michael Paquier <michael@paquier.xyz>Discussion:https://postgr.es/m/PH0PR11MB519113E738814BDDA702EDADD6EFA%40PH0PR11MB5191.namprd11.prod.outlook.com
1 parent7e57208 commit012b80a

File tree

2 files changed

+27
-26
lines changed

2 files changed

+27
-26
lines changed

‎src/backend/utils/cache/typcache.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,15 @@ static const dshash_parameters srtr_typmod_table_params = {
263263
/* hashtable for recognizing registered record types */
264264
staticHTAB*RecordCacheHash=NULL;
265265

266-
/* arrays of info about registered record types, indexed by assigned typmod */
267-
staticTupleDesc*RecordCacheArray=NULL;
268-
staticuint64*RecordIdentifierArray=NULL;
269-
staticint32RecordCacheArrayLen=0;/* allocated length of above arrays */
266+
typedefstructRecordCacheArrayEntry
267+
{
268+
uint64id;
269+
TupleDesctupdesc;
270+
}RecordCacheArrayEntry;
271+
272+
/* array of info about registered record types, indexed by assigned typmod */
273+
staticRecordCacheArrayEntry*RecordCacheArray=NULL;
274+
staticint32RecordCacheArrayLen=0;/* allocated length of above array */
270275
staticint32NextRecordTypmod=0;/* number of entries used */
271276

272277
/*
@@ -1525,10 +1530,8 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
15251530
{
15261531
if (RecordCacheArray==NULL)
15271532
{
1528-
RecordCacheArray= (TupleDesc*)
1529-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(TupleDesc));
1530-
RecordIdentifierArray= (uint64*)
1531-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(uint64));
1533+
RecordCacheArray= (RecordCacheArrayEntry*)
1534+
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(RecordCacheArrayEntry));
15321535
RecordCacheArrayLen=64;
15331536
}
15341537

@@ -1539,14 +1542,11 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
15391542
while (typmod >=newlen)
15401543
newlen *=2;
15411544

1542-
RecordCacheArray= (TupleDesc*)repalloc(RecordCacheArray,
1543-
newlen*sizeof(TupleDesc));
1545+
RecordCacheArray= (RecordCacheArrayEntry*)
1546+
repalloc(RecordCacheArray,
1547+
newlen*sizeof(RecordCacheArrayEntry));
15441548
memset(RecordCacheArray+RecordCacheArrayLen,0,
1545-
(newlen-RecordCacheArrayLen)*sizeof(TupleDesc));
1546-
RecordIdentifierArray= (uint64*)repalloc(RecordIdentifierArray,
1547-
newlen*sizeof(uint64));
1548-
memset(RecordIdentifierArray+RecordCacheArrayLen,0,
1549-
(newlen-RecordCacheArrayLen)*sizeof(uint64));
1549+
(newlen-RecordCacheArrayLen)*sizeof(RecordCacheArrayEntry));
15501550
RecordCacheArrayLen=newlen;
15511551
}
15521552
}
@@ -1584,8 +1584,8 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
15841584
{
15851585
/* It is already in our local cache? */
15861586
if (typmod<RecordCacheArrayLen&&
1587-
RecordCacheArray[typmod]!=NULL)
1588-
returnRecordCacheArray[typmod];
1587+
RecordCacheArray[typmod].tupdesc!=NULL)
1588+
returnRecordCacheArray[typmod].tupdesc;
15891589

15901590
/* Are we attached to a shared record typmod registry? */
15911591
if (CurrentSession->shared_typmod_registry!=NULL)
@@ -1611,19 +1611,19 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
16111611
* Our local array can now point directly to the TupleDesc
16121612
* in shared memory, which is non-reference-counted.
16131613
*/
1614-
RecordCacheArray[typmod]=tupdesc;
1614+
RecordCacheArray[typmod].tupdesc=tupdesc;
16151615
Assert(tupdesc->tdrefcount==-1);
16161616

16171617
/*
16181618
* We don't share tupdesc identifiers across processes, so
16191619
* assign one locally.
16201620
*/
1621-
RecordIdentifierArray[typmod]=++tupledesc_id_counter;
1621+
RecordCacheArray[typmod].id=++tupledesc_id_counter;
16221622

16231623
dshash_release_lock(CurrentSession->shared_typmod_table,
16241624
entry);
16251625

1626-
returnRecordCacheArray[typmod];
1626+
returnRecordCacheArray[typmod].tupdesc;
16271627
}
16281628
}
16291629
}
@@ -1834,10 +1834,10 @@ assign_record_type_typmod(TupleDesc tupDesc)
18341834
ensure_record_cache_typmod_slot_exists(entDesc->tdtypmod);
18351835
}
18361836

1837-
RecordCacheArray[entDesc->tdtypmod]=entDesc;
1837+
RecordCacheArray[entDesc->tdtypmod].tupdesc=entDesc;
18381838

18391839
/* Assign a unique tupdesc identifier, too. */
1840-
RecordIdentifierArray[entDesc->tdtypmod]=++tupledesc_id_counter;
1840+
RecordCacheArray[entDesc->tdtypmod].id=++tupledesc_id_counter;
18411841

18421842
/* Fully initialized; create the hash table entry */
18431843
recentry= (RecordCacheEntry*)hash_search(RecordCacheHash,
@@ -1886,10 +1886,10 @@ assign_record_type_identifier(Oid type_id, int32 typmod)
18861886
* It's a transient record type, so look in our record-type table.
18871887
*/
18881888
if (typmod >=0&&typmod<RecordCacheArrayLen&&
1889-
RecordCacheArray[typmod]!=NULL)
1889+
RecordCacheArray[typmod].tupdesc!=NULL)
18901890
{
1891-
Assert(RecordIdentifierArray[typmod]!=0);
1892-
returnRecordIdentifierArray[typmod];
1891+
Assert(RecordCacheArray[typmod].id!=0);
1892+
returnRecordCacheArray[typmod].id;
18931893
}
18941894

18951895
/* For anonymous or unrecognized record type, generate a new ID */
@@ -1969,7 +1969,7 @@ SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *registry,
19691969
TupleDesctupdesc;
19701970
boolfound;
19711971

1972-
tupdesc=RecordCacheArray[typmod];
1972+
tupdesc=RecordCacheArray[typmod].tupdesc;
19731973
if (tupdesc==NULL)
19741974
continue;
19751975

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,7 @@ ReadExtraTocPtrType
19651965
ReadFunc
19661966
ReassignOwnedStmt
19671967
RecheckForeignScan_function
1968+
RecordCacheArrayEntry
19681969
RecordCacheEntry
19691970
RecordCompareData
19701971
RecordIOData

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp