Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit da5f1dd

Browse files
committed
Revise union_planner and associated routines to clean up breakage
from EXCEPT/HAVING patch. Cases involving nontrivial GROUP BY expressions now work again. Also, the code is at least somewhat better documented...
1 parent 605d849 commit da5f1dd

File tree

5 files changed

+566
-560
lines changed

5 files changed

+566
-560
lines changed

src/backend/optimizer/plan/planmain.c

Lines changed: 10 additions & 216 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
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
*/
@@ -44,9 +44,6 @@
4444
static Plan *subplanner(Query *root, List *flat_tlist, List *qual);
4545
static 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
*/
178175
if (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,
185179
subplan);
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

193186
return 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
*/
209202
else
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);
214206
return subplan;
215207
}
216208

@@ -321,201 +313,3 @@ make_result(List *tlist,
321313

322314
return 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-
}

0 commit comments

Comments
 (0)