diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 1999-08-26 05:09:06 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 1999-08-26 05:09:06 +0000 |
commit | 37d20eb8558607e18816849a0a3f3d941317dc13 (patch) | |
tree | 95109e75dd63b2c488256f68c63b9386b9ac9d3c /src/backend/optimizer/util/var.c | |
parent | 5adebf83b6cffbf4133ff97dbe6d5da0ff59bff1 (diff) |
Clean up some mistakes in handling of uplevel Vars in planner.
Most parts of the planner should ignore, or indeed never even see, uplevel
Vars because they will be or have been replaced by Params. There were a
couple of places that got it wrong though, probably my fault from recent
changes...
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); } |