aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/utils/adt/ruleutils.c34
-rw-r--r--src/test/regress/expected/rules.out12
-rw-r--r--src/test/regress/sql/rules.sql2
3 files changed, 38 insertions, 10 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 4c83cae5e92..13685a0a0e4 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -5370,19 +5370,20 @@ get_select_query_def(Query *query, deparse_context *context,
}
/*
- * Detect whether query looks like SELECT ... FROM VALUES();
- * if so, return the VALUES RTE. Otherwise return NULL.
+ * Detect whether query looks like SELECT ... FROM VALUES(),
+ * with no need to rename the output columns of the VALUES RTE.
+ * If so, return the VALUES RTE. Otherwise return NULL.
*/
static RangeTblEntry *
-get_simple_values_rte(Query *query)
+get_simple_values_rte(Query *query, TupleDesc resultDesc)
{
RangeTblEntry *result = NULL;
ListCell *lc;
/*
- * We want to return true even if the Query also contains OLD or NEW rule
- * RTEs. So the idea is to scan the rtable and see if there is only one
- * inFromCl RTE that is a VALUES RTE.
+ * We want to detect a match even if the Query also contains OLD or NEW
+ * rule RTEs. So the idea is to scan the rtable and see if there is only
+ * one inFromCl RTE that is a VALUES RTE.
*/
foreach(lc, query->rtable)
{
@@ -5405,23 +5406,36 @@ get_simple_values_rte(Query *query)
* parser/analyze.c will never generate a "bare" VALUES RTE --- they only
* appear inside auto-generated sub-queries with very restricted
* structure. However, DefineView might have modified the tlist by
- * injecting new column aliases; so compare tlist resnames against the
- * RTE's names to detect that.
+ * injecting new column aliases, or we might have some other column
+ * aliases forced by a resultDesc. We can only simplify if the RTE's
+ * column names match the names that get_target_list() would select.
*/
if (result)
{
ListCell *lcn;
+ int colno;
if (list_length(query->targetList) != list_length(result->eref->colnames))
return NULL; /* this probably cannot happen */
+ colno = 0;
forboth(lc, query->targetList, lcn, result->eref->colnames)
{
TargetEntry *tle = (TargetEntry *) lfirst(lc);
char *cname = strVal(lfirst(lcn));
+ char *colname;
if (tle->resjunk)
return NULL; /* this probably cannot happen */
- if (tle->resname == NULL || strcmp(tle->resname, cname) != 0)
+
+ /* compute name that get_target_list would use for column */
+ colno++;
+ if (resultDesc && colno <= resultDesc->natts)
+ colname = NameStr(TupleDescAttr(resultDesc, colno - 1)->attname);
+ else
+ colname = tle->resname;
+
+ /* does it match the VALUES RTE? */
+ if (colname == NULL || strcmp(colname, cname) != 0)
return NULL; /* column name has been changed */
}
}
@@ -5449,7 +5463,7 @@ get_basic_select_query(Query *query, deparse_context *context,
* VALUES part. This reverses what transformValuesClause() did at parse
* time.
*/
- values_rte = get_simple_values_rte(query);
+ values_rte = get_simple_values_rte(query, resultDesc);
if (values_rte)
{
get_values_def(values_rte->values_lists, context);
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 14e72143468..abe3a43cd27 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -3025,6 +3025,18 @@ create view rule_v1 as values(1,2);
View definition:
VALUES (1,2);
+alter table rule_v1 rename column column2 to q2;
+\d+ rule_v1
+ View "public.rule_v1"
+ Column | Type | Collation | Nullable | Default | Storage | Description
+---------+---------+-----------+----------+---------+---------+-------------
+ column1 | integer | | | | plain |
+ q2 | integer | | | | plain |
+View definition:
+ SELECT "*VALUES*".column1,
+ "*VALUES*".column2 AS q2
+ FROM (VALUES (1,2)) "*VALUES*";
+
drop view rule_v1;
create view rule_v1(x) as values(1,2);
\d+ rule_v1
diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql
index a042e595469..b7d7f434b6a 100644
--- a/src/test/regress/sql/rules.sql
+++ b/src/test/regress/sql/rules.sql
@@ -1047,6 +1047,8 @@ DROP TABLE rule_t1;
--
create view rule_v1 as values(1,2);
\d+ rule_v1
+alter table rule_v1 rename column column2 to q2;
+\d+ rule_v1
drop view rule_v1;
create view rule_v1(x) as values(1,2);
\d+ rule_v1