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

Appearance settings

Commit 43c2175

Browse filesBrowse files
committed
Fix ruleutils.c's dumping of whole-row Vars in more contexts.
Commit 7745bc3 intended to ensure that whole-row Vars would be printed with "::type" decoration in all contexts where plain "var.*" notation would result in star-expansion, notably in ROW() and VALUES() constructs. However, it missed the case of INSERT with a single-row VALUES, as reported by Timur Khanjanov. Nosing around ruleutils.c, I found a second oversight: the code for RowCompareExpr generates ROW() notation without benefit of an actual RowExpr, and naturally it wasn't in sync :-(. (The code for FieldStore also does this, but we don't expect that to generate strictly parsable SQL anyway, so I left it alone.) Back-patch to all supported branches. Discussion: https://postgr.es/m/efaba6f9-4190-56be-8ff2-7a1674f9194f@intrans.baku.az
1 parent dfc0cb3 commit 43c2175
Copy full SHA for 43c2175

File tree

Expand file treeCollapse file tree

3 files changed

+57
-23
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+57
-23
lines changed

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

Copy file name to clipboardExpand all lines: src/backend/utils/adt/ruleutils.c
+34-22Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@ static void get_rule_expr(Node *node, deparse_context *context,
438438
bool showimplicit);
439439
static void get_rule_expr_toplevel(Node *node, deparse_context *context,
440440
bool showimplicit);
441+
static void get_rule_list_toplevel(List *lst, deparse_context *context,
442+
bool showimplicit);
441443
static void get_rule_expr_funccall(Node *node, deparse_context *context,
442444
bool showimplicit);
443445
static bool looks_like_function(Node *node);
@@ -6632,7 +6634,7 @@ get_insert_query_def(Query *query, deparse_context *context)
66326634
/* Add the single-VALUES expression list */
66336635
appendContextKeyword(context, "VALUES (",
66346636
-PRETTYINDENT_STD, PRETTYINDENT_STD, 2);
6635-
get_rule_expr((Node *) strippedexprs, context, false);
6637+
get_rule_list_toplevel(strippedexprs, context, false);
66366638
appendStringInfoChar(buf, ')');
66376639
}
66386640
else
@@ -8996,23 +8998,15 @@ get_rule_expr(Node *node, deparse_context *context,
89968998
case T_RowCompareExpr:
89978999
{
89989000
RowCompareExpr *rcexpr = (RowCompareExpr *) node;
8999-
ListCell *arg;
9000-
char *sep;
90019001

90029002
/*
90039003
* SQL99 allows "ROW" to be omitted when there is more than
9004-
* one column, but for simplicity we always print it.
9004+
* one column, but for simplicity we always print it. Within
9005+
* a ROW expression, whole-row Vars need special treatment, so
9006+
* use get_rule_list_toplevel.
90059007
*/
90069008
appendStringInfoString(buf, "(ROW(");
9007-
sep = "";
9008-
foreach(arg, rcexpr->largs)
9009-
{
9010-
Node *e = (Node *) lfirst(arg);
9011-
9012-
appendStringInfoString(buf, sep);
9013-
get_rule_expr(e, context, true);
9014-
sep = ", ";
9015-
}
9009+
get_rule_list_toplevel(rcexpr->largs, context, true);
90169010

90179011
/*
90189012
* We assume that the name of the first-column operator will
@@ -9025,15 +9019,7 @@ get_rule_expr(Node *node, deparse_context *context,
90259019
generate_operator_name(linitial_oid(rcexpr->opnos),
90269020
exprType(linitial(rcexpr->largs)),
90279021
exprType(linitial(rcexpr->rargs))));
9028-
sep = "";
9029-
foreach(arg, rcexpr->rargs)
9030-
{
9031-
Node *e = (Node *) lfirst(arg);
9032-
9033-
appendStringInfoString(buf, sep);
9034-
get_rule_expr(e, context, true);
9035-
sep = ", ";
9036-
}
9022+
get_rule_list_toplevel(rcexpr->rargs, context, true);
90379023
appendStringInfoString(buf, "))");
90389024
}
90399025
break;
@@ -9578,6 +9564,32 @@ get_rule_expr_toplevel(Node *node, deparse_context *context,
95789564
get_rule_expr(node, context, showimplicit);
95799565
}
95809566

9567+
/*
9568+
* get_rule_list_toplevel - Parse back a list of toplevel expressions
9569+
*
9570+
* Apply get_rule_expr_toplevel() to each element of a List.
9571+
*
9572+
* This adds commas between the expressions, but caller is responsible
9573+
* for printing surrounding decoration.
9574+
*/
9575+
static void
9576+
get_rule_list_toplevel(List *lst, deparse_context *context,
9577+
bool showimplicit)
9578+
{
9579+
const char *sep;
9580+
ListCell *lc;
9581+
9582+
sep = "";
9583+
foreach(lc, lst)
9584+
{
9585+
Node *e = (Node *) lfirst(lc);
9586+
9587+
appendStringInfoString(context->buf, sep);
9588+
get_rule_expr_toplevel(e, context, showimplicit);
9589+
sep = ", ";
9590+
}
9591+
}
9592+
95819593
/*
95829594
* get_rule_expr_funccall - Parse back a function-call expression
95839595
*

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

Copy file name to clipboardExpand all lines: src/test/regress/expected/create_view.out
+18-1Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1681,6 +1681,22 @@ select * from int8_tbl i where i.* in (values(i.*::int8_tbl));
16811681
4567890123456789 | -4567890123456789
16821682
(5 rows)
16831683

1684+
create table tt15v_log(o tt15v, n tt15v, incr bool);
1685+
create rule updlog as on update to tt15v do also
1686+
insert into tt15v_log values(old, new, row(old,old) < row(new,new));
1687+
\d+ tt15v
1688+
View "testviewschm2.tt15v"
1689+
Column | Type | Collation | Nullable | Default | Storage | Description
1690+
--------+-----------------+-----------+----------+---------+----------+-------------
1691+
row | nestedcomposite | | | | extended |
1692+
View definition:
1693+
SELECT ROW(i.*::int8_tbl)::nestedcomposite AS "row"
1694+
FROM int8_tbl i;
1695+
Rules:
1696+
updlog AS
1697+
ON UPDATE TO tt15v DO INSERT INTO tt15v_log (o, n, incr)
1698+
VALUES (old.*::tt15v, new.*::tt15v, (ROW(old.*::tt15v, old.*::tt15v) < ROW(new.*::tt15v, new.*::tt15v)))
1699+
16841700
-- check unique-ification of overlength names
16851701
create view tt18v as
16861702
select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy
@@ -1994,7 +2010,7 @@ drop cascades to view aliased_view_2
19942010
drop cascades to view aliased_view_3
19952011
drop cascades to view aliased_view_4
19962012
DROP SCHEMA testviewschm2 CASCADE;
1997-
NOTICE: drop cascades to 73 other objects
2013+
NOTICE: drop cascades to 74 other objects
19982014
DETAIL: drop cascades to table t1
19992015
drop cascades to view temporal1
20002016
drop cascades to view temporal2
@@ -2058,6 +2074,7 @@ drop cascades to type nestedcomposite
20582074
drop cascades to view tt15v
20592075
drop cascades to view tt16v
20602076
drop cascades to view tt17v
2077+
drop cascades to table tt15v_log
20612078
drop cascades to view tt18v
20622079
drop cascades to view tt19v
20632080
drop cascades to view tt20v

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

Copy file name to clipboardExpand all lines: src/test/regress/sql/create_view.sql
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,11 @@ select * from tt17v;
565565
select pg_get_viewdef('tt17v', true);
566566
select * from int8_tbl i where i.* in (values(i.*::int8_tbl));
567567

568+
create table tt15v_log(o tt15v, n tt15v, incr bool);
569+
create rule updlog as on update to tt15v do also
570+
insert into tt15v_log values(old, new, row(old,old) < row(new,new));
571+
\d+ tt15v
572+
568573
-- check unique-ification of overlength names
569574

570575
create view tt18v as

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.