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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy