Skip to content
Snippets Groups Projects
Commit 994cfba1 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev
Browse files

Fix GroupBY func broken by HAVING.

parent 6866cbc7
Branches
Tags
No related merge requests found
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.33 1998/09/03 02:34:30 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.34 1998/09/08 02:50:20 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -95,17 +95,9 @@ Plan * ...@@ -95,17 +95,9 @@ Plan *
union_planner(Query *parse) union_planner(Query *parse)
{ {
List *tlist = parse->targetList; List *tlist = parse->targetList;
int tlist_len = length(tlist);
/*
* copy the original tlist, we will need the original one for the AGG
* node later on
*/
List *new_tlist = new_unsorted_tlist(tlist);
List *rangetable = parse->rtable; List *rangetable = parse->rtable;
Plan *result_plan = (Plan *) NULL; Plan *result_plan = (Plan *) NULL;
Index rt_index; Index rt_index;
...@@ -133,36 +125,18 @@ union_planner(Query *parse) ...@@ -133,36 +125,18 @@ union_planner(Query *parse)
List **vpm = NULL; List **vpm = NULL;
/* /*
* This is only necessary if aggregates are in use in queries * check_having_qual_for_vars takes the havingQual and the tlist
* like: SELECT sid FROM part GROUP BY sid HAVING MIN(pid) > 1; * as arguments and recursively scans the havingQual for VAR nodes
* (pid is used but never selected for!!!) because the function * that are not contained in tlist yet. If so, it creates a new entry
* 'query_planner' creates the plan for the lefttree of the * and attaches it to the tlist. Latter, we use tlist_len to
* 'GROUP' node and returns only those attributes contained in * truncate tlist - ie restore actual tlist...
* 'tlist'. The original 'tlist' contains only 'sid' here and
* that's why we have to to extend it to attributes which are not
* selected but are used in the havingQual.
*/
/*
* 'check_having_qual_for_vars' takes the havingQual and the
* actual 'tlist' as arguments and recursively scans the
* havingQual for attributes (VAR nodes) that are not contained in
* 'tlist' yet. If so, it creates a new entry and attaches it to
* the list 'new_tlist' (consisting of the VAR node and the RESDOM
* node as usual with tlists :-) )
*/ */
if (parse->hasAggs) if (parse->hasAggs)
{ {
if (parse->havingQual != NULL) if (parse->havingQual != NULL)
new_tlist = check_having_qual_for_vars(parse->havingQual, new_tlist); tlist = check_having_qual_for_vars(parse->havingQual, tlist);
} }
new_tlist = preprocess_targetlist(new_tlist,
parse->commandType,
parse->resultRelation,
parse->rtable);
/* Here starts the original (pre having) code */
tlist = preprocess_targetlist(tlist, tlist = preprocess_targetlist(tlist,
parse->commandType, parse->commandType,
parse->resultRelation, parse->resultRelation,
...@@ -176,7 +150,7 @@ union_planner(Query *parse) ...@@ -176,7 +150,7 @@ union_planner(Query *parse)
PlannerVarParam = lcons(vpm, PlannerVarParam); PlannerVarParam = lcons(vpm, PlannerVarParam);
result_plan = query_planner(parse, result_plan = query_planner(parse,
parse->commandType, parse->commandType,
new_tlist, tlist,
(List *) parse->qual); (List *) parse->qual);
PlannerVarParam = lnext(PlannerVarParam); PlannerVarParam = lnext(PlannerVarParam);
if (vpm != NULL) if (vpm != NULL)
...@@ -199,9 +173,8 @@ union_planner(Query *parse) ...@@ -199,9 +173,8 @@ union_planner(Query *parse)
*/ */
tuplePerGroup = parse->hasAggs; tuplePerGroup = parse->hasAggs;
/* Use 'new_tlist' instead of 'tlist' */
result_plan = result_plan =
make_groupPlan(&new_tlist, make_groupPlan(&tlist,
tuplePerGroup, tuplePerGroup,
parse->groupClause, parse->groupClause,
result_plan); result_plan);
...@@ -215,11 +188,6 @@ union_planner(Query *parse) ...@@ -215,11 +188,6 @@ union_planner(Query *parse)
int old_length = 0, int old_length = 0,
new_length = 0; new_length = 0;
/*
* Create the AGG node but use 'tlist' not 'new_tlist' as target
* list because we don't want the additional attributes (only used
* for the havingQual, see above) to show up in the result
*/
result_plan = (Plan *) make_agg(tlist, result_plan); result_plan = (Plan *) make_agg(tlist, result_plan);
/* /*
...@@ -235,6 +203,21 @@ union_planner(Query *parse) ...@@ -235,6 +203,21 @@ union_planner(Query *parse)
List *clause; List *clause;
List **vpm = NULL; List **vpm = NULL;
/*
* Restore target list: get rid of Vars added for havingQual.
* Assumption: tlist_len > 0...
*/
{
List *l;
int tlen = 0;
foreach (l, ((Agg *) result_plan)->plan.targetlist)
{
if (++tlen == tlist_len)
break;
}
lnext(l) = NIL;
}
/* /*
* stuff copied from above to handle the use of attributes * stuff copied from above to handle the use of attributes
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment