summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim B. Mikheev1998-09-09 03:48:17 +0000
committerVadim B. Mikheev1998-09-09 03:48:17 +0000
commit9a2949e5dd92f9584d6f8e496e3e64b83814f72b (patch)
tree3761f0114af05ec2e203c601e8a429b060d3b3bd
parent04abb54197860c8882390db9af9606d7a50fb41b (diff)
Fix using GroupBy/non-GroupBy expressions in HAVING.
-rw-r--r--src/backend/optimizer/plan/planner.c26
-rw-r--r--src/backend/optimizer/plan/setrefs.c24
-rw-r--r--src/backend/parser/parse_agg.c10
3 files changed, 6 insertions, 54 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 4fa4a11b7b4..9cf0746145a 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.34 1998/09/08 02:50:20 vadim Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.35 1998/09/09 03:48:01 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -185,9 +185,6 @@ union_planner(Query *parse)
*/
if (parse->hasAggs)
{
- int old_length = 0,
- new_length = 0;
-
result_plan = (Plan *) make_agg(tlist, result_plan);
/*
@@ -256,31 +253,10 @@ union_planner(Query *parse)
*/
foreach(clause, ((Agg *) result_plan)->plan.qual)
{
-
- /*
- * Make sure there are aggregates in the havingQual if so,
- * the list must be longer after
- * check_having_qual_for_aggs
- */
- old_length = length(((Agg *) result_plan)->aggs);
-
((Agg *) result_plan)->aggs = nconc(((Agg *) result_plan)->aggs,
check_having_qual_for_aggs((Node *) lfirst(clause),
((Agg *) result_plan)->plan.lefttree->targetlist,
((List *) parse->groupClause)));
-
- /*
- * Have a look at the length of the returned list. If
- * there is no difference, no aggregates have been found
- * and that means, that the Qual belongs to the where
- * clause
- */
- if (((new_length = length(((Agg *) result_plan)->aggs)) == old_length) ||
- (new_length == 0))
- {
- elog(ERROR, "This could have been done in a where clause!!");
- return (Plan *) NIL;
- }
}
PlannerVarParam = lnext(PlannerVarParam);
if (vpm != NULL)
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 6f134acddba..72c5bc66fe3 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.26 1998/09/01 04:29:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.27 1998/09/09 03:48:02 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1045,36 +1045,15 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupCla
else if (is_funcclause(clause) || not_clause(clause) ||
or_clause(clause) || and_clause(clause))
{
- int new_length = 0,
- old_length = 0;
-
/*
* This is a function. Recursively call this routine for its
* arguments... (i.e. for AND, OR, ... clauses!)
*/
foreach(t, ((Expr *) clause)->args)
{
- old_length = length((List *) agg_list);
-
agg_list = nconc(agg_list,
check_having_qual_for_aggs(lfirst(t), subplanTargetList,
groupClause));
-
- /*
- * The arguments of OR or AND clauses are comparisons or
- * relations and because we are in the havingQual there must
- * be at least one operand using an aggregate function. If so,
- * we will find it and the lenght of the agg_list will be
- * increased after the above call to
- * check_having_qual_for_aggs. If there are no aggregates
- * used, the query could have been formulated using the
- * 'where' clause
- */
- if (((new_length = length((List *) agg_list)) == old_length) || (new_length == 0))
- {
- elog(ERROR, "This could have been done in a where clause!!");
- return NIL;
- }
}
return agg_list;
}
@@ -1199,7 +1178,6 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupCla
}
else
{
-
/*
* Ooops! we can not handle that!
*/
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index bb8d87d383b..eef2808f50d 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.13 1998/09/01 04:30:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.14 1998/09/09 03:48:17 vadim Exp $
*
*-------------------------------------------------------------------------
*/
@@ -104,7 +104,8 @@ exprIsAggOrGroupCol(Node *expr, List *groupClause)
List *gl;
if (expr == NULL || IsA(expr, Const) ||
- IsA(expr, Param) ||IsA(expr, Aggreg))
+ IsA(expr, Param) || IsA(expr, Aggreg) ||
+ IsA(expr, SubLink)) /* can't handle currently !!! */
return TRUE;
foreach(gl, groupClause)
@@ -207,13 +208,10 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
* the expression specified in the HAVING clause has the same
* restriction as those in the target list.
*/
-/*
- * Need to change here when we get HAVING works. Currently
- * qry->havingQual is NULL. - vadim 04/05/97
+
if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
elog(ERROR,
"parser: illegal use of aggregates or non-group column in HAVING clause");
- */
return;
}