diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/partition.c | 29 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 40 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 11 | ||||
-rw-r--r-- | src/backend/partitioning/partbounds.c | 4 | ||||
-rw-r--r-- | src/backend/utils/cache/partcache.c | 7 |
5 files changed, 26 insertions, 65 deletions
diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index 5f85b9b99ca..3c2bec25b9e 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -181,17 +181,14 @@ index_get_partition(Relation partition, Oid indexId) } /* - * map_partition_varattnos - maps varattno of any Vars in expr from the - * attno's of 'from_rel' to the attno's of 'to_rel' partition, each of which - * may be either a leaf partition or a partitioned table, but both of which - * must be from the same partitioning hierarchy. + * map_partition_varattnos - maps varattnos of all Vars in 'expr' (that have + * varno 'fromrel_varno') from the attnums of 'from_rel' to the attnums of + * 'to_rel', each of which may be either a leaf partition or a partitioned + * table, but both of which must be from the same partitioning hierarchy. * - * Even though all of the same column names must be present in all relations - * in the hierarchy, and they must also have the same types, the attnos may - * be different. - * - * If found_whole_row is not NULL, *found_whole_row returns whether a - * whole-row variable was found in the input expression. + * We need this because even though all of the same column names must be + * present in all relations in the hierarchy, and they must also have the + * same types, the attnums may be different. * * Note: this will work on any node tree, so really the argument and result * should be declared "Node *". But a substantial majority of the callers @@ -199,14 +196,12 @@ index_get_partition(Relation partition, Oid indexId) */ List * map_partition_varattnos(List *expr, int fromrel_varno, - Relation to_rel, Relation from_rel, - bool *found_whole_row) + Relation to_rel, Relation from_rel) { - bool my_found_whole_row = false; - if (expr != NIL) { AttrMap *part_attmap; + bool found_whole_row; part_attmap = build_attrmap_by_name(RelationGetDescr(to_rel), RelationGetDescr(from_rel)); @@ -214,12 +209,10 @@ map_partition_varattnos(List *expr, int fromrel_varno, fromrel_varno, 0, part_attmap, RelationGetForm(to_rel)->reltype, - &my_found_whole_row); + &found_whole_row); + /* Since we provided a to_rowtype, we may ignore found_whole_row. */ } - if (found_whole_row) - *found_whole_row = my_found_whole_row; - return expr; } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index a776e652f4b..e19772aa903 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15168,15 +15168,11 @@ ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNu */ /* - * Cannot have expressions containing whole-row references or - * system column references. + * Cannot allow system column references, since that would + * make partition routing impossible: their values won't be + * known yet when we need to do that. */ pull_varattnos(expr, 1, &expr_attrs); - if (bms_is_member(0 - FirstLowInvalidHeapAttributeNumber, - expr_attrs)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("partition key expressions cannot contain whole-row references"))); for (i = FirstLowInvalidHeapAttributeNumber; i < 0; i++) { if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber, @@ -15196,7 +15192,8 @@ ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNu { AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; - if (TupleDescAttr(RelationGetDescr(rel), attno - 1)->attgenerated) + if (attno > 0 && + TupleDescAttr(RelationGetDescr(rel), attno - 1)->attgenerated) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("cannot use generated column in partition key"), @@ -15451,7 +15448,6 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, for (i = 0; i < partdesc->nparts; i++) { Relation part_rel; - bool found_whole_row; List *thisPartConstraint; /* @@ -15465,10 +15461,7 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, */ thisPartConstraint = map_partition_varattnos(partConstraint, 1, - part_rel, scanrel, &found_whole_row); - /* There can never be a whole-row reference here */ - if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in partition constraint"); + part_rel, scanrel); QueuePartitionConstraintValidation(wqueue, part_rel, thisPartConstraint, @@ -15497,7 +15490,6 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) TupleDesc tupleDesc; ObjectAddress address; const char *trigger_name; - bool found_whole_row; Oid defaultPartOid; List *partBoundConstraint; @@ -15714,11 +15706,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) * numbers. */ partConstraint = map_partition_varattnos(partConstraint, 1, attachrel, - rel, &found_whole_row); - /* There can never be a whole-row reference here */ - if (found_whole_row) - elog(ERROR, - "unexpected whole-row reference found in partition key"); + rel); /* Validate partition constraints against the table being attached. */ QueuePartitionConstraintValidation(wqueue, attachrel, partConstraint, @@ -15750,7 +15738,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) */ defPartConstraint = map_partition_varattnos(defPartConstraint, - 1, defaultrel, rel, NULL); + 1, defaultrel, rel); QueuePartitionConstraintValidation(wqueue, defaultrel, defPartConstraint, true); @@ -16004,19 +15992,11 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) RelationGetDescr(pg_trigger), &isnull); if (!isnull) { - bool found_whole_row; - qual = stringToNode(TextDatumGetCString(value)); qual = (Node *) map_partition_varattnos((List *) qual, PRS2_OLD_VARNO, - partition, parent, - &found_whole_row); - if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in trigger WHEN clause"); + partition, parent); qual = (Node *) map_partition_varattnos((List *) qual, PRS2_NEW_VARNO, - partition, parent, - &found_whole_row); - if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in trigger WHEN clause"); + partition, parent); } /* diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 7e9bcb317d5..b9fca3af3c7 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -1144,7 +1144,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, CreateTrigStmt *childStmt; Relation childTbl; Node *qual; - bool found_whole_row; childTbl = table_open(partdesc->oids[i], ShareRowExclusiveLock); @@ -1177,16 +1176,10 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, qual = copyObject(whenClause); qual = (Node *) map_partition_varattnos((List *) qual, PRS2_OLD_VARNO, - childTbl, rel, - &found_whole_row); - if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in trigger WHEN clause"); + childTbl, rel); qual = (Node *) map_partition_varattnos((List *) qual, PRS2_NEW_VARNO, - childTbl, rel, - &found_whole_row); - if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in trigger WHEN clause"); + childTbl, rel); CreateTrigger(childStmt, queryString, partdesc->oids[i], refRelOid, diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c index 4c6ca899fe8..4f7ac5bf829 100644 --- a/src/backend/partitioning/partbounds.c +++ b/src/backend/partitioning/partbounds.c @@ -1247,7 +1247,7 @@ check_default_partition_contents(Relation parent, Relation default_rel, */ def_part_constraints = map_partition_varattnos(def_part_constraints, 1, default_rel, - parent, NULL); + parent); /* * If the existing constraints on the default partition imply that it will @@ -1297,7 +1297,7 @@ check_default_partition_contents(Relation parent, Relation default_rel, partition_constraint = make_ands_explicit(def_part_constraints); partition_constraint = (Expr *) map_partition_varattnos((List *) partition_constraint, 1, - part_rel, default_rel, NULL); + part_rel, default_rel); /* * If the partition constraints on default partition child imply diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c index e2144c83aba..bf1754ea382 100644 --- a/src/backend/utils/cache/partcache.c +++ b/src/backend/utils/cache/partcache.c @@ -342,7 +342,6 @@ generate_partition_qual(Relation rel) List *my_qual = NIL, *result = NIL; Relation parent; - bool found_whole_row; /* Guard against stack overflow due to overly deep partition tree */ check_stack_depth(); @@ -388,11 +387,7 @@ generate_partition_qual(Relation rel) * in it to bear this relation's attnos. It's safe to assume varno = 1 * here. */ - result = map_partition_varattnos(result, 1, rel, parent, - &found_whole_row); - /* There can never be a whole-row reference here */ - if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in partition key"); + result = map_partition_varattnos(result, 1, rel, parent); /* Assert that we're not leaking any old data during assignments below */ Assert(rel->rd_partcheckcxt == NULL); |