diff --git a/contrib/pg_plan_advice/expected/partitionwise.out b/contrib/pg_plan_advice/expected/partitionwise.out index 0ae22600a4f..e87d35d04b7 100644 --- a/contrib/pg_plan_advice/expected/partitionwise.out +++ b/contrib/pg_plan_advice/expected/partitionwise.out @@ -49,6 +49,24 @@ INSERT INTO ptmismatch (id, dimm, valm) SELECT g, 'yet another text ' || g, (g % 2) + 1 FROM generate_series(1,3000) g; VACUUM ANALYZE ptmismatch; +CREATE TABLE mllpt (a int not null, b int not null) + PARTITION BY LIST (a); +CREATE TABLE mllpt_a1 PARTITION OF mllpt FOR VALUES IN (1) + PARTITION BY LIST (b); +CREATE TABLE mllpt_a1_b1 PARTITION OF mllpt_a1 FOR VALUES IN (1) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a1_b2 PARTITION OF mllpt_a1 FOR VALUES IN (2) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a1_b3 PARTITION OF mllpt_a1 FOR VALUES IN (3) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a2 PARTITION OF mllpt FOR VALUES IN (2) + PARTITION BY LIST (b); +CREATE TABLE mllpt_a2_b1 PARTITION OF mllpt_a2 FOR VALUES IN (1) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a2_b2 PARTITION OF mllpt_a2 FOR VALUES IN (2) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a2_b3 PARTITION OF mllpt_a2 FOR VALUES IN (3) + WITH (autovacuum_enabled = false); EXPLAIN (PLAN_ADVICE, COSTS OFF) SELECT * FROM pt1, pt2, pt3 WHERE pt1.id = pt2.id AND pt2.id = pt3.id AND val1 = 1 AND val2 = 1 AND val3 = 1; @@ -424,3 +442,37 @@ SELECT * FROM pt1, pt2, pt3 WHERE pt1.id = pt2.id AND pt2.id = pt3.id (49 rows) COMMIT; +-- We should get PARTITIONWISE advice for all unpruned partition tables. +EXPLAIN (PLAN_ADVICE, COSTS OFF) +SELECT * FROM mllpt WHERE a = 1 UNION ALL SELECT * FROM mllpt; + QUERY PLAN +----------------------------------------------------------------------------------------- + Append + -> Append + -> Seq Scan on mllpt_a1_b1 mllpt_7 + Filter: (a = 1) + -> Seq Scan on mllpt_a1_b2 mllpt_8 + Filter: (a = 1) + -> Seq Scan on mllpt_a1_b3 mllpt_9 + Filter: (a = 1) + -> Seq Scan on mllpt_a1_b1 mllpt + -> Seq Scan on mllpt_a1_b2 mllpt_1 + -> Seq Scan on mllpt_a1_b3 mllpt_2 + -> Seq Scan on mllpt_a2_b1 mllpt_3 + -> Seq Scan on mllpt_a2_b2 mllpt_4 + -> Seq Scan on mllpt_a2_b3 mllpt_5 + Generated Plan Advice: + SEQ_SCAN(mllpt/public.mllpt_a1_b1@unnamed_subquery + mllpt/public.mllpt_a1_b2@unnamed_subquery + mllpt/public.mllpt_a1_b3@unnamed_subquery mllpt/public.mllpt_a1_b1 + mllpt/public.mllpt_a1_b2 mllpt/public.mllpt_a1_b3 mllpt/public.mllpt_a2_b1 + mllpt/public.mllpt_a2_b2 mllpt/public.mllpt_a2_b3) + PARTITIONWISE(mllpt mllpt/public.mllpt_a1 mllpt/public.mllpt_a2 + mllpt/public.mllpt_a1@unnamed_subquery mllpt@unnamed_subquery) + NO_GATHER(unnamed_subquery#3 mllpt/public.mllpt_a1_b1 + mllpt/public.mllpt_a1_b2 mllpt/public.mllpt_a1_b3 mllpt/public.mllpt_a2_b1 + mllpt/public.mllpt_a2_b2 mllpt/public.mllpt_a2_b3 + mllpt/public.mllpt_a1_b1@unnamed_subquery + mllpt/public.mllpt_a1_b2@unnamed_subquery mllpt/public.mllpt_a1_b3@unnamed_subquery) +(27 rows) + diff --git a/contrib/pg_plan_advice/pgpa_scan.c b/contrib/pg_plan_advice/pgpa_scan.c index 4da77936216..ca2128be193 100644 --- a/contrib/pg_plan_advice/pgpa_scan.c +++ b/contrib/pg_plan_advice/pgpa_scan.c @@ -200,8 +200,13 @@ pgpa_build_scan(pgpa_plan_walker_context *walker, Plan *plan, child_nonjoin_relids = pgpa_filter_out_join_relids(child_relids, walker->pstmt->rtable); - (void) pgpa_make_scan(walker, plan, strategy, - child_nonjoin_relids); + if (unique_nonjoin_rtekind(child_nonjoin_relids, walker->pstmt->rtable) + == RTE_RELATION) + (void) pgpa_make_scan(walker, plan, PGPA_SCAN_PARTITIONWISE, + child_nonjoin_relids); + else + (void) pgpa_make_scan(walker, plan, PGPA_SCAN_ORDINARY, + child_nonjoin_relids); } /* diff --git a/contrib/pg_plan_advice/sql/partitionwise.sql b/contrib/pg_plan_advice/sql/partitionwise.sql index ce10d2abd7a..940ea49e64d 100644 --- a/contrib/pg_plan_advice/sql/partitionwise.sql +++ b/contrib/pg_plan_advice/sql/partitionwise.sql @@ -54,6 +54,25 @@ INSERT INTO ptmismatch (id, dimm, valm) FROM generate_series(1,3000) g; VACUUM ANALYZE ptmismatch; +CREATE TABLE mllpt (a int not null, b int not null) + PARTITION BY LIST (a); +CREATE TABLE mllpt_a1 PARTITION OF mllpt FOR VALUES IN (1) + PARTITION BY LIST (b); +CREATE TABLE mllpt_a1_b1 PARTITION OF mllpt_a1 FOR VALUES IN (1) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a1_b2 PARTITION OF mllpt_a1 FOR VALUES IN (2) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a1_b3 PARTITION OF mllpt_a1 FOR VALUES IN (3) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a2 PARTITION OF mllpt FOR VALUES IN (2) + PARTITION BY LIST (b); +CREATE TABLE mllpt_a2_b1 PARTITION OF mllpt_a2 FOR VALUES IN (1) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a2_b2 PARTITION OF mllpt_a2 FOR VALUES IN (2) + WITH (autovacuum_enabled = false); +CREATE TABLE mllpt_a2_b3 PARTITION OF mllpt_a2 FOR VALUES IN (3) + WITH (autovacuum_enabled = false); + EXPLAIN (PLAN_ADVICE, COSTS OFF) SELECT * FROM pt1, pt2, pt3 WHERE pt1.id = pt2.id AND pt2.id = pt3.id AND val1 = 1 AND val2 = 1 AND val3 = 1; @@ -100,3 +119,7 @@ EXPLAIN (PLAN_ADVICE, COSTS OFF) SELECT * FROM pt1, pt2, pt3 WHERE pt1.id = pt2.id AND pt2.id = pt3.id AND val1 = 1 AND val2 = 1 AND val3 = 1; COMMIT; + +-- We should get PARTITIONWISE advice for all unpruned partition tables. +EXPLAIN (PLAN_ADVICE, COSTS OFF) +SELECT * FROM mllpt WHERE a = 1 UNION ALL SELECT * FROM mllpt;