diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index b9781eb3b95..1dbf0ffff9e 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -5641,7 +5641,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) /* Create state for FOR PORTION OF operation */ fpoState = makeNode(ForPortionOfState); - fpoState->fp_rangeName = forPortionOf->range_name; fpoState->fp_rangeType = forPortionOf->rangeType; fpoState->fp_rangeAttno = forPortionOf->rangeVar->varattno; fpoState->fp_targetRange = targetRange; @@ -5928,7 +5927,6 @@ ExecInitForPortionOf(ModifyTableState *mtstate, EState *estate, leafState = makeNode(ForPortionOfState); - leafState->fp_rangeName = fpoState->fp_rangeName; leafState->fp_rangeType = fpoState->fp_rangeType; leafState->fp_targetRange = fpoState->fp_targetRange; map = ExecGetChildToRootMap(resultRelInfo); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 3225185d16f..a0ff9159ae0 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -871,7 +871,9 @@ subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot use generated column \"%s\" in FOR PORTION OF", - forPortionOf->range_name))); + get_attname(rte->relid, + forPortionOf->rangeVar->varattno, + false)))); } /* diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 562e4facd74..581457c69c9 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -1606,7 +1606,6 @@ transformForPortionOfClause(ParseState *pstate, else result->rangeTargetList = NIL; - result->range_name = forPortionOf->range_name; result->location = forPortionOf->location; result->targetLocation = forPortionOf->target_location; diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 043e43b6309..908134594cb 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -527,6 +527,7 @@ static void get_rte_alias(RangeTblEntry *rte, int varno, bool use_as, static void get_column_alias_list(deparse_columns *colinfo, deparse_context *context); static void get_for_portion_of(ForPortionOfExpr *forPortionOf, + RangeTblEntry *rte, deparse_context *context); static void get_from_clause_coldeflist(RangeTblFunction *rtfunc, deparse_columns *colinfo, @@ -7556,7 +7557,7 @@ get_update_query_def(Query *query, deparse_context *context) generate_relation_name(rte->relid, NIL)); /* Print the FOR PORTION OF, if needed */ - get_for_portion_of(query->forPortionOf, context); + get_for_portion_of(query->forPortionOf, rte, context); /* Print the relation alias, if needed */ get_rte_alias(rte, query->resultRelation, false, context); @@ -7763,7 +7764,7 @@ get_delete_query_def(Query *query, deparse_context *context) generate_relation_name(rte->relid, NIL)); /* Print the FOR PORTION OF, if needed */ - get_for_portion_of(query->forPortionOf, context); + get_for_portion_of(query->forPortionOf, rte, context); /* Print the relation alias, if needed */ get_rte_alias(rte, query->resultRelation, false, context); @@ -13479,12 +13480,18 @@ get_rte_alias(RangeTblEntry *rte, int varno, bool use_as, * alias and SET will be on their own line with a leading space. */ static void -get_for_portion_of(ForPortionOfExpr *forPortionOf, deparse_context *context) +get_for_portion_of(ForPortionOfExpr *forPortionOf, RangeTblEntry *rte, + deparse_context *context) { if (forPortionOf) { + char *range_name; + + range_name = get_attname(rte->relid, + forPortionOf->rangeVar->varattno, + false); appendStringInfo(context->buf, " FOR PORTION OF %s", - quote_identifier(forPortionOf->range_name)); + quote_identifier(range_name)); /* * Try to write it as FROM ... TO ... if we received it that way, diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 83d462f4d4a..f20ea73ed39 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202607271 +#define CATALOG_VERSION_NO 202607273 #endif diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index e64fd8c7ea3..e95ac3eda35 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -476,7 +476,6 @@ typedef struct ForPortionOfState { NodeTag type; - char *fp_rangeName; /* the column named in FOR PORTION OF */ Oid fp_rangeType; /* the base type (not domain) of the FOR * PORTION OF expression */ int fp_rangeAttno; /* the attno of the range column */ diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 1f712666511..44f828cbb37 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -2438,7 +2438,6 @@ typedef struct ForPortionOfExpr { NodeTag type; Var *rangeVar; /* Range column */ - char *range_name; /* Range name */ Node *targetFrom; /* FOR PORTION OF FROM bound, if given */ Node *targetTo; /* FOR PORTION OF TO bound, if given */ Node *targetRange; /* FOR PORTION OF bounds as a range/multirange */ diff --git a/src/test/regress/expected/for_portion_of.out b/src/test/regress/expected/for_portion_of.out index 0e217f104ef..3c592f90e70 100644 --- a/src/test/regress/expected/for_portion_of.out +++ b/src/test/regress/expected/for_portion_of.out @@ -2255,6 +2255,39 @@ SELECT * FROM fpo_rule ORDER BY f1; (2 rows) DROP TABLE fpo_rule; +-- Deparsing FOR PORTION OF must use the range column's current name, +-- not the name it had when the rule was created. +CREATE TABLE fpo_rename (f1 bigint, f2 int4range); +CREATE TABLE fpo_rename_src (x int); +CREATE RULE fpo_rename_rule1 AS ON UPDATE TO fpo_rename_src + DO INSTEAD UPDATE fpo_rename FOR PORTION OF f2 FROM 3 TO 6 SET f1 = 2; +CREATE RULE fpo_rename_rule2 AS ON DELETE TO fpo_rename_src + DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF f2 (int4range(3, 6)); +\d+ fpo_rename_src + Table "public.fpo_rename_src" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + x | integer | | | | plain | | +Rules: + fpo_rename_rule1 AS + ON UPDATE TO fpo_rename_src DO INSTEAD UPDATE fpo_rename FOR PORTION OF f2 FROM 3 TO 6 SET f1 = 2 + fpo_rename_rule2 AS + ON DELETE TO fpo_rename_src DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF f2 (int4range(3, 6)) + +ALTER TABLE fpo_rename RENAME COLUMN f1 TO ff1; +ALTER TABLE fpo_rename RENAME COLUMN f2 TO ff2; +\d+ fpo_rename_src + Table "public.fpo_rename_src" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + x | integer | | | | plain | | +Rules: + fpo_rename_rule1 AS + ON UPDATE TO fpo_rename_src DO INSTEAD UPDATE fpo_rename FOR PORTION OF ff2 FROM 3 TO 6 SET ff1 = 2 + fpo_rename_rule2 AS + ON DELETE TO fpo_rename_src DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF ff2 (int4range(3, 6)) + +DROP TABLE fpo_rename, fpo_rename_src; -- UPDATE/DELETE FOR PORTION OF on a GENERATED VIRTUAL range column: CREATE TABLE fpo_gen_virtual ( a int, diff --git a/src/test/regress/sql/for_portion_of.sql b/src/test/regress/sql/for_portion_of.sql index a8d29a76b22..5f7b04fdf6b 100644 --- a/src/test/regress/sql/for_portion_of.sql +++ b/src/test/regress/sql/for_portion_of.sql @@ -1495,6 +1495,22 @@ SELECT * FROM fpo_rule ORDER BY f1; DROP TABLE fpo_rule; +-- Deparsing FOR PORTION OF must use the range column's current name, +-- not the name it had when the rule was created. +CREATE TABLE fpo_rename (f1 bigint, f2 int4range); +CREATE TABLE fpo_rename_src (x int); +CREATE RULE fpo_rename_rule1 AS ON UPDATE TO fpo_rename_src + DO INSTEAD UPDATE fpo_rename FOR PORTION OF f2 FROM 3 TO 6 SET f1 = 2; +CREATE RULE fpo_rename_rule2 AS ON DELETE TO fpo_rename_src + DO INSTEAD DELETE FROM fpo_rename FOR PORTION OF f2 (int4range(3, 6)); + +\d+ fpo_rename_src +ALTER TABLE fpo_rename RENAME COLUMN f1 TO ff1; +ALTER TABLE fpo_rename RENAME COLUMN f2 TO ff2; +\d+ fpo_rename_src + +DROP TABLE fpo_rename, fpo_rename_src; + -- UPDATE/DELETE FOR PORTION OF on a GENERATED VIRTUAL range column: CREATE TABLE fpo_gen_virtual ( a int,