mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Move code for managing PartitionDescs into a new file, partdesc.c
This is similar in spirit to the existing partbounds.c file in the same directory, except that there's a lot less code in the new file created by this commit. Pending work in this area proposes to add a bunch more code related to PartitionDescs, though, and this will give us a good place to put it. Discussion: http://postgr.es/m/CA+TgmoZUwPf_uanjF==gTGBMJrn8uCq52XYvAEorNkLrUdoawg@mail.gmail.com
This commit is contained in:
124
src/backend/utils/cache/partcache.c
vendored
124
src/backend/utils/cache/partcache.c
vendored
@ -243,130 +243,6 @@ RelationBuildPartitionKey(Relation relation)
|
||||
relation->rd_partkey = key;
|
||||
}
|
||||
|
||||
/*
|
||||
* RelationBuildPartitionDesc
|
||||
* Form rel's partition descriptor
|
||||
*
|
||||
* Not flushed from the cache by RelationClearRelation() unless changed because
|
||||
* of addition or removal of partition.
|
||||
*/
|
||||
void
|
||||
RelationBuildPartitionDesc(Relation rel)
|
||||
{
|
||||
PartitionDesc partdesc;
|
||||
PartitionBoundInfo boundinfo = NULL;
|
||||
List *inhoids;
|
||||
PartitionBoundSpec **boundspecs = NULL;
|
||||
Oid *oids = NULL;
|
||||
ListCell *cell;
|
||||
int i,
|
||||
nparts;
|
||||
PartitionKey key = RelationGetPartitionKey(rel);
|
||||
MemoryContext oldcxt;
|
||||
int *mapping;
|
||||
|
||||
/* Get partition oids from pg_inherits */
|
||||
inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock);
|
||||
nparts = list_length(inhoids);
|
||||
|
||||
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;
|
||||
PartitionBoundSpec *boundspec;
|
||||
|
||||
tuple = SearchSysCache1(RELOID, inhrelid);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "cache lookup failed for relation %u", inhrelid);
|
||||
|
||||
datum = SysCacheGetAttr(RELOID, tuple,
|
||||
Anum_pg_class_relpartbound,
|
||||
&isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "null relpartbound for relation %u", inhrelid);
|
||||
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 (boundspec->is_default)
|
||||
{
|
||||
Oid partdefid;
|
||||
|
||||
partdefid = get_default_partition_oid(RelationGetRelid(rel));
|
||||
if (partdefid != inhrelid)
|
||||
elog(ERROR, "expected partdefid %u, but got %u",
|
||||
inhrelid, partdefid);
|
||||
}
|
||||
|
||||
oids[i] = inhrelid;
|
||||
boundspecs[i] = boundspec;
|
||||
++i;
|
||||
ReleaseSysCache(tuple);
|
||||
}
|
||||
|
||||
/* Now build the actual relcache partition descriptor */
|
||||
rel->rd_pdcxt = AllocSetContextCreate(CacheMemoryContext,
|
||||
"partition descriptor",
|
||||
ALLOCSET_DEFAULT_SIZES);
|
||||
MemoryContextCopyAndSetIdentifier(rel->rd_pdcxt, RelationGetRelationName(rel));
|
||||
|
||||
oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt);
|
||||
partdesc = (PartitionDescData *) palloc0(sizeof(PartitionDescData));
|
||||
partdesc->nparts = nparts;
|
||||
/* oids and boundinfo are allocated below. */
|
||||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
if (nparts == 0)
|
||||
{
|
||||
rel->rd_partdesc = partdesc;
|
||||
return;
|
||||
}
|
||||
|
||||
/* First create PartitionBoundInfo */
|
||||
boundinfo = partition_bounds_create(boundspecs, nparts, key, &mapping);
|
||||
|
||||
/* Now copy boundinfo and oids into partdesc. */
|
||||
oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt);
|
||||
partdesc->boundinfo = partition_bounds_copy(boundinfo, key);
|
||||
partdesc->oids = (Oid *) palloc(partdesc->nparts * sizeof(Oid));
|
||||
partdesc->is_leaf = (bool *) palloc(partdesc->nparts * sizeof(bool));
|
||||
|
||||
/*
|
||||
* Now assign OIDs from the original array into mapped indexes of the
|
||||
* result array. The order of OIDs in the former is defined by the
|
||||
* catalog scan that retrieved them, whereas that in the latter is defined
|
||||
* by canonicalized representation of the partition bounds.
|
||||
*/
|
||||
for (i = 0; i < partdesc->nparts; i++)
|
||||
{
|
||||
int index = mapping[i];
|
||||
|
||||
partdesc->oids[index] = oids[i];
|
||||
/* Record if the partition is a leaf partition */
|
||||
partdesc->is_leaf[index] =
|
||||
(get_rel_relkind(oids[i]) != RELKIND_PARTITIONED_TABLE);
|
||||
}
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
rel->rd_partdesc = partdesc;
|
||||
}
|
||||
|
||||
/*
|
||||
* RelationGetPartitionQual
|
||||
*
|
||||
|
Reference in New Issue
Block a user