]> granicus.if.org Git - postgresql/blob - src/backend/optimizer/util/var.c
Used modified version of indent that understands over 100 typedefs.
[postgresql] / src / backend / optimizer / util / var.c
1 /*-------------------------------------------------------------------------
2  *
3  * var.c--
4  *        Var node manipulation routines
5  *
6  * Copyright (c) 1994, Regents of the University of California
7  *
8  *
9  * IDENTIFICATION
10  *        $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.6 1997/09/08 21:45:56 momjian Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include <sys/types.h>
15
16 #include "postgres.h"
17
18 #include <nodes/relation.h>
19
20 #include "nodes/primnodes.h"
21 #include "nodes/nodeFuncs.h"
22
23 #include "optimizer/internal.h"
24 #include "optimizer/clauses.h"
25 #include "optimizer/var.h"
26
27 #include "parser/parsetree.h"
28
29 /*
30  *              find_varnos
31  *
32  *              Descends down part of a parsetree (qual or tlist),
33  *
34  *              XXX assumes varno's are always integers, which shouldn't be true...
35  *              (though it currently is, see primnodes.h)
36  */
37 List       *
38 pull_varnos(Node *me)
39 {
40         List       *i,
41                            *result = NIL;
42
43         if (me == NULL)
44                 return (NIL);
45
46         switch (nodeTag(me))
47         {
48                 case T_List:
49                         foreach(i, (List *) me)
50                         {
51                                 result = nconc(result, pull_varnos(lfirst(i)));
52                         }
53                         break;
54                 case T_ArrayRef:
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));
60                         break;
61                 case T_Var:
62                         result = lconsi(((Var *) me)->varno, NIL);
63                         break;
64                 default:
65                         break;
66         }
67         return (result);
68 }
69
70 /*
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.
74  *
75  *        Returns true if any varnode found.
76  */
77 bool
78 contain_var_clause(Node *clause)
79 {
80         if (clause == NULL)
81                 return FALSE;
82         else if (IsA(clause, Var))
83                 return TRUE;
84         else if (IsA(clause, Iter))
85                 return contain_var_clause(((Iter *) clause)->iterexpr);
86         else if (single_node(clause))
87                 return FALSE;
88         else if (or_clause(clause))
89         {
90                 List       *temp;
91
92                 foreach(temp, ((Expr *) clause)->args)
93                 {
94                         if (contain_var_clause(lfirst(temp)))
95                                 return TRUE;
96                 }
97                 return FALSE;
98         }
99         else if (is_funcclause(clause))
100         {
101                 List       *temp;
102
103                 foreach(temp, ((Expr *) clause)->args)
104                 {
105                         if (contain_var_clause(lfirst(temp)))
106                                 return TRUE;
107                 }
108                 return FALSE;
109         }
110         else if (IsA(clause, ArrayRef))
111         {
112                 List       *temp;
113
114                 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
115                 {
116                         if (contain_var_clause(lfirst(temp)))
117                                 return TRUE;
118                 }
119                 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
120                 {
121                         if (contain_var_clause(lfirst(temp)))
122                                 return TRUE;
123                 }
124                 if (contain_var_clause(((ArrayRef *) clause)->refexpr))
125                         return TRUE;
126                 if (contain_var_clause(((ArrayRef *) clause)->refassgnexpr))
127                         return TRUE;
128                 return FALSE;
129         }
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)));
135
136         return FALSE;
137 }
138
139 /*
140  * pull_var_clause--
141  *        Recursively pulls all var nodes from a clause by pulling vars from the
142  *        left and right operands of the clause.
143  *
144  *        Returns list of varnodes found.
145  */
146 List       *
147 pull_var_clause(Node *clause)
148 {
149         List       *retval = NIL;
150
151         if (clause == NULL)
152                 return (NIL);
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))
158                 retval = NIL;
159         else if (or_clause(clause))
160         {
161                 List       *temp;
162
163                 foreach(temp, ((Expr *) clause)->args)
164                         retval = nconc(retval, pull_var_clause(lfirst(temp)));
165         }
166         else if (is_funcclause(clause))
167         {
168                 List       *temp;
169
170                 foreach(temp, ((Expr *) clause)->args)
171                         retval = nconc(retval, pull_var_clause(lfirst(temp)));
172         }
173         else if (IsA(clause, Aggreg))
174         {
175                 retval = pull_var_clause(((Aggreg *) clause)->target);
176         }
177         else if (IsA(clause, ArrayRef))
178         {
179                 List       *temp;
180
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));
189         }
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)));
195         else
196                 retval = NIL;
197
198         return (retval);
199 }
200
201 /*
202  *              var_equal
203  *
204  *              Returns t iff two var nodes correspond to the same attribute.
205  */
206 bool
207 var_equal(Var *var1, Var *var2)
208 {
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))
213         {
214
215                 return (true);
216         }
217         else
218                 return (false);
219 }