diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index b8340557b34..4163d9a5930 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -1213,8 +1213,8 @@ parseCheckAggregates(ParseState *pstate, Query *qry) } /* - * Build a list of the acceptable GROUP BY expressions for use by - * substitute_grouped_columns(). + * Build a list of the acceptable GROUP BY expressions to save in the + * RTE_GROUP RTE, and for use by substitute_grouped_columns(). * * We get the TLE, not just the expr, because GROUPING wants to know the * sortgroupref. @@ -1231,6 +1231,23 @@ parseCheckAggregates(ParseState *pstate, Query *qry) groupClauses = lappend(groupClauses, expr); } + /* + * If there are any acceptable GROUP BY expressions, build an RTE and + * nsitem for the result of the grouping step. (It's important to do this + * before flattening join alias vars in groupClauses, because the RTE + * should preserve any alias vars that were in the input.) + */ + if (groupClauses) + { + pstate->p_grouping_nsitem = + addRangeTableEntryForGroup(pstate, groupClauses); + + /* Set qry->rtable again in case it was previously NIL */ + qry->rtable = pstate->p_rtable; + /* Mark the Query as having RTE_GROUP RTE */ + qry->hasGroupRTE = 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 @@ -1266,21 +1283,6 @@ parseCheckAggregates(ParseState *pstate, Query *qry) } } - /* - * If there are any acceptable GROUP BY expressions, build an RTE and - * nsitem for the result of the grouping step. - */ - if (groupClauses) - { - pstate->p_grouping_nsitem = - addRangeTableEntryForGroup(pstate, groupClauses); - - /* Set qry->rtable again in case it was previously NIL */ - qry->rtable = pstate->p_rtable; - /* Mark the Query as having RTE_GROUP RTE */ - qry->hasGroupRTE = true; - } - /* * Replace grouped variables in the targetlist and HAVING clause with Vars * that reference the RTE_GROUP RTE. Emit an error message if we find any diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index 4cfbe424603..6e0c86d79fc 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -1561,6 +1561,19 @@ group by f2; ----+------- (0 rows) +-- check that we preserve join alias in GROUP BY expressions +create temp view v1 as +select f1::int from t1 left join t2 using (f1) group by f1; +select pg_get_viewdef('v1'::regclass); + pg_get_viewdef +------------------------------- + SELECT (f1)::integer AS f1 + + FROM (t1 + + LEFT JOIN t2 USING (f1))+ + GROUP BY f1; +(1 row) + +drop view v1; drop table t1, t2; -- -- Test planner's selection of pathkeys for ORDER BY aggregates diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql index 79eca85c985..c383890bc85 100644 --- a/src/test/regress/sql/aggregates.sql +++ b/src/test/regress/sql/aggregates.sql @@ -567,6 +567,12 @@ select f2, count(*) from t1 x(x0,x1) left join (t1 left join t2 using(f2)) on (x0 = 0) group by f2; +-- check that we preserve join alias in GROUP BY expressions +create temp view v1 as +select f1::int from t1 left join t2 using (f1) group by f1; +select pg_get_viewdef('v1'::regclass); + +drop view v1; drop table t1, t2; --