@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $ Header : / cvsroot / pgsql / src / backend / optimizer / util / var . c , v 1.23 1999 / 08 / 22 20 : 14 : 54 tgl Exp $
* $ Header : / cvsroot / pgsql / src / backend / optimizer / util / var . c , v 1.24 1999 / 08 / 26 05 : 09 : 06 tgl Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -19,16 +19,23 @@
# include "optimizer/var.h"
typedef struct {
List * varlist ;
bool includeUpperVars ;
} pull_var_clause_context ;
static bool pull_varnos_walker ( Node * node , List * * listptr ) ;
static bool contain_var_clause_walker ( Node * node , void * context ) ;
static bool pull_var_clause_walker ( Node * node , List * * listptr ) ;
static bool pull_var_clause_walker ( Node * node ,
pull_var_clause_context * context ) ;
/*
* pull_varnos
*
* Create a list of all the distinct varnos present in a parsetree
* ( tlist or qual ) .
* ( tlist or qual ) . Note that only varnos attached to level - zero
* Vars are considered - - - upper Vars refer to some other rtable !
*/
List *
pull_varnos ( Node * node )
@ -47,7 +54,7 @@ pull_varnos_walker(Node *node, List **listptr)
if ( IsA ( node , Var ) )
{
Var * var = ( Var * ) node ;
if ( ! intMember ( var - > varno , * listptr ) )
if ( var - > varlevelsup = = 0 & & ! intMember ( var - > varno , * listptr ) )
* listptr = lconsi ( var - > varno , * listptr ) ;
return false ;
}
@ -56,7 +63,8 @@ pull_varnos_walker(Node *node, List **listptr)
/*
* contain_var_clause
* Recursively scan a clause to discover whether it contains any Var nodes .
* Recursively scan a clause to discover whether it contains any Var nodes
* ( of the current query level ) .
*
* Returns true if any varnode found .
*/
@ -72,7 +80,11 @@ contain_var_clause_walker(Node *node, void *context)
if ( node = = NULL )
return false ;
if ( IsA ( node , Var ) )
return true ; /* abort the tree traversal and return true */
{
if ( ( ( Var * ) node ) - > varlevelsup = = 0 )
return true ; /* abort the tree traversal and return true */
return false ;
}
return expression_tree_walker ( node , contain_var_clause_walker , context ) ;
}
@ -80,28 +92,36 @@ contain_var_clause_walker(Node *node, void *context)
* pull_var_clause
* Recursively pulls all var nodes from an expression clause .
*
* Upper - level vars ( with varlevelsup > 0 ) are included only
* if includeUpperVars is true . Most callers probably want
* to ignore upper - level vars .
*
* Returns list of varnodes found . Note the varnodes themselves are not
* copied , only referenced .
*/
List *
pull_var_clause ( Node * clause )
pull_var_clause ( Node * clause , bool includeUpperVars )
{
List * result = NIL ;
pull_var_clause_context context ;
pull_var_clause_walker ( clause , & result ) ;
return result ;
context . varlist = NIL ;
context . includeUpperVars = includeUpperVars ;
pull_var_clause_walker ( clause , & context ) ;
return context . varlist ;
}
static bool
pull_var_clause_walker ( Node * node , List * * listptr )
pull_var_clause_walker ( Node * node , pull_var_clause_context * context )
{
if ( node = = NULL )
return false ;
if ( IsA ( node , Var ) )
{
* listptr = lappend ( * listptr , node ) ;
if ( ( ( Var * ) node ) - > varlevelsup = = 0 | | context - > includeUpperVars )
context - > varlist = lappend ( context - > varlist , node ) ;
return false ;
}
return expression_tree_walker ( node , pull_var_clause_walker ,
( void * ) listptr ) ;
( void * ) context ) ;
}