1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-27 07:42:10 +03:00

Fix ruleutils.c for domain-over-array cases, too.

Further investigation shows that ruleutils isn't quite up to speed either
for cases where we have a domain-over-array: it needs to be prepared to
look past a CoerceToDomain at the top level of field and element
assignments, else it decompiles them incorrectly.  Potentially this would
result in failure to dump/reload a rule, if it looked like the one in the
new test case.  (I also added a test for EXPLAIN; that output isn't broken,
but clearly we need more test coverage here.)

Like commit b1cb32fb6, this bug is reachable in cases we already support,
so back-patch all the way.
This commit is contained in:
Tom Lane
2017-07-12 18:00:04 -04:00
parent 11854dee01
commit aea1a3f0eb
3 changed files with 69 additions and 9 deletions

View File

@@ -8634,12 +8634,17 @@ get_opclass_name(Oid opclass, Oid actual_datatype,
* We strip any top-level FieldStore or assignment ArrayRef nodes that
* appear in the input, and return the subexpression that's to be assigned.
* If printit is true, we also print out the appropriate decoration for the
* base column name (that the caller just printed).
* base column name (that the caller just printed). We might also need to
* strip CoerceToDomain nodes, but only ones that appear above assignment
* nodes.
*
* Returns the subexpression that's to be assigned.
*/
static Node *
processIndirection(Node *node, deparse_context *context, bool printit)
{
StringInfo buf = context->buf;
CoerceToDomain *cdomain = NULL;
for (;;)
{
@@ -8689,10 +8694,28 @@ processIndirection(Node *node, deparse_context *context, bool printit)
*/
node = (Node *) aref->refassgnexpr;
}
else if (IsA(node, CoerceToDomain))
{
cdomain = (CoerceToDomain *) node;
/* If it's an explicit domain coercion, we're done */
if (cdomain->coercionformat != COERCE_IMPLICIT_CAST)
break;
/* Tentatively descend past the CoerceToDomain */
node = (Node *) cdomain->arg;
}
else
break;
}
/*
* If we descended past a CoerceToDomain whose argument turned out not to
* be a FieldStore or array assignment, back up to the CoerceToDomain.
* (This is not enough to be fully correct if there are nested implicit
* CoerceToDomains, but such cases shouldn't ever occur.)
*/
if (cdomain && node == (Node *) cdomain->arg)
node = (Node *) cdomain;
return node;
}