mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +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:
parent
9eefba181f
commit
1bb5e78218
@ -69,6 +69,7 @@
|
|||||||
#include "parser/parse_collate.h"
|
#include "parser/parse_collate.h"
|
||||||
#include "parser/parse_expr.h"
|
#include "parser/parse_expr.h"
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "storage/predicate.h"
|
#include "storage/predicate.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
|
@ -253,22 +253,6 @@ has_partition_attrs(Relation rel, Bitmapset *attnums, bool *used_in_expr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* get_default_oid_from_partdesc
|
|
||||||
*
|
|
||||||
* Given a partition descriptor, return the OID of the default partition, if
|
|
||||||
* one exists; else, return InvalidOid.
|
|
||||||
*/
|
|
||||||
Oid
|
|
||||||
get_default_oid_from_partdesc(PartitionDesc partdesc)
|
|
||||||
{
|
|
||||||
if (partdesc && partdesc->boundinfo &&
|
|
||||||
partition_bound_has_default(partdesc->boundinfo))
|
|
||||||
return partdesc->oids[partdesc->boundinfo->default_index];
|
|
||||||
|
|
||||||
return InvalidOid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_default_partition_oid
|
* get_default_partition_oid
|
||||||
*
|
*
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/objectaccess.h"
|
#include "catalog/objectaccess.h"
|
||||||
#include "catalog/partition.h"
|
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/index.h"
|
#include "catalog/index.h"
|
||||||
#include "catalog/indexing.h"
|
#include "catalog/indexing.h"
|
||||||
#include "catalog/partition.h"
|
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "catalog/pg_constraint.h"
|
#include "catalog/pg_constraint.h"
|
||||||
#include "catalog/pg_inherits.h"
|
#include "catalog/pg_inherits.h"
|
||||||
@ -46,6 +45,7 @@
|
|||||||
#include "parser/parse_coerce.h"
|
#include "parser/parse_coerce.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "parser/parse_oper.h"
|
#include "parser/parse_oper.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "rewrite/rewriteManip.h"
|
#include "rewrite/rewriteManip.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
|
@ -74,6 +74,7 @@
|
|||||||
#include "parser/parse_utilcmd.h"
|
#include "parser/parse_utilcmd.h"
|
||||||
#include "parser/parser.h"
|
#include "parser/parser.h"
|
||||||
#include "partitioning/partbounds.h"
|
#include "partitioning/partbounds.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "pgstat.h"
|
#include "pgstat.h"
|
||||||
#include "rewrite/rewriteDefine.h"
|
#include "rewrite/rewriteDefine.h"
|
||||||
#include "rewrite/rewriteHandler.h"
|
#include "rewrite/rewriteHandler.h"
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "pgstat.h"
|
#include "pgstat.h"
|
||||||
#include "rewrite/rewriteManip.h"
|
#include "rewrite/rewriteManip.h"
|
||||||
#include "storage/bufmgr.h"
|
#include "storage/bufmgr.h"
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "partitioning/partbounds.h"
|
#include "partitioning/partbounds.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "partitioning/partprune.h"
|
#include "partitioning/partprune.h"
|
||||||
#include "rewrite/rewriteManip.h"
|
#include "rewrite/rewriteManip.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "optimizer/inherit.h"
|
#include "optimizer/inherit.h"
|
||||||
#include "optimizer/planner.h"
|
#include "optimizer/planner.h"
|
||||||
#include "optimizer/prep.h"
|
#include "optimizer/prep.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "utils/rel.h"
|
#include "utils/rel.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
#include "catalog/dependency.h"
|
#include "catalog/dependency.h"
|
||||||
#include "catalog/heap.h"
|
#include "catalog/heap.h"
|
||||||
#include "catalog/partition.h"
|
|
||||||
#include "catalog/pg_am.h"
|
#include "catalog/pg_am.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_statistic_ext.h"
|
#include "catalog/pg_statistic_ext.h"
|
||||||
@ -41,6 +40,7 @@
|
|||||||
#include "optimizer/plancat.h"
|
#include "optimizer/plancat.h"
|
||||||
#include "optimizer/prep.h"
|
#include "optimizer/prep.h"
|
||||||
#include "partitioning/partbounds.h"
|
#include "partitioning/partbounds.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
#include "rewrite/rewriteManip.h"
|
#include "rewrite/rewriteManip.h"
|
||||||
|
@ -12,6 +12,6 @@ subdir = src/backend/partitioning
|
|||||||
top_builddir = ../../..
|
top_builddir = ../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS = partprune.o partbounds.o
|
OBJS = partbounds.o partdesc.o partprune.o
|
||||||
|
|
||||||
include $(top_srcdir)/src/backend/common.mk
|
include $(top_srcdir)/src/backend/common.mk
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
* src/backend/partitioning/partbounds.c
|
* src/backend/partitioning/partbounds.c
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
@ -23,8 +24,9 @@
|
|||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
#include "parser/parse_coerce.h"
|
#include "parser/parse_coerce.h"
|
||||||
#include "partitioning/partprune.h"
|
|
||||||
#include "partitioning/partbounds.h"
|
#include "partitioning/partbounds.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
|
#include "partitioning/partprune.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/datum.h"
|
#include "utils/datum.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
221
src/backend/partitioning/partdesc.c
Normal file
221
src/backend/partitioning/partdesc.c
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* partdesc.c
|
||||||
|
* Support routines for manipulating partition descriptors
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/backend/partitioning/partdesc.c
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "catalog/partition.h"
|
||||||
|
#include "catalog/pg_inherits.h"
|
||||||
|
#include "partitioning/partbounds.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
|
#include "utils/builtins.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
#include "utils/memutils.h"
|
||||||
|
#include "utils/rel.h"
|
||||||
|
#include "utils/partcache.h"
|
||||||
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* equalPartitionDescs
|
||||||
|
* Compare two partition descriptors for logical equality
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1,
|
||||||
|
PartitionDesc partdesc2)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (partdesc1 != NULL)
|
||||||
|
{
|
||||||
|
if (partdesc2 == NULL)
|
||||||
|
return false;
|
||||||
|
if (partdesc1->nparts != partdesc2->nparts)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Assert(key != NULL || partdesc1->nparts == 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Same oids? If the partitioning structure did not change, that is,
|
||||||
|
* no partitions were added or removed to the relation, the oids array
|
||||||
|
* should still match element-by-element.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < partdesc1->nparts; i++)
|
||||||
|
{
|
||||||
|
if (partdesc1->oids[i] != partdesc2->oids[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now compare partition bound collections. The logic to iterate over
|
||||||
|
* the collections is private to partition.c.
|
||||||
|
*/
|
||||||
|
if (partdesc1->boundinfo != NULL)
|
||||||
|
{
|
||||||
|
if (partdesc2->boundinfo == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!partition_bounds_equal(key->partnatts, key->parttyplen,
|
||||||
|
key->parttypbyval,
|
||||||
|
partdesc1->boundinfo,
|
||||||
|
partdesc2->boundinfo))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (partdesc2->boundinfo != NULL)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (partdesc2 != NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_default_oid_from_partdesc
|
||||||
|
*
|
||||||
|
* Given a partition descriptor, return the OID of the default partition, if
|
||||||
|
* one exists; else, return InvalidOid.
|
||||||
|
*/
|
||||||
|
Oid
|
||||||
|
get_default_oid_from_partdesc(PartitionDesc partdesc)
|
||||||
|
{
|
||||||
|
if (partdesc && partdesc->boundinfo &&
|
||||||
|
partition_bound_has_default(partdesc->boundinfo))
|
||||||
|
return partdesc->oids[partdesc->boundinfo->default_index];
|
||||||
|
|
||||||
|
return InvalidOid;
|
||||||
|
}
|
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;
|
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
|
* RelationGetPartitionQual
|
||||||
*
|
*
|
||||||
|
57
src/backend/utils/cache/relcache.c
vendored
57
src/backend/utils/cache/relcache.c
vendored
@ -72,6 +72,7 @@
|
|||||||
#include "nodes/nodeFuncs.h"
|
#include "nodes/nodeFuncs.h"
|
||||||
#include "optimizer/optimizer.h"
|
#include "optimizer/optimizer.h"
|
||||||
#include "partitioning/partbounds.h"
|
#include "partitioning/partbounds.h"
|
||||||
|
#include "partitioning/partdesc.h"
|
||||||
#include "rewrite/rewriteDefine.h"
|
#include "rewrite/rewriteDefine.h"
|
||||||
#include "rewrite/rowsecurity.h"
|
#include "rewrite/rowsecurity.h"
|
||||||
#include "storage/lmgr.h"
|
#include "storage/lmgr.h"
|
||||||
@ -283,8 +284,6 @@ static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
|
|||||||
StrategyNumber numSupport);
|
StrategyNumber numSupport);
|
||||||
static void RelationCacheInitFileRemoveInDir(const char *tblspcpath);
|
static void RelationCacheInitFileRemoveInDir(const char *tblspcpath);
|
||||||
static void unlink_initfile(const char *initfilename, int elevel);
|
static void unlink_initfile(const char *initfilename, int elevel);
|
||||||
static bool equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1,
|
|
||||||
PartitionDesc partdesc2);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -995,60 +994,6 @@ equalRSDesc(RowSecurityDesc *rsdesc1, RowSecurityDesc *rsdesc2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* equalPartitionDescs
|
|
||||||
* Compare two partition descriptors for logical equality
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1,
|
|
||||||
PartitionDesc partdesc2)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (partdesc1 != NULL)
|
|
||||||
{
|
|
||||||
if (partdesc2 == NULL)
|
|
||||||
return false;
|
|
||||||
if (partdesc1->nparts != partdesc2->nparts)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Assert(key != NULL || partdesc1->nparts == 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Same oids? If the partitioning structure did not change, that is,
|
|
||||||
* no partitions were added or removed to the relation, the oids array
|
|
||||||
* should still match element-by-element.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < partdesc1->nparts; i++)
|
|
||||||
{
|
|
||||||
if (partdesc1->oids[i] != partdesc2->oids[i])
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now compare partition bound collections. The logic to iterate over
|
|
||||||
* the collections is private to partition.c.
|
|
||||||
*/
|
|
||||||
if (partdesc1->boundinfo != NULL)
|
|
||||||
{
|
|
||||||
if (partdesc2->boundinfo == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!partition_bounds_equal(key->partnatts, key->parttyplen,
|
|
||||||
key->parttypbyval,
|
|
||||||
partdesc1->boundinfo,
|
|
||||||
partdesc2->boundinfo))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (partdesc2->boundinfo != NULL)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (partdesc2 != NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RelationBuildDesc
|
* RelationBuildDesc
|
||||||
*
|
*
|
||||||
|
@ -19,20 +19,6 @@
|
|||||||
/* Seed for the extended hash function */
|
/* Seed for the extended hash function */
|
||||||
#define HASH_PARTITION_SEED UINT64CONST(0x7A5B22367996DCFD)
|
#define HASH_PARTITION_SEED UINT64CONST(0x7A5B22367996DCFD)
|
||||||
|
|
||||||
/*
|
|
||||||
* Information about partitions of a partitioned table.
|
|
||||||
*/
|
|
||||||
typedef struct PartitionDescData
|
|
||||||
{
|
|
||||||
int nparts; /* Number of partitions */
|
|
||||||
Oid *oids; /* Array of 'nparts' elements containing
|
|
||||||
* partition OIDs in order of the their bounds */
|
|
||||||
bool *is_leaf; /* Array of 'nparts' elements storing whether
|
|
||||||
* the corresponding 'oids' element belongs to
|
|
||||||
* a leaf partition or not */
|
|
||||||
PartitionBoundInfo boundinfo; /* collection of partition bounds */
|
|
||||||
} PartitionDescData;
|
|
||||||
|
|
||||||
extern Oid get_partition_parent(Oid relid);
|
extern Oid get_partition_parent(Oid relid);
|
||||||
extern List *get_partition_ancestors(Oid relid);
|
extern List *get_partition_ancestors(Oid relid);
|
||||||
extern List *map_partition_varattnos(List *expr, int fromrel_varno,
|
extern List *map_partition_varattnos(List *expr, int fromrel_varno,
|
||||||
@ -41,7 +27,6 @@ extern List *map_partition_varattnos(List *expr, int fromrel_varno,
|
|||||||
extern bool has_partition_attrs(Relation rel, Bitmapset *attnums,
|
extern bool has_partition_attrs(Relation rel, Bitmapset *attnums,
|
||||||
bool *used_in_expr);
|
bool *used_in_expr);
|
||||||
|
|
||||||
extern Oid get_default_oid_from_partdesc(PartitionDesc partdesc);
|
|
||||||
extern Oid get_default_partition_oid(Oid parentId);
|
extern Oid get_default_partition_oid(Oid parentId);
|
||||||
extern void update_default_partition_oid(Oid parentId, Oid defaultPartId);
|
extern void update_default_partition_oid(Oid parentId, Oid defaultPartId);
|
||||||
extern List *get_proposed_default_constraint(List *new_part_constaints);
|
extern List *get_proposed_default_constraint(List *new_part_constaints);
|
||||||
|
39
src/include/partitioning/partdesc.h
Normal file
39
src/include/partitioning/partdesc.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* partdesc.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
||||||
|
*
|
||||||
|
* src/include/utils/partdesc.h
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PARTDESC_H
|
||||||
|
#define PARTDESC_H
|
||||||
|
|
||||||
|
#include "partitioning/partdefs.h"
|
||||||
|
#include "utils/relcache.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Information about partitions of a partitioned table.
|
||||||
|
*/
|
||||||
|
typedef struct PartitionDescData
|
||||||
|
{
|
||||||
|
int nparts; /* Number of partitions */
|
||||||
|
Oid *oids; /* Array of 'nparts' elements containing
|
||||||
|
* partition OIDs in order of the their bounds */
|
||||||
|
bool *is_leaf; /* Array of 'nparts' elements storing whether
|
||||||
|
* the corresponding 'oids' element belongs to
|
||||||
|
* a leaf partition or not */
|
||||||
|
PartitionBoundInfo boundinfo; /* collection of partition bounds */
|
||||||
|
} PartitionDescData;
|
||||||
|
|
||||||
|
extern void RelationBuildPartitionDesc(Relation rel);
|
||||||
|
|
||||||
|
extern Oid get_default_oid_from_partdesc(PartitionDesc partdesc);
|
||||||
|
|
||||||
|
extern bool equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1,
|
||||||
|
PartitionDesc partdesc2);
|
||||||
|
|
||||||
|
#endif /* PARTCACHE_H */
|
@ -47,7 +47,6 @@ typedef struct PartitionKeyData
|
|||||||
} PartitionKeyData;
|
} PartitionKeyData;
|
||||||
|
|
||||||
extern void RelationBuildPartitionKey(Relation relation);
|
extern void RelationBuildPartitionKey(Relation relation);
|
||||||
extern void RelationBuildPartitionDesc(Relation rel);
|
|
||||||
extern List *RelationGetPartitionQual(Relation rel);
|
extern List *RelationGetPartitionQual(Relation rel);
|
||||||
extern Expr *get_partition_qual_relid(Oid relid);
|
extern Expr *get_partition_qual_relid(Oid relid);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user