Fix oversight in check_ungrouped_columns optimization that avoids

unnecessary checks for complex grouping expressions: we cannot check
whether the expressions are simple Vars until after we apply
flatten_join_alias_vars, because in the case of FULL JOIN that routine
can introduce non-Var expressions.  Per example from Joel Knight.
This commit is contained in:
Tom Lane 2004-01-28 07:46:44 +00:00
parent 4405b3e05e
commit 31a0f1d33b
1 changed files with 18 additions and 7 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.60 2003/11/29 19:51:51 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/parser/parse_agg.c,v 1.61 2004/01/28 07:46:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -98,7 +98,7 @@ void
parseCheckAggregates(ParseState *pstate, Query *qry) parseCheckAggregates(ParseState *pstate, Query *qry)
{ {
List *groupClauses = NIL; List *groupClauses = NIL;
bool have_non_var_grouping = false; bool have_non_var_grouping;
List *lst; List *lst;
bool hasJoinRTEs; bool hasJoinRTEs;
Node *clause; Node *clause;
@ -127,9 +127,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
* No aggregates allowed in GROUP BY clauses, either. * No aggregates allowed in GROUP BY clauses, either.
* *
* While we are at it, build a list of the acceptable GROUP BY * While we are at it, build a list of the acceptable GROUP BY
* expressions for use by check_ungrouped_columns() (this avoids * expressions for use by check_ungrouped_columns().
* repeated scans of the targetlist within the recursive routine...).
* And detect whether any of the expressions aren't simple Vars.
*/ */
foreach(lst, qry->groupClause) foreach(lst, qry->groupClause)
{ {
@ -144,8 +142,6 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
(errcode(ERRCODE_GROUPING_ERROR), (errcode(ERRCODE_GROUPING_ERROR),
errmsg("aggregates not allowed in GROUP BY clause"))); errmsg("aggregates not allowed in GROUP BY clause")));
groupClauses = lcons(expr, groupClauses); groupClauses = lcons(expr, groupClauses);
if (!IsA(expr, Var))
have_non_var_grouping = true;
} }
/* /*
@ -170,6 +166,21 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
groupClauses = (List *) flatten_join_alias_vars(qry, groupClauses = (List *) flatten_join_alias_vars(qry,
(Node *) groupClauses); (Node *) groupClauses);
/*
* Detect whether any of the grouping expressions aren't simple Vars;
* if they're all Vars then we don't have to work so hard in the
* recursive scans. (Note we have to flatten aliases before this.)
*/
have_non_var_grouping = false;
foreach(lst, groupClauses)
{
if (!IsA((Node *) lfirst(lst), Var))
{
have_non_var_grouping = true;
break;
}
}
/* /*
* Check the targetlist and HAVING clause for ungrouped variables. * Check the targetlist and HAVING clause for ungrouped variables.
*/ */