mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
Replaced targetlist entry in GroupClause by reference number
in Resdom and GroupClause so changing of resno's doesn't confuse the grouping any more. Jan
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.50 1999/05/10 00:45:20 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.51 1999/05/12 15:01:37 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -260,7 +260,8 @@ union_planner(Query *parse)
|
||||
* belong to?)
|
||||
*/
|
||||
check_having_for_ungrouped_vars(parse->havingQual,
|
||||
parse->groupClause);
|
||||
parse->groupClause,
|
||||
parse->targetList);
|
||||
}
|
||||
|
||||
/* Calculate the opfids from the opnos */
|
||||
@@ -426,8 +427,7 @@ make_subplanTargetList(Query *parse,
|
||||
GroupClause *grpcl = (GroupClause *) lfirst(gl);
|
||||
|
||||
keyno++; /* sort key # for this GroupClause */
|
||||
/* Is it safe to use just resno to match tlist and glist items?? */
|
||||
if (grpcl->entry->resdom->resno == resdom->resno)
|
||||
if (grpcl->tleGroupref == resdom->resgroupref)
|
||||
{
|
||||
/* Found a matching groupclause; record info for sorting */
|
||||
foundGroupClause = true;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.45 1999/05/06 23:07:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.46 1999/05/12 15:01:39 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -961,7 +961,8 @@ del_agg_clause(Node *clause)
|
||||
*/
|
||||
|
||||
void
|
||||
check_having_for_ungrouped_vars(Node *clause, List *groupClause)
|
||||
check_having_for_ungrouped_vars(Node *clause, List *groupClause,
|
||||
List *targetList)
|
||||
{
|
||||
List *t;
|
||||
|
||||
@@ -981,7 +982,7 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
|
||||
else if (IsA(clause, Iter))
|
||||
{
|
||||
check_having_for_ungrouped_vars(((Iter *) clause)->iterexpr,
|
||||
groupClause);
|
||||
groupClause, targetList);
|
||||
}
|
||||
else if (is_subplan(clause))
|
||||
{
|
||||
@@ -997,7 +998,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
|
||||
foreach(gl, groupClause)
|
||||
{
|
||||
if (var_equal(lfirst(t),
|
||||
get_expr(((GroupClause *) lfirst(gl))->entry)))
|
||||
get_groupclause_expr((GroupClause *)
|
||||
lfirst(gl), targetList)))
|
||||
{
|
||||
contained_in_group_clause = true;
|
||||
break;
|
||||
@@ -1016,7 +1018,8 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
|
||||
* subplan is a kind of Expr node.
|
||||
*/
|
||||
foreach(t, ((Expr *) clause)->args)
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause);
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause,
|
||||
targetList);
|
||||
}
|
||||
else if (IsA(clause, List))
|
||||
{
|
||||
@@ -1024,12 +1027,13 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
|
||||
* Recursively scan AND subclauses (see NOTE above).
|
||||
*/
|
||||
foreach(t, ((List *) clause))
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause);
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause,
|
||||
targetList);
|
||||
}
|
||||
else if (IsA(clause, Aggref))
|
||||
{
|
||||
check_having_for_ungrouped_vars(((Aggref *) clause)->target,
|
||||
groupClause);
|
||||
groupClause, targetList);
|
||||
}
|
||||
else if (IsA(clause, ArrayRef))
|
||||
{
|
||||
@@ -1040,22 +1044,28 @@ check_having_for_ungrouped_vars(Node *clause, List *groupClause)
|
||||
* expression and its index expression...
|
||||
*/
|
||||
foreach(t, aref->refupperindexpr)
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause);
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause,
|
||||
targetList);
|
||||
foreach(t, aref->reflowerindexpr)
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause);
|
||||
check_having_for_ungrouped_vars(aref->refexpr, groupClause);
|
||||
check_having_for_ungrouped_vars(aref->refassgnexpr, groupClause);
|
||||
check_having_for_ungrouped_vars(lfirst(t), groupClause,
|
||||
targetList);
|
||||
check_having_for_ungrouped_vars(aref->refexpr, groupClause,
|
||||
targetList);
|
||||
check_having_for_ungrouped_vars(aref->refassgnexpr, groupClause,
|
||||
targetList);
|
||||
}
|
||||
else if (case_clause(clause))
|
||||
{
|
||||
foreach(t, ((CaseExpr *) clause)->args)
|
||||
{
|
||||
CaseWhen *when = (CaseWhen *) lfirst(t);
|
||||
check_having_for_ungrouped_vars(when->expr, groupClause);
|
||||
check_having_for_ungrouped_vars(when->result, groupClause);
|
||||
check_having_for_ungrouped_vars(when->expr, groupClause,
|
||||
targetList);
|
||||
check_having_for_ungrouped_vars(when->result, groupClause,
|
||||
targetList);
|
||||
}
|
||||
check_having_for_ungrouped_vars(((CaseExpr *) clause)->defresult,
|
||||
groupClause);
|
||||
groupClause, targetList);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.18 1999/02/13 23:16:38 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.19 1999/05/12 15:01:41 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -229,6 +229,49 @@ replace_matching_resname(List *new_tlist, List *old_tlist)
|
||||
new_tl = makeTargetEntry(newresno, old_tle->expr);
|
||||
t_list = lappend(t_list, new_tl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Also it is possible that the parser or rewriter added
|
||||
* some junk attributes to hold GROUP BY expressions which
|
||||
* are not part of the result attributes.
|
||||
* We can simply identify them by looking at the resgroupref
|
||||
* in the TLE's resdom, which is a unique number telling which
|
||||
* TLE belongs to which GroupClause.
|
||||
*/
|
||||
if (old_tle->resdom->resgroupref > 0)
|
||||
{
|
||||
bool already_there = FALSE;
|
||||
TargetEntry *new_tle;
|
||||
Resdom *newresno;
|
||||
|
||||
/*
|
||||
* Check if the tle is already in the new list
|
||||
*/
|
||||
foreach(i, t_list)
|
||||
{
|
||||
new_tle = (TargetEntry *)lfirst(i);
|
||||
|
||||
if (new_tle->resdom->resgroupref ==
|
||||
old_tle->resdom->resgroupref)
|
||||
{
|
||||
already_there = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* If not, add it and make sure it is now a junk attribute
|
||||
*/
|
||||
if (!already_there)
|
||||
{
|
||||
newresno = (Resdom *) copyObject((Node *) old_tle->resdom);
|
||||
newresno->resno = length(t_list) + 1;
|
||||
newresno->resjunk = 1;
|
||||
new_tl = makeTargetEntry(newresno, old_tle->expr);
|
||||
t_list = lappend(t_list, new_tl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return t_list;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.29 1999/05/06 23:07:33 tgl Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/tlist.c,v 1.30 1999/05/12 15:01:44 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -518,6 +518,25 @@ get_expr(TargetEntry *tle)
|
||||
}
|
||||
|
||||
|
||||
Var *
|
||||
get_groupclause_expr(GroupClause *groupClause, List *targetList)
|
||||
{
|
||||
List *l;
|
||||
TargetEntry *tle;
|
||||
|
||||
foreach(l, targetList)
|
||||
{
|
||||
tle = (TargetEntry *)lfirst(l);
|
||||
if (tle->resdom->resgroupref == groupClause->tleGroupref)
|
||||
return get_expr(tle);
|
||||
}
|
||||
|
||||
elog(ERROR,
|
||||
"get_groupclause_expr: GROUP BY expression not found in targetlist");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
*****************************************************************************/
|
||||
@@ -528,6 +547,11 @@ get_expr(TargetEntry *tle)
|
||||
* in there.
|
||||
*/
|
||||
#ifdef NOT_USED
|
||||
/*
|
||||
* WARNING!!! If this ever get's used again, the new reference
|
||||
* mechanism from group clause to targetlist entry must be implemented
|
||||
* here too. Jan
|
||||
*/
|
||||
void
|
||||
AddGroupAttrToTlist(List *tlist, List *grpCl)
|
||||
{
|
||||
|
Reference in New Issue
Block a user