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.12 1998/06/15 19:28:50 momjian Exp $
12 *-------------------------------------------------------------------------
14 #include <sys/types.h>
18 #include <nodes/relation.h>
20 #include "nodes/primnodes.h"
21 #include "nodes/plannodes.h"
22 #include "nodes/nodeFuncs.h"
24 #include "optimizer/internal.h"
25 #include "optimizer/clauses.h"
26 #include "optimizer/var.h"
28 #include "parser/parsetree.h"
33 * Descends down part of a parsetree (qual or tlist),
35 * XXX assumes varno's are always integers, which shouldn't be true...
36 * (though it currently is, see primnodes.h)
50 foreach(i, (List *) me)
51 result = nconc(result, pull_varnos(lfirst(i)));
54 foreach(i, ((ArrayRef *) me)->refupperindexpr)
55 result = nconc(result, pull_varnos(lfirst(i)));
56 foreach(i, ((ArrayRef *) me)->reflowerindexpr)
57 result = nconc(result, pull_varnos(lfirst(i)));
58 result = nconc(result, pull_varnos(((ArrayRef *) me)->refassgnexpr));
61 result = lconsi(((Var *) me)->varno, NIL);
70 * contain_var_clause--
71 * Recursively find var nodes from a clause by pulling vars from the
72 * left and right operands of the clause.
74 * Returns true if any varnode found.
77 contain_var_clause(Node *clause)
81 else if (IsA(clause, Var))
83 else if (IsA(clause, Iter))
84 return contain_var_clause(((Iter *) clause)->iterexpr);
85 else if (single_node(clause))
87 else if (or_clause(clause) || and_clause(clause) || is_funcclause(clause))
91 foreach(temp, ((Expr *) clause)->args)
93 if (contain_var_clause(lfirst(temp)))
98 else if (is_subplan(clause))
102 foreach(temp, ((Expr *) clause)->args)
104 if (contain_var_clause(lfirst(temp)))
107 /* Ok - check left sides of Oper-s */
108 foreach(temp, ((SubPlan *) ((Expr *) clause)->oper)->sublink->oper)
110 if (contain_var_clause(lfirst(((Expr *) lfirst(temp))->args)))
115 else if (IsA(clause, ArrayRef))
119 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
121 if (contain_var_clause(lfirst(temp)))
124 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
126 if (contain_var_clause(lfirst(temp)))
129 if (contain_var_clause(((ArrayRef *) clause)->refexpr))
131 if (contain_var_clause(((ArrayRef *) clause)->refassgnexpr))
135 else if (not_clause(clause))
136 return contain_var_clause((Node *) get_notclausearg((Expr *) clause));
137 else if (is_opclause(clause))
138 return (contain_var_clause((Node *) get_leftop((Expr *) clause)) ||
139 contain_var_clause((Node *) get_rightop((Expr *) clause)));
146 * Recursively pulls all var nodes from a clause by pulling vars from the
147 * left and right operands of the clause.
149 * Returns list of varnodes found.
152 pull_var_clause(Node *clause)
158 else if (IsA(clause, Var))
159 retval = lcons(clause, NIL);
160 else if (IsA(clause, Iter))
161 retval = pull_var_clause(((Iter *) clause)->iterexpr);
162 else if (single_node(clause))
164 else if (or_clause(clause) || and_clause(clause) || is_funcclause(clause))
168 foreach(temp, ((Expr *) clause)->args)
169 retval = nconc(retval, pull_var_clause(lfirst(temp)));
171 else if (is_subplan(clause))
175 foreach(temp, ((Expr *) clause)->args)
176 retval = nconc(retval, pull_var_clause(lfirst(temp)));
177 /* Ok - get Var-s from left sides of Oper-s */
178 foreach(temp, ((SubPlan *) ((Expr *) clause)->oper)->sublink->oper)
179 retval = nconc(retval,
180 pull_var_clause(lfirst(((Expr *) lfirst(temp))->args)));
182 else if (IsA(clause, Aggreg))
183 retval = pull_var_clause(((Aggreg *) clause)->target);
184 else if (IsA(clause, ArrayRef))
188 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
189 retval = nconc(retval, pull_var_clause(lfirst(temp)));
190 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
191 retval = nconc(retval, pull_var_clause(lfirst(temp)));
192 retval = nconc(retval,
193 pull_var_clause(((ArrayRef *) clause)->refexpr));
194 retval = nconc(retval,
195 pull_var_clause(((ArrayRef *) clause)->refassgnexpr));
197 else if (not_clause(clause))
198 retval = pull_var_clause((Node *) get_notclausearg((Expr *) clause));
199 else if (is_opclause(clause))
200 retval = nconc(pull_var_clause((Node *) get_leftop((Expr *) clause)),
201 pull_var_clause((Node *) get_rightop((Expr *) clause)));
211 * Returns t iff two var nodes correspond to the same attribute.
214 var_equal(Var *var1, Var *var2)
216 if (IsA(var1, Var) &&IsA(var2, Var) &&
217 (((Var *) var1)->varno == ((Var *) var2)->varno) &&
218 (((Var *) var1)->vartype == ((Var *) var2)->vartype) &&
219 (((Var *) var1)->vartypmod == ((Var *) var2)->vartypmod) &&
220 (((Var *) var1)->varlevelsup == ((Var *) var2)->varlevelsup) &&
221 (((Var *) var1)->varattno == ((Var *) var2)->varattno))
223 Assert(((Var *) var1)->varlevelsup == 0);