Commit 6fdc44be authored by Tom Lane's avatar Tom Lane

Tweak querytree-dependency-extraction code so that columns of tables

that are explicitly JOINed are not considered dependencies unless they
are actually used in the query: mere presence in the joinaliasvars
list of a JOIN RTE doesn't count as being used.  The patch touches
a number of files because I needed to generalize the API of
query_tree_walker to support an additional flag bit, but the changes
are otherwise quite small.
parent d634a590
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.9 2002/09/04 20:31:13 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.10 2002/09/11 14:48:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -684,6 +684,12 @@ recordDependencyOnExpr(const ObjectAddress *depender, ...@@ -684,6 +684,12 @@ recordDependencyOnExpr(const ObjectAddress *depender,
/* /*
* Recursively search an expression tree for object references. * Recursively search an expression tree for object references.
*
* Note: we avoid creating references to columns of tables that participate
* in an SQL JOIN construct, but are not actually used anywhere in the query.
* To do so, we do not scan the joinaliasvars list of a join RTE while
* scanning the query rangetable, but instead scan each individual entry
* of the alias list when we find a reference to it.
*/ */
static bool static bool
find_expr_references_walker(Node *node, find_expr_references_walker(Node *node,
...@@ -716,10 +722,24 @@ find_expr_references_walker(Node *node, ...@@ -716,10 +722,24 @@ find_expr_references_walker(Node *node,
elog(ERROR, "find_expr_references_walker: bogus varno %d", elog(ERROR, "find_expr_references_walker: bogus varno %d",
var->varno); var->varno);
rte = rt_fetch(var->varno, rtable); rte = rt_fetch(var->varno, rtable);
/* If it's a plain relation, reference this column */
if (rte->rtekind == RTE_RELATION) if (rte->rtekind == RTE_RELATION)
{
/* If it's a plain relation, reference this column */
/* NB: this code works for whole-row Var with attno 0, too */
add_object_address(OCLASS_CLASS, rte->relid, var->varattno, add_object_address(OCLASS_CLASS, rte->relid, var->varattno,
&context->addrs); &context->addrs);
}
else if (rte->rtekind == RTE_JOIN)
{
/* Scan join output column to add references to join inputs */
if (var->varattno <= 0 ||
var->varattno > length(rte->joinaliasvars))
elog(ERROR, "find_expr_references_walker: bogus varattno %d",
var->varattno);
find_expr_references_walker((Node *) nth(var->varattno - 1,
rte->joinaliasvars),
context);
}
return false; return false;
} }
if (IsA(node, Expr)) if (IsA(node, Expr))
...@@ -766,7 +786,7 @@ find_expr_references_walker(Node *node, ...@@ -766,7 +786,7 @@ find_expr_references_walker(Node *node,
* Add whole-relation refs for each plain relation mentioned in * Add whole-relation refs for each plain relation mentioned in
* the subquery's rtable. (Note: query_tree_walker takes care of * the subquery's rtable. (Note: query_tree_walker takes care of
* recursing into RTE_FUNCTION and RTE_SUBQUERY RTEs, so no need * recursing into RTE_FUNCTION and RTE_SUBQUERY RTEs, so no need
* to do that here.) * to do that here. But keep it from looking at join alias lists.)
*/ */
foreach(rtable, query->rtable) foreach(rtable, query->rtable)
{ {
...@@ -781,7 +801,8 @@ find_expr_references_walker(Node *node, ...@@ -781,7 +801,8 @@ find_expr_references_walker(Node *node,
context->rtables = lcons(query->rtable, context->rtables); context->rtables = lcons(query->rtable, context->rtables);
result = query_tree_walker(query, result = query_tree_walker(query,
find_expr_references_walker, find_expr_references_walker,
(void *) context, true); (void *) context,
QTW_IGNORE_JOINALIASES);
context->rtables = lnext(context->rtables); context->rtables = lnext(context->rtables);
return result; return result;
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.78 2002/09/04 20:31:22 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.79 2002/09/11 14:48:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -774,7 +774,7 @@ adjust_inherited_attrs(Node *node, ...@@ -774,7 +774,7 @@ adjust_inherited_attrs(Node *node,
if (newnode->resultRelation == old_rt_index) if (newnode->resultRelation == old_rt_index)
newnode->resultRelation = new_rt_index; newnode->resultRelation = new_rt_index;
query_tree_mutator(newnode, adjust_inherited_attrs_mutator, query_tree_mutator(newnode, adjust_inherited_attrs_mutator,
(void *) &context, false); (void *) &context, QTW_IGNORE_SUBQUERIES);
return (Node *) newnode; return (Node *) newnode;
} }
else else
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.108 2002/09/04 20:31:22 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.109 2002/09/11 14:48:54 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -1788,7 +1788,7 @@ simplify_op_or_func(Expr *expr, List *args) ...@@ -1788,7 +1788,7 @@ simplify_op_or_func(Expr *expr, List *args)
* { * {
* adjust context for subquery; * adjust context for subquery;
* result = query_tree_walker((Query *) node, my_walker, context, * result = query_tree_walker((Query *) node, my_walker, context,
* true); // to visit subquery RTEs too * 0); // to visit rtable items too
* restore context if needed; * restore context if needed;
* return result; * return result;
* } * }
...@@ -1994,16 +1994,17 @@ expression_tree_walker(Node *node, ...@@ -1994,16 +1994,17 @@ expression_tree_walker(Node *node,
* walker intends to descend into subqueries. It is also useful for * walker intends to descend into subqueries. It is also useful for
* descending into subqueries within a walker. * descending into subqueries within a walker.
* *
* If visitQueryRTEs is true, the walker will also be called on sub-Query * Some callers want to suppress visitation of certain items in the sub-Query,
* nodes present in subquery rangetable entries of the given Query. This * typically because they need to process them specially, or don't actually
* is optional since some callers handle those sub-queries separately, * want to recurse into subqueries. This is supported by the flags argument,
* or don't really want to see subqueries anyway. * which is the bitwise OR of flag values to suppress visitation of
* indicated items. (More flag bits may be added as needed.)
*/ */
bool bool
query_tree_walker(Query *query, query_tree_walker(Query *query,
bool (*walker) (), bool (*walker) (),
void *context, void *context,
bool visitQueryRTEs) int flags)
{ {
List *rt; List *rt;
...@@ -2028,11 +2029,12 @@ query_tree_walker(Query *query, ...@@ -2028,11 +2029,12 @@ query_tree_walker(Query *query,
/* nothing to do */ /* nothing to do */
break; break;
case RTE_SUBQUERY: case RTE_SUBQUERY:
if (visitQueryRTEs) if (! (flags & QTW_IGNORE_SUBQUERIES))
if (walker(rte->subquery, context)) if (walker(rte->subquery, context))
return true; return true;
break; break;
case RTE_JOIN: case RTE_JOIN:
if (! (flags & QTW_IGNORE_JOINALIASES))
if (walker(rte->joinaliasvars, context)) if (walker(rte->joinaliasvars, context))
return true; return true;
break; break;
...@@ -2388,16 +2390,17 @@ expression_tree_mutator(Node *node, ...@@ -2388,16 +2390,17 @@ expression_tree_mutator(Node *node,
* if you don't want to change the original. All substructure is safely * if you don't want to change the original. All substructure is safely
* copied, however. * copied, however.
* *
* If visitQueryRTEs is true, the mutator will also be called on sub-Query * Some callers want to suppress mutating of certain items in the sub-Query,
* nodes present in subquery rangetable entries of the given Query. This * typically because they need to process them specially, or don't actually
* is optional since some callers handle those sub-queries separately, * want to recurse into subqueries. This is supported by the flags argument,
* or don't really want to see subqueries anyway. * which is the bitwise OR of flag values to suppress mutating of
* indicated items. (More flag bits may be added as needed.)
*/ */
void void
query_tree_mutator(Query *query, query_tree_mutator(Query *query,
Node *(*mutator) (), Node *(*mutator) (),
void *context, void *context,
bool visitQueryRTEs) int flags)
{ {
List *newrt = NIL; List *newrt = NIL;
List *rt; List *rt;
...@@ -2420,7 +2423,7 @@ query_tree_mutator(Query *query, ...@@ -2420,7 +2423,7 @@ query_tree_mutator(Query *query,
/* nothing to do, don't bother to make a copy */ /* nothing to do, don't bother to make a copy */
break; break;
case RTE_SUBQUERY: case RTE_SUBQUERY:
if (visitQueryRTEs) if (! (flags & QTW_IGNORE_SUBQUERIES))
{ {
FLATCOPY(newrte, rte, RangeTblEntry); FLATCOPY(newrte, rte, RangeTblEntry);
CHECKFLATCOPY(newrte->subquery, rte->subquery, Query); CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
...@@ -2429,9 +2432,12 @@ query_tree_mutator(Query *query, ...@@ -2429,9 +2432,12 @@ query_tree_mutator(Query *query,
} }
break; break;
case RTE_JOIN: case RTE_JOIN:
if (! (flags & QTW_IGNORE_JOINALIASES))
{
FLATCOPY(newrte, rte, RangeTblEntry); FLATCOPY(newrte, rte, RangeTblEntry);
MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *); MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
rte = newrte; rte = newrte;
}
break; break;
case RTE_FUNCTION: case RTE_FUNCTION:
FLATCOPY(newrte, rte, RangeTblEntry); FLATCOPY(newrte, rte, RangeTblEntry);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.39 2002/09/04 20:31:22 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.40 2002/09/11 14:48:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -82,7 +82,7 @@ pull_varnos(Node *node) ...@@ -82,7 +82,7 @@ pull_varnos(Node *node)
*/ */
if (node && IsA(node, Query)) if (node && IsA(node, Query))
query_tree_walker((Query *) node, pull_varnos_walker, query_tree_walker((Query *) node, pull_varnos_walker,
(void *) &context, true); (void *) &context, 0);
else else
pull_varnos_walker(node, &context); pull_varnos_walker(node, &context);
...@@ -128,7 +128,7 @@ pull_varnos_walker(Node *node, pull_varnos_context *context) ...@@ -128,7 +128,7 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
context->sublevels_up++; context->sublevels_up++;
result = query_tree_walker((Query *) node, pull_varnos_walker, result = query_tree_walker((Query *) node, pull_varnos_walker,
(void *) context, true); (void *) context, 0);
context->sublevels_up--; context->sublevels_up--;
return result; return result;
} }
...@@ -165,7 +165,7 @@ contain_var_reference(Node *node, int varno, int varattno, int levelsup) ...@@ -165,7 +165,7 @@ contain_var_reference(Node *node, int varno, int varattno, int levelsup)
if (node && IsA(node, Query)) if (node && IsA(node, Query))
return query_tree_walker((Query *) node, return query_tree_walker((Query *) node,
contain_var_reference_walker, contain_var_reference_walker,
(void *) &context, true); (void *) &context, 0);
else else
return contain_var_reference_walker(node, &context); return contain_var_reference_walker(node, &context);
} }
...@@ -212,7 +212,7 @@ contain_var_reference_walker(Node *node, ...@@ -212,7 +212,7 @@ contain_var_reference_walker(Node *node,
context->sublevels_up++; context->sublevels_up++;
result = query_tree_walker((Query *) node, result = query_tree_walker((Query *) node,
contain_var_reference_walker, contain_var_reference_walker,
(void *) context, true); (void *) context, 0);
context->sublevels_up--; context->sublevels_up--;
return result; return result;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.79 2002/09/04 20:31:25 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.80 2002/09/11 14:48:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -464,9 +464,10 @@ setRuleCheckAsUser(Query *qry, Oid userid) ...@@ -464,9 +464,10 @@ setRuleCheckAsUser(Query *qry, Oid userid)
} }
/* If there are sublinks, search for them and process their RTEs */ /* If there are sublinks, search for them and process their RTEs */
/* ignore subqueries in rtable because we already processed them */
if (qry->hasSubLinks) if (qry->hasSubLinks)
query_tree_walker(qry, setRuleCheckAsUser_walker, (void *) &userid, query_tree_walker(qry, setRuleCheckAsUser_walker, (void *) &userid,
false /* already did the ones in rtable */ ); QTW_IGNORE_SUBQUERIES);
} }
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.108 2002/09/04 20:31:25 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.109 2002/09/11 14:48:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -822,11 +822,12 @@ fireRIRrules(Query *parsetree) ...@@ -822,11 +822,12 @@ fireRIRrules(Query *parsetree)
} }
/* /*
* Recurse into sublink subqueries, too. * Recurse into sublink subqueries, too. But we already did the ones
* in the rtable.
*/ */
if (parsetree->hasSubLinks) if (parsetree->hasSubLinks)
query_tree_walker(parsetree, fireRIRonSubLink, NULL, query_tree_walker(parsetree, fireRIRonSubLink, NULL,
false /* already handled the ones in rtable */ ); QTW_IGNORE_SUBQUERIES);
/* /*
* If the query was marked having aggregates, check if this is still * If the query was marked having aggregates, check if this is still
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.65 2002/09/04 20:31:25 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.66 2002/09/11 14:48:54 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -49,7 +49,7 @@ checkExprHasAggs(Node *node) ...@@ -49,7 +49,7 @@ checkExprHasAggs(Node *node)
*/ */
if (node && IsA(node, Query)) if (node && IsA(node, Query))
return query_tree_walker((Query *) node, checkExprHasAggs_walker, return query_tree_walker((Query *) node, checkExprHasAggs_walker,
NULL, false); NULL, QTW_IGNORE_SUBQUERIES);
else else
return checkExprHasAggs_walker(node, NULL); return checkExprHasAggs_walker(node, NULL);
} }
...@@ -79,7 +79,7 @@ checkExprHasSubLink(Node *node) ...@@ -79,7 +79,7 @@ checkExprHasSubLink(Node *node)
*/ */
if (node && IsA(node, Query)) if (node && IsA(node, Query))
return query_tree_walker((Query *) node, checkExprHasSubLink_walker, return query_tree_walker((Query *) node, checkExprHasSubLink_walker,
NULL, false); NULL, QTW_IGNORE_SUBQUERIES);
else else
return checkExprHasSubLink_walker(node, NULL); return checkExprHasSubLink_walker(node, NULL);
} }
...@@ -155,7 +155,7 @@ OffsetVarNodes_walker(Node *node, OffsetVarNodes_context *context) ...@@ -155,7 +155,7 @@ OffsetVarNodes_walker(Node *node, OffsetVarNodes_context *context)
context->sublevels_up++; context->sublevels_up++;
result = query_tree_walker((Query *) node, OffsetVarNodes_walker, result = query_tree_walker((Query *) node, OffsetVarNodes_walker,
(void *) context, true); (void *) context, 0);
context->sublevels_up--; context->sublevels_up--;
return result; return result;
} }
...@@ -196,7 +196,7 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up) ...@@ -196,7 +196,7 @@ OffsetVarNodes(Node *node, int offset, int sublevels_up)
lfirsti(l) += offset; lfirsti(l) += offset;
} }
query_tree_walker(qry, OffsetVarNodes_walker, query_tree_walker(qry, OffsetVarNodes_walker,
(void *) &context, true); (void *) &context, 0);
} }
else else
OffsetVarNodes_walker(node, &context); OffsetVarNodes_walker(node, &context);
...@@ -265,7 +265,7 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context) ...@@ -265,7 +265,7 @@ ChangeVarNodes_walker(Node *node, ChangeVarNodes_context *context)
context->sublevels_up++; context->sublevels_up++;
result = query_tree_walker((Query *) node, ChangeVarNodes_walker, result = query_tree_walker((Query *) node, ChangeVarNodes_walker,
(void *) context, true); (void *) context, 0);
context->sublevels_up--; context->sublevels_up--;
return result; return result;
} }
...@@ -310,7 +310,7 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up) ...@@ -310,7 +310,7 @@ ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
} }
} }
query_tree_walker(qry, ChangeVarNodes_walker, query_tree_walker(qry, ChangeVarNodes_walker,
(void *) &context, true); (void *) &context, 0);
} }
else else
ChangeVarNodes_walker(node, &context); ChangeVarNodes_walker(node, &context);
...@@ -361,7 +361,7 @@ IncrementVarSublevelsUp_walker(Node *node, ...@@ -361,7 +361,7 @@ IncrementVarSublevelsUp_walker(Node *node,
context->min_sublevels_up++; context->min_sublevels_up++;
result = query_tree_walker((Query *) node, result = query_tree_walker((Query *) node,
IncrementVarSublevelsUp_walker, IncrementVarSublevelsUp_walker,
(void *) context, true); (void *) context, 0);
context->min_sublevels_up--; context->min_sublevels_up--;
return result; return result;
} }
...@@ -385,7 +385,7 @@ IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, ...@@ -385,7 +385,7 @@ IncrementVarSublevelsUp(Node *node, int delta_sublevels_up,
*/ */
if (node && IsA(node, Query)) if (node && IsA(node, Query))
query_tree_walker((Query *) node, IncrementVarSublevelsUp_walker, query_tree_walker((Query *) node, IncrementVarSublevelsUp_walker,
(void *) &context, true); (void *) &context, 0);
else else
IncrementVarSublevelsUp_walker(node, &context); IncrementVarSublevelsUp_walker(node, &context);
} }
...@@ -443,7 +443,7 @@ rangeTableEntry_used_walker(Node *node, ...@@ -443,7 +443,7 @@ rangeTableEntry_used_walker(Node *node,
context->sublevels_up++; context->sublevels_up++;
result = query_tree_walker((Query *) node, rangeTableEntry_used_walker, result = query_tree_walker((Query *) node, rangeTableEntry_used_walker,
(void *) context, true); (void *) context, 0);
context->sublevels_up--; context->sublevels_up--;
return result; return result;
} }
...@@ -466,7 +466,7 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up) ...@@ -466,7 +466,7 @@ rangeTableEntry_used(Node *node, int rt_index, int sublevels_up)
*/ */
if (node && IsA(node, Query)) if (node && IsA(node, Query))
return query_tree_walker((Query *) node, rangeTableEntry_used_walker, return query_tree_walker((Query *) node, rangeTableEntry_used_walker,
(void *) &context, true); (void *) &context, 0);
else else
return rangeTableEntry_used_walker(node, &context); return rangeTableEntry_used_walker(node, &context);
} }
...@@ -508,7 +508,7 @@ attribute_used_walker(Node *node, ...@@ -508,7 +508,7 @@ attribute_used_walker(Node *node,
context->sublevels_up++; context->sublevels_up++;
result = query_tree_walker((Query *) node, attribute_used_walker, result = query_tree_walker((Query *) node, attribute_used_walker,
(void *) context, true); (void *) context, 0);
context->sublevels_up--; context->sublevels_up--;
return result; return result;
} }
...@@ -532,7 +532,7 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up) ...@@ -532,7 +532,7 @@ attribute_used(Node *node, int rt_index, int attno, int sublevels_up)
*/ */
if (node && IsA(node, Query)) if (node && IsA(node, Query))
return query_tree_walker((Query *) node, attribute_used_walker, return query_tree_walker((Query *) node, attribute_used_walker,
(void *) &context, true); (void *) &context, 0);
else else
return attribute_used_walker(node, &context); return attribute_used_walker(node, &context);
} }
...@@ -851,7 +851,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context) ...@@ -851,7 +851,7 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
FLATCOPY(newnode, query, Query); FLATCOPY(newnode, query, Query);
context->sublevels_up++; context->sublevels_up++;
query_tree_mutator(newnode, ResolveNew_mutator, context, true); query_tree_mutator(newnode, ResolveNew_mutator, context, 0);
context->sublevels_up--; context->sublevels_up--;
return (Node *) newnode; return (Node *) newnode;
} }
...@@ -883,7 +883,7 @@ ResolveNew(Node *node, int target_varno, int sublevels_up, ...@@ -883,7 +883,7 @@ ResolveNew(Node *node, int target_varno, int sublevels_up,
FLATCOPY(newnode, query, Query); FLATCOPY(newnode, query, Query);
query_tree_mutator(newnode, ResolveNew_mutator, query_tree_mutator(newnode, ResolveNew_mutator,
(void *) &context, true); (void *) &context, 0);
return (Node *) newnode; return (Node *) newnode;
} }
else else
...@@ -991,7 +991,7 @@ HandleRIRAttributeRule_mutator(Node *node, ...@@ -991,7 +991,7 @@ HandleRIRAttributeRule_mutator(Node *node,
FLATCOPY(newnode, query, Query); FLATCOPY(newnode, query, Query);
context->sublevels_up++; context->sublevels_up++;
query_tree_mutator(newnode, HandleRIRAttributeRule_mutator, query_tree_mutator(newnode, HandleRIRAttributeRule_mutator,
context, true); context, 0);
context->sublevels_up--; context->sublevels_up--;
return (Node *) newnode; return (Node *) newnode;
} }
...@@ -1019,7 +1019,7 @@ HandleRIRAttributeRule(Query *parsetree, ...@@ -1019,7 +1019,7 @@ HandleRIRAttributeRule(Query *parsetree,
context.sublevels_up = 0; context.sublevels_up = 0;
query_tree_mutator(parsetree, HandleRIRAttributeRule_mutator, query_tree_mutator(parsetree, HandleRIRAttributeRule_mutator,
(void *) &context, true); (void *) &context, 0);
} }
#endif /* NOT_USED */ #endif /* NOT_USED */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: clauses.h,v 1.53 2002/06/20 20:29:51 momjian Exp $ * $Id: clauses.h,v 1.54 2002/09/11 14:48:55 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -66,10 +66,15 @@ extern bool expression_tree_walker(Node *node, bool (*walker) (), ...@@ -66,10 +66,15 @@ extern bool expression_tree_walker(Node *node, bool (*walker) (),
void *context); void *context);
extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (), extern Node *expression_tree_mutator(Node *node, Node *(*mutator) (),
void *context); void *context);
/* flags bits for query_tree_walker and query_tree_mutator */
#define QTW_IGNORE_SUBQUERIES 0x01 /* subqueries in rtable */
#define QTW_IGNORE_JOINALIASES 0x02 /* JOIN alias var lists */
extern bool query_tree_walker(Query *query, bool (*walker) (), extern bool query_tree_walker(Query *query, bool (*walker) (),
void *context, bool visitQueryRTEs); void *context, int flags);
extern void query_tree_mutator(Query *query, Node *(*mutator) (), extern void query_tree_mutator(Query *query, Node *(*mutator) (),
void *context, bool visitQueryRTEs); void *context, int flags);
#define is_subplan(clause) ((clause) != NULL && \ #define is_subplan(clause) ((clause) != NULL && \
IsA(clause, Expr) && \ IsA(clause, Expr) && \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment