aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/plan/planner.c8
-rw-r--r--src/backend/optimizer/plan/setrefs.c38
-rw-r--r--src/backend/optimizer/prep/preptlist.c45
-rw-r--r--src/backend/optimizer/util/tlist.c26
4 files changed, 97 insertions, 20 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 50d93942ec8..a55d444a8b3 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -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;
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index cf3c3edfc1f..ee3250080ce 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -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
{
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 084809c9d9e..5b70b368ca9 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -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;
diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c
index 6d25950bca0..a914930cc93 100644
--- a/src/backend/optimizer/util/tlist.c
+++ b/src/backend/optimizer/util/tlist.c
@@ -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)
{