aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planmain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planmain.c')
-rw-r--r--src/backend/optimizer/plan/planmain.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c
index f94552d3720..7f70d76ac6c 100644
--- a/src/backend/optimizer/plan/planmain.c
+++ b/src/backend/optimizer/plan/planmain.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.3 1997/04/05 06:37:37 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.4 1997/04/29 04:32:50 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -359,8 +359,9 @@ make_groupPlan(List **tlist,
List *sort_tlist;
List *sl, *gl;
List *glc = listCopy (groupClause);
- List *aggvals = NIL; /* list of vars of aggregates */
- int aggvcnt;
+ List *otles = NIL; /* list of removed non-GroupBy entries */
+ List *otlvars = NIL; /* list of var in them */
+ int otlvcnt;
Sort *sortplan;
Group *grpplan;
int numCols;
@@ -375,7 +376,8 @@ make_groupPlan(List **tlist,
/*
* Make template TL for subplan, Sort & Group:
- * 1. Take away Aggregates and re-set resno-s accordantly.
+ * 1. If there are aggregates (tuplePerGroup is true) then take
+ * away non-GroupBy entries and re-set resno-s accordantly.
* 2. Make grpColIdx
*
* Note: we assume that TLEs in *tlist are ordered in accordance
@@ -390,7 +392,7 @@ make_groupPlan(List **tlist,
{
GroupClause *grpcl = (GroupClause*)lfirst(gl);
- if ( grpcl->resdom->resno == te->resdom->resno )
+ if ( grpcl->entry->resdom->resno == te->resdom->resno )
{
resdom = te->resdom;
@@ -403,15 +405,20 @@ make_groupPlan(List **tlist,
break;
}
}
- if ( resdom == NULL ) /* Not GroupBy-ed entry: remove */
- { /* aggregate(s) from Group/Sort TL */
- if ( IsA (te->expr, Aggreg) )
- { /* save Aggregate' Vars */
- aggvals = nconc (aggvals, pull_var_clause (te->expr));
- sort_tlist = lremove (lfirst (sl), sort_tlist);
+ /*
+ * Non-GroupBy entry: remove it from Group/Sort TL if there are
+ * aggregates in query - it will be evaluated by Aggregate plan
+ */
+ if ( resdom == NULL )
+ {
+ if ( tuplePerGroup )
+ {
+ otlvars = nconc (otlvars, pull_var_clause (te->expr));
+ otles = lcons (te, otles);
+ sort_tlist = lremove (te, sort_tlist);
}
else
- resdom->resno = last_resno++; /* re-set */
+ te->resdom->resno = last_resno++;
}
}
@@ -421,12 +428,12 @@ make_groupPlan(List **tlist,
}
/*
- * Aggregates were removed from TL - we are to add Vars for them
- * to the end of TL if there are no such Vars in TL already.
+ * If non-GroupBy entries were removed from TL - we are to add Vars for
+ * them to the end of TL if there are no such Vars in TL already.
*/
- aggvcnt = length (aggvals);
- foreach (gl, aggvals)
+ otlvcnt = length (otlvars);
+ foreach (gl, otlvars)
{
Var *v = (Var*)lfirst (gl);
@@ -437,9 +444,9 @@ make_groupPlan(List **tlist,
last_resno++;
}
else /* already in TL */
- aggvcnt--;
+ otlvcnt--;
}
- /* Now aggvcnt is number of Vars added in TL for Aggregates */
+ /* Now otlvcnt is number of Vars added in TL for non-GroupBy entries */
/* Make TL for subplan: substitute Vars from subplan TL into new TL */
sl = flatten_tlist_vars (sort_tlist, subplan->targetlist);
@@ -489,17 +496,28 @@ make_groupPlan(List **tlist,
grpColIdx, sortplan);
/*
- * Make TL for parent: "restore" Aggregates and
- * resno-s of others accordantly.
+ * Make TL for parent: "restore" non-GroupBy entries (if they
+ * were removed) and set resno-s of others accordantly.
*/
sl = sort_tlist;
sort_tlist = NIL; /* to be new parent TL */
foreach (gl, *tlist)
{
+ List *temp = NIL;
TargetEntry *te = (TargetEntry *) lfirst (gl);
-
- if ( !IsA (te->expr, Aggreg) ) /* It's "our" TLE - we're to return */
- { /* it from Sort/Group plans */
+
+ foreach (temp, otles) /* Is it removed non-GroupBy entry ? */
+ {
+ TargetEntry *ote = (TargetEntry *) lfirst (temp);
+
+ if ( ote->resdom->resno == te->resdom->resno )
+ {
+ otles = lremove (ote, otles);
+ break;
+ }
+ }
+ if ( temp == NIL ) /* It's "our" TLE - we're to return */
+ { /* it from Sort/Group plans */
TargetEntry *my = (TargetEntry *) lfirst (sl); /* get it */
sl = sl->next; /* prepare for the next "our" */
@@ -508,15 +526,16 @@ make_groupPlan(List **tlist,
sort_tlist = lappend (sort_tlist, my);
continue;
}
- /* TLE of an aggregate */
+ /* else - it's TLE of an non-GroupBy entry */
sort_tlist = lappend (sort_tlist, copyObject(te));
}
/*
- * Pure aggregates Vars were at the end of Group' TL.
+ * Pure non-GroupBy entries Vars were at the end of Group' TL.
* They shouldn't appear in parent TL, all others shouldn't
* disappear.
*/
- Assert ( aggvcnt == length (sl) );
+ Assert ( otlvcnt == length (sl) );
+ Assert ( length (otles) == 0 );
*tlist = sort_tlist;