77 *
88 *
99 * 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 $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -95,17 +95,9 @@ Plan *
9595union_planner (Query * parse )
9696{
9797List * 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 );
10599List * rangetable = parse -> rtable ;
106-
107100Plan * result_plan = (Plan * )NULL ;
108-
109101Index rt_index ;
110102
111103
@@ -133,36 +125,18 @@ union_planner(Query *parse)
133125List * * vpm = NULL ;
134126
135127/*
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...
153133 */
154134if (parse -> hasAggs )
155135{
156136if (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 );
158138}
159139
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 */
166140tlist = preprocess_targetlist (tlist ,
167141parse -> commandType ,
168142parse -> resultRelation ,
@@ -176,7 +150,7 @@ union_planner(Query *parse)
176150PlannerVarParam = lcons (vpm ,PlannerVarParam );
177151result_plan = query_planner (parse ,
178152parse -> commandType ,
179- new_tlist ,
153+ tlist ,
180154(List * )parse -> qual );
181155PlannerVarParam = lnext (PlannerVarParam );
182156if (vpm != NULL )
@@ -199,9 +173,8 @@ union_planner(Query *parse)
199173 */
200174tuplePerGroup = parse -> hasAggs ;
201175
202- /* Use 'new_tlist' instead of 'tlist' */
203176result_plan =
204- make_groupPlan (& new_tlist ,
177+ make_groupPlan (& tlist ,
205178tuplePerGroup ,
206179parse -> groupClause ,
207180result_plan );
@@ -215,11 +188,6 @@ union_planner(Query *parse)
215188int old_length = 0 ,
216189new_length = 0 ;
217190
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- */
223191result_plan = (Plan * )make_agg (tlist ,result_plan );
224192
225193/*
@@ -235,7 +203,22 @@ union_planner(Query *parse)
235203List * clause ;
236204List * * vpm = NULL ;
237205
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+
239222/*
240223 * stuff copied from above to handle the use of attributes
241224 * from outside in subselects