1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-30 11:03:19 +03:00

Make pg_get_expr() more bulletproof.

Since this function is defined to accept pg_node_tree values, it could
get applied to any nodetree that can appear in a cataloged pg_node_tree
column.  Some such cases can't be supported --- for example, its API
doesn't allow providing referents for more than one relation --- but
we should try to throw a user-facing error rather than an internal
error when encountering such a case.

In support of this, extend expression_tree_walker/mutator to be sure
they'll work on any such node tree (which basically means adding
support for relpartbound node types).  That allows us to run pull_varnos
and check for the case of multiple relations before we start processing
the tree.  The alternative of changing the low-level error thrown for an
out-of-range varno isn't appealing, because that could mask actual bugs
in other usages of ruleutils.

Per report from Justin Pryzby.  This is basically cosmetic, so no
back-patch.

Discussion: https://postgr.es/m/20211219205422.GT17618@telsasoft.com
This commit is contained in:
Tom Lane
2022-01-09 12:43:09 -05:00
parent 96a6f11c06
commit 6867f963e3
3 changed files with 94 additions and 3 deletions

View File

@ -2201,6 +2201,26 @@ expression_tree_walker(Node *node,
return true;
}
break;
case T_PartitionBoundSpec:
{
PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
if (walker(pbs->listdatums, context))
return true;
if (walker(pbs->lowerdatums, context))
return true;
if (walker(pbs->upperdatums, context))
return true;
}
break;
case T_PartitionRangeDatum:
{
PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
if (walker(prd->value, context))
return true;
}
break;
case T_List:
foreach(temp, (List *) node)
{
@ -3092,6 +3112,28 @@ expression_tree_mutator(Node *node,
return (Node *) newnode;
}
break;
case T_PartitionBoundSpec:
{
PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
PartitionBoundSpec *newnode;
FLATCOPY(newnode, pbs, PartitionBoundSpec);
MUTATE(newnode->listdatums, pbs->listdatums, List *);
MUTATE(newnode->lowerdatums, pbs->lowerdatums, List *);
MUTATE(newnode->upperdatums, pbs->upperdatums, List *);
return (Node *) newnode;
}
break;
case T_PartitionRangeDatum:
{
PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
PartitionRangeDatum *newnode;
FLATCOPY(newnode, prd, PartitionRangeDatum);
MUTATE(newnode->value, prd->value, Node *);
return (Node *) newnode;
}
break;
case T_List:
{
/*