Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf7b4190

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 needto attach nondefault column aliases, because there's noplace to do thatin the minimal VALUES() syntax. So modify get_simple_values_rte() todetect nondefault aliases and treat that as a non-simple case. Thisfurther exposes that the "non-simple" path never actually worked;it didn't produce valid syntax. Fix that too. Per bug #12789 fromCurtis McEnroe, and analysis by Andrew Gierth.Back-patch to all supported branches. Before 9.3, this also requiresback-patching the part of commit092d7dethat created get_simple_values_rte() to begin with; inserting the extratest into the old factorization of that logic would've been too messy.
1 parent25576be commitf7b4190

File tree

3 files changed

+144
-15
lines changed

3 files changed

+144
-15
lines changed

‎src/backend/utils/adt/ruleutils.c

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,11 +2878,72 @@ get_select_query_def(Query *query, deparse_context *context,
28782878
context->windowTList=save_windowtlist;
28792879
}
28802880

2881+
/*
2882+
* Detect whether query looks like SELECT ... FROM VALUES();
2883+
* if so, return the VALUES RTE. Otherwise return NULL.
2884+
*/
2885+
staticRangeTblEntry*
2886+
get_simple_values_rte(Query*query)
2887+
{
2888+
RangeTblEntry*result=NULL;
2889+
ListCell*lc;
2890+
2891+
/*
2892+
* We want to return TRUE even if the Query also contains OLD or NEW rule
2893+
* RTEs. So the idea is to scan the rtable and see if there is only one
2894+
* inFromCl RTE that is a VALUES RTE.
2895+
*/
2896+
foreach(lc,query->rtable)
2897+
{
2898+
RangeTblEntry*rte= (RangeTblEntry*)lfirst(lc);
2899+
2900+
if (rte->rtekind==RTE_VALUES&&rte->inFromCl)
2901+
{
2902+
if (result)
2903+
returnNULL;/* multiple VALUES (probably not possible) */
2904+
result=rte;
2905+
}
2906+
elseif (rte->rtekind==RTE_RELATION&& !rte->inFromCl)
2907+
continue;/* ignore rule entries */
2908+
else
2909+
returnNULL;/* something else -> not simple VALUES */
2910+
}
2911+
2912+
/*
2913+
* We don't need to check the targetlist in any great detail, because
2914+
* parser/analyze.c will never generate a "bare" VALUES RTE --- they only
2915+
* appear inside auto-generated sub-queries with very restricted
2916+
* structure. However, DefineView might have modified the tlist by
2917+
* injecting new column aliases; so compare tlist resnames against the
2918+
* RTE's names to detect that.
2919+
*/
2920+
if (result)
2921+
{
2922+
ListCell*lcn;
2923+
2924+
if (list_length(query->targetList)!=list_length(result->eref->colnames))
2925+
returnNULL;/* this probably cannot happen */
2926+
forboth(lc,query->targetList,lcn,result->eref->colnames)
2927+
{
2928+
TargetEntry*tle= (TargetEntry*)lfirst(lc);
2929+
char*cname=strVal(lfirst(lcn));
2930+
2931+
if (tle->resjunk)
2932+
returnNULL;/* this probably cannot happen */
2933+
if (tle->resname==NULL||strcmp(tle->resname,cname)!=0)
2934+
returnNULL;/* column name has been changed */
2935+
}
2936+
}
2937+
2938+
returnresult;
2939+
}
2940+
28812941
staticvoid
28822942
get_basic_select_query(Query*query,deparse_context*context,
28832943
TupleDescresultDesc)
28842944
{
28852945
StringInfobuf=context->buf;
2946+
RangeTblEntry*values_rte;
28862947
char*sep;
28872948
ListCell*l;
28882949

@@ -2895,23 +2956,13 @@ get_basic_select_query(Query *query, deparse_context *context,
28952956
/*
28962957
* If the query looks like SELECT * FROM (VALUES ...), then print just the
28972958
* VALUES part. This reverses what transformValuesClause() did at parse
2898-
* time. If the jointree contains just a single VALUES RTE, we assume
2899-
* this case applies (without looking at the targetlist...)
2959+
* time.
29002960
*/
2901-
if (list_length(query->jointree->fromlist)==1)
2961+
values_rte=get_simple_values_rte(query);
2962+
if (values_rte)
29022963
{
2903-
RangeTblRef*rtr= (RangeTblRef*)linitial(query->jointree->fromlist);
2904-
2905-
if (IsA(rtr,RangeTblRef))
2906-
{
2907-
RangeTblEntry*rte=rt_fetch(rtr->rtindex,query->rtable);
2908-
2909-
if (rte->rtekind==RTE_VALUES)
2910-
{
2911-
get_values_def(rte->values_lists,context);
2912-
return;
2913-
}
2914-
}
2964+
get_values_def(values_rte->values_lists,context);
2965+
return;
29152966
}
29162967

29172968
/*
@@ -6474,7 +6525,9 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
64746525
break;
64756526
caseRTE_VALUES:
64766527
/* Values list RTE */
6528+
appendStringInfoChar(buf,'(');
64776529
get_values_def(rte->values_lists,context);
6530+
appendStringInfoChar(buf,')');
64786531
break;
64796532
caseRTE_CTE:
64806533
appendStringInfoString(buf,quote_identifier(rte->ctename));
@@ -6514,6 +6567,13 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
65146567
quote_identifier(rte->eref->aliasname));
65156568
gavealias= true;
65166569
}
6570+
elseif (rte->rtekind==RTE_VALUES)
6571+
{
6572+
/* Alias is syntactically required for VALUES */
6573+
appendStringInfo(buf," %s",
6574+
quote_identifier(rte->eref->aliasname));
6575+
gavealias= true;
6576+
}
65176577

65186578
if (rte->rtekind==RTE_FUNCTION)
65196579
{

‎src/test/regress/expected/rules.out

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,3 +1590,54 @@ select * from only t1_2;
15901590
19
15911591
(10 rows)
15921592

1593+
reset constraint_exclusion;
1594+
--
1595+
-- check display of VALUES in view definitions
1596+
--
1597+
create view rule_v1 as values(1,2);
1598+
\d+ rule_v1
1599+
View "public.rule_v1"
1600+
Column | Type | Modifiers | Storage | Description
1601+
---------+---------+-----------+---------+-------------
1602+
column1 | integer | | plain |
1603+
column2 | integer | | plain |
1604+
View definition:
1605+
VALUES (1,2);
1606+
1607+
drop view rule_v1;
1608+
create view rule_v1(x) as values(1,2);
1609+
\d+ rule_v1
1610+
View "public.rule_v1"
1611+
Column | Type | Modifiers | Storage | Description
1612+
---------+---------+-----------+---------+-------------
1613+
x | integer | | plain |
1614+
column2 | integer | | plain |
1615+
View definition:
1616+
SELECT "*VALUES*".column1 AS x, "*VALUES*".column2
1617+
FROM (VALUES (1,2)) "*VALUES*";
1618+
1619+
drop view rule_v1;
1620+
create view rule_v1(x) as select * from (values(1,2)) v;
1621+
\d+ rule_v1
1622+
View "public.rule_v1"
1623+
Column | Type | Modifiers | Storage | Description
1624+
---------+---------+-----------+---------+-------------
1625+
x | integer | | plain |
1626+
column2 | integer | | plain |
1627+
View definition:
1628+
SELECT v.column1 AS x, v.column2
1629+
FROM ( VALUES (1,2)) v;
1630+
1631+
drop view rule_v1;
1632+
create view rule_v1(x) as select * from (values(1,2)) v(q,w);
1633+
\d+ rule_v1
1634+
View "public.rule_v1"
1635+
Column | Type | Modifiers | Storage | Description
1636+
--------+---------+-----------+---------+-------------
1637+
x | integer | | plain |
1638+
w | integer | | plain |
1639+
View definition:
1640+
SELECT v.q AS x, v.w
1641+
FROM ( VALUES (1,2)) v(q, w);
1642+
1643+
drop view rule_v1;

‎src/test/regress/sql/rules.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,3 +942,21 @@ update t1 set a = 4 where a = 5;
942942
select*from only t1;
943943
select*from only t1_1;
944944
select*from only t1_2;
945+
946+
reset constraint_exclusion;
947+
948+
--
949+
-- check display of VALUES in view definitions
950+
--
951+
createviewrule_v1asvalues(1,2);
952+
\d+ rule_v1
953+
dropview rule_v1;
954+
createviewrule_v1(x)asvalues(1,2);
955+
\d+ rule_v1
956+
dropview rule_v1;
957+
createviewrule_v1(x)asselect*from (values(1,2)) v;
958+
\d+ rule_v1
959+
dropview rule_v1;
960+
createviewrule_v1(x)asselect*from (values(1,2)) v(q,w);
961+
\d+ rule_v1
962+
dropview rule_v1;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp