88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.122 2003/01/15 19:35:44 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.123 2003/01/17 02:01:16 tgl Exp $
1212 *
1313 * HISTORY
1414 * AUTHORDATEMAJOR EVENT
@@ -2153,7 +2153,7 @@ substitute_actual_parameters_mutator(Node *node,
21532153 *{
21542154 *adjust context for subquery;
21552155 *result = query_tree_walker((Query *) node, my_walker, context,
2156- * 0); //to visit rtable items too
2156+ * 0); //adjust flags as needed
21572157 *restore context if needed;
21582158 *return result;
21592159 *}
@@ -2414,7 +2414,7 @@ query_tree_walker(Query *query,
24142414/* nothing to do */
24152415break ;
24162416case RTE_SUBQUERY :
2417- if (! (flags & QTW_IGNORE_SUBQUERIES ))
2417+ if (! (flags & QTW_IGNORE_RT_SUBQUERIES ))
24182418if (walker (rte -> subquery ,context ))
24192419return true;
24202420break ;
@@ -2477,17 +2477,22 @@ query_tree_walker(Query *query,
24772477 * expression_tree_mutator include all those normally found in target lists
24782478 * and qualifier clauses during the planning stage.
24792479 *
2480+ * expression_tree_mutator will handle SubLink nodes by recursing normally
2481+ * into the "lefthand" arguments (which are expressions belonging to the outer
2482+ * plan). It will also call the mutator on the sub-Query node; however, when
2483+ * expression_tree_mutator itself is called on a Query node, it does nothing
2484+ * and returns the unmodified Query node. The net effect is that unless the
2485+ * mutator does something special at a Query node, sub-selects will not be
2486+ * visited or modified; the original sub-select will be linked to by the new
2487+ * SubLink node. Mutators that want to descend into sub-selects will usually
2488+ * do so by recognizing Query nodes and calling query_tree_mutator (below).
2489+ *
24802490 * expression_tree_mutator will handle a SubPlan node by recursing into
24812491 * the "exprs" and "args" lists (which belong to the outer plan), but it
24822492 * will simply copy the link to the inner plan, since that's typically what
24832493 * expression tree mutators want. A mutator that wants to modify the subplan
24842494 * can force appropriate behavior by recognizing SubPlan expression nodes
24852495 * and doing the right thing.
2486- *
2487- * SubLink nodes are handled by recursing into the "lefthand" argument list
2488- * only. (A SubLink will be seen only if the tree has not yet been
2489- * processed by subselect.c.) Again, this can be overridden by the mutator,
2490- * but it seems to be the most useful default behavior.
24912496 *--------------------
24922497 */
24932498
@@ -2593,14 +2598,16 @@ expression_tree_mutator(Node *node,
25932598break ;
25942599case T_SubLink :
25952600{
2596- /*
2597- * We transform the lefthand side, but not the subquery.
2598- */
25992601SubLink * sublink = (SubLink * )node ;
26002602SubLink * newnode ;
26012603
26022604FLATCOPY (newnode ,sublink ,SubLink );
26032605MUTATE (newnode -> lefthand ,sublink -> lefthand ,List * );
2606+ /*
2607+ * Also invoke the mutator on the sublink's Query node, so
2608+ * it can recurse into the sub-query if it wants to.
2609+ */
2610+ MUTATE (newnode -> subselect ,sublink -> subselect ,Node * );
26042611return (Node * )newnode ;
26052612}
26062613break ;
@@ -2707,6 +2714,9 @@ expression_tree_mutator(Node *node,
27072714return (Node * )newnode ;
27082715}
27092716break ;
2717+ case T_Query :
2718+ /* Do nothing with a sub-Query, per discussion above */
2719+ return node ;
27102720case T_List :
27112721{
27122722/*
@@ -2781,17 +2791,17 @@ expression_tree_mutator(Node *node,
27812791 * mutator intends to descend into subqueries.It is also useful for
27822792 * descending into subqueries within a mutator.
27832793 *
2784- * The specified Query node is modified-in-place; do a FLATCOPY() beforehand
2785- * if you don't want to change the original. All substructure is safely
2786- * copied, however.
2787- *
2788- * Some callers want to suppress mutating of certain items in the sub-Query,
2794+ * Some callers want to suppress mutating of certain items in the Query,
27892795 * typically because they need to process them specially, or don't actually
27902796 * want to recurse into subqueries. This is supported by the flags argument,
27912797 * which is the bitwise OR of flag values to suppress mutating of
27922798 * indicated items. (More flag bits may be added as needed.)
2799+ *
2800+ * Normally the Query node itself is copied, but some callers want it to be
2801+ * modified in-place; they must pass QTW_DONT_COPY_QUERY in flags. All
2802+ * modified substructure is safely copied in any case.
27932803 */
2794- void
2804+ Query *
27952805query_tree_mutator (Query * query ,
27962806Node * (* mutator ) (),
27972807void * context ,
@@ -2802,6 +2812,14 @@ query_tree_mutator(Query *query,
28022812
28032813Assert (query != NULL && IsA (query ,Query ));
28042814
2815+ if (! (flags & QTW_DONT_COPY_QUERY ))
2816+ {
2817+ Query * newquery ;
2818+
2819+ FLATCOPY (newquery ,query ,Query );
2820+ query = newquery ;
2821+ }
2822+
28052823MUTATE (query -> targetList ,query -> targetList ,List * );
28062824MUTATE (query -> jointree ,query -> jointree ,FromExpr * );
28072825MUTATE (query -> setOperations ,query -> setOperations ,Node * );
@@ -2818,7 +2836,7 @@ query_tree_mutator(Query *query,
28182836/* nothing to do, don't bother to make a copy */
28192837break ;
28202838case RTE_SUBQUERY :
2821- if (! (flags & QTW_IGNORE_SUBQUERIES ))
2839+ if (! (flags & QTW_IGNORE_RT_SUBQUERIES ))
28222840{
28232841FLATCOPY (newrte ,rte ,RangeTblEntry );
28242842CHECKFLATCOPY (newrte -> subquery ,rte -> subquery ,Query );
@@ -2843,4 +2861,51 @@ query_tree_mutator(Query *query,
28432861newrt = lappend (newrt ,rte );
28442862}
28452863query -> rtable = newrt ;
2864+ return query ;
2865+ }
2866+
2867+ /*
2868+ * query_or_expression_tree_walker --- hybrid form
2869+ *
2870+ * This routine will invoke query_tree_walker if called on a Query node,
2871+ * else will invoke the walker directly. This is a useful way of starting
2872+ * the recursion when the walker's normal change of state is not appropriate
2873+ * for the outermost Query node.
2874+ */
2875+ bool
2876+ query_or_expression_tree_walker (Node * node ,
2877+ bool (* walker ) (),
2878+ void * context ,
2879+ int flags )
2880+ {
2881+ if (node && IsA (node ,Query ))
2882+ return query_tree_walker ((Query * )node ,
2883+ walker ,
2884+ context ,
2885+ flags );
2886+ else
2887+ return walker (node ,context );
2888+ }
2889+
2890+ /*
2891+ * query_or_expression_tree_mutator --- hybrid form
2892+ *
2893+ * This routine will invoke query_tree_mutator if called on a Query node,
2894+ * else will invoke the mutator directly. This is a useful way of starting
2895+ * the recursion when the mutator's normal change of state is not appropriate
2896+ * for the outermost Query node.
2897+ */
2898+ Node *
2899+ query_or_expression_tree_mutator (Node * node ,
2900+ Node * (* mutator ) (),
2901+ void * context ,
2902+ int flags )
2903+ {
2904+ if (node && IsA (node ,Query ))
2905+ return (Node * )query_tree_mutator ((Query * )node ,
2906+ mutator ,
2907+ context ,
2908+ flags );
2909+ else
2910+ return mutator (node ,context );
28462911}