From 6867f963e319934cbdafeb4bd5beaea5797c7be2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 9 Jan 2022 12:43:09 -0500 Subject: 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 --- src/backend/nodes/nodeFuncs.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/backend/nodes/nodeFuncs.c') diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 7d1a3aff8c..acc17da717 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -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: { /* -- cgit v1.2.1