9
9
*
10
10
*
11
11
* IDENTIFICATION
12
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.63 2000/05/30 00:49:47 momjian Exp $
12
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.64 2000/06/04 20:50:50 tgl Exp $
13
13
*
14
14
*-------------------------------------------------------------------------
15
15
*/
@@ -35,6 +35,7 @@ typedef struct
35
35
List * subplanTargetList ;
36
36
} replace_vars_with_subplan_refs_context ;
37
37
38
+ static void fix_expr_references (Plan * plan , Node * node );
38
39
static void set_join_references (Join * join );
39
40
static void set_uppernode_references (Plan * plan , Index subvarno );
40
41
static Node * join_references_mutator (Node * node ,
@@ -86,34 +87,39 @@ set_plan_references(Plan *plan)
86
87
switch (nodeTag (plan ))
87
88
{
88
89
case T_SeqScan :
89
- /* nothing special */
90
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
91
+ fix_expr_references (plan , (Node * ) plan -> qual );
90
92
break ;
91
93
case T_IndexScan :
92
- fix_opids ((Node * ) ((IndexScan * ) plan )-> indxqual );
93
- fix_opids ((Node * ) ((IndexScan * ) plan )-> indxqualorig );
94
- plan -> subPlan =
95
- nconc (plan -> subPlan ,
96
- pull_subplans ((Node * ) ((IndexScan * ) plan )-> indxqual ));
97
- plan -> subPlan =
98
- nconc (plan -> subPlan ,
99
- 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 );
100
104
break ;
101
105
case T_NestLoop :
102
106
set_join_references ((Join * ) plan );
107
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
108
+ fix_expr_references (plan , (Node * ) plan -> qual );
103
109
break ;
104
110
case T_MergeJoin :
105
111
set_join_references ((Join * ) plan );
106
- fix_opids ( (Node * ) (( MergeJoin * ) plan ) -> mergeclauses );
107
- plan -> subPlan =
108
- nconc (plan -> subPlan ,
109
- 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 );
110
116
break ;
111
117
case T_HashJoin :
112
118
set_join_references ((Join * ) plan );
113
- fix_opids ( (Node * ) (( HashJoin * ) plan ) -> hashclauses );
114
- plan -> subPlan =
115
- nconc (plan -> subPlan ,
116
- 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 );
117
123
break ;
118
124
case T_Material :
119
125
case T_Sort :
@@ -125,12 +131,17 @@ set_plan_references(Plan *plan)
125
131
* targetlists or quals (because they just return their
126
132
* unmodified input tuples). The optimizer is lazy about
127
133
* creating really valid targetlists for them. Best to just
128
- * 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!
129
138
*/
130
139
break ;
131
140
case T_Agg :
132
141
case T_Group :
133
142
set_uppernode_references (plan , (Index ) 0 );
143
+ fix_expr_references (plan , (Node * ) plan -> targetlist );
144
+ fix_expr_references (plan , (Node * ) plan -> qual );
134
145
break ;
135
146
case T_Result :
136
147
@@ -142,37 +153,25 @@ set_plan_references(Plan *plan)
142
153
*/
143
154
if (plan -> lefttree != NULL )
144
155
set_uppernode_references (plan , (Index ) OUTER );
145
- fix_opids (((Result * ) plan )-> resconstantqual );
146
- plan -> subPlan =
147
- nconc (plan -> subPlan ,
148
- 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 );
149
159
break ;
150
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
+ */
151
166
foreach (pl , ((Append * ) plan )-> appendplans )
152
167
set_plan_references ((Plan * ) lfirst (pl ));
153
168
break ;
154
- case T_TidScan :
155
- /* nothing special */
156
- break ;
157
169
default :
158
170
elog (ERROR , "set_plan_references: unknown plan type %d" ,
159
171
nodeTag (plan ));
160
172
break ;
161
173
}
162
174
163
- /*
164
- * For all plan types, fix operators in targetlist and qual
165
- * expressions, and find subplans therein.
166
- */
167
- fix_opids ((Node * ) plan -> targetlist );
168
- fix_opids ((Node * ) plan -> qual );
169
- plan -> subPlan =
170
- nconc (plan -> subPlan ,
171
- pull_subplans ((Node * ) plan -> targetlist ));
172
- plan -> subPlan =
173
- nconc (plan -> subPlan ,
174
- pull_subplans ((Node * ) plan -> qual ));
175
-
176
175
/*
177
176
* Now recurse into subplans, if any
178
177
*
@@ -200,6 +199,20 @@ set_plan_references(Plan *plan)
200
199
}
201
200
}
202
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
+
203
216
/*
204
217
* set_join_references
205
218
* Modifies the target list of a join node to reference its subplans,
0 commit comments