diff options
Diffstat (limited to 'src/backend/optimizer/util/var.c')
-rw-r--r-- | src/backend/optimizer/util/var.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index 367d080ccf9..8065237a189 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -76,6 +76,7 @@ static bool pull_varattnos_walker(Node *node, pull_varattnos_context *context); static bool pull_vars_walker(Node *node, pull_vars_context *context); static bool contain_var_clause_walker(Node *node, void *context); static bool contain_vars_of_level_walker(Node *node, int *sublevels_up); +static bool contain_vars_returning_old_or_new_walker(Node *node, void *context); static bool locate_var_of_level_walker(Node *node, locate_var_of_level_context *context); static bool pull_var_clause_walker(Node *node, @@ -493,6 +494,49 @@ contain_vars_of_level_walker(Node *node, int *sublevels_up) /* + * contain_vars_returning_old_or_new + * Recursively scan a clause to discover whether it contains any Var nodes + * (of the current query level) whose varreturningtype is VAR_RETURNING_OLD + * or VAR_RETURNING_NEW. + * + * Returns true if any found. + * + * Any ReturningExprs are also detected --- if an OLD/NEW Var was rewritten, + * we still regard this as a clause that returns OLD/NEW values. + * + * Does not examine subqueries, therefore must only be used after reduction + * of sublinks to subplans! + */ +bool +contain_vars_returning_old_or_new(Node *node) +{ + return contain_vars_returning_old_or_new_walker(node, NULL); +} + +static bool +contain_vars_returning_old_or_new_walker(Node *node, void *context) +{ + if (node == NULL) + return false; + if (IsA(node, Var)) + { + if (((Var *) node)->varlevelsup == 0 && + ((Var *) node)->varreturningtype != VAR_RETURNING_DEFAULT) + return true; /* abort the tree traversal and return true */ + return false; + } + if (IsA(node, ReturningExpr)) + { + if (((ReturningExpr *) node)->retlevelsup == 0) + return true; /* abort the tree traversal and return true */ + return false; + } + return expression_tree_walker(node, contain_vars_returning_old_or_new_walker, + context); +} + + +/* * locate_var_of_level * Find the parse location of any Var of the specified query level. * |