Commit cc2ca931 authored by Tom Lane's avatar Tom Lane

Fix deparsing of ON CONFLICT arbiter WHERE clauses.

The parser doesn't allow qualification of column names appearing in
these clauses, but ruleutils.c would sometimes qualify them, leading
to dump/reload failures.  Per bug #13891 from Onder Kalaci.

(In passing, make stanzas in ruleutils.c that save/restore varprefix
more consistent.)

Peter Geoghegan
parent 1d76c972
......@@ -5532,9 +5532,21 @@ get_insert_query_def(Query *query, deparse_context *context)
/* Add a WHERE clause (for partial indexes) if given */
if (confl->arbiterWhere != NULL)
{
bool save_varprefix;
/*
* Force non-prefixing of Vars, since parser assumes that they
* belong to target relation. WHERE clause does not use
* InferenceElem, so this is separately required.
*/
save_varprefix = context->varprefix;
context->varprefix = false;
appendContextKeyword(context, " WHERE ",
-PRETTYINDENT_STD, PRETTYINDENT_STD, 1);
get_rule_expr(confl->arbiterWhere, context, false);
context->varprefix = save_varprefix;
}
}
else if (confl->constraint != InvalidOid)
......@@ -7956,13 +7968,14 @@ get_rule_expr(Node *node, deparse_context *context,
case T_InferenceElem:
{
InferenceElem *iexpr = (InferenceElem *) node;
bool varprefix = context->varprefix;
bool save_varprefix;
bool need_parens;
/*
* InferenceElem can only refer to target relation, so a
* prefix is never useful.
* prefix is not useful, and indeed would cause parse errors.
*/
save_varprefix = context->varprefix;
context->varprefix = false;
/*
......@@ -7982,7 +7995,7 @@ get_rule_expr(Node *node, deparse_context *context,
if (need_parens)
appendStringInfoChar(buf, ')');
context->varprefix = varprefix;
context->varprefix = save_varprefix;
if (iexpr->infercollid)
appendStringInfo(buf, " COLLATE %s",
......
......@@ -2846,7 +2846,7 @@ SELECT definition FROM pg_rules WHERE tablename = 'hats' ORDER BY rulename;
CREATE RULE hat_nosert AS +
ON INSERT TO hats DO INSTEAD INSERT INTO hat_data (hat_name, hat_color) +
VALUES (new.hat_name, new.hat_color) ON CONFLICT(hat_name COLLATE "C" bpchar_pattern_ops)+
WHERE (hat_data.hat_color = 'green'::bpchar) DO NOTHING +
WHERE (hat_color = 'green'::bpchar) DO NOTHING +
RETURNING hat_data.hat_name, +
hat_data.hat_color;
(1 row)
......@@ -2871,7 +2871,7 @@ SELECT tablename, rulename, definition FROM pg_rules
hats | hat_nosert | CREATE RULE hat_nosert AS +
| | ON INSERT TO hats DO INSTEAD INSERT INTO hat_data (hat_name, hat_color) +
| | VALUES (new.hat_name, new.hat_color) ON CONFLICT(hat_name COLLATE "C" bpchar_pattern_ops)+
| | WHERE (hat_data.hat_color = 'green'::bpchar) DO NOTHING +
| | WHERE (hat_color = 'green'::bpchar) DO NOTHING +
| | RETURNING hat_data.hat_name, +
| | hat_data.hat_color;
(1 row)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment