7
7
*
8
8
*
9
9
* IDENTIFICATION
10
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.33 1998/09/03 02:34:30 momjian Exp $
10
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.34 1998/09/08 02:50:20 vadim Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -95,17 +95,9 @@ Plan *
95
95
union_planner (Query * parse )
96
96
{
97
97
List * tlist = parse -> targetList ;
98
-
99
- /*
100
- * copy the original tlist, we will need the original one for the AGG
101
- * node later on
102
- */
103
- List * new_tlist = new_unsorted_tlist (tlist );
104
-
98
+ int tlist_len = length (tlist );
105
99
List * rangetable = parse -> rtable ;
106
-
107
100
Plan * result_plan = (Plan * ) NULL ;
108
-
109
101
Index rt_index ;
110
102
111
103
@@ -133,36 +125,18 @@ union_planner(Query *parse)
133
125
List * * vpm = NULL ;
134
126
135
127
/*
136
- * This is only necessary if aggregates are in use in queries
137
- * like: SELECT sid FROM part GROUP BY sid HAVING MIN(pid) > 1;
138
- * (pid is used but never selected for!!!) because the function
139
- * 'query_planner' creates the plan for the lefttree of the
140
- * 'GROUP' node and returns only those attributes contained in
141
- * 'tlist'. The original 'tlist' contains only 'sid' here and
142
- * that's why we have to to extend it to attributes which are not
143
- * selected but are used in the havingQual.
144
- */
145
-
146
- /*
147
- * 'check_having_qual_for_vars' takes the havingQual and the
148
- * actual 'tlist' as arguments and recursively scans the
149
- * havingQual for attributes (VAR nodes) that are not contained in
150
- * 'tlist' yet. If so, it creates a new entry and attaches it to
151
- * the list 'new_tlist' (consisting of the VAR node and the RESDOM
152
- * node as usual with tlists :-) )
128
+ * check_having_qual_for_vars takes the havingQual and the tlist
129
+ * as arguments and recursively scans the havingQual for VAR nodes
130
+ * that are not contained in tlist yet. If so, it creates a new entry
131
+ * and attaches it to the tlist. Latter, we use tlist_len to
132
+ * truncate tlist - ie restore actual tlist...
153
133
*/
154
134
if (parse -> hasAggs )
155
135
{
156
136
if (parse -> havingQual != NULL )
157
- new_tlist = check_having_qual_for_vars (parse -> havingQual , new_tlist );
137
+ tlist = check_having_qual_for_vars (parse -> havingQual , tlist );
158
138
}
159
139
160
- new_tlist = preprocess_targetlist (new_tlist ,
161
- parse -> commandType ,
162
- parse -> resultRelation ,
163
- parse -> rtable );
164
-
165
- /* Here starts the original (pre having) code */
166
140
tlist = preprocess_targetlist (tlist ,
167
141
parse -> commandType ,
168
142
parse -> resultRelation ,
@@ -176,7 +150,7 @@ union_planner(Query *parse)
176
150
PlannerVarParam = lcons (vpm , PlannerVarParam );
177
151
result_plan = query_planner (parse ,
178
152
parse -> commandType ,
179
- new_tlist ,
153
+ tlist ,
180
154
(List * ) parse -> qual );
181
155
PlannerVarParam = lnext (PlannerVarParam );
182
156
if (vpm != NULL )
@@ -199,9 +173,8 @@ union_planner(Query *parse)
199
173
*/
200
174
tuplePerGroup = parse -> hasAggs ;
201
175
202
- /* Use 'new_tlist' instead of 'tlist' */
203
176
result_plan =
204
- make_groupPlan (& new_tlist ,
177
+ make_groupPlan (& tlist ,
205
178
tuplePerGroup ,
206
179
parse -> groupClause ,
207
180
result_plan );
@@ -215,11 +188,6 @@ union_planner(Query *parse)
215
188
int old_length = 0 ,
216
189
new_length = 0 ;
217
190
218
- /*
219
- * Create the AGG node but use 'tlist' not 'new_tlist' as target
220
- * list because we don't want the additional attributes (only used
221
- * for the havingQual, see above) to show up in the result
222
- */
223
191
result_plan = (Plan * ) make_agg (tlist , result_plan );
224
192
225
193
/*
@@ -235,7 +203,22 @@ union_planner(Query *parse)
235
203
List * clause ;
236
204
List * * vpm = NULL ;
237
205
238
-
206
+ /*
207
+ * Restore target list: get rid of Vars added for havingQual.
208
+ * Assumption: tlist_len > 0...
209
+ */
210
+ {
211
+ List * l ;
212
+ int tlen = 0 ;
213
+
214
+ foreach (l , ((Agg * ) result_plan )-> plan .targetlist )
215
+ {
216
+ if (++ tlen == tlist_len )
217
+ break ;
218
+ }
219
+ lnext (l ) = NIL ;
220
+ }
221
+
239
222
/*
240
223
* stuff copied from above to handle the use of attributes
241
224
* from outside in subselects
0 commit comments