diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2016-02-07 14:57:24 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2016-02-07 14:57:24 -0500 |
commit | cc2ca9319a5dbe89ea47d87944650e65e3bb4ce8 (patch) | |
tree | 4f4ab1390ce67acdd591003ddfd5866cf3a98897 /src | |
parent | 1d76c9725087121bfa008f875450570a5c46241f (diff) | |
download | postgresql-cc2ca9319a5dbe89ea47d87944650e65e3bb4ce8.tar.gz postgresql-cc2ca9319a5dbe89ea47d87944650e65e3bb4ce8.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 19 | ||||
-rw-r--r-- | src/test/regress/expected/rules.out | 4 |
2 files changed, 18 insertions, 5 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 4efd2988e79..490a0906e8e 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -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", diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 28b061f9d55..2bdba2d1a18 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -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) |