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

Commitbe8801e

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 parentc76e6dd commitbe8801e

File tree

3 files changed

+141
-15
lines changed

3 files changed

+141
-15
lines changed

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

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

2936+
/*
2937+
* Detect whether query looks like SELECT ... FROM VALUES();
2938+
* if so, return the VALUES RTE. Otherwise return NULL.
2939+
*/
2940+
staticRangeTblEntry*
2941+
get_simple_values_rte(Query*query)
2942+
{
2943+
RangeTblEntry*result=NULL;
2944+
ListCell*lc;
2945+
2946+
/*
2947+
* We want to return TRUE even if the Query also contains OLD or NEW rule
2948+
* RTEs. So the idea is to scan the rtable and see if there is only one
2949+
* inFromCl RTE that is a VALUES RTE.
2950+
*/
2951+
foreach(lc,query->rtable)
2952+
{
2953+
RangeTblEntry*rte= (RangeTblEntry*)lfirst(lc);
2954+
2955+
if (rte->rtekind==RTE_VALUES&&rte->inFromCl)
2956+
{
2957+
if (result)
2958+
returnNULL;/* multiple VALUES (probably not possible) */
2959+
result=rte;
2960+
}
2961+
elseif (rte->rtekind==RTE_RELATION&& !rte->inFromCl)
2962+
continue;/* ignore rule entries */
2963+
else
2964+
returnNULL;/* something else -> not simple VALUES */
2965+
}
2966+
2967+
/*
2968+
* We don't need to check the targetlist in any great detail, because
2969+
* parser/analyze.c will never generate a "bare" VALUES RTE --- they only
2970+
* appear inside auto-generated sub-queries with very restricted
2971+
* structure. However, DefineView might have modified the tlist by
2972+
* injecting new column aliases; so compare tlist resnames against the
2973+
* RTE's names to detect that.
2974+
*/
2975+
if (result)
2976+
{
2977+
ListCell*lcn;
2978+
2979+
if (list_length(query->targetList)!=list_length(result->eref->colnames))
2980+
returnNULL;/* this probably cannot happen */
2981+
forboth(lc,query->targetList,lcn,result->eref->colnames)
2982+
{
2983+
TargetEntry*tle= (TargetEntry*)lfirst(lc);
2984+
char*cname=strVal(lfirst(lcn));
2985+
2986+
if (tle->resjunk)
2987+
returnNULL;/* this probably cannot happen */
2988+
if (tle->resname==NULL||strcmp(tle->resname,cname)!=0)
2989+
returnNULL;/* column name has been changed */
2990+
}
2991+
}
2992+
2993+
returnresult;
2994+
}
2995+
29362996
staticvoid
29372997
get_basic_select_query(Query*query,deparse_context*context,
29382998
TupleDescresultDesc)
29392999
{
29403000
StringInfobuf=context->buf;
3001+
RangeTblEntry*values_rte;
29413002
char*sep;
29423003
ListCell*l;
29433004

@@ -2950,23 +3011,13 @@ get_basic_select_query(Query *query, deparse_context *context,
29503011
/*
29513012
* If the query looks like SELECT * FROM (VALUES ...), then print just the
29523013
* VALUES part. This reverses what transformValuesClause() did at parse
2953-
* time. If the jointree contains just a single VALUES RTE, we assume
2954-
* this case applies (without looking at the targetlist...)
3014+
* time.
29553015
*/
2956-
if (list_length(query->jointree->fromlist)==1)
3016+
values_rte=get_simple_values_rte(query);
3017+
if (values_rte)
29573018
{
2958-
RangeTblRef*rtr= (RangeTblRef*)linitial(query->jointree->fromlist);
2959-
2960-
if (IsA(rtr,RangeTblRef))
2961-
{
2962-
RangeTblEntry*rte=rt_fetch(rtr->rtindex,query->rtable);
2963-
2964-
if (rte->rtekind==RTE_VALUES)
2965-
{
2966-
get_values_def(rte->values_lists,context);
2967-
return;
2968-
}
2969-
}
3019+
get_values_def(values_rte->values_lists,context);
3020+
return;
29703021
}
29713022

29723023
/*
@@ -6681,7 +6732,9 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
66816732
break;
66826733
caseRTE_VALUES:
66836734
/* Values list RTE */
6735+
appendStringInfoChar(buf,'(');
66846736
get_values_def(rte->values_lists,context);
6737+
appendStringInfoChar(buf,')');
66856738
break;
66866739
caseRTE_CTE:
66876740
appendStringInfoString(buf,quote_identifier(rte->ctename));
@@ -6721,6 +6774,13 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
67216774
quote_identifier(rte->eref->aliasname));
67226775
gavealias= true;
67236776
}
6777+
elseif (rte->rtekind==RTE_VALUES)
6778+
{
6779+
/* Alias is syntactically required for VALUES */
6780+
appendStringInfo(buf," %s",
6781+
quote_identifier(rte->eref->aliasname));
6782+
gavealias= true;
6783+
}
67246784

67256785
if (rte->rtekind==RTE_FUNCTION)
67266786
{

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,3 +1623,53 @@ select pg_get_viewdef('shoe'::regclass,0) as prettier;
16231623
WHERE sh.slunit = un.un_name;
16241624
(1 row)
16251625

1626+
--
1627+
-- check display of VALUES in view definitions
1628+
--
1629+
create view rule_v1 as values(1,2);
1630+
\d+ rule_v1
1631+
View "public.rule_v1"
1632+
Column | Type | Modifiers | Storage | Description
1633+
---------+---------+-----------+---------+-------------
1634+
column1 | integer | | plain |
1635+
column2 | integer | | plain |
1636+
View definition:
1637+
VALUES (1,2);
1638+
1639+
drop view rule_v1;
1640+
create view rule_v1(x) as values(1,2);
1641+
\d+ rule_v1
1642+
View "public.rule_v1"
1643+
Column | Type | Modifiers | Storage | Description
1644+
---------+---------+-----------+---------+-------------
1645+
x | integer | | plain |
1646+
column2 | integer | | plain |
1647+
View definition:
1648+
SELECT "*VALUES*".column1 AS x, "*VALUES*".column2
1649+
FROM (VALUES (1,2)) "*VALUES*";
1650+
1651+
drop view rule_v1;
1652+
create view rule_v1(x) as select * from (values(1,2)) v;
1653+
\d+ rule_v1
1654+
View "public.rule_v1"
1655+
Column | Type | Modifiers | Storage | Description
1656+
---------+---------+-----------+---------+-------------
1657+
x | integer | | plain |
1658+
column2 | integer | | plain |
1659+
View definition:
1660+
SELECT v.column1 AS x, v.column2
1661+
FROM ( VALUES (1,2)) v;
1662+
1663+
drop view rule_v1;
1664+
create view rule_v1(x) as select * from (values(1,2)) v(q,w);
1665+
\d+ rule_v1
1666+
View "public.rule_v1"
1667+
Column | Type | Modifiers | Storage | Description
1668+
--------+---------+-----------+---------+-------------
1669+
x | integer | | plain |
1670+
w | integer | | plain |
1671+
View definition:
1672+
SELECT v.q AS x, v.w
1673+
FROM ( VALUES (1,2)) v(q, w);
1674+
1675+
drop view rule_v1;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,3 +948,19 @@ select * from only t1_2;
948948
select pg_get_viewdef('shoe'::regclass)as unpretty;
949949
select pg_get_viewdef('shoe'::regclass,true)as pretty;
950950
select pg_get_viewdef('shoe'::regclass,0)as prettier;
951+
952+
--
953+
-- check display of VALUES in view definitions
954+
--
955+
createviewrule_v1asvalues(1,2);
956+
\d+ rule_v1
957+
dropview rule_v1;
958+
createviewrule_v1(x)asvalues(1,2);
959+
\d+ rule_v1
960+
dropview rule_v1;
961+
createviewrule_v1(x)asselect*from (values(1,2)) v;
962+
\d+ rule_v1
963+
dropview rule_v1;
964+
createviewrule_v1(x)asselect*from (values(1,2)) v(q,w);
965+
\d+ rule_v1
966+
dropview rule_v1;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp