1 /*-------------------------------------------------------------------------
4 * Var node manipulation routines
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.6 1997/09/08 21:45:56 momjian Exp $
12 *-------------------------------------------------------------------------
14 #include <sys/types.h>
18 #include <nodes/relation.h>
20 #include "nodes/primnodes.h"
21 #include "nodes/nodeFuncs.h"
23 #include "optimizer/internal.h"
24 #include "optimizer/clauses.h"
25 #include "optimizer/var.h"
27 #include "parser/parsetree.h"
32 * Descends down part of a parsetree (qual or tlist),
34 * XXX assumes varno's are always integers, which shouldn't be true...
35 * (though it currently is, see primnodes.h)
49 foreach(i, (List *) me)
51 result = nconc(result, pull_varnos(lfirst(i)));
55 foreach(i, ((ArrayRef *) me)->refupperindexpr)
56 result = nconc(result, pull_varnos(lfirst(i)));
57 foreach(i, ((ArrayRef *) me)->reflowerindexpr)
58 result = nconc(result, pull_varnos(lfirst(i)));
59 result = nconc(result, pull_varnos(((ArrayRef *) me)->refassgnexpr));
62 result = lconsi(((Var *) me)->varno, NIL);
71 * contain_var_clause--
72 * Recursively find var nodes from a clause by pulling vars from the
73 * left and right operands of the clause.
75 * Returns true if any varnode found.
78 contain_var_clause(Node *clause)
82 else if (IsA(clause, Var))
84 else if (IsA(clause, Iter))
85 return contain_var_clause(((Iter *) clause)->iterexpr);
86 else if (single_node(clause))
88 else if (or_clause(clause))
92 foreach(temp, ((Expr *) clause)->args)
94 if (contain_var_clause(lfirst(temp)))
99 else if (is_funcclause(clause))
103 foreach(temp, ((Expr *) clause)->args)
105 if (contain_var_clause(lfirst(temp)))
110 else if (IsA(clause, ArrayRef))
114 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
116 if (contain_var_clause(lfirst(temp)))
119 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
121 if (contain_var_clause(lfirst(temp)))
124 if (contain_var_clause(((ArrayRef *) clause)->refexpr))
126 if (contain_var_clause(((ArrayRef *) clause)->refassgnexpr))
130 else if (not_clause(clause))
131 return contain_var_clause((Node *) get_notclausearg((Expr *) clause));
132 else if (is_opclause(clause))
133 return (contain_var_clause((Node *) get_leftop((Expr *) clause)) ||
134 contain_var_clause((Node *) get_rightop((Expr *) clause)));
141 * Recursively pulls all var nodes from a clause by pulling vars from the
142 * left and right operands of the clause.
144 * Returns list of varnodes found.
147 pull_var_clause(Node *clause)
153 else if (IsA(clause, Var))
154 retval = lcons(clause, NIL);
155 else if (IsA(clause, Iter))
156 retval = pull_var_clause(((Iter *) clause)->iterexpr);
157 else if (single_node(clause))
159 else if (or_clause(clause))
163 foreach(temp, ((Expr *) clause)->args)
164 retval = nconc(retval, pull_var_clause(lfirst(temp)));
166 else if (is_funcclause(clause))
170 foreach(temp, ((Expr *) clause)->args)
171 retval = nconc(retval, pull_var_clause(lfirst(temp)));
173 else if (IsA(clause, Aggreg))
175 retval = pull_var_clause(((Aggreg *) clause)->target);
177 else if (IsA(clause, ArrayRef))
181 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
182 retval = nconc(retval, pull_var_clause(lfirst(temp)));
183 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
184 retval = nconc(retval, pull_var_clause(lfirst(temp)));
185 retval = nconc(retval,
186 pull_var_clause(((ArrayRef *) clause)->refexpr));
187 retval = nconc(retval,
188 pull_var_clause(((ArrayRef *) clause)->refassgnexpr));
190 else if (not_clause(clause))
191 retval = pull_var_clause((Node *) get_notclausearg((Expr *) clause));
192 else if (is_opclause(clause))
193 retval = nconc(pull_var_clause((Node *) get_leftop((Expr *) clause)),
194 pull_var_clause((Node *) get_rightop((Expr *) clause)));
204 * Returns t iff two var nodes correspond to the same attribute.
207 var_equal(Var *var1, Var *var2)
209 if (IsA(var1, Var) &&IsA(var2, Var) &&
210 (((Var *) var1)->varno == ((Var *) var2)->varno) &&
211 (((Var *) var1)->vartype == ((Var *) var2)->vartype) &&
212 (((Var *) var1)->varattno == ((Var *) var2)->varattno))