summaryrefslogtreecommitdiff
path: root/src/backend/nodes/nodeFuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-01-09 12:43:09 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2022-01-09 12:43:09 -0500
commit6867f963e319934cbdafeb4bd5beaea5797c7be2 (patch)
treec055dadf62dfd6b32ad9b631dcd3065e30acd8ce /src/backend/nodes/nodeFuncs.c
parent96a6f11c06252b046ca9a6ee1f581a2f5d599301 (diff)
downloadpostgresql-6867f963e319934cbdafeb4bd5beaea5797c7be2.tar.gz
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
Diffstat (limited to 'src/backend/nodes/nodeFuncs.c')
-rw-r--r--src/backend/nodes/nodeFuncs.c42
1 files changed, 42 insertions, 0 deletions
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:
{
/*