Skip to content

Commit 994cfba

Browse files
committed
Fix GroupBY func broken by HAVING.
1 parent 6866cbc commit 994cfba

File tree

1 file changed

+26
-43
lines changed

1 file changed

+26
-43
lines changed

src/backend/optimizer/plan/planner.c

Lines changed: 26 additions & 43 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/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 *
9595
union_planner(Query *parse)
9696
{
9797
List *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);
10599
List *rangetable = parse->rtable;
106-
107100
Plan *result_plan = (Plan *) NULL;
108-
109101
Index rt_index;
110102

111103

@@ -133,36 +125,18 @@ union_planner(Query *parse)
133125
List **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
*/
154134
if (parse->hasAggs)
155135
{
156136
if (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 */
166140
tlist = preprocess_targetlist(tlist,
167141
parse->commandType,
168142
parse->resultRelation,
@@ -176,7 +150,7 @@ union_planner(Query *parse)
176150
PlannerVarParam = lcons(vpm, PlannerVarParam);
177151
result_plan = query_planner(parse,
178152
parse->commandType,
179-
new_tlist,
153+
tlist,
180154
(List *) parse->qual);
181155
PlannerVarParam = lnext(PlannerVarParam);
182156
if (vpm != NULL)
@@ -199,9 +173,8 @@ union_planner(Query *parse)
199173
*/
200174
tuplePerGroup = parse->hasAggs;
201175

202-
/* Use 'new_tlist' instead of 'tlist' */
203176
result_plan =
204-
make_groupPlan(&new_tlist,
177+
make_groupPlan(&tlist,
205178
tuplePerGroup,
206179
parse->groupClause,
207180
result_plan);
@@ -215,11 +188,6 @@ union_planner(Query *parse)
215188
int old_length = 0,
216189
new_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-
*/
223191
result_plan = (Plan *) make_agg(tlist, result_plan);
224192

225193
/*
@@ -235,7 +203,22 @@ union_planner(Query *parse)
235203
List *clause;
236204
List **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

0 commit comments

Comments
 (0)