mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Reduce unnecessary list construction in RelationBuildPartitionDesc.
The 'partoids' list which was constructed by the previous version of this code was necessarily identical to 'inhoids'. There's no point to duplicating the list, so avoid that. Instead, construct the array representation directly from the original 'inhoids' list. Also, use an array rather than a list for 'boundspecs'. We know exactly how many items we need to store, so there's really no reason to use a list. Using an array instead reduces the number of memory allocations we perform. Patch by me, reviewed by Michael Paquier and Amit Langote, the latter of whom also helped with rebasing.
This commit is contained in:
40
src/backend/utils/cache/partcache.c
vendored
40
src/backend/utils/cache/partcache.c
vendored
@ -255,28 +255,36 @@ void
|
||||
RelationBuildPartitionDesc(Relation rel)
|
||||
{
|
||||
PartitionDesc partdesc;
|
||||
PartitionBoundInfo boundinfo;
|
||||
PartitionBoundInfo boundinfo = NULL;
|
||||
List *inhoids;
|
||||
List *boundspecs = NIL;
|
||||
PartitionBoundSpec **boundspecs = NULL;
|
||||
Oid *oids = NULL;
|
||||
ListCell *cell;
|
||||
int i,
|
||||
nparts;
|
||||
PartitionKey key = RelationGetPartitionKey(rel);
|
||||
MemoryContext oldcxt;
|
||||
Oid *oids_orig;
|
||||
int *mapping;
|
||||
|
||||
/* Get partition oids from pg_inherits */
|
||||
inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock);
|
||||
nparts = list_length(inhoids);
|
||||
|
||||
/* Collect bound spec nodes in a list */
|
||||
if (nparts > 0)
|
||||
{
|
||||
oids = palloc(nparts * sizeof(Oid));
|
||||
boundspecs = palloc(nparts * sizeof(PartitionBoundSpec *));
|
||||
}
|
||||
|
||||
/* Collect bound spec nodes for each partition */
|
||||
i = 0;
|
||||
foreach(cell, inhoids)
|
||||
{
|
||||
Oid inhrelid = lfirst_oid(cell);
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
Node *boundspec;
|
||||
PartitionBoundSpec *boundspec;
|
||||
|
||||
tuple = SearchSysCache1(RELOID, inhrelid);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
@ -287,14 +295,16 @@ RelationBuildPartitionDesc(Relation rel)
|
||||
&isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "null relpartbound for relation %u", inhrelid);
|
||||
boundspec = (Node *) stringToNode(TextDatumGetCString(datum));
|
||||
boundspec = stringToNode(TextDatumGetCString(datum));
|
||||
if (!IsA(boundspec, PartitionBoundSpec))
|
||||
elog(ERROR, "invalid relpartbound for relation %u", inhrelid);
|
||||
|
||||
/*
|
||||
* Sanity check: If the PartitionBoundSpec says this is the default
|
||||
* partition, its OID should correspond to whatever's stored in
|
||||
* pg_partitioned_table.partdefid; if not, the catalog is corrupt.
|
||||
*/
|
||||
if (castNode(PartitionBoundSpec, boundspec)->is_default)
|
||||
if (boundspec->is_default)
|
||||
{
|
||||
Oid partdefid;
|
||||
|
||||
@ -304,12 +314,12 @@ RelationBuildPartitionDesc(Relation rel)
|
||||
inhrelid, partdefid);
|
||||
}
|
||||
|
||||
boundspecs = lappend(boundspecs, boundspec);
|
||||
oids[i] = inhrelid;
|
||||
boundspecs[i] = boundspec;
|
||||
++i;
|
||||
ReleaseSysCache(tuple);
|
||||
}
|
||||
|
||||
nparts = list_length(boundspecs);
|
||||
|
||||
/* Now build the actual relcache partition descriptor */
|
||||
rel->rd_pdcxt = AllocSetContextCreate(CacheMemoryContext,
|
||||
"partition descriptor",
|
||||
@ -330,11 +340,7 @@ RelationBuildPartitionDesc(Relation rel)
|
||||
}
|
||||
|
||||
/* First create PartitionBoundInfo */
|
||||
boundinfo = partition_bounds_create(boundspecs, key, &mapping);
|
||||
oids_orig = (Oid *) palloc(sizeof(Oid) * partdesc->nparts);
|
||||
i = 0;
|
||||
foreach(cell, inhoids)
|
||||
oids_orig[i++] = lfirst_oid(cell);
|
||||
boundinfo = partition_bounds_create(boundspecs, nparts, key, &mapping);
|
||||
|
||||
/* Now copy boundinfo and oids into partdesc. */
|
||||
oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt);
|
||||
@ -352,10 +358,10 @@ RelationBuildPartitionDesc(Relation rel)
|
||||
{
|
||||
int index = mapping[i];
|
||||
|
||||
partdesc->oids[index] = oids_orig[i];
|
||||
partdesc->oids[index] = oids[i];
|
||||
/* Record if the partition is a leaf partition */
|
||||
partdesc->is_leaf[index] =
|
||||
(get_rel_relkind(oids_orig[i]) != RELKIND_PARTITIONED_TABLE);
|
||||
(get_rel_relkind(oids[i]) != RELKIND_PARTITIONED_TABLE);
|
||||
}
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
|
Reference in New Issue
Block a user