mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-04 18:36:52 +02:00
Fix ruleutils.c's dumping of whole-row Vars in more contexts.
Commit 7745bc352
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
This commit is contained in:
parent
850c704c72
commit
45a3cefad6
@ -421,6 +421,8 @@ static void get_rule_expr(Node *node, deparse_context *context,
|
||||
bool showimplicit);
|
||||
static void get_rule_expr_toplevel(Node *node, deparse_context *context,
|
||||
bool showimplicit);
|
||||
static void get_rule_list_toplevel(List *lst, deparse_context *context,
|
||||
bool showimplicit);
|
||||
static void get_rule_expr_funccall(Node *node, deparse_context *context,
|
||||
bool showimplicit);
|
||||
static bool looks_like_function(Node *node);
|
||||
@ -6278,7 +6280,7 @@ get_insert_query_def(Query *query, deparse_context *context)
|
||||
/* Add the single-VALUES expression list */
|
||||
appendContextKeyword(context, "VALUES (",
|
||||
-PRETTYINDENT_STD, PRETTYINDENT_STD, 2);
|
||||
get_rule_expr((Node *) strippedexprs, context, false);
|
||||
get_rule_list_toplevel(strippedexprs, context, false);
|
||||
appendStringInfoChar(buf, ')');
|
||||
}
|
||||
else
|
||||
@ -8466,23 +8468,15 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
case T_RowCompareExpr:
|
||||
{
|
||||
RowCompareExpr *rcexpr = (RowCompareExpr *) node;
|
||||
ListCell *arg;
|
||||
char *sep;
|
||||
|
||||
/*
|
||||
* SQL99 allows "ROW" to be omitted when there is more than
|
||||
* one column, but for simplicity we always print it.
|
||||
* one column, but for simplicity we always print it. Within
|
||||
* a ROW expression, whole-row Vars need special treatment, so
|
||||
* use get_rule_list_toplevel.
|
||||
*/
|
||||
appendStringInfoString(buf, "(ROW(");
|
||||
sep = "";
|
||||
foreach(arg, rcexpr->largs)
|
||||
{
|
||||
Node *e = (Node *) lfirst(arg);
|
||||
|
||||
appendStringInfoString(buf, sep);
|
||||
get_rule_expr(e, context, true);
|
||||
sep = ", ";
|
||||
}
|
||||
get_rule_list_toplevel(rcexpr->largs, context, true);
|
||||
|
||||
/*
|
||||
* We assume that the name of the first-column operator will
|
||||
@ -8495,15 +8489,7 @@ get_rule_expr(Node *node, deparse_context *context,
|
||||
generate_operator_name(linitial_oid(rcexpr->opnos),
|
||||
exprType(linitial(rcexpr->largs)),
|
||||
exprType(linitial(rcexpr->rargs))));
|
||||
sep = "";
|
||||
foreach(arg, rcexpr->rargs)
|
||||
{
|
||||
Node *e = (Node *) lfirst(arg);
|
||||
|
||||
appendStringInfoString(buf, sep);
|
||||
get_rule_expr(e, context, true);
|
||||
sep = ", ";
|
||||
}
|
||||
get_rule_list_toplevel(rcexpr->rargs, context, true);
|
||||
appendStringInfoString(buf, "))");
|
||||
}
|
||||
break;
|
||||
@ -9048,6 +9034,32 @@ get_rule_expr_toplevel(Node *node, deparse_context *context,
|
||||
get_rule_expr(node, context, showimplicit);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_rule_list_toplevel - Parse back a list of toplevel expressions
|
||||
*
|
||||
* Apply get_rule_expr_toplevel() to each element of a List.
|
||||
*
|
||||
* This adds commas between the expressions, but caller is responsible
|
||||
* for printing surrounding decoration.
|
||||
*/
|
||||
static void
|
||||
get_rule_list_toplevel(List *lst, deparse_context *context,
|
||||
bool showimplicit)
|
||||
{
|
||||
const char *sep;
|
||||
ListCell *lc;
|
||||
|
||||
sep = "";
|
||||
foreach(lc, lst)
|
||||
{
|
||||
Node *e = (Node *) lfirst(lc);
|
||||
|
||||
appendStringInfoString(context->buf, sep);
|
||||
get_rule_expr_toplevel(e, context, showimplicit);
|
||||
sep = ", ";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_rule_expr_funccall - Parse back a function-call expression
|
||||
*
|
||||
|
@ -1612,6 +1612,22 @@ select * from int8_tbl i where i.* in (values(i.*::int8_tbl));
|
||||
4567890123456789 | -4567890123456789
|
||||
(5 rows)
|
||||
|
||||
create table tt15v_log(o tt15v, n tt15v, incr bool);
|
||||
create rule updlog as on update to tt15v do also
|
||||
insert into tt15v_log values(old, new, row(old,old) < row(new,new));
|
||||
\d+ tt15v
|
||||
View "testviewschm2.tt15v"
|
||||
Column | Type | Collation | Nullable | Default | Storage | Description
|
||||
--------+-----------------+-----------+----------+---------+----------+-------------
|
||||
row | nestedcomposite | | | | extended |
|
||||
View definition:
|
||||
SELECT ROW(i.*::int8_tbl)::nestedcomposite AS "row"
|
||||
FROM int8_tbl i;
|
||||
Rules:
|
||||
updlog AS
|
||||
ON UPDATE TO tt15v DO INSERT INTO tt15v_log (o, n, incr)
|
||||
VALUES (old.*::tt15v, new.*::tt15v, (ROW(old.*::tt15v, old.*::tt15v) < ROW(new.*::tt15v, new.*::tt15v)))
|
||||
|
||||
-- check unique-ification of overlength names
|
||||
create view tt18v as
|
||||
select * from int8_tbl xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxy
|
||||
@ -1782,7 +1798,7 @@ drop cascades to view aliased_view_2
|
||||
drop cascades to view aliased_view_3
|
||||
drop cascades to view aliased_view_4
|
||||
DROP SCHEMA testviewschm2 CASCADE;
|
||||
NOTICE: drop cascades to 63 other objects
|
||||
NOTICE: drop cascades to 64 other objects
|
||||
DETAIL: drop cascades to table t1
|
||||
drop cascades to view temporal1
|
||||
drop cascades to view temporal2
|
||||
@ -1840,6 +1856,7 @@ drop cascades to type nestedcomposite
|
||||
drop cascades to view tt15v
|
||||
drop cascades to view tt16v
|
||||
drop cascades to view tt17v
|
||||
drop cascades to table tt15v_log
|
||||
drop cascades to view tt18v
|
||||
drop cascades to view tt19v
|
||||
drop cascades to view tt20v
|
||||
|
@ -548,6 +548,11 @@ select * from tt17v;
|
||||
select pg_get_viewdef('tt17v', true);
|
||||
select * from int8_tbl i where i.* in (values(i.*::int8_tbl));
|
||||
|
||||
create table tt15v_log(o tt15v, n tt15v, incr bool);
|
||||
create rule updlog as on update to tt15v do also
|
||||
insert into tt15v_log values(old, new, row(old,old) < row(new,new));
|
||||
\d+ tt15v
|
||||
|
||||
-- check unique-ification of overlength names
|
||||
|
||||
create view tt18v as
|
||||
|
Loading…
Reference in New Issue
Block a user