77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.34 1999/02/21 03:48:49 scrappy Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.35 1999/05/03 00:38:43 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
4444static Plan * subplanner (Query * root ,List * flat_tlist ,List * qual );
4545static Result * make_result (List * tlist ,Node * resconstantqual ,Plan * subplan );
4646
47- extern Plan * make_groupPlan (List * * tlist ,bool tuplePerGroup ,
48- List * groupClause ,Plan * subplan );
49-
5047/*
5148 * query_planner
5249 * Routine to create a query plan. It does so by first creating a
@@ -177,18 +174,14 @@ query_planner(Query *root,
177174 */
178175if (constant_qual )
179176{
180- subplan = (Plan * )make_result ((!root -> hasAggs &&
181- !root -> groupClause &&
182- !root -> havingQual )
183- ?tlist :subplan -> targetlist ,
177+ subplan = (Plan * )make_result (tlist ,
184178 (Node * )constant_qual ,
185179subplan );
186180
187181/*
188- *Change all varno's of the Result's node target list.
182+ *Fix all varno's of the Result's node target list.
189183 */
190- if (!root -> hasAggs && !root -> groupClause && !root -> havingQual )
191- set_tlist_references (subplan );
184+ set_tlist_references (subplan );
192185
193186return subplan ;
194187}
@@ -201,16 +194,15 @@ query_planner(Query *root,
201194 * responsibility to optimally push these expressions down the plan
202195 * tree. -- Wei
203196 *
204- *But now nothing to do if there are GroupBy and/or Aggregates: 1.
205- *make_groupPlan fixes tlist; 2. flatten_tlist_vars does nothing with
206- *aggregates fixing only other entries (i.e. - GroupBy-ed and so
207- *fixed by make_groupPlan). - vadim 04/05/97
197+ *Note: formerly there was a test here to skip the flatten call if we
198+ *expected union_planner to insert a Group or Agg node above our result.
199+ *However, now union_planner tells us exactly what it wants returned,
200+ *and we just do it. Much cleaner.
208201 */
209202else
210203{
211- if (!root -> hasAggs && !root -> groupClause && !root -> havingQual )
212- subplan -> targetlist = flatten_tlist_vars (tlist ,
213- subplan -> targetlist );
204+ subplan -> targetlist = flatten_tlist_vars (tlist ,
205+ subplan -> targetlist );
214206return subplan ;
215207}
216208
@@ -321,201 +313,3 @@ make_result(List *tlist,
321313
322314return node ;
323315}
324-
325- /*****************************************************************************
326- *
327- *****************************************************************************/
328-
329- Plan *
330- make_groupPlan (List * * tlist ,
331- bool tuplePerGroup ,
332- List * groupClause ,
333- Plan * subplan )
334- {
335- List * sort_tlist ;
336- List * sl ,
337- * gl ;
338- List * glc = listCopy (groupClause );
339- List * otles = NIL ;/* list of removed non-GroupBy entries */
340- List * otlvars = NIL ;/* list of var in them */
341- int otlvcnt ;
342- Sort * sortplan ;
343- Group * grpplan ;
344- int numCols ;
345- AttrNumber * grpColIdx ;
346- int last_resno = 1 ;
347-
348- numCols = length (groupClause );
349- grpColIdx = (AttrNumber * )palloc (sizeof (AttrNumber )* numCols );
350-
351- sort_tlist = new_unsorted_tlist (* tlist );/* it's copy */
352-
353- /*
354- * Make template TL for subplan, Sort & Group: 1. If there are
355- * aggregates (tuplePerGroup is true) then take away non-GroupBy
356- * entries and re-set resno-s accordantly. 2. Make grpColIdx
357- *
358- * Note: we assume that TLEs in *tlist are ordered in accordance with
359- * their resdom->resno.
360- */
361- foreach (sl ,sort_tlist )
362- {
363- Resdom * resdom = NULL ;
364- TargetEntry * te = (TargetEntry * )lfirst (sl );
365- int keyno = 0 ;
366-
367- foreach (gl ,groupClause )
368- {
369- GroupClause * grpcl = (GroupClause * )lfirst (gl );
370-
371- keyno ++ ;
372- if (grpcl -> entry -> resdom -> resno == te -> resdom -> resno )
373- {
374-
375- resdom = te -> resdom ;
376- resdom -> reskey = keyno ;
377- resdom -> reskeyop = get_opcode (grpcl -> grpOpoid );
378- resdom -> resno = last_resno ;/* re-set */
379- grpColIdx [keyno - 1 ]= last_resno ++ ;
380- glc = lremove (lfirst (gl ),glc );/* TLE found for it */
381- break ;
382- }
383- }
384-
385- /*
386- * Non-GroupBy entry: remove it from Group/Sort TL if there are
387- * aggregates in query - it will be evaluated by Aggregate plan
388- */
389- if (resdom == NULL )
390- {
391- if (tuplePerGroup )
392- {
393- otlvars = nconc (otlvars ,pull_var_clause (te -> expr ));
394- otles = lcons (te ,otles );
395- sort_tlist = lremove (te ,sort_tlist );
396- }
397- else
398- te -> resdom -> resno = last_resno ++ ;
399- }
400- }
401-
402- if (length (glc )!= 0 )
403- elog (ERROR ,"group attribute disappeared from target list" );
404-
405- /*
406- * If non-GroupBy entries were removed from TL - we are to add Vars
407- * for them to the end of TL if there are no such Vars in TL already.
408- */
409-
410- otlvcnt = length (otlvars );
411- foreach (gl ,otlvars )
412- {
413- Var * v = (Var * )lfirst (gl );
414-
415- if (tlist_member (v ,sort_tlist )== NULL )
416- {
417- sort_tlist = lappend (sort_tlist ,
418- create_tl_element (v ,last_resno ));
419- last_resno ++ ;
420- }
421- else
422- /* already in TL */
423- otlvcnt -- ;
424- }
425- /* Now otlvcnt is number of Vars added in TL for non-GroupBy entries */
426-
427- /* Make TL for subplan: substitute Vars from subplan TL into new TL */
428- sl = flatten_tlist_vars (sort_tlist ,subplan -> targetlist );
429-
430- subplan -> targetlist = new_unsorted_tlist (sl );/* there */
431-
432- /*
433- * Make Sort/Group TL : 1. make Var nodes (with varno = 1 and varnoold
434- * = -1) for all functions, 'couse they will be evaluated by subplan;
435- * 2. for real Vars: set varno = 1 and varattno to its resno in
436- * subplan
437- */
438- foreach (sl ,sort_tlist )
439- {
440- TargetEntry * te = (TargetEntry * )lfirst (sl );
441- Resdom * resdom = te -> resdom ;
442- Node * expr = te -> expr ;
443-
444- if (IsA (expr ,Var ))
445- {
446- #ifdef NOT_USED /* subplanVar->resdom->resno expected to
447- * be = te->resdom->resno */
448- TargetEntry * subplanVar ;
449-
450- subplanVar = match_varid ((Var * )expr ,subplan -> targetlist );
451- ((Var * )expr )-> varattno = subplanVar -> resdom -> resno ;
452- #endif
453- ((Var * )expr )-> varattno = te -> resdom -> resno ;
454- ((Var * )expr )-> varno = 1 ;
455- }
456- else
457- te -> expr = (Node * )makeVar (1 ,resdom -> resno ,
458- resdom -> restype ,
459- resdom -> restypmod ,
460- 0 ,-1 ,resdom -> resno );
461- }
462-
463- sortplan = make_sort (sort_tlist ,
464- _NONAME_RELATION_ID_ ,
465- subplan ,
466- numCols );
467- sortplan -> plan .cost = subplan -> cost ;/* XXX assume no cost */
468-
469- /*
470- * make the Group node
471- */
472- sort_tlist = copyObject (sort_tlist );
473- grpplan = make_group (sort_tlist ,tuplePerGroup ,numCols ,
474- grpColIdx ,sortplan );
475-
476- /*
477- * Make TL for parent: "restore" non-GroupBy entries (if they were
478- * removed) and set resno-s of others accordantly.
479- */
480- sl = sort_tlist ;
481- sort_tlist = NIL ;/* to be new parent TL */
482- foreach (gl ,* tlist )
483- {
484- List * temp = NIL ;
485- TargetEntry * te = (TargetEntry * )lfirst (gl );
486-
487- foreach (temp ,otles )/* Is it removed non-GroupBy entry ? */
488- {
489- TargetEntry * ote = (TargetEntry * )lfirst (temp );
490-
491- if (ote -> resdom -> resno == te -> resdom -> resno )
492- {
493- otles = lremove (ote ,otles );
494- break ;
495- }
496- }
497- if (temp == NIL )/* It's "our" TLE - we're to return */
498- {/* it from Sort/Group plans */
499- TargetEntry * my = (TargetEntry * )lfirst (sl );/* get it */
500-
501- sl = sl -> next ;/* prepare for the next "our" */
502- my = copyObject (my );
503- my -> resdom -> resno = te -> resdom -> resno ;/* order of parent TL */
504- sort_tlist = lappend (sort_tlist ,my );
505- continue ;
506- }
507- /* else - it's TLE of an non-GroupBy entry */
508- sort_tlist = lappend (sort_tlist ,copyObject (te ));
509- }
510-
511- /*
512- * Pure non-GroupBy entries Vars were at the end of Group' TL. They
513- * shouldn't appear in parent TL, all others shouldn't disappear.
514- */
515- Assert (otlvcnt == length (sl ));
516- Assert (length (otles )== 0 );
517-
518- * tlist = sort_tlist ;
519-
520- return (Plan * )grpplan ;
521- }