From 951ea5fed2402d475b4325bf3f75992fb4abec6a Mon Sep 17 00:00:00 2001 From: Julien Rouhaud Date: Wed, 26 Jun 2019 21:53:20 +0200 Subject: [PATCH] Add regression test for rutime partitiong pruning, pg11+ This unfortunately can't be supported in pg11. Current code is currently broken, so later commit will add a proper fix to disable runtime partition pruning on hypothetically partitioned tables. --- expected/hypo_table.out | 178 ++++++++++++++++++++++++++++++++++++++++ test/sql/hypo_table.sql | 33 ++++++++ 2 files changed, 211 insertions(+) diff --git a/expected/hypo_table.out b/expected/hypo_table.out index 2221a8a..1228962 100644 --- a/expected/hypo_table.out +++ b/expected/hypo_table.out @@ -1381,6 +1381,184 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_hash t1, hypo_part_hash t2 WHERE t1.id = -> Seq Scan on part_hash_9 t1_9 (51 rows) +-- Runtime partition pruning +-- ------------------------- +-- 6B.0 Add function to easily simulate runtime partitioning +CREATE FUNCTION hypo_number_one() RETURNS integer AS +$_$ +BEGIN + RETURN 1; +END; +$_$ LANGUAGE plpgsql STABLE; +-- 6B.1 disable runtime partition pruning +SET enable_partition_pruning to false; +-- 6B.2 simple case +EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id = hypo_number_one(); + QUERY PLAN +------------------------------------------ + Append + -> Seq Scan on part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on part_range_20000_30000 + Filter: (id = hypo_number_one()) +(7 rows) + +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id = hypo_number_one(); + QUERY PLAN +--------------------------------------------------------------- + Append + -> Seq Scan on hypo_part_range hypo_part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_20000_30000 + Filter: (id = hypo_number_one()) +(7 rows) + +-- 6B.3 CTE +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s; + QUERY PLAN +-------------------------------------------------- + CTE Scan on s + CTE s + -> Append + -> Seq Scan on part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on part_range_20000_30000 + Filter: (id = hypo_number_one()) +(9 rows) + +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s; + QUERY PLAN +----------------------------------------------------------------------- + CTE Scan on s + CTE s + -> Append + -> Seq Scan on hypo_part_range hypo_part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_20000_30000 + Filter: (id = hypo_number_one()) +(9 rows) + +-- 6B.4 InitPlan +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s); + QUERY PLAN +---------------------------------------------------------- + Result + InitPlan 2 (returns $1) + -> CTE Scan on s + CTE s + -> Append + -> Seq Scan on part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on part_range_20000_30000 + Filter: (id = hypo_number_one()) +(11 rows) + +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s); + QUERY PLAN +------------------------------------------------------------------------------- + Result + InitPlan 2 (returns $1) + -> CTE Scan on s + CTE s + -> Append + -> Seq Scan on hypo_part_range hypo_part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_20000_30000 + Filter: (id = hypo_number_one()) +(11 rows) + +-- 6B.5 enable runtime partition pruning +SET enable_partition_pruning to true; +-- 6B.6 simple case +EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id = hypo_number_one(); + QUERY PLAN +------------------------------------------ + Append + Subplans Removed: 2 + -> Seq Scan on part_range_1_10000 + Filter: (id = hypo_number_one()) +(4 rows) + +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id = hypo_number_one(); + QUERY PLAN +--------------------------------------------------------------- + Append + -> Seq Scan on hypo_part_range hypo_part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_20000_30000 + Filter: (id = hypo_number_one()) +(7 rows) + +-- 6B.7 CTE +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s; + QUERY PLAN +-------------------------------------------------- + CTE Scan on s + CTE s + -> Append + Subplans Removed: 2 + -> Seq Scan on part_range_1_10000 + Filter: (id = hypo_number_one()) +(6 rows) + +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s; + QUERY PLAN +----------------------------------------------------------------------- + CTE Scan on s + CTE s + -> Append + -> Seq Scan on hypo_part_range hypo_part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_20000_30000 + Filter: (id = hypo_number_one()) +(9 rows) + +-- 6B.8 InitPlan +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s); + QUERY PLAN +---------------------------------------------------------- + Result + InitPlan 2 (returns $1) + -> CTE Scan on s + CTE s + -> Append + Subplans Removed: 2 + -> Seq Scan on part_range_1_10000 + Filter: (id = hypo_number_one()) +(8 rows) + +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s); + QUERY PLAN +------------------------------------------------------------------------------- + Result + InitPlan 2 (returns $1) + -> CTE Scan on s + CTE s + -> Append + -> Seq Scan on hypo_part_range hypo_part_range_1_10000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_10000_20000 + Filter: (id = hypo_number_one()) + -> Seq Scan on hypo_part_range hypo_part_range_20000_30000 + Filter: (id = hypo_number_one()) +(11 rows) + -- Tests for sanity checks -- ======================= -- 7.1 Duplicate name diff --git a/test/sql/hypo_table.sql b/test/sql/hypo_table.sql index 4c2d3a9..6e959ed 100644 --- a/test/sql/hypo_table.sql +++ b/test/sql/hypo_table.sql @@ -232,6 +232,39 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash t1, hypo_part_hash t2 WHERE t1. EXPLAIN (COSTS OFF) SELECT * FROM part_range t1, hypo_part_range t2 WHERE t1.id = t2.id and t1.id < 15000; EXPLAIN (COSTS OFF) SELECT * FROM part_hash t1, hypo_part_hash t2 WHERE t1.id = t2.id; +-- Runtime partition pruning +-- ------------------------- + +-- 6B.0 Add function to easily simulate runtime partitioning +CREATE FUNCTION hypo_number_one() RETURNS integer AS +$_$ +BEGIN + RETURN 1; +END; +$_$ LANGUAGE plpgsql STABLE; +-- 6B.1 disable runtime partition pruning +SET enable_partition_pruning to false; +-- 6B.2 simple case +EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id = hypo_number_one(); +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id = hypo_number_one(); +-- 6B.3 CTE +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s; +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s; +-- 6B.4 InitPlan +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s); +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s); +-- 6B.5 enable runtime partition pruning +SET enable_partition_pruning to true; +-- 6B.6 simple case +EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id = hypo_number_one(); +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id = hypo_number_one(); +-- 6B.7 CTE +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s; +EXPLAIN (COSTS OFF) WITH s AS (SELECT * FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s; +-- 6B.8 InitPlan +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM part_range WHERE id = hypo_number_one()) SELECT * FROM s); +EXPLAIN (COSTS OFF) SELECT (WITH s AS (SELECT 1 FROM hypo_part_range WHERE id = hypo_number_one()) SELECT * FROM s); + -- Tests for sanity checks -- =======================