Fix GroupBY func broken by HAVING.
This commit is contained in:
parent
6866cbc7c7
commit
994cfba1e5
@ -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 *
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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,7 +203,22 @@ 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
|
||||||
* from outside in subselects
|
* from outside in subselects
|
||||||
|
Loading…
Reference in New Issue
Block a user