77 *
88 *
99 * 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 $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
1919#include "optimizer/var.h"
2020
2121
22+ typedef struct {
23+ List * varlist ;
24+ bool includeUpperVars ;
25+ }pull_var_clause_context ;
26+
2227static bool pull_varnos_walker (Node * node ,List * * listptr );
2328static 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 );
2531
2632
2733/*
2834 *pull_varnos
2935 *
3036 *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!
3239 */
3340List *
3441pull_varnos (Node * node )
@@ -47,7 +54,7 @@ pull_varnos_walker(Node *node, List **listptr)
4754if (IsA (node ,Var ))
4855{
4956Var * var = (Var * )node ;
50- if (!intMember (var -> varno ,* listptr ))
57+ if (var -> varlevelsup == 0 && !intMember (var -> varno ,* listptr ))
5158* listptr = lconsi (var -> varno ,* listptr );
5259return false;
5360}
@@ -56,7 +63,8 @@ pull_varnos_walker(Node *node, List **listptr)
5663
5764/*
5865 * 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).
6068 *
6169 * Returns true if any varnode found.
6270 */
@@ -72,36 +80,48 @@ contain_var_clause_walker(Node *node, void *context)
7280if (node == NULL )
7381return false;
7482if (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+ }
7688return expression_tree_walker (node ,contain_var_clause_walker ,context );
7789}
7890
7991/*
8092 * pull_var_clause
8193 * Recursively pulls all var nodes from an expression clause.
8294 *
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+ *
8399 * Returns list of varnodes found. Note the varnodes themselves are not
84100 * copied, only referenced.
85101 */
86102List *
87- pull_var_clause (Node * clause )
103+ pull_var_clause (Node * clause , bool includeUpperVars )
88104{
89- List * result = NIL ;
105+ pull_var_clause_context context ;
90106
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 ;
93112}
94113
95114static bool
96- pull_var_clause_walker (Node * node ,List * * listptr )
115+ pull_var_clause_walker (Node * node ,pull_var_clause_context * context )
97116{
98117if (node == NULL )
99118return false;
100119if (IsA (node ,Var ))
101120{
102- * listptr = lappend (* listptr ,node );
121+ if (((Var * )node )-> varlevelsup == 0 || context -> includeUpperVars )
122+ context -> varlist = lappend (context -> varlist ,node );
103123return false;
104124}
105125return expression_tree_walker (node ,pull_var_clause_walker ,
106- (void * )listptr );
126+ (void * )context );
107127}