diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index eadc04222e..401299e542 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -3124,6 +3124,14 @@ remove_useless_groupby_columns(PlannerInfo *root) if (rte->rtekind != RTE_RELATION) continue; + /* + * We must skip inheritance parent tables as some of the child rels + * may cause duplicate rows. This cannot happen with partitioned + * tables, however. + */ + if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE) + continue; + /* Nothing to do unless this rel has multiple Vars in GROUP BY */ relattnos = groupbyattnos[relid]; if (bms_membership(relattnos) != BMS_MULTIPLE) diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index 2e5ce8cc32..ef8eec3fbf 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -1147,9 +1147,52 @@ explain (costs off) select * from t3 group by a,b,c; -> Seq Scan on t3 (3 rows) -drop table t1; +create temp table t1c () inherits (t1); +-- Ensure we don't remove any columns when t1 has a child table +explain (costs off) select * from t1 group by a,b,c,d; + QUERY PLAN +------------------------------------- + HashAggregate + Group Key: t1.a, t1.b, t1.c, t1.d + -> Append + -> Seq Scan on t1 + -> Seq Scan on t1c +(5 rows) + +-- Okay to remove columns if we're only querying the parent. +explain (costs off) select * from only t1 group by a,b,c,d; + QUERY PLAN +---------------------- + HashAggregate + Group Key: a, b + -> Seq Scan on t1 +(3 rows) + +create temp table p_t1 ( + a int, + b int, + c int, + d int, + primary key(a,b) +) partition by list(a); +create temp table p_t1_1 partition of p_t1 for values in(1); +create temp table p_t1_2 partition of p_t1 for values in(2); +-- Ensure we can remove non-PK columns for partitioned tables. +explain (costs off) select * from p_t1 group by a,b,c,d; + QUERY PLAN +--------------------------------- + HashAggregate + Group Key: p_t1_1.a, p_t1_1.b + -> Append + -> Seq Scan on p_t1_1 + -> Seq Scan on p_t1_2 +(5 rows) + +drop table t1 cascade; +NOTICE: drop cascades to table t1c drop table t2; drop table t3; +drop table p_t1; -- -- Test combinations of DISTINCT and/or ORDER BY -- diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql index ca0d5e66b2..17fb256aec 100644 --- a/src/test/regress/sql/aggregates.sql +++ b/src/test/regress/sql/aggregates.sql @@ -406,9 +406,31 @@ group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z; -- Cannot optimize when PK is deferrable explain (costs off) select * from t3 group by a,b,c; -drop table t1; +create temp table t1c () inherits (t1); + +-- Ensure we don't remove any columns when t1 has a child table +explain (costs off) select * from t1 group by a,b,c,d; + +-- Okay to remove columns if we're only querying the parent. +explain (costs off) select * from only t1 group by a,b,c,d; + +create temp table p_t1 ( + a int, + b int, + c int, + d int, + primary key(a,b) +) partition by list(a); +create temp table p_t1_1 partition of p_t1 for values in(1); +create temp table p_t1_2 partition of p_t1 for values in(2); + +-- Ensure we can remove non-PK columns for partitioned tables. +explain (costs off) select * from p_t1 group by a,b,c,d; + +drop table t1 cascade; drop table t2; drop table t3; +drop table p_t1; -- -- Test combinations of DISTINCT and/or ORDER BY