diff options
Diffstat (limited to 'src/backend/optimizer/util/var.c')
-rw-r--r-- | src/backend/optimizer/util/var.c | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index a544041122b..af58b2556d6 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.23 1999/08/22 20:14:54 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.24 1999/08/26 05:09:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,16 +19,23 @@ #include "optimizer/var.h" +typedef struct { + List *varlist; + bool includeUpperVars; +} pull_var_clause_context; + static bool pull_varnos_walker(Node *node, List **listptr); static bool contain_var_clause_walker(Node *node, void *context); -static bool pull_var_clause_walker(Node *node, List **listptr); +static bool pull_var_clause_walker(Node *node, + pull_var_clause_context *context); /* * pull_varnos * * Create a list of all the distinct varnos present in a parsetree - * (tlist or qual). + * (tlist or qual). Note that only varnos attached to level-zero + * Vars are considered --- upper Vars refer to some other rtable! */ List * pull_varnos(Node *node) @@ -47,7 +54,7 @@ pull_varnos_walker(Node *node, List **listptr) if (IsA(node, Var)) { Var *var = (Var *) node; - if (!intMember(var->varno, *listptr)) + if (var->varlevelsup == 0 && !intMember(var->varno, *listptr)) *listptr = lconsi(var->varno, *listptr); return false; } @@ -56,7 +63,8 @@ pull_varnos_walker(Node *node, List **listptr) /* * contain_var_clause - * Recursively scan a clause to discover whether it contains any Var nodes. + * Recursively scan a clause to discover whether it contains any Var nodes + * (of the current query level). * * Returns true if any varnode found. */ @@ -72,7 +80,11 @@ contain_var_clause_walker(Node *node, void *context) if (node == NULL) return false; if (IsA(node, Var)) - return true; /* abort the tree traversal and return true */ + { + if (((Var *) node)->varlevelsup == 0) + return true; /* abort the tree traversal and return true */ + return false; + } return expression_tree_walker(node, contain_var_clause_walker, context); } @@ -80,28 +92,36 @@ contain_var_clause_walker(Node *node, void *context) * pull_var_clause * Recursively pulls all var nodes from an expression clause. * + * Upper-level vars (with varlevelsup > 0) are included only + * if includeUpperVars is true. Most callers probably want + * to ignore upper-level vars. + * * Returns list of varnodes found. Note the varnodes themselves are not * copied, only referenced. */ List * -pull_var_clause(Node *clause) +pull_var_clause(Node *clause, bool includeUpperVars) { - List *result = NIL; + pull_var_clause_context context; - pull_var_clause_walker(clause, &result); - return result; + context.varlist = NIL; + context.includeUpperVars = includeUpperVars; + + pull_var_clause_walker(clause, &context); + return context.varlist; } static bool -pull_var_clause_walker(Node *node, List **listptr) +pull_var_clause_walker(Node *node, pull_var_clause_context *context) { if (node == NULL) return false; if (IsA(node, Var)) { - *listptr = lappend(*listptr, node); + if (((Var *) node)->varlevelsup == 0 || context->includeUpperVars) + context->varlist = lappend(context->varlist, node); return false; } return expression_tree_walker(node, pull_var_clause_walker, - (void *) listptr); + (void *) context); } |