summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2019-07-03 23:46:26 +1200
committerDavid Rowley <drowley@postgresql.org>2019-07-03 23:46:26 +1200
commit388d05a5e1551e34e3908c2bfad21860adfcc5a7 (patch)
treeb8449c37fb64d26c3619bbefd95812e9e71f1b1c
parent78aaffd285c4a66452004f8f2c4ff2771cee4cb4 (diff)
Don't remove surplus columns from GROUP BY for inheritance parents
d4c3a156c added code to remove columns that were not part of a table's PRIMARY KEY constraint from the GROUP BY clause when all the primary key columns were present in the group by. This is fine to do since we know that there will only be one row per group coming from this relation. However, the logic failed to consider inheritance parent relations. These can have child relations without a primary key, but even if they did, they could duplicate one of the parent's rows or one from another child relation. In this case, those additional GROUP BY columns are required. Fix this by disabling the optimization for inheritance parent tables. In v11 and beyond, partitioned tables are fine since partitions cannot overlap and before v11 partitioned tables could not have a primary key. Reported-by: Manuel Rigger Discussion: http://postgr.es/m/CA+u7OA7VLKf_vEr6kLF3MnWSA9LToJYncgpNX2tQ-oWzYCBQAw@mail.gmail.com Backpatch-through: 9.6
-rw-r--r--src/backend/optimizer/plan/planner.c7
-rw-r--r--src/test/regress/expected/aggregates.out24
-rw-r--r--src/test/regress/sql/aggregates.sql10
3 files changed, 39 insertions, 2 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 078df86b5ea..cbf55c51a22 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -2643,6 +2643,13 @@ 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.
+ */
+ if (rte->inh)
+ 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 a1663f08c22..ec13dc02d01 100644
--- a/src/test/regress/expected/aggregates.out
+++ b/src/test/regress/expected/aggregates.out
@@ -1014,7 +1014,29 @@ 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)
+
+drop table t1 cascade;
+NOTICE: drop cascades to table t1c
drop table t2;
drop table t3;
--
diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql
index 7e129f74bc2..bcf719f28ff 100644
--- a/src/test/regress/sql/aggregates.sql
+++ b/src/test/regress/sql/aggregates.sql
@@ -362,7 +362,15 @@ 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;
+
+drop table t1 cascade;
drop table t2;
drop table t3;