1
0
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:
Robert Haas
2018-11-19 12:10:41 -05:00
parent 16fbac39ff
commit 7ee5f88e65
3 changed files with 53 additions and 58 deletions

View File

@ -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);