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

Commit7745bc3

Browse files
committed
Fix ruleutils.c's dumping of whole-row Vars in ROW() and VALUES() contexts.
Normally ruleutils prints a whole-row Var as "foo.*". We already knew thatthat doesn't work at top level of a SELECT list, because the parser wouldtreat the "*" as a directive to expand the reference into separate columns,not a whole-row Var. However, Joshua Yanovski points out in bug #13776that the same thing happens at top level of a ROW() construct; and somenosing around in the parser shows that the same is true in VALUES().Hence, apply the same workaround already devised for the SELECT-list case,namely to add a forced cast to the appropriate rowtype in these cases.(The alternative of just printing "foo" was rejected because it isdifficult to avoid ambiguity against plain columns named "foo".)Back-patch to all supported branches.
1 parent7d9a473 commit7745bc3

File tree

3 files changed

+139
-5
lines changed

3 files changed

+139
-5
lines changed

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,8 @@ static void appendContextKeyword(deparse_context *context, const char *str,
391391
staticvoidremoveStringInfoSpaces(StringInfostr);
392392
staticvoidget_rule_expr(Node*node,deparse_context*context,
393393
boolshowimplicit);
394+
staticvoidget_rule_expr_toplevel(Node*node,deparse_context*context,
395+
boolshowimplicit);
394396
staticvoidget_oper_expr(OpExpr*expr,deparse_context*context);
395397
staticvoidget_func_expr(FuncExpr*expr,deparse_context*context,
396398
boolshowimplicit);
@@ -4347,10 +4349,10 @@ get_values_def(List *values_lists, deparse_context *context)
43474349

43484350
/*
43494351
* Strip any top-level nodes representing indirection assignments,
4350-
* then print the result.
4352+
* then print the result. Whole-row Vars need special treatment.
43514353
*/
4352-
get_rule_expr(processIndirection(col,context, false),
4353-
context, false);
4354+
get_rule_expr_toplevel(processIndirection(col,context, false),
4355+
context, false);
43544356
}
43554357
appendStringInfoChar(buf,')');
43564358
}
@@ -4771,7 +4773,8 @@ get_target_list(List *targetList, deparse_context *context,
47714773
* the top level of a SELECT list it's not right (the parser will
47724774
* expand that notation into multiple columns, yielding behavior
47734775
* different from a whole-row Var). We need to call get_variable
4774-
* directly so that we can tell it to do the right thing.
4776+
* directly so that we can tell it to do the right thing, and so that
4777+
* we can get the attribute name which is the default AS label.
47754778
*/
47764779
if (tle->expr&& (IsA(tle->expr,Var)))
47774780
{
@@ -7515,7 +7518,8 @@ get_rule_expr(Node *node, deparse_context *context,
75157518
!tupdesc->attrs[i]->attisdropped)
75167519
{
75177520
appendStringInfoString(buf,sep);
7518-
get_rule_expr(e,context, true);
7521+
/* Whole-row Vars need special treatment here */
7522+
get_rule_expr_toplevel(e,context, true);
75197523
sep=", ";
75207524
}
75217525
i++;
@@ -7941,6 +7945,27 @@ get_rule_expr(Node *node, deparse_context *context,
79417945
}
79427946
}
79437947

7948+
/*
7949+
* get_rule_expr_toplevel- Parse back a toplevel expression
7950+
*
7951+
* Same as get_rule_expr(), except that if the expr is just a Var, we pass
7952+
* istoplevel = true not false to get_variable(). This causes whole-row Vars
7953+
* to get printed with decoration that will prevent expansion of "*".
7954+
* We need to use this in contexts such as ROW() and VALUES(), where the
7955+
* parser would expand "foo.*" appearing at top level. (In principle we'd
7956+
* use this in get_target_list() too, but that has additional worries about
7957+
* whether to print AS, so it needs to invoke get_variable() directly anyway.)
7958+
*/
7959+
staticvoid
7960+
get_rule_expr_toplevel(Node*node,deparse_context*context,
7961+
boolshowimplicit)
7962+
{
7963+
if (node&&IsA(node,Var))
7964+
(void)get_variable((Var*)node,0, true,context);
7965+
else
7966+
get_rule_expr(node,context,showimplicit);
7967+
}
7968+
79447969

