9
9
*
10
10
*
11
11
* IDENTIFICATION
12
- * $Header: /c
10000
vsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62 2000/04/12 17:15:22 momjian Exp $
12
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62.2.1 2000/09/23 23:41:05 tgl Exp $
13
13
*
14
14
*-------------------------------------------------------------------------
15
15
*/
16
16
#include <sys/types.h>
17
17
18
18
#include "postgres.h"
19
19
20
- #include "nodes/makefuncs.h"
21
20
#include "nodes/nodeFuncs.h"
22
21
#include "optimizer/clauses.h"
23
22
#include "optimizer/planmain.h"
24
23
#include "optimizer/tlist.h"
25
- #include "optimizer/var.h"
26
24
27
25
typedef struct
28
26
{
@@ -37,6 +35,7 @@ typedef struct
37
35
List * subplanTargetList ;
38
36
} replace_vars_with_subplan_refs_context ;
39
37
38
+ static void fix_expr_references (Plan * plan , Node * node );
40
39
static void set_join_references (Join * join );
41
40
static void set_uppernode_references (Plan * plan , Index subvarno );
42
41
static Node * join_references_mutator (Node * node ,
@@ -88,34 +87,39 @@ set_plan_references(Plan *plan)
88
87
switch (nodeTag (plan ))
89
88
{
90
89
case T_SeqScan :
91
- /* nothing special */
90
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
91
+ fix_expr_references (plan , (Node * ) plan -> qual );
92
92
break ;
93
93
case T_IndexScan :
94
- fix_opids ((Node * ) ((IndexScan * ) plan )-> indxqual );
95
- fix_opids ((Node * ) ((IndexScan * ) plan )-> indxqualorig );
96
- plan -> subPlan =
97
- nconc (plan -> subPlan ,
<
10000
/code>
98
- pull_subplans ((Node * ) ((IndexScan * ) plan )-> indxqual ));
99
- plan -> subPlan =
100
- nconc (plan -> subPlan ,
101
- pull_subplans ((Node * ) ((IndexScan * ) plan )-> indxqualorig ));
94
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
95
+ fix_expr_references (plan , (Node * ) plan -> qual );
96
+ fix_expr_references (plan ,
97
+ (Node * ) ((IndexScan * ) plan )-> indxqual );
98
+ fix_expr_references (plan ,
99
+ (Node * ) ((IndexScan * ) plan )-> indxqualorig );
100
+ break ;
101
+ case T_TidScan :
102
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
103
+ fix_expr_references (plan , (Node * ) plan -> qual );
102
104
break ;
103
105
case T_NestLoop :
104
106
set_join_references ((Join * ) plan );
107
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
108
+ fix_expr_references (plan , (Node * ) plan -> qual );
105
109
break ;
106
110
case T_MergeJoin :
107
111
set_join_references ((Join * ) plan );
108
- fix_opids ( (Node * ) (( MergeJoin * ) plan ) -> mergeclauses );
109
- plan -> subPlan =
110
- nconc (plan -> subPlan ,
111
- pull_subplans (( Node * ) ((MergeJoin * ) plan )-> mergeclauses ) );
112
+ fix_expr_references ( plan , (Node * ) plan -> targetlist );
113
+ fix_expr_references ( plan , ( Node * ) plan -> qual );
114
+ fix_expr_references (plan ,
115
+ ( Node * ) ((MergeJoin * ) plan )-> mergeclauses );
112
116
break ;
113
117
case T_HashJoin :
114
118
set_join_references ((Join * ) plan );
115
- fix_opids ( (Node * ) (( HashJoin * ) plan ) -> hashclauses );
116
- plan -> subPlan =
117
- nconc (plan -> subPlan ,
118
- pull_subplans (( Node * ) ((HashJoin * ) plan )-> hashclauses ) );
119
+ fix_expr_references ( plan , (Node * ) plan -> targetlist );
120
+ fix_expr_references ( plan , ( Node * ) plan -> qual );
121
+ fix_expr_references (plan ,
122
+ ( Node * ) ((HashJoin * ) plan )-> hashclauses );
119
123
break ;
120
124
case T_Material :
121
125
case T_Sort :
@@ -127,12 +131,17 @@ set_plan_references(Plan *plan)
127
131
* targetlists or quals (because they just return their
128
132
* unmodified input tuples). The optimizer is lazy about
129
133
* creating really valid targetlists for them. Best to just
130
- * leave the targetlist alone.
134
+ * leave the targetlist alone. In particular, we do not want
135
+ * to pull a subplan list for them, since we will likely end
136
+ * up with duplicate list entries for subplans that also appear
137
+ * in lower levels of the plan tree!
131
138
*/
132
139
break ;
133
140
case T_Agg :
134
141
case T_Group :
135
142
set_uppernode_references (plan , (Index ) 0 );
143
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
144
+ fix_expr_references (plan , (Node * ) plan -> qual );
136
145
break ;
137
146
case T_Result :
138
147
@@ -144,37 +153,25 @@ set_plan_references(Plan *plan)
144
153
*/
145
154
if (plan -> lefttree != NULL )
146
155
set_uppernode_references (plan , (Index ) OUTER );
147
- fix_opids (((Result * ) plan )-> resconstantqual );
148
- plan -> subPlan =
149
- nconc (plan -> subPlan ,
150
- pull_subplans (((Result * ) plan )-> resconstantqual ));
156
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
157
+ fix_expr_references (plan , (Node * ) plan -> qual );
158
+ fix_expr_references (plan , ((Result * ) plan )-> resconstantqual );
151
159
break ;
152
160
case T_Append :
161
+ /*
162
+ * Append, like Sort et al, doesn't actually evaluate its
163
+ * targetlist or quals, and we haven't bothered to give it
164
+ * its own tlist copy. So, don't fix targetlist/qual.
165
+ */
153
166
foreach (pl , ((Append * ) plan )-> appendplans )
154
167
set_plan_references ((Plan * ) lfirst (pl ));
155
168
break ;
156
- case T_TidScan :
157
- /* nothing special */
158
- break ;
159
169
default :
160
170
elog (ERROR , "set_plan_references: unknown plan type %d" ,
161
171
nodeTag (plan ));
162
172
break ;
163
173
}
164
174
165
- /*
166
- * For all plan types, fix operators in targetlist and qual
167
- * expressions, and find subplans therein.
168
- */
169
- fix_opids ((Node * ) plan -> targetlist );
170
- fix_opids ((Node * ) plan -> qual );
171
- plan -> subPlan =
172
- nconc (plan -> subPlan ,
173
- pull_subplans ((Node * ) plan -> targetlist ));
174
- plan -> subPlan =
175
- nconc (plan -> subPlan ,
176
- pull_subplans ((Node * ) plan -> qual ));
177
-
178
175
/*
179
176
* Now recurse into subplans, if any
180
177
*
@@ -202,6 +199,20 @@ set_plan_references(Plan *plan)
202
199
}
203
200
}
204
201
202
+ /*
203
+ * fix_expr_references
204
+ * Do final cleanup on expressions (targetlists or quals).
205
+ *
206
+ * This consists of looking up operator opcode info for Oper nodes
207
+ * and adding subplans to the Plan node's list of contained subplans.
208
+ */
209
+ static void
210
+ fix_expr_references (Plan * plan , Node * node )
211
+ {
212
+ fix_opids (node );
213
+ plan -> subPlan = nconc (plan -> subPlan , pull_subplans (node ));
214
+ }
215
+
205
216
/*
206
217
* set_join_references
207
218
* Modifies the target list of a join node to reference its subplans,
0 commit comments