/*
* If the relation is a partition, we must grab exclusive lock on its
- * parent because we need to update its partition descriptor. We must
- * take a table lock strong enough to prevent all queries on the parent
- * from proceeding until we commit and send out a shared-cache-inval
- * notice that will make them update their partition descriptor.
- * Sometimes, doing this is cycles spent uselessly, especially if the
- * parent will be dropped as part of the same command anyway.
+ * parent because we need to update its partition descriptor. We must take
+ * a table lock strong enough to prevent all queries on the parent from
+ * proceeding until we commit and send out a shared-cache-inval notice
+ * that will make them update their partition descriptor. Sometimes, doing
+ * this is cycles spent uselessly, especially if the parent will be
+ * dropped as part of the same command anyway.
*/
if (rel->rd_rel->relispartition)
{
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
- errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
- RelationGetRelationName(rel))));
+ errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
+ RelationGetRelationName(rel))));
/*
* Create the Check Constraint
HeapTuple tuple;
Datum values[Natts_pg_partitioned_table];
bool nulls[Natts_pg_partitioned_table];
- ObjectAddress myself;
- ObjectAddress referenced;
+ ObjectAddress myself;
+ ObjectAddress referenced;
Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
/* Convert the expressions (if any) to a text datum */
if (partexprs)
{
- char *exprString;
+ char *exprString;
exprString = nodeToString(partexprs);
partexprDatum = CStringGetTextDatum(exprString);
values[Anum_pg_partitioned_table_partrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
- values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
+ values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
/*
* Anything mentioned in the expressions. We must ignore the column
- * references, which will depend on the table itself; there is no
- * separate partition key object.
+ * references, which will depend on the table itself; there is no separate
+ * partition key object.
*/
if (partexprs)
recordDependencyOnSingleRelExpr(&myself,
}
/*
- * RemovePartitionKeyByRelId
+ * RemovePartitionKeyByRelId
* Remove pg_partitioned_table entry for a relation
*/
void
Relation classRel;
HeapTuple tuple,
newtuple;
- Datum new_val[Natts_pg_class];
- bool new_null[Natts_pg_class],
- new_repl[Natts_pg_class];
+ Datum new_val[Natts_pg_class];
+ bool new_null[Natts_pg_class],
+ new_repl[Natts_pg_class];
/* Update pg_class tuple */
classRel = heap_open(RelationRelationId, RowExclusiveLock);
#ifdef USE_ASSERT_CHECKING
{
- Form_pg_class classForm;
- bool isnull;
+ Form_pg_class classForm;
+ bool isnull;
classForm = (Form_pg_class) GETSTRUCT(tuple);
Assert(!classForm->relispartition);
Relation partrel = lfirst(lc1);
Relation parent = lfirst(lc2);
PartitionKey partkey = RelationGetPartitionKey(partrel);
- TupleDesc tupdesc = RelationGetDescr(partrel);
+ TupleDesc tupdesc = RelationGetDescr(partrel);
PartitionDesc partdesc = RelationGetPartitionDesc(partrel);
int j,
m;
if (parent != NULL)
{
/*
- * For every partitioned table other than root, we must store
- * a tuple table slot initialized with its tuple descriptor and
- * a tuple conversion map to convert a tuple from its parent's
- * rowtype to its own. That is to make sure that we are looking
- * at the correct row using the correct tuple descriptor when
+ * For every partitioned table other than root, we must store a
+ * tuple table slot initialized with its tuple descriptor and a
+ * tuple conversion map to convert a tuple from its parent's
+ * rowtype to its own. That is to make sure that we are looking at
+ * the correct row using the correct tuple descriptor when
* computing its partition key for tuple routing.
*/
pd[i]->tupslot = MakeSingleTupleTableSlot(tupdesc);
pd[i]->tupmap = convert_tuples_by_name(RelationGetDescr(parent),
tupdesc,
- gettext_noop("could not convert row type"));
+ gettext_noop("could not convert row type"));
}
else
{
result = my_qual;
/*
- * Change Vars to have partition's attnos instead of the parent's.
- * We do this after we concatenate the parent's quals, because
- * we want every Var in it to bear this relation's attnos.
- * It's safe to assume varno = 1 here.
+ * Change Vars to have partition's attnos instead of the parent's. We do
+ * this after we concatenate the parent's quals, because we want every Var
+ * in it to bear this relation's attnos. It's safe to assume varno = 1
+ * here.
*/
result = map_partition_varattnos(result, 1, rel, parent);
List *range_table;
PartitionDispatch *partition_dispatch_info;
- int num_dispatch; /* Number of entries in the above array */
- int num_partitions; /* Number of members in the following
- * arrays */
- ResultRelInfo *partitions; /* Per partition result relation */
+ int num_dispatch; /* Number of entries in the above array */
+ int num_partitions; /* Number of members in the following arrays */
+ ResultRelInfo *partitions; /* Per partition result relation */
TupleConversionMap **partition_tupconv_maps;
TupleTableSlot *partition_tuple_slot;
/* Initialize state for CopyFrom tuple routing. */
if (is_from && rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
- PartitionDispatch *partition_dispatch_info;
- ResultRelInfo *partitions;
+ PartitionDispatch *partition_dispatch_info;
+ ResultRelInfo *partitions;
TupleConversionMap **partition_tupconv_maps;
- TupleTableSlot *partition_tuple_slot;
- int num_parted,
- num_partitions;
+ TupleTableSlot *partition_tuple_slot;
+ int num_parted,
+ num_partitions;
ExecSetupPartitionTupleRouting(rel,
&partition_dispatch_info,
for (;;)
{
TupleTableSlot *slot,
- *oldslot;
+ *oldslot;
bool skip_tuple;
Oid loaded_oid = InvalidOid;
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("\"%s\" is a partitioned table",
RelationGetRelationName(rel)),
- errdetail("Partitioned tables cannot have ROW triggers.")));
+ errdetail("Partitioned tables cannot have ROW triggers.")));
}
else if (rel->rd_rel->relkind == RELKIND_VIEW)
{
Relation partition_root,
int instrument_options)
{
- List *partition_check = NIL;
+ List *partition_check = NIL;
MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
resultRelInfo->type = T_ResultRelInfo;
*/
if (resultRelInfo->ri_PartitionCheckExpr == NULL)
{
- List *qual = resultRelInfo->ri_PartitionCheck;
+ List *qual = resultRelInfo->ri_PartitionCheck;
resultRelInfo->ri_PartitionCheckExpr = (List *)
- ExecPrepareExpr((Expr *) qual, estate);
+ ExecPrepareExpr((Expr *) qual, estate);
}
/*
ereport(ERROR,
(errcode(ERRCODE_NOT_NULL_VIOLATION),
errmsg("null value in column \"%s\" violates not-null constraint",
- NameStr(orig_tupdesc->attrs[attrChk - 1]->attname)),
+ NameStr(orig_tupdesc->attrs[attrChk - 1]->attname)),
val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
errtablecol(orig_rel, attrChk)));
}
64);
ereport(ERROR,
(errcode(ERRCODE_CHECK_VIOLATION),
- errmsg("new row for relation \"%s\" violates partition constraint",
- RelationGetRelationName(orig_rel)),
- val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
+ errmsg("new row for relation \"%s\" violates partition constraint",
+ RelationGetRelationName(orig_rel)),
+ val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
}
}
*partitions = (ResultRelInfo *) palloc(*num_partitions *
sizeof(ResultRelInfo));
*tup_conv_maps = (TupleConversionMap **) palloc0(*num_partitions *
- sizeof(TupleConversionMap *));
+ sizeof(TupleConversionMap *));
/*
* Initialize an empty slot that will be used to manipulate tuples of any
InitResultRelInfo(leaf_part_rri,
partrel,
- 1, /* dummy */
+ 1, /* dummy */
rel,
0);
ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
TupleTableSlot *slot, EState *estate)
{
- int result;
- Oid failed_at;
+ int result;
+ Oid failed_at;
ExprContext *econtext = GetPerTupleExprContext(estate);
econtext->ecxt_scantuple = slot;
(errcode(ERRCODE_CHECK_VIOLATION),
errmsg("no partition of relation \"%s\" found for row",
get_rel_name(failed_at)),
- val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
+ val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
}
return result;
Oid newId;
List *recheckIndexes = NIL;
TupleTableSlot *oldslot = slot,
- *result = NULL;
+ *result = NULL;
/*
* get the heap tuple out of the tuple table slot, making sure we have a
/* Determine the partition to heap_insert the tuple into */
if (mtstate->mt_partition_dispatch_info)
{
- int leaf_part_index;
+ int leaf_part_index;
TupleConversionMap *map;
/*
* Away we go ... If we end up not finding a partition after all,
* ExecFindPartition() does not return and errors out instead.
- * Otherwise, the returned value is to be used as an index into
- * arrays mt_partitions[] and mt_partition_tupconv_maps[] that
- * will get us the ResultRelInfo and TupleConversionMap for the
- * partition, respectively.
+ * Otherwise, the returned value is to be used as an index into arrays
+ * mt_partitions[] and mt_partition_tupconv_maps[] that will get us
+ * the ResultRelInfo and TupleConversionMap for the partition,
+ * respectively.
*/
leaf_part_index = ExecFindPartition(resultRelInfo,
- mtstate->mt_partition_dispatch_info,
+ mtstate->mt_partition_dispatch_info,
slot,
estate);
Assert(leaf_part_index >= 0 &&
if (resultRelInfo->ri_FdwRoutine)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot route inserted tuples to a foreign table")));
+ errmsg("cannot route inserted tuples to a foreign table")));
/* For ExecInsertIndexTuples() to work on the partition's indexes */
estate->es_result_relation_info = resultRelInfo;
map = mtstate->mt_partition_tupconv_maps[leaf_part_index];
if (map)
{
- Relation partrel = resultRelInfo->ri_RelationDesc;
+ Relation partrel = resultRelInfo->ri_RelationDesc;
tuple = do_convert_tuple(tuple, map);
/*
- * We must use the partition's tuple descriptor from this
- * point on, until we're finished dealing with the partition.
- * Use the dedicated slot for that.
+ * We must use the partition's tuple descriptor from this point
+ * on, until we're finished dealing with the partition. Use the
+ * dedicated slot for that.
*/
slot = mtstate->mt_partition_tuple_slot;
Assert(slot != NULL);
if (operation == CMD_INSERT &&
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
- PartitionDispatch *partition_dispatch_info;
- ResultRelInfo *partitions;
+ PartitionDispatch *partition_dispatch_info;
+ ResultRelInfo *partitions;
TupleConversionMap **partition_tupconv_maps;
- TupleTableSlot *partition_tuple_slot;
- int num_parted,
- num_partitions;
+ TupleTableSlot *partition_tuple_slot;
+ int num_parted,
+ num_partitions;
ExecSetupPartitionTupleRouting(rel,
&partition_dispatch_info,
{
TupleTableSlot *slot;
ExprContext *econtext;
- List *returningList;
+ List *returningList;
/*
* Initialize result tuple slot and assign its rowtype using the first
/*
* Build a projection for each leaf partition rel. Note that we
* didn't build the returningList for each partition within the
- * planner, but simple translation of the varattnos for each
- * partition will suffice. This only occurs for the INSERT case;
- * UPDATE/DELETE are handled above.
+ * planner, but simple translation of the varattnos for each partition
+ * will suffice. This only occurs for the INSERT case; UPDATE/DELETE
+ * are handled above.
*/
resultRelInfo = mtstate->mt_partitions;
returningList = linitial(node->returningLists);
resultRelInfo);
}
- /* Close all the partitioned tables, leaf partitions, and their indices
+ /*
+ * Close all the partitioned tables, leaf partitions, and their indices
*
* Remember node->mt_partition_dispatch_info[0] corresponds to the root
* partitioned table, which we must not try to close, because it is the
Oid relid = PG_GETARG_OID(0);
PG_RETURN_TEXT_P(string_to_text(pg_get_partkeydef_worker(relid,
- PRETTYFLAG_INDENT)));
+ PRETTYFLAG_INDENT)));
}
/*
static char *
pg_get_partkeydef_worker(Oid relid, int prettyFlags)
{
- Form_pg_partitioned_table form;
+ Form_pg_partitioned_table form;
HeapTuple tuple;
oidvector *partclass;
oidvector *partcollation;
/*
* Get the expressions, if any. (NOTE: we do not use the relcache
- * versions of the expressions, because we want to display non-const-folded
- * expressions.)
+ * versions of the expressions, because we want to display
+ * non-const-folded expressions.)
*/
if (!heap_attisnull(tuple, Anum_pg_partitioned_table_partexprs))
{
char *exprsString;
exprsDatum = SysCacheGetAttr(PARTRELID, tuple,
- Anum_pg_partitioned_table_partexprs, &isnull);
+ Anum_pg_partitioned_table_partexprs, &isnull);
Assert(!isnull);
exprsString = TextDatumGetCString(exprsDatum);
partexprs = (List *) stringToNode(exprsString);
if (!IsA(partexprs, List))
elog(ERROR, "unexpected node type found in partexprs: %d",
- (int) nodeTag(partexprs));
+ (int) nodeTag(partexprs));
pfree(exprsString);
}
break;
default:
elog(ERROR, "unexpected partition strategy: %d",
- (int) form->partstrat);
+ (int) form->partstrat);
}
appendStringInfo(&buf, " (");
case T_PartitionBoundSpec:
{
PartitionBoundSpec *spec = (PartitionBoundSpec *) node;
- ListCell *cell;
- char *sep;
+ ListCell *cell;
+ char *sep;
switch (spec->strategy)
{
appendStringInfoString(buf, "FOR VALUES");
appendStringInfoString(buf, " IN (");
sep = "";
- foreach (cell, spec->listdatums)
+ foreach(cell, spec->listdatums)
{
- Const *val = lfirst(cell);
+ Const *val = lfirst(cell);
appendStringInfoString(buf, sep);
get_const_expr(val, context, -1);
appendStringInfoString(buf, " FROM");
appendStringInfoString(buf, " (");
sep = "";
- foreach (cell, spec->lowerdatums)
+ foreach(cell, spec->lowerdatums)
{
PartitionRangeDatum *datum = lfirst(cell);
- Const *val;
+ Const *val;
appendStringInfoString(buf, sep);
if (datum->infinite)
appendStringInfoString(buf, " TO");
appendStringInfoString(buf, " (");
sep = "";
- foreach (cell, spec->upperdatums)
+ foreach(cell, spec->upperdatums)
{
PartitionRangeDatum *datum = lfirst(cell);
- Const *val;
+ Const *val;
appendStringInfoString(buf, sep);
if (datum->infinite)
/* pg_partitioned_table catalog manipulation functions */
extern void StorePartitionKey(Relation rel,
- char strategy,
- int16 partnatts,
- AttrNumber *partattrs,
- List *partexprs,
- Oid *partopclass,
- Oid *partcollation);
+ char strategy,
+ int16 partnatts,
+ AttrNumber *partattrs,
+ List *partexprs,
+ Oid *partopclass,
+ Oid *partcollation);
extern void RemovePartitionKeyByRelId(Oid relid);
extern void StorePartitionBound(Relation rel, Relation parent, Node *bound);
#define ReplicationOriginNameIndex 6002
DECLARE_UNIQUE_INDEX(pg_partitioned_table_partrelid_index, 3351, on pg_partitioned_table using btree(partrelid oid_ops));
-#define PartitionedRelidIndexId 3351
+#define PartitionedRelidIndexId 3351
DECLARE_UNIQUE_INDEX(pg_publication_oid_index, 6110, on pg_publication using btree(oid oid_ops));
#define PublicationObjectIndexId 6110
*/
typedef struct PartitionDescData
{
- int nparts; /* Number of partitions */
- Oid *oids; /* OIDs of partitions */
- PartitionBoundInfo boundinfo; /* collection of partition bounds */
+ int nparts; /* Number of partitions */
+ Oid *oids; /* OIDs of partitions */
+ PartitionBoundInfo boundinfo; /* collection of partition bounds */
} PartitionDescData;
typedef struct PartitionDescData *PartitionDesc;
*/
typedef struct PartitionDispatchData
{
- Relation reldesc;
- PartitionKey key;
- List *keystate; /* list of ExprState */
- PartitionDesc partdesc;
- TupleTableSlot *tupslot;
- TupleConversionMap *tupmap;
- int *indexes;
+ Relation reldesc;
+ PartitionKey key;
+ List *keystate; /* list of ExprState */
+ PartitionDesc partdesc;
+ TupleTableSlot *tupslot;
+ TupleConversionMap *tupmap;
+ int *indexes;
} PartitionDispatchData;
typedef struct PartitionDispatchData *PartitionDispatch;
PartitionBoundInfo p1, PartitionBoundInfo p2);
extern void check_new_partition_bound(char *relname, Relation parent, Node *bound);
-extern Oid get_partition_parent(Oid relid);
+extern Oid get_partition_parent(Oid relid);
extern List *get_qual_from_partbound(Relation rel, Relation parent, Node *bound);
extern List *map_partition_varattnos(List *expr, int target_varno,
Relation partrel, Relation parent);
int lockmode, int *num_parted,
List **leaf_part_oids);
extern int get_partition_for_tuple(PartitionDispatch *pd,
- TupleTableSlot *slot,
- EState *estate,
- Oid *failed_at);
+ TupleTableSlot *slot,
+ EState *estate,
+ Oid *failed_at);
#endif /* PARTITION_H */
* not */
bool relispopulated; /* matview currently holds query results */
char relreplident; /* see REPLICA_IDENTITY_xxx constants */
- bool relispartition; /* is relation a partition? */
+ bool relispartition; /* is relation a partition? */
TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */
TransactionId relminmxid; /* all multixacts in this rel are >= this.
* this is really a MultiXactId */
DESCR("role name by OID (with fallback)");
DATA(insert OID = 1643 ( pg_get_indexdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_indexdef _null_ _null_ _null_ ));
DESCR("index description");
-DATA(insert OID = 3352 ( pg_get_partkeydef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_partkeydef _null_ _null_ _null_ ));
+DATA(insert OID = 3352 ( pg_get_partkeydef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_partkeydef _null_ _null_ _null_ ));
DESCR("partition key description");
DATA(insert OID = 1662 ( pg_get_triggerdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_triggerdef _null_ _null_ _null_ ));
DESCR("trigger description");
List *attributeList,
List *exclusionOpNames);
extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
-extern Oid ResolveOpClass(List *opclass, Oid attrType,
+extern Oid ResolveOpClass(List *opclass, Oid attrType,
char *accessMethodName, Oid accessMethodId);
/* commands/functioncmds.c */
typedef struct PartitionElem
{
NodeTag type;
- char *name; /* name of column to partition on, or NULL */
- Node *expr; /* expression to partition on, or NULL */
- List *collation; /* name of collation; NIL = default */
- List *opclass; /* name of desired opclass; NIL = default */
- int location; /* token location, or -1 if unknown */
+ char *name; /* name of column to partition on, or NULL */
+ Node *expr; /* expression to partition on, or NULL */
+ List *collation; /* name of collation; NIL = default */
+ List *opclass; /* name of desired opclass; NIL = default */
+ int location; /* token location, or -1 if unknown */
} PartitionElem;
/*
typedef struct PartitionSpec
{
NodeTag type;
- char *strategy; /* partitioning strategy ('list' or 'range') */
- List *partParams; /* List of PartitionElems */
- int location; /* token location, or -1 if unknown */
+ char *strategy; /* partitioning strategy ('list' or 'range') */
+ List *partParams; /* List of PartitionElems */
+ int location; /* token location, or -1 if unknown */
} PartitionSpec;
#define PARTITION_STRATEGY_LIST 'l'
List *listdatums;
/*
- * Range partition lower and upper bounds; each member of the lists
- * is a PartitionRangeDatum (see below).
+ * Range partition lower and upper bounds; each member of the lists is a
+ * PartitionRangeDatum (see below).
*/
List *lowerdatums;
List *upperdatums;
List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */
bool rd_fkeyvalid; /* true if list has been computed */
- MemoryContext rd_partkeycxt; /* private memory cxt for the below */
- struct PartitionKeyData *rd_partkey; /* partition key, or NULL */
- MemoryContext rd_pdcxt; /* private context for partdesc */
- struct PartitionDescData *rd_partdesc; /* partitions, or NULL */
- List *rd_partcheck; /* partition CHECK quals */
+ MemoryContext rd_partkeycxt; /* private memory cxt for the below */
+ struct PartitionKeyData *rd_partkey; /* partition key, or NULL */
+ MemoryContext rd_pdcxt; /* private context for partdesc */
+ struct PartitionDescData *rd_partdesc; /* partitions, or NULL */
+ List *rd_partcheck; /* partition CHECK quals */
/* data managed by RelationGetIndexList: */
List *rd_indexlist; /* list of OIDs of indexes on relation */