1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Clean up some mistakes in handling of uplevel Vars in planner.

Most parts of the planner should ignore, or indeed never even see, uplevel
Vars because they will be or have been replaced by Params.  There were a
couple of places that got it wrong though, probably my fault from recent
changes...
This commit is contained in:
Tom Lane
1999-08-26 05:09:06 +00:00
parent 5adebf83b6
commit 37d20eb855
6 changed files with 65 additions and 34 deletions

View File

@@ -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);
}