79457970
/*
79467971
* get_oper_expr- Parse back an OpExpr node

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,97 @@ select * from tt14v;
13841384
foo | | quux
13851385
(1 row)
13861386

1387+
-- check display of whole-row variables in some corner cases
1388+
create type nestedcomposite as (x int8_tbl);
1389+
create view tt15v as select row(i)::nestedcomposite from int8_tbl i;
1390+
select * from tt15v;
1391+
row
1392+
------------------------------------------
1393+
("(123,456)")
1394+
("(123,4567890123456789)")
1395+
("(4567890123456789,123)")
1396+
("(4567890123456789,4567890123456789)")
1397+
("(4567890123456789,-4567890123456789)")
1398+
(5 rows)
1399+
1400+
select pg_get_viewdef('tt15v', true);
1401+
pg_get_viewdef
1402+
------------------------------------------------------
1403+
SELECT ROW(i.*::int8_tbl)::nestedcomposite AS "row"+
1404+
FROM int8_tbl i;
1405+
(1 row)
1406+
1407+
select row(i.*::int8_tbl)::nestedcomposite from int8_tbl i;
1408+
row
1409+
------------------------------------------
1410+
("(123,456)")
1411+
("(123,4567890123456789)")
1412+
("(4567890123456789,123)")
1413+
("(4567890123456789,4567890123456789)")
1414+
("(4567890123456789,-4567890123456789)")
1415+
(5 rows)
1416+
1417+
create view tt16v as select * from int8_tbl i, lateral(values(i)) ss;
1418+
select * from tt16v;
1419+
q1 | q2 | column1
1420+
------------------+-------------------+--------------------------------------
1421+
123 | 456 | (123,456)
1422+
123 | 4567890123456789 | (123,4567890123456789)
1423+
4567890123456789 | 123 | (4567890123456789,123)
1424+
4567890123456789 | 4567890123456789 | (4567890123456789,4567890123456789)
1425+
4567890123456789 | -4567890123456789 | (4567890123456789,-4567890123456789)
1426+
(5 rows)
1427+
1428+
select pg_get_viewdef('tt16v', true);
1429+
pg_get_viewdef
1430+
-------------------------------------------
1431+
SELECT i.q1, +
1432+
i.q2, +
1433+
ss.column1 +
1434+
FROM int8_tbl i, +
1435+
LATERAL ( VALUES (i.*::int8_tbl)) ss;
1436+
(1 row)
1437+
1438+
select * from int8_tbl i, lateral(values(i.*::int8_tbl)) ss;
1439+
q1 | q2 | column1
1440+
------------------+-------------------+--------------------------------------
1441+
123 | 456 | (123,456)
1442+
123 | 4567890123456789 | (123,4567890123456789)
1443+
4567890123456789 | 123 | (4567890123456789,123)
1444+
4567890123456789 | 4567890123456789 | (4567890123456789,4567890123456789)
1445+
4567890123456789 | -4567890123456789 | (4567890123456789,-4567890123456789)
1446+
(5 rows)
1447+
1448+
create view tt17v as select * from int8_tbl i where i in (values(i));
1449+
select * from tt17v;
1450+
q1 | q2
1451+
------------------+-------------------
1452+
123 | 456
1453+
123 | 4567890123456789
1454+
4567890123456789 | 123
1455+
4567890123456789 | 4567890123456789
1456+
4567890123456789 | -4567890123456789
1457+
(5 rows)
1458+
1459+
select pg_get_viewdef('tt17v', true);
1460+
pg_get_viewdef
1461+
---------------------------------------------
1462+
SELECT i.q1, +
1463+
i.q2 +
1464+
FROM int8_tbl i +
1465+
WHERE (i.* IN ( VALUES (i.*::int8_tbl)));
1466+
(1 row)
1467+
1468+
select * from int8_tbl i where i.* in (values(i.*::int8_tbl));
1469+
q1 | q2
1470+
------------------+-------------------
1471+
123 | 456
1472+
123 | 4567890123456789
1473+
4567890123456789 | 123
1474+
4567890123456789 | 4567890123456789
1475+
4567890123456789 | -4567890123456789
1476+
(5 rows)
1477+
13871478
-- clean up all the random objects we made above
13881479
set client_min_messages = warning;
13891480
DROP SCHEMA temp_view_test CASCADE;

‎src/test/regress/sql/create_view.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,24 @@ alter table tt14t drop column f3;
469469
select pg_get_viewdef('tt14v', true);
470470
select*from tt14v;
471471

472+
-- check display of whole-row variables in some corner cases
473+
474+
createtypenestedcompositeas (x int8_tbl);
475+
createviewtt15vasselect row(i)::nestedcompositefrom int8_tbl i;
476+
select*from tt15v;
477+
select pg_get_viewdef('tt15v', true);
478+
select row(i.*::int8_tbl)::nestedcompositefrom int8_tbl i;
479+
480+
createviewtt16vasselect*from int8_tbl i, lateral(values(i)) ss;
481+
select*from tt16v;
482+
select pg_get_viewdef('tt16v', true);
483+
select*from int8_tbl i, lateral(values(i.*::int8_tbl)) ss;
484+
485+
createviewtt17vasselect*from int8_tbl iwhere iin (values(i));
486+
select*from tt17v;
487+
select pg_get_viewdef('tt17v', true);
488+
select*from int8_tbl iwhere i.*in (values(i.*::int8_tbl));
489+
472490
-- clean up all the random objects we made above
473491
set client_min_messages= warning;
474492
DROPSCHEMA temp_view_test CASCADE;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp