Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 2164a0d

Browse files
committed
Fix dumping of views that are just VALUES(...) but have column aliases.
The "simple" path for printing VALUES clauses doesn't work if we need to attach nondefault column aliases, because there's noplace to do that in the minimal VALUES() syntax. So modify get_simple_values_rte() to detect nondefault aliases and treat that as a non-simple case. This further exposes that the "non-simple" path never actually worked; it didn't produce valid syntax. Fix that too. Per bug #12789 from Curtis McEnroe, and analysis by Andrew Gierth. Back-patch to all supported branches. Before 9.3, this also requires back-patching the part of commit 092d7de that created get_simple_values_rte() to begin with; inserting the extra test into the old factorization of that logic would've been too messy.
1 parent 89629f2 commit 2164a0d

File tree

3 files changed

+104
-4
lines changed

3 files changed

+104
-4
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4495,10 +4495,7 @@ get_simple_values_rte(Query *query)
44954495
/*
44964496
* We want to return TRUE even if the Query also contains OLD or NEW rule
44974497
* RTEs. So the idea is to scan the rtable and see if there is only one
4498-
* inFromCl RTE that is a VALUES RTE. We don't look at the targetlist at
4499-
* all. This is okay because parser/analyze.c will never generate a
4500-
* "bare" VALUES RTE --- they only appear inside auto-generated
4501-
* sub-queries with very restricted structure.
4498+
* inFromCl RTE that is a VALUES RTE.
45024499
*/
45034500
foreach(lc, query->rtable)
45044501
{
@@ -4515,6 +4512,33 @@ get_simple_values_rte(Query *query)
45154512
else
45164513
return NULL; /* something else -> not simple VALUES */
45174514
}
4515+
4516+
/*
4517+
* We don't need to check the targetlist in any great detail, because
4518+
* parser/analyze.c will never generate a "bare" VALUES RTE --- they only
4519+
* appear inside auto-generated sub-queries with very restricted
4520+
* structure. However, DefineView might have modified the tlist by
4521+
* injecting new column aliases; so compare tlist resnames against the
4522+
* RTE's names to detect that.
4523+
*/
4524+
if (result)
4525+
{
4526+
ListCell *lcn;
4527+
4528+
if (list_length(query->targetList) != list_length(result->eref->colnames))
4529+
return NULL; /* this probably cannot happen */
4530+
forboth(lc, query->targetList, lcn, result->eref->colnames)
4531+
{
4532+
TargetEntry *tle = (TargetEntry *) lfirst(lc);
4533+
char *cname = strVal(lfirst(lcn));
4534+
4535+
if (tle->resjunk)
4536+
return NULL; /* this probably cannot happen */
4537+
if (tle->resname == NULL || strcmp(tle->resname, cname) != 0)
4538+
return NULL; /* column name has been changed */
4539+
}
4540+
}
4541+
45184542
return result;
45194543
}
45204544

@@ -8419,7 +8443,9 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
84198443
break;
84208444
case RTE_VALUES:
84218445
/* Values list RTE */
8446+
appendStringInfoChar(buf, '(');
84228447
get_values_def(rte->values_lists, context);
8448+
appendStringInfoChar(buf, ')');
84238449
break;
84248450
case RTE_CTE:
84258451
appendStringInfoString(buf, quote_identifier(rte->ctename));
@@ -8461,6 +8487,11 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
84618487
*/
84628488
printalias = true;
84638489
}
8490+
else if (rte->rtekind == RTE_VALUES)
8491+
{
8492+
/* Alias is syntactically required for VALUES */
8493+
printalias = true;
8494+
}
84648495
else if (rte->rtekind == RTE_CTE)
84658496
{
84668497
/*

src/test/regress/expected/rules.out

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,3 +2651,56 @@ ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc; -- ON SELECT rule cannot be renam
26512651
ERROR: renaming an ON SELECT rule is not allowed
26522652
DROP VIEW rule_v1;
26532653
DROP TABLE rule_t1;
2654+
--
2655+
-- check display of VALUES in view definitions
2656+
--
2657+
create view rule_v1 as values(1,2);
2658+
\d+ rule_v1
2659+
View "public.rule_v1"
2660+
Column | Type | Modifiers | Storage | Description
2661+
---------+---------+-----------+---------+-------------
2662+
column1 | integer | | plain |
2663+
column2 | integer | | plain |
2664+
View definition:
2665+
VALUES (1,2);
2666+
2667+
drop view rule_v1;
2668+
create view rule_v1(x) as values(1,2);
2669+
\d+ rule_v1
2670+
View "public.rule_v1"
2671+
Column | Type | Modifiers | Storage | Description
2672+
---------+---------+-----------+---------+-------------
2673+
x | integer | | plain |
2674+
column2 | integer | | plain |
2675+
View definition:
2676+
SELECT "*VALUES*".column1 AS x,
2677+
"*VALUES*".column2
2678+
FROM (VALUES (1,2)) "*VALUES*";
2679+
2680+
drop view rule_v1;
2681+
create view rule_v1(x) as select * from (values(1,2)) v;
2682+
\d+ rule_v1
2683+
View "public.rule_v1"
2684+
Column | Type | Modifiers | Storage | Description
2685+
---------+---------+-----------+---------+-------------
2686+
x | integer | | plain |
2687+
column2 | integer | | plain |
2688+
View definition:
2689+
SELECT v.column1 AS x,
2690+
v.column2
2691+
FROM ( VALUES (1,2)) v;
2692+
2693+
drop view rule_v1;
2694+
create view rule_v1(x) as select * from (values(1,2)) v(q,w);
2695+
\d+ rule_v1
2696+
View "public.rule_v1"
2697+
Column | Type | Modifiers | Storage | Description
2698+
--------+---------+-----------+---------+-------------
2699+
x | integer | | plain |
2700+
w | integer | | plain |
2701+
View definition:
2702+
SELECT v.q AS x,
2703+
v.w
2704+
FROM ( VALUES (1,2)) v(q, w);
2705+
2706+
drop view rule_v1;

src/test/regress/sql/rules.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,3 +1007,19 @@ ALTER RULE "_RETURN" ON rule_v1 RENAME TO abc; -- ON SELECT rule cannot be renam
10071007

10081008
DROP VIEW rule_v1;
10091009
DROP TABLE rule_t1;
1010+
1011+
--
1012+
-- check display of VALUES in view definitions
1013+
--
1014+
create view rule_v1 as values(1,2);
1015+
\d+ rule_v1
1016+
drop view rule_v1;
1017+
create view rule_v1(x) as values(1,2);
1018+
\d+ rule_v1
1019+
drop view rule_v1;
1020+
create view rule_v1(x) as select * from (values(1,2)) v;
1021+
\d+ rule_v1
1022+
drop view rule_v1;
1023+
create view rule_v1(x) as select * from (values(1,2)) v(q,w);
1024+
\d+ rule_v1
1025+
drop view rule_v1;

0 commit comments

Comments
 (0)