Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita4d82dd

Browse files
committed
Adjust API of expression_tree_mutator and query_tree_mutator to
simplify callers. It turns out the common case is that the callerdoes want to recurse into sub-queries, so push support for that intothese subroutines.
1 parent227a404 commita4d82dd

File tree

8 files changed

+167
-220
lines changed

8 files changed

+167
-220
lines changed

‎src/backend/optimizer/plan/subselect.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.66 2003/01/13 18:10:53 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/subselect.c,v 1.67 2003/01/17 02:01:11 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -628,12 +628,12 @@ process_sublinks_mutator(Node *node, bool *isTopQual)
628628
}
629629

630630
/*
631-
* Note that we will never see a SubPlan expression in the input
632-
* (since this is the very routine that creates 'em to begin with). So
633-
* the code in expression_tree_mutator() that might do inappropriate
634-
* things with SubPlans or SubLinks will not be exercised.
631+
* We should never see a SubPlan expression in the input (since this is
632+
* the very routine that creates 'em to begin with). We shouldn't find
633+
* ourselves invoked directly on a Query, either.
635634
*/
636635
Assert(!is_subplan(node));
636+
Assert(!IsA(node,Query));
637637

638638
/*
639639
* If we recurse down through anything other than a List node, we are

‎src/backend/optimizer/prep/prepunion.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.86 2003/01/15 19:35:44 tgl Exp $
17+
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.87 2003/01/17 02:01:16 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -34,11 +34,6 @@
3434
#include"parser/parsetree.h"
3535
#include"utils/lsyscache.h"
3636

37-
/* macros borrowed from expression_tree_mutator */
38-
39-
#defineFLATCOPY(newnode,node,nodetype) \
40-
( (newnode) = makeNode(nodetype), \
41-
memcpy((newnode), (node), sizeof(nodetype)) )
4237

4338
typedefstruct
4439
{
@@ -765,12 +760,12 @@ adjust_inherited_attrs(Node *node,
765760
*/
766761
if (node&&IsA(node,Query))
767762
{
768-
Query*query= (Query*)node;
769763
Query*newnode;
770764

771-
FLATCOPY(newnode,query,Query);
772-
query_tree_mutator(newnode,adjust_inherited_attrs_mutator,
773-
(void*)&context,QTW_IGNORE_SUBQUERIES);
765+
newnode=query_tree_mutator((Query*)node,
766+
adjust_inherited_attrs_mutator,
767+
(void*)&context,
768+
QTW_IGNORE_RT_SUBQUERIES);
774769
if (newnode->resultRelation==old_rt_index)
775770
{
776771
newnode->resultRelation=new_rt_index;
@@ -899,6 +894,7 @@ adjust_inherited_attrs_mutator(Node *node,
899894
* already have been converted to subplans before we see them.
900895
*/
901896
Assert(!IsA(node,SubLink));
897+
Assert(!IsA(node,Query));
902898

903899
/*
904900
* BUT: although we don't need to recurse into subplans, we do need to

‎src/backend/optimizer/util/clauses.c

Lines changed: 83 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
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 */
24152415
break;
24162416
caseRTE_SUBQUERY:
2417-
if (! (flags&QTW_IGNORE_SUBQUERIES))
2417+
if (! (flags&QTW_IGNORE_RT_SUBQUERIES))
24182418
if (walker(rte->subquery,context))
24192419
return true;
24202420
break;
@@ -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,
25932598
break;
25942599
caseT_SubLink:
25952600
{
2596-
/*
2597-
* We transform the lefthand side, but not the subquery.
2598-
*/
25992601
SubLink*sublink= (SubLink*)node;
26002602
SubLink*newnode;
26012603

26022604
FLATCOPY(newnode,sublink,SubLink);
26032605
MUTATE(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*);
26042611
return (Node*)newnode;
26052612
}
26062613
break;
@@ -2707,6 +2714,9 @@ expression_tree_mutator(Node *node,
27072714
return (Node*)newnode;
27082715
}
27092716
break;
2717+
caseT_Query:
2718+
/* Do nothing with a sub-Query, per discussion above */
2719+
returnnode;
27102720
caseT_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*
27952805
query_tree_mutator(Query*query,
27962806
Node*(*mutator) (),
27972807
void*context,
@@ -2802,6 +2812,14 @@ query_tree_mutator(Query *query,
28022812

28032813
Assert(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+
28052823
MUTATE(query->targetList,query->targetList,List*);
28062824
MUTATE(query->jointree,query->jointree,FromExpr*);
28072825
MUTATE(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 */
28192837
break;
28202838
caseRTE_SUBQUERY:
2821-
if (! (flags&QTW_IGNORE_SUBQUERIES))
2839+
if (! (flags&QTW_IGNORE_RT_SUBQUERIES))
28222840
{
28232841
FLATCOPY(newrte,rte,RangeTblEntry);
28242842
CHECKFLATCOPY(newrte->subquery,rte->subquery,Query);
@@ -2843,4 +2861,51 @@ query_tree_mutator(Query *query,
28432861
newrt=lappend(newrt,rte);
28442862
}
28452863
query->rtable=newrt;
2864+
returnquery;
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+
intflags)
2880+
{
2881+
if (node&&IsA(node,Query))
2882+
returnquery_tree_walker((Query*)node,
2883+
walker,
2884+
context,
2885+
flags);
2886+
else
2887+
returnwalker(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+
intflags)
2903+
{
2904+
if (node&&IsA(node,Query))
2905+
return (Node*)query_tree_mutator((Query*)node,
2906+
mutator,
2907+
context,
2908+
flags);
2909+
else
2910+
returnmutator(node,context);
28462911
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp