7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.23 1999/08/22 20:14:54 tgl Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.24 1999/08/26 05:09:06 tgl Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
19
19
#include "optimizer/var.h"
20
20
21
21
22
+ typedef struct {
23
+ List * varlist ;
24
+ bool includeUpperVars ;
25
+ } pull_var_clause_context ;
26
+
22
27
static bool pull_varnos_walker (Node * node , List * * listptr );
23
28
static bool contain_var_clause_walker (Node * node , void * context );
24
- static bool pull_var_clause_walker (Node * node , List * * listptr );
29
+ static bool pull_var_clause_walker (Node * node ,
30
+ pull_var_clause_context * context );
25
31
26
32
27
33
/*
28
34
* pull_varnos
29
35
*
30
36
* Create a list of all the distinct varnos present in a parsetree
31
- * (tlist or qual).
37
+ * (tlist or qual). Note that only varnos attached to level-zero
38
+ * Vars are considered --- upper Vars refer to some other rtable!
32
39
*/
33
40
List *
34
41
pull_varnos (Node * node )
@@ -47,7 +54,7 @@ pull_varnos_walker(Node *node, List **listptr)
47
54
if (IsA (node , Var ))
48
55
{
49
56
Var * var = (Var * ) node ;
50
- if (!intMember (var -> varno , * listptr ))
57
+ if (var -> varlevelsup == 0 && !intMember (var -> varno , * listptr ))
51
58
* listptr = lconsi (var -> varno , * listptr );
52
59
return false;
53
60
}
@@ -56,7 +63,8 @@ pull_varnos_walker(Node *node, List **listptr)
56
63
57
64
/*
58
65
* contain_var_clause
59
- * Recursively scan a clause to discover whether it contains any Var nodes.
66
+ * Recursively scan a clause to discover whether it contains any Var nodes
67
+ * (of the current query level).
60
68
*
61
69
* Returns true if any varnode found.
62
70
*/
@@ -72,36 +80,48 @@ contain_var_clause_walker(Node *node, void *context)
72
80
if (node == NULL )
73
81
return false;
74
82
if (IsA (node , Var ))
75
- return true; /* abort the tree traversal and return true */
83
+ {
84
+ if (((Var * ) node )-> varlevelsup == 0 )
85
+ return true; /* abort the tree traversal and return true */
86
+ return false;
87
+ }
76
88
return expression_tree_walker (node , contain_var_clause_walker , context );
77
89
}
78
90
79
91
/*
80
92
* pull_var_clause
81
93
* Recursively pulls all var nodes from an expression clause.
82
94
*
95
+ * Upper-level vars (with varlevelsup > 0) are included only
96
+ * if includeUpperVars is true. Most callers probably want
97
+ * to ignore upper-level vars.
98
+ *
83
99
* Returns list of varnodes found. Note the varnodes themselves are not
84
100
* copied, only referenced.
85
101
*/
86
102
List *
87
- pull_var_clause (Node * clause )
103
+ pull_var_clause (Node * clause , bool includeUpperVars )
88
104
{
89
- List * result = NIL ;
105
+ pull_var_clause_context context ;
90
106
91
- pull_var_clause_walker (clause , & result );
92
- return result ;
107
+ context .varlist = NIL ;
108
+ context .includeUpperVars = includeUpperVars ;
109
+
110
+ pull_var_clause_walker (clause , & context );
111
+ return context .varlist ;
93
112
}
94
113
95
114
static bool
96
- pull_var_clause_walker (Node * node , List * * listptr )
115
+ pull_var_clause_walker (Node * node , pull_var_clause_context * context )
97
116
{
98
117
if (node == NULL )
99
118
return false;
100
119
if (IsA (node , Var ))
101
120
{
102
- * listptr = lappend (* listptr , node );
121
+ if (((Var * ) node )-> varlevelsup == 0 || context -> includeUpperVars )
122
+ context -> varlist = lappend (context -> varlist , node );
103
123
return false;
104
124
}
105
125
return expression_tree_walker (node , pull_var_clause_walker ,
106
- (void * ) listptr );
126
+ (void * ) context );
107
127
}
0 commit comments