summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/var.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/var.c')
-rw-r--r--src/backend/optimizer/util/var.c46
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);
}