aboutsummaryrefslogtreecommitdiff
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.c222
1 files changed, 52 insertions, 170 deletions
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index fd57067cdd2..d31f13d56d2 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.19 1999/05/25 16:10:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.20 1999/06/19 03:41:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,8 +15,7 @@
#include "postgres.h"
-#include <nodes/relation.h>
-
+#include "nodes/relation.h"
#include "nodes/primnodes.h"
#include "nodes/plannodes.h"
#include "nodes/nodeFuncs.h"
@@ -27,43 +26,40 @@
#include "parser/parsetree.h"
+
+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);
+
+
/*
- * find_varnos
- *
- * Descends down part of a parsetree (qual or tlist),
+ * pull_varnos
*
- * XXX assumes varno's are always integers, which shouldn't be true...
- * (though it currently is, see primnodes.h)
+ * Create a list of all the distinct varnos present in a parsetree
+ * (tlist or qual).
*/
List *
-pull_varnos(Node *me)
+pull_varnos(Node *node)
{
- List *i,
- *result = NIL;
+ List *result = NIL;
- if (me == NULL)
- return NIL;
+ pull_varnos_walker(node, &result);
+ return result;
+}
- switch (nodeTag(me))
+static bool
+pull_varnos_walker(Node *node, List **listptr)
+{
+ if (node == NULL)
+ return false;
+ if (IsA(node, Var))
{
- case T_List:
- foreach(i, (List *) me)
- result = nconc(result, pull_varnos(lfirst(i)));
- break;
- case T_ArrayRef:
- foreach(i, ((ArrayRef *) me)->refupperindexpr)
- result = nconc(result, pull_varnos(lfirst(i)));
- foreach(i, ((ArrayRef *) me)->reflowerindexpr)
- result = nconc(result, pull_varnos(lfirst(i)));
- result = nconc(result, pull_varnos(((ArrayRef *) me)->refassgnexpr));
- break;
- case T_Var:
- result = lconsi(((Var *) me)->varno, NIL);
- break;
- default:
- break;
+ Var *var = (Var *) node;
+ if (!intMember(var->varno, *listptr))
+ *listptr = lconsi(var->varno, *listptr);
+ return false;
}
- return result;
+ return expression_tree_walker(node, pull_varnos_walker, (void *) listptr);
}
/*
@@ -75,92 +71,22 @@ pull_varnos(Node *me)
bool
contain_var_clause(Node *clause)
{
- List *temp;
-
- if (clause == NULL)
- return FALSE;
- else if (IsA(clause, Var))
- return TRUE;
- else if (single_node(clause))
- return FALSE;
- else if (IsA(clause, Iter))
- return contain_var_clause(((Iter *) clause)->iterexpr);
- else if (is_subplan(clause))
- {
- foreach(temp, ((Expr *) clause)->args)
- {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
- }
- /* Also check left sides of Oper-s */
- foreach(temp, ((SubPlan *) ((Expr *) clause)->oper)->sublink->oper)
- {
- if (contain_var_clause(lfirst(((Expr *) lfirst(temp))->args)))
- return TRUE;
- }
- return FALSE;
- }
- else if (IsA(clause, Expr))
- {
-
- /*
- * Recursively scan the arguments of an expression. NOTE: this
- * must come after is_subplan() case since subplan is a kind of
- * Expr node.
- */
- foreach(temp, ((Expr *) clause)->args)
- {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
- }
- return FALSE;
- }
- else if (IsA(clause, Aggref))
- return contain_var_clause(((Aggref *) clause)->target);
- else if (IsA(clause, ArrayRef))
- {
- foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
- {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
- }
- foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
- {
- if (contain_var_clause(lfirst(temp)))
- return TRUE;
- }
- if (contain_var_clause(((ArrayRef *) clause)->refexpr))
- return TRUE;
- if (contain_var_clause(((ArrayRef *) clause)->refassgnexpr))
- return TRUE;
- return FALSE;
- }
- else if (case_clause(clause))
- {
- foreach(temp, ((CaseExpr *) clause)->args)
- {
- CaseWhen *when = (CaseWhen *) lfirst(temp);
-
- if (contain_var_clause(when->expr))
- return TRUE;
- if (contain_var_clause(when->result))
- return TRUE;
- }
- return (contain_var_clause(((CaseExpr *) clause)->defresult));
- }
- else
- {
- elog(ERROR, "contain_var_clause: Cannot handle node type %d",
- nodeTag(clause));
- }
+ return contain_var_clause_walker(clause, NULL);
+}
- return FALSE;
+static bool
+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 */
+ return expression_tree_walker(node, contain_var_clause_walker, context);
}
/*
* pull_var_clause
- * Recursively pulls all var nodes from a clause by pulling vars from the
- * left and right operands of the clause.
+ * Recursively pulls all var nodes from an expression clause.
*
* Returns list of varnodes found. Note the varnodes themselves are not
* copied, only referenced.
@@ -168,68 +94,24 @@ contain_var_clause(Node *clause)
List *
pull_var_clause(Node *clause)
{
- List *retval = NIL;
- List *temp;
+ List *result = NIL;
- if (clause == NULL)
- return NIL;
- else if (IsA(clause, Var))
- retval = lcons(clause, NIL);
- else if (single_node(clause))
- retval = NIL;
- else if (IsA(clause, Iter))
- retval = pull_var_clause(((Iter *) clause)->iterexpr);
- else if (is_subplan(clause))
- {
- foreach(temp, ((Expr *) clause)->args)
- retval = nconc(retval, pull_var_clause(lfirst(temp)));
- /* Also get Var-s from left sides of Oper-s */
- foreach(temp, ((SubPlan *) ((Expr *) clause)->oper)->sublink->oper)
- retval = nconc(retval,
- pull_var_clause(lfirst(((Expr *) lfirst(temp))->args)));
- }
- else if (IsA(clause, Expr))
- {
-
- /*
- * Recursively scan the arguments of an expression. NOTE: this
- * must come after is_subplan() case since subplan is a kind of
- * Expr node.
- */
- foreach(temp, ((Expr *) clause)->args)
- retval = nconc(retval, pull_var_clause(lfirst(temp)));
- }
- else if (IsA(clause, Aggref))
- retval = pull_var_clause(((Aggref *) clause)->target);
- else if (IsA(clause, ArrayRef))
- {
- foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
- retval = nconc(retval, pull_var_clause(lfirst(temp)));
- foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
- retval = nconc(retval, pull_var_clause(lfirst(temp)));
- retval = nconc(retval,
- pull_var_clause(((ArrayRef *) clause)->refexpr));
- retval = nconc(retval,
- pull_var_clause(((ArrayRef *) clause)->refassgnexpr));
- }
- else if (case_clause(clause))
- {
- foreach(temp, ((CaseExpr *) clause)->args)
- {
- CaseWhen *when = (CaseWhen *) lfirst(temp);
+ pull_var_clause_walker(clause, &result);
+ return result;
+}
- retval = nconc(retval, pull_var_clause(when->expr));
- retval = nconc(retval, pull_var_clause(when->result));
- }
- retval = nconc(retval, pull_var_clause(((CaseExpr *) clause)->defresult));
- }
- else
+static bool
+pull_var_clause_walker(Node *node, List **listptr)
+{
+ if (node == NULL)
+ return false;
+ if (IsA(node, Var))
{
- elog(ERROR, "pull_var_clause: Cannot handle node type %d",
- nodeTag(clause));
+ *listptr = lappend(*listptr, node);
+ return false;
}
-
- return retval;
+ return expression_tree_walker(node, pull_var_clause_walker,
+ (void *) listptr);
}
/*