diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index f980d52f2b0e72e2fbee05a4f094227dcc2aa367..92ea3b9bd9e4b54198c802e78cc11fdbb11988f1 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.51 2003/01/17 03:25:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.52 2003/04/03 18:04:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,6 +16,7 @@ #include "optimizer/clauses.h" #include "optimizer/tlist.h" +#include "optimizer/var.h" #include "parser/parse_agg.h" #include "parser/parsetree.h" @@ -179,7 +180,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry) { List *groupClauses = NIL; bool have_non_var_grouping = false; - List *tl; + List *lst; + bool hasJoinRTEs; + Node *clause; /* This should only be called if we found aggregates, GROUP, or HAVING */ Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual); @@ -205,9 +208,9 @@ parseCheckAggregates(ParseState *pstate, Query *qry) * repeated scans of the targetlist within the recursive routine...). * And detect whether any of the expressions aren't simple Vars. */ - foreach(tl, qry->groupClause) + foreach(lst, qry->groupClause) { - GroupClause *grpcl = lfirst(tl); + GroupClause *grpcl = (GroupClause *) lfirst(lst); Node *expr; expr = get_sortgroupclause_expr(grpcl, qry->targetList); @@ -220,14 +223,40 @@ parseCheckAggregates(ParseState *pstate, Query *qry) have_non_var_grouping = true; } + /* + * If there are join alias vars involved, we have to flatten them + * to the underlying vars, so that aliased and unaliased vars will be + * correctly taken as equal. We can skip the expense of doing this + * if no rangetable entries are RTE_JOIN kind. + */ + hasJoinRTEs = false; + foreach(lst, pstate->p_rtable) + { + RangeTblEntry *rte = (RangeTblEntry *) lfirst(lst); + + if (rte->rtekind == RTE_JOIN) + { + hasJoinRTEs = true; + break; + } + } + + if (hasJoinRTEs) + groupClauses = (List *) flatten_join_alias_vars(qry, + (Node *) groupClauses); + /* * Check the targetlist and HAVING clause for ungrouped variables. */ - check_ungrouped_columns((Node *) qry->targetList, pstate, - groupClauses, have_non_var_grouping); - check_ungrouped_columns((Node *) qry->havingQual, pstate, + clause = (Node *) qry->targetList; + if (hasJoinRTEs) + clause = flatten_join_alias_vars(qry, clause); + check_ungrouped_columns(clause, pstate, groupClauses, have_non_var_grouping); - /* Release the list storage (but not the pointed-to expressions!) */ - freeList(groupClauses); + clause = (Node *) qry->havingQual; + if (hasJoinRTEs) + clause = flatten_join_alias_vars(qry, clause); + check_ungrouped_columns(clause, pstate, + groupClauses, have_non_var_grouping); }