1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Adjust API of expression_tree_mutator and query_tree_mutator to

simplify callers.  It turns out the common case is that the caller
does want to recurse into sub-queries, so push support for that into
these subroutines.
This commit is contained in:
Tom Lane
2003-01-17 02:01:21 +00:00
parent 227a404cf4
commit a4d82dd4b4
8 changed files with 167 additions and 220 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.45 2003/01/16 18:26:02 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.46 2003/01/17 02:01:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -20,16 +20,6 @@
#include "parser/parsetree.h"
/* macros borrowed from expression_tree_mutator */
#define FLATCOPY(newnode, node, nodetype) \
( (newnode) = makeNode(nodetype), \
memcpy((newnode), (node), sizeof(nodetype)) )
#define MUTATE(newfield, oldfield, fieldtype, mutator, context) \
( (newfield) = (fieldtype) mutator((Node *) (oldfield), (context)) )
typedef struct
{
List *varlist;
@ -87,14 +77,12 @@ pull_varnos(Node *node)
/*
* Must be prepared to start with a Query or a bare expression tree;
* if it's a Query, go straight to query_tree_walker to make sure that
* sublevels_up doesn't get incremented prematurely.
* if it's a Query, we don't want to increment sublevels_up.
*/
if (node && IsA(node, Query))
query_tree_walker((Query *) node, pull_varnos_walker,
(void *) &context, 0);
else
pull_varnos_walker(node, &context);
query_or_expression_tree_walker(node,
pull_varnos_walker,
(void *) &context,
0);
return context.varlist;
}
@ -113,24 +101,6 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
context->varlist = lconsi(var->varno, context->varlist);
return false;
}
if (is_subplan(node))
{
/*
* Already-planned subquery. Examine the args list (parameters to
* be passed to subquery), as well as the exprs list which is
* executed by the outer query. But short-circuit recursion into
* the subquery itself, which would be a waste of effort.
*/
SubPlan *subplan = (SubPlan *) node;
if (pull_varnos_walker((Node *) subplan->exprs,
context))
return true;
if (pull_varnos_walker((Node *) subplan->args,
context))
return true;
return false;
}
if (IsA(node, Query))
{
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
@ -169,15 +139,12 @@ contain_var_reference(Node *node, int varno, int varattno, int levelsup)
/*
* Must be prepared to start with a Query or a bare expression tree;
* if it's a Query, go straight to query_tree_walker to make sure that
* sublevels_up doesn't get incremented prematurely.
* if it's a Query, we don't want to increment sublevels_up.
*/
if (node && IsA(node, Query))
return query_tree_walker((Query *) node,
contain_var_reference_walker,
(void *) &context, 0);
else
return contain_var_reference_walker(node, &context);
return query_or_expression_tree_walker(node,
contain_var_reference_walker,
(void *) &context,
0);
}
static bool
@ -196,24 +163,6 @@ contain_var_reference_walker(Node *node,
return true;
return false;
}
if (is_subplan(node))
{
/*
* Already-planned subquery. Examine the args list (parameters to
* be passed to subquery), as well as the exprs list which is
* executed by the outer query. But short-circuit recursion into
* the subquery itself, which would be a waste of effort.
*/
SubPlan *subplan = (SubPlan *) node;
if (contain_var_reference_walker((Node *) subplan->exprs,
context))
return true;
if (contain_var_reference_walker((Node *) subplan->args,
context))
return true;
return false;
}
if (IsA(node, Query))
{
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
@ -361,32 +310,16 @@ flatten_join_alias_vars_mutator(Node *node,
return flatten_join_alias_vars_mutator(newvar, context);
}
/*
* Since expression_tree_mutator won't touch subselects, we have to
* handle them specially.
*/
if (IsA(node, SubLink))
{
SubLink *sublink = (SubLink *) node;
SubLink *newnode;
FLATCOPY(newnode, sublink, SubLink);
MUTATE(newnode->lefthand, sublink->lefthand, List *,
flatten_join_alias_vars_mutator, context);
MUTATE(newnode->subselect, sublink->subselect, Node *,
flatten_join_alias_vars_mutator, context);
return (Node *) newnode;
}
if (IsA(node, Query))
{
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
Query *query = (Query *) node;
Query *newnode;
FLATCOPY(newnode, query, Query);
context->sublevels_up++;
query_tree_mutator(newnode, flatten_join_alias_vars_mutator,
(void *) context, QTW_IGNORE_JOINALIASES);
newnode = query_tree_mutator((Query *) node,
flatten_join_alias_vars_mutator,
(void *) context,
QTW_IGNORE_JOINALIASES);
context->sublevels_up--;
return (Node *) newnode;
}