From 7d3f7c2bf4a8b9d663093e117ad5a388dcd4909d Mon Sep 17 00:00:00 2001 From: Murat Tuncer Date: Mon, 3 Sep 2018 12:45:00 +0300 Subject: [PATCH] Add regression tests related to new PG11 partitioning features --- .../regress/expected/multi_partitioning.out | 352 +++++++++++++++++- .../regress/expected/multi_partitioning_0.out | 280 +++++++++++++- .../regress/expected/multi_partitioning_1.out | 264 ++++++++++++- src/test/regress/sql/multi_partitioning.sql | 145 +++++++- 4 files changed, 1017 insertions(+), 24 deletions(-) diff --git a/src/test/regress/expected/multi_partitioning.out b/src/test/regress/expected/multi_partitioning.out index c0bb19567..4286515ab 100644 --- a/src/test/regress/expected/multi_partitioning.out +++ b/src/test/regress/expected/multi_partitioning.out @@ -18,15 +18,21 @@ SELECT substring(:'server_version', '\d+')::int AS server_version; -- 1-) Distributing partitioned table -- create partitioned table CREATE TABLE partitioning_test(id int, time date) PARTITION BY RANGE (time); - +CREATE TABLE partitioning_hash_test(id int, subid int) PARTITION BY HASH(subid); -- create its partitions CREATE TABLE partitioning_test_2009 PARTITION OF partitioning_test FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); CREATE TABLE partitioning_test_2010 PARTITION OF partitioning_test FOR VALUES FROM ('2010-01-01') TO ('2011-01-01'); +CREATE TABLE partitioning_hash_test_0 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +CREATE TABLE partitioning_hash_test_1 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); -- load some data and distribute tables INSERT INTO partitioning_test VALUES (1, '2009-06-06'); INSERT INTO partitioning_test VALUES (2, '2010-07-07'); INSERT INTO partitioning_test_2009 VALUES (3, '2009-09-09'); INSERT INTO partitioning_test_2010 VALUES (4, '2010-03-03'); +INSERT INTO partitioning_hash_test VALUES (1, 2); +INSERT INTO partitioning_hash_test VALUES (2, 13); +INSERT INTO partitioning_hash_test VALUES (3, 7); +INSERT INTO partitioning_hash_test VALUES (4, 4); -- distribute partitioned table SELECT create_distributed_table('partitioning_test', 'id'); NOTICE: Copying data from local table... @@ -36,6 +42,14 @@ NOTICE: Copying data from local table... (1 row) +SELECT create_distributed_table('partitioning_hash_test', 'id'); +NOTICE: Copying data from local table... +NOTICE: Copying data from local table... + create_distributed_table +-------------------------- + +(1 row) + -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; id | time @@ -46,6 +60,15 @@ SELECT * FROM partitioning_test ORDER BY 1; 4 | 03-03-2010 (4 rows) +SELECT * FROM partitioning_hash_test ORDER BY 1; + id | subid +----+------- + 1 | 2 + 2 | 13 + 3 | 7 + 4 | 4 +(4 rows) + -- see partitioned table and its partitions are distributed SELECT logicalrelid @@ -76,6 +99,35 @@ ORDER BY partitioning_test_2010 | 4 (3 rows) +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +ORDER BY 1; + logicalrelid +-------------------------- + partitioning_hash_test + partitioning_hash_test_0 + partitioning_hash_test_1 +(3 rows) + +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------+------- + partitioning_hash_test | 4 + partitioning_hash_test_0 | 4 + partitioning_hash_test_1 | 4 +(3 rows) + -- 2-) Creating partition of a distributed table CREATE TABLE partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01'); -- new partition is automatically distributed as well @@ -141,6 +193,21 @@ ORDER BY partitioning_test_2012 | 4 (2 rows) +-- try to insert a new data to hash partitioned table +-- no partition is defined for value 5 +INSERT INTO partitioning_hash_test VALUES (8, 5); +ERROR: no partition of relation "partitioning_hash_test_1660012" found for row +DETAIL: Partition key of the failing row contains (subid) = (5). +CONTEXT: while executing command on localhost:57637 +INSERT INTO partitioning_hash_test VALUES (9, 12); +ERROR: no partition of relation "partitioning_hash_test_1660015" found for row +DETAIL: Partition key of the failing row contains (subid) = (12). +CONTEXT: while executing command on localhost:57638 +CREATE TABLE partitioning_hash_test_2 (id int, subid int); +INSERT INTO partitioning_hash_test_2 VALUES (8, 5); +ALTER TABLE partitioning_hash_test ATTACH PARTITION partitioning_hash_test_2 FOR VALUES WITH (MODULUS 3, REMAINDER 2); +NOTICE: Copying data from local table... +INSERT INTO partitioning_hash_test VALUES (9, 12); -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; id | time @@ -153,6 +220,17 @@ SELECT * FROM partitioning_test ORDER BY 1; 6 | 07-07-2012 (6 rows) +SELECT * FROM partitioning_hash_test ORDER BY 1; + id | subid +----+------- + 1 | 2 + 2 | 13 + 3 | 7 + 4 | 4 + 8 | 5 + 9 | 12 +(6 rows) + -- 4-) Attaching distributed table to distributed table CREATE TABLE partitioning_test_2013(id int, time date); SELECT create_distributed_table('partitioning_test_2013', 'id'); @@ -343,12 +421,70 @@ SELECT * FROM partitioning_test WHERE id = 9 OR id = 10 ORDER BY 1; ----+------ (0 rows) +-- create default partition +CREATE TABLE partitioning_test_default PARTITION OF partitioning_test DEFAULT; +\d+ partitioning_test + Table "public.partitioning_test" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + id | integer | | | | plain | | + time | date | | | | plain | | +Partition key: RANGE ("time") +Partitions: partitioning_test_2009 FOR VALUES FROM ('01-01-2009') TO ('01-01-2010'), + partitioning_test_2010 FOR VALUES FROM ('01-01-2010') TO ('01-01-2011'), + partitioning_test_2011 FOR VALUES FROM ('01-01-2011') TO ('01-01-2012'), + partitioning_test_2012 FOR VALUES FROM ('01-01-2012') TO ('01-01-2013'), + partitioning_test_2013 FOR VALUES FROM ('01-01-2013') TO ('01-01-2014'), + partitioning_test_default DEFAULT + +INSERT INTO partitioning_test VALUES(21, '2014-02-02'); +INSERT INTO partitioning_test VALUES(22, '2015-04-02'); +-- see they are inserted into default partition +SELECT * FROM partitioning_test WHERE id > 20; + id | time +----+------------ + 21 | 02-02-2014 + 22 | 04-02-2015 +(2 rows) + +SELECT * FROM partitioning_test_default; + id | time +----+------------ + 21 | 02-02-2014 + 22 | 04-02-2015 +(2 rows) + +-- create a new partition (will fail) +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +ERROR: updated partition constraint for default partition would be violated by some row +CONTEXT: while executing command on localhost:57637 +BEGIN; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_default; +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +INSERT INTO partitioning_test SELECT * FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +DELETE FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_default DEFAULT; +END; +-- see data is in the table, but some moved out from default partition +SELECT * FROM partitioning_test WHERE id > 20; + id | time +----+------------ + 21 | 02-02-2014 + 22 | 04-02-2015 +(2 rows) + +SELECT * FROM partitioning_test_default; + id | time +----+------------ + 22 | 04-02-2015 +(1 row) + -- test master_modify_multiple_shards -- master_modify_multiple_shards on partitioned table SELECT master_modify_multiple_shards('UPDATE partitioning_test SET time = time + INTERVAL ''1 day'''); master_modify_multiple_shards ------------------------------- - 24 + 26 (1 row) -- see rows are UPDATED @@ -379,7 +515,9 @@ SELECT * FROM partitioning_test ORDER BY 1; 18 | 02-02-2012 19 | 02-03-2009 20 | 02-03-2010 -(24 rows) + 21 | 02-03-2014 + 22 | 04-03-2015 +(26 rows) -- master_modify_multiple_shards on partition directly SELECT master_modify_multiple_shards('UPDATE partitioning_test_2009 SET time = time + INTERVAL ''1 day'''); @@ -418,16 +556,18 @@ CREATE INDEX partitioning_2009_index ON partitioning_test_2009(id); CREATE INDEX CONCURRENTLY partitioned_2010_index ON partitioning_test_2010(id); -- see index is created SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'partitioning_test%' ORDER BY indexname; - tablename | indexname -------------------------+------------------------------- - partitioning_test_2010 | partitioned_2010_index - partitioning_test_2009 | partitioning_2009_index - partitioning_test_2009 | partitioning_test_2009_id_idx - partitioning_test_2010 | partitioning_test_2010_id_idx - partitioning_test_2011 | partitioning_test_2011_id_idx - partitioning_test_2012 | partitioning_test_2012_id_idx - partitioning_test_2013 | partitioning_test_2013_id_idx -(7 rows) + tablename | indexname +---------------------------+---------------------------------- + partitioning_test_2010 | partitioned_2010_index + partitioning_test_2009 | partitioning_2009_index + partitioning_test_2009 | partitioning_test_2009_id_idx + partitioning_test_2010 | partitioning_test_2010_id_idx + partitioning_test_2011 | partitioning_test_2011_id_idx + partitioning_test_2012 | partitioning_test_2012_id_idx + partitioning_test_2013 | partitioning_test_2013_id_idx + partitioning_test_2014 | partitioning_test_2014_id_idx + partitioning_test_default | partitioning_test_default_id_idx +(9 rows) -- test add COLUMN -- add COLUMN to partitioned table @@ -474,8 +614,29 @@ WHERE partitioning_test_2009 | partitioning_2009_primary | PRIMARY KEY (1 row) +-- however, you can add primary key if it contains both distribution and partition key +ALTER TABLE partitioning_hash_test ADD CONSTRAINT partitioning_hash_primary PRIMARY KEY (id, subid); +-- see PRIMARY KEY is created +SELECT + table_name, + constraint_name, + constraint_type +FROM + information_schema.table_constraints +WHERE + table_name LIKE 'partitioning_hash_test%' AND + constraint_type = 'PRIMARY KEY' +ORDER BY 1; + table_name | constraint_name | constraint_type +--------------------------+-------------------------------+----------------- + partitioning_hash_test | partitioning_hash_primary | PRIMARY KEY + partitioning_hash_test_0 | partitioning_hash_test_0_pkey | PRIMARY KEY + partitioning_hash_test_1 | partitioning_hash_test_1_pkey | PRIMARY KEY + partitioning_hash_test_2 | partitioning_hash_test_2_pkey | PRIMARY KEY +(4 rows) + -- test ADD FOREIGN CONSTRAINT --- add FOREIGN CONSTRAINT to partitioned table -- this will error out +-- add FOREIGN CONSTRAINT to partitioned table -- this will error out (it is a self reference) ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_foreign FOREIGN KEY (id) REFERENCES partitioning_test_2009 (id); ERROR: cannot ALTER TABLE "partitioning_test_2009" because it is being used by active queries in this session -- add FOREIGN CONSTRAINT to partition @@ -512,6 +673,40 @@ SELECT * FROM partitioning_test WHERE time >= '2009-01-01' AND time < '2010-01-0 ----+------+------------ (0 rows) +-- delete from default partition +DELETE FROM partitioning_test WHERE time >= '2015-01-01'; +SELECT * FROM partitioning_test_default; + id | time | new_column +----+------+------------ +(0 rows) + +-- create a reference table for foreign key test +CREATE TABLE partitioning_test_reference(id int PRIMARY KEY, subid int); +INSERT INTO partitioning_test_reference SELECT a, a FROM generate_series(1, 50) a; +SELECT create_reference_table('partitioning_test_reference'); +NOTICE: Copying data from local table... + create_reference_table +------------------------ + +(1 row) + +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_reference_fkey FOREIGN KEY (id) REFERENCES partitioning_test_reference(id) ON DELETE CASCADE; +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + id | time | new_column +----+------------+------------ + 11 | 01-02-2011 | + 11 | 01-02-2011 | + 12 | 01-02-2012 | + 12 | 01-02-2012 | +(4 rows) + +DELETE FROM partitioning_test_reference WHERE id = 11 or id = 12; +-- see data is deleted from referencing table +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + id | time | new_column +----+------+------------ +(0 rows) + -- -- Transaction tests -- @@ -663,6 +858,7 @@ SELECT * FROM partitioning_test WHERE time >= '2010-01-01' AND time < '2011-01-0 -- test DROP partitioned table DROP TABLE partitioning_test; +DROP TABLE partitioning_test_reference; -- dropping the parent should CASCADE to the children as well SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'partitioning_test%' ORDER BY 1; table_name @@ -913,7 +1109,7 @@ INSERT INTO multi_column_partitioning VALUES(1, 1); INSERT INTO multi_column_partitioning_0_0_10_0 VALUES(5, -5); -- test INSERT to multi-column partitioned table where no suitable partition exists INSERT INTO multi_column_partitioning VALUES(10, 1); -ERROR: no partition of relation "multi_column_partitioning_1660068" found for row +ERROR: no partition of relation "multi_column_partitioning_1660097" found for row DETAIL: Partition key of the failing row contains (c1, c2) = (10, 1). CONTEXT: while executing command on localhost:57637 -- test with MINVALUE/MAXVALUE @@ -923,7 +1119,7 @@ INSERT INTO multi_column_partitioning VALUES(11, -11); INSERT INTO multi_column_partitioning_10_max_20_min VALUES(19, -19); -- test INSERT to multi-column partitioned table where no suitable partition exists INSERT INTO multi_column_partitioning VALUES(20, -20); -ERROR: no partition of relation "multi_column_partitioning_1660068" found for row +ERROR: no partition of relation "multi_column_partitioning_1660097" found for row DETAIL: Partition key of the failing row contains (c1, c2) = (20, -20). CONTEXT: while executing command on localhost:57637 -- see data is loaded to multi-column partitioned table @@ -1237,6 +1433,130 @@ ORDER BY (12 rows) COMMIT; +-- test partition-wise join +CREATE TABLE partitioning_hash_join_test(id int, subid int) PARTITION BY HASH(subid); +CREATE TABLE partitioning_hash_join_test_0 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +CREATE TABLE partitioning_hash_join_test_1 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +CREATE TABLE partitioning_hash_join_test_2 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 2); +SELECT create_distributed_table('partitioning_hash_join_test', 'id'); + create_distributed_table +-------------------------- + +(1 row) + +-- see the query plan without partition-wise join +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=57637 dbname=regression + -> Merge Join (cost=563.58..752.73 rows=383 width=8) + Merge Cond: ((partitioning_hash_test.id = partitioning_hash_join_test.id) AND (partitioning_hash_test.subid = partitioning_hash_join_test.subid)) + -> Merge Append (cost=0.43..123.59 rows=2262 width=8) + Sort Key: partitioning_hash_test.id, partitioning_hash_test.subid + -> Index Only Scan using partitioning_hash_test_0_1660016_pkey on partitioning_hash_test_0_1660016 partitioning_hash_test (cost=0.12..8.14 rows=1 width=8) + -> Index Only Scan using partitioning_hash_test_1_1660020_pkey on partitioning_hash_test_1_1660020 partitioning_hash_test_1 (cost=0.15..78.06 rows=2260 width=8) + -> Index Only Scan using partitioning_hash_test_2_1660032_pkey on partitioning_hash_test_2_1660032 partitioning_hash_test_2 (cost=0.12..8.14 rows=1 width=8) + -> Sort (cost=563.15..580.10 rows=6780 width=8) + Sort Key: partitioning_hash_join_test.id, partitioning_hash_join_test.subid + -> Append (cost=0.00..131.70 rows=6780 width=8) + -> Seq Scan on partitioning_hash_join_test_0_1660129 partitioning_hash_join_test (cost=0.00..32.60 rows=2260 width=8) + -> Seq Scan on partitioning_hash_join_test_1_1660133 partitioning_hash_join_test_1 (cost=0.00..32.60 rows=2260 width=8) + -> Seq Scan on partitioning_hash_join_test_2_1660137 partitioning_hash_join_test_2 (cost=0.00..32.60 rows=2260 width=8) +(18 rows) + +-- set partition-wise join on +SELECT success FROM run_command_on_workers('alter system set enable_partitionwise_join to on'); + success +--------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------- + t + t +(2 rows) + +SET enable_partitionwise_join TO on; +-- see the new query plan +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=57637 dbname=regression + -> Append (cost=1.02..367.91 rows=130 width=8) + -> Hash Join (cost=1.02..50.59 rows=1 width=8) + Hash Cond: ((partitioning_hash_join_test.id = partitioning_hash_test.id) AND (partitioning_hash_join_test.subid = partitioning_hash_test.subid)) + -> Seq Scan on partitioning_hash_join_test_0_1660129 partitioning_hash_join_test (cost=0.00..32.60 rows=2260 width=8) + -> Hash (cost=1.01..1.01 rows=1 width=8) + -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test (cost=0.00..1.01 rows=1 width=8) + -> Merge Join (cost=158.66..266.09 rows=128 width=8) + Merge Cond: ((partitioning_hash_test_1.id = partitioning_hash_join_test_1.id) AND (partitioning_hash_test_1.subid = partitioning_hash_join_test_1.subid)) + -> Index Only Scan using partitioning_hash_test_1_1660020_pkey on partitioning_hash_test_1_1660020 partitioning_hash_test_1 (cost=0.15..78.06 rows=2260 width=8) + -> Sort (cost=158.51..164.16 rows=2260 width=8) + Sort Key: partitioning_hash_join_test_1.id, partitioning_hash_join_test_1.subid + -> Seq Scan on partitioning_hash_join_test_1_1660133 partitioning_hash_join_test_1 (cost=0.00..32.60 rows=2260 width=8) + -> Hash Join (cost=1.02..50.59 rows=1 width=8) + Hash Cond: ((partitioning_hash_join_test_2.id = partitioning_hash_test_2.id) AND (partitioning_hash_join_test_2.subid = partitioning_hash_test_2.subid)) + -> Seq Scan on partitioning_hash_join_test_2_1660137 partitioning_hash_join_test_2 (cost=0.00..32.60 rows=2260 width=8) + -> Hash (cost=1.01..1.01 rows=1 width=8) + -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_2 (cost=0.00..1.01 rows=1 width=8) +(22 rows) + +-- note that partition-wise joins only work when partition key is in the join +-- following join does not have that, therefore join will not be pushed down to +-- partitions +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Custom Scan (Citus Real-Time) (cost=0.00..0.00 rows=0 width=0) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=57637 dbname=regression + -> Merge Join (cost=563.58..1842.63 rows=76682 width=12) + Merge Cond: (partitioning_hash_test.id = partitioning_hash_join_test.id) + -> Merge Append (cost=0.43..123.59 rows=2262 width=8) + Sort Key: partitioning_hash_test.id + -> Index Only Scan using partitioning_hash_test_0_1660016_pkey on partitioning_hash_test_0_1660016 partitioning_hash_test (cost=0.12..8.14 rows=1 width=8) + -> Index Only Scan using partitioning_hash_test_1_1660020_pkey on partitioning_hash_test_1_1660020 partitioning_hash_test_1 (cost=0.15..78.06 rows=2260 width=8) + -> Index Only Scan using partitioning_hash_test_2_1660032_pkey on partitioning_hash_test_2_1660032 partitioning_hash_test_2 (cost=0.12..8.14 rows=1 width=8) + -> Sort (cost=563.15..580.10 rows=6780 width=8) + Sort Key: partitioning_hash_join_test.id + -> Append (cost=0.00..131.70 rows=6780 width=8) + -> Seq Scan on partitioning_hash_join_test_0_1660129 partitioning_hash_join_test (cost=0.00..32.60 rows=2260 width=8) + -> Seq Scan on partitioning_hash_join_test_1_1660133 partitioning_hash_join_test_1 (cost=0.00..32.60 rows=2260 width=8) + -> Seq Scan on partitioning_hash_join_test_2_1660137 partitioning_hash_join_test_2 (cost=0.00..32.60 rows=2260 width=8) +(18 rows) + +-- reset partition-wise join +SELECT success FROM run_command_on_workers('reset enable_partitionwise_join'); + success +--------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------- + t + t +(2 rows) + +RESET enable_partitionwise_join; DROP TABLE IF EXISTS partitioning_test_2009, diff --git a/src/test/regress/expected/multi_partitioning_0.out b/src/test/regress/expected/multi_partitioning_0.out index 0ed0e0792..60870c556 100644 --- a/src/test/regress/expected/multi_partitioning_0.out +++ b/src/test/regress/expected/multi_partitioning_0.out @@ -18,15 +18,40 @@ SELECT substring(:'server_version', '\d+')::int AS server_version; -- 1-) Distributing partitioned table -- create partitioned table CREATE TABLE partitioning_test(id int, time date) PARTITION BY RANGE (time); - +CREATE TABLE partitioning_hash_test(id int, subid int) PARTITION BY HASH(subid); +ERROR: unrecognized partitioning strategy "hash" -- create its partitions CREATE TABLE partitioning_test_2009 PARTITION OF partitioning_test FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); CREATE TABLE partitioning_test_2010 PARTITION OF partitioning_test FOR VALUES FROM ('2010-01-01') TO ('2011-01-01'); +CREATE TABLE partitioning_hash_test_0 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +ERROR: syntax error at or near "WITH" +LINE 1: ..._0 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODU... + ^ +CREATE TABLE partitioning_hash_test_1 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +ERROR: syntax error at or near "WITH" +LINE 1: ..._1 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODU... + ^ -- load some data and distribute tables INSERT INTO partitioning_test VALUES (1, '2009-06-06'); INSERT INTO partitioning_test VALUES (2, '2010-07-07'); INSERT INTO partitioning_test_2009 VALUES (3, '2009-09-09'); INSERT INTO partitioning_test_2010 VALUES (4, '2010-03-03'); +INSERT INTO partitioning_hash_test VALUES (1, 2); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (1, 2); + ^ +INSERT INTO partitioning_hash_test VALUES (2, 13); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (2, 13); + ^ +INSERT INTO partitioning_hash_test VALUES (3, 7); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (3, 7); + ^ +INSERT INTO partitioning_hash_test VALUES (4, 4); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (4, 4); + ^ -- distribute partitioned table SELECT create_distributed_table('partitioning_test', 'id'); NOTICE: Copying data from local table... @@ -36,6 +61,10 @@ NOTICE: Copying data from local table... (1 row) +SELECT create_distributed_table('partitioning_hash_test', 'id'); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: SELECT create_distributed_table('partitioning_hash_test', 'i... + ^ -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; id | time @@ -46,6 +75,10 @@ SELECT * FROM partitioning_test ORDER BY 1; 4 | 03-03-2010 (4 rows) +SELECT * FROM partitioning_hash_test ORDER BY 1; +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: SELECT * FROM partitioning_hash_test ORDER BY 1; + ^ -- see partitioned table and its partitions are distributed SELECT logicalrelid @@ -76,6 +109,27 @@ ORDER BY partitioning_test_2010 | 4 (3 rows) +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +ORDER BY 1; +ERROR: relation "partitioning_hash_test" does not exist +LINE 6: logicalrelid IN ('partitioning_hash_test', 'partitioning_ha... + ^ +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +GROUP BY + logicalrelid +ORDER BY + 1,2; +ERROR: relation "partitioning_hash_test" does not exist +LINE 4: WHERE logicalrelid IN ('partitioning_hash_test', 'partition... + ^ -- 2-) Creating partition of a distributed table CREATE TABLE partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01'); -- new partition is automatically distributed as well @@ -141,6 +195,26 @@ ORDER BY partitioning_test_2012 | 4 (2 rows) +-- try to insert a new data to hash partitioned table +-- no partition is defined for value 5 +INSERT INTO partitioning_hash_test VALUES (8, 5); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (8, 5); + ^ +INSERT INTO partitioning_hash_test VALUES (9, 12); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (9, 12); + ^ +CREATE TABLE partitioning_hash_test_2 (id int, subid int); +INSERT INTO partitioning_hash_test_2 VALUES (8, 5); +ALTER TABLE partitioning_hash_test ATTACH PARTITION partitioning_hash_test_2 FOR VALUES WITH (MODULUS 3, REMAINDER 2); +ERROR: syntax error at or near "WITH" +LINE 1: ...ACH PARTITION partitioning_hash_test_2 FOR VALUES WITH (MODU... + ^ +INSERT INTO partitioning_hash_test VALUES (9, 12); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (9, 12); + ^ -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; id | time @@ -153,6 +227,10 @@ SELECT * FROM partitioning_test ORDER BY 1; 6 | 07-07-2012 (6 rows) +SELECT * FROM partitioning_hash_test ORDER BY 1; +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: SELECT * FROM partitioning_hash_test ORDER BY 1; + ^ -- 4-) Attaching distributed table to distributed table CREATE TABLE partitioning_test_2013(id int, time date); SELECT create_distributed_table('partitioning_test_2013', 'id'); @@ -343,6 +421,68 @@ SELECT * FROM partitioning_test WHERE id = 9 OR id = 10 ORDER BY 1; ----+------ (0 rows) +-- create default partition +CREATE TABLE partitioning_test_default PARTITION OF partitioning_test DEFAULT; +ERROR: syntax error at or near "DEFAULT" +LINE 1: ...tioning_test_default PARTITION OF partitioning_test DEFAULT; + ^ +\d+ partitioning_test + Table "public.partitioning_test" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + id | integer | | | | plain | | + time | date | | | | plain | | +Partition key: RANGE ("time") +Partitions: partitioning_test_2009 FOR VALUES FROM ('01-01-2009') TO ('01-01-2010'), + partitioning_test_2010 FOR VALUES FROM ('01-01-2010') TO ('01-01-2011'), + partitioning_test_2011 FOR VALUES FROM ('01-01-2011') TO ('01-01-2012'), + partitioning_test_2012 FOR VALUES FROM ('01-01-2012') TO ('01-01-2013'), + partitioning_test_2013 FOR VALUES FROM ('01-01-2013') TO ('01-01-2014') + +INSERT INTO partitioning_test VALUES(21, '2014-02-02'); +ERROR: no partition of relation "partitioning_test_1660002" found for row +DETAIL: Partition key of the failing row contains ("time") = (2014-02-02). +CONTEXT: while executing command on localhost:57637 +INSERT INTO partitioning_test VALUES(22, '2015-04-02'); +ERROR: no partition of relation "partitioning_test_1660003" found for row +DETAIL: Partition key of the failing row contains ("time") = (2015-04-02). +CONTEXT: while executing command on localhost:57638 +-- see they are inserted into default partition +SELECT * FROM partitioning_test WHERE id > 20; + id | time +----+------ +(0 rows) + +SELECT * FROM partitioning_test_default; +ERROR: relation "partitioning_test_default" does not exist +LINE 1: SELECT * FROM partitioning_test_default; + ^ +-- create a new partition (will fail) +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +BEGIN; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_default; +ERROR: relation "partitioning_test_default" does not exist +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +ERROR: current transaction is aborted, commands ignored until end of transaction block +INSERT INTO partitioning_test SELECT * FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +ERROR: current transaction is aborted, commands ignored until end of transaction block +DELETE FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +ERROR: current transaction is aborted, commands ignored until end of transaction block +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_default DEFAULT; +ERROR: syntax error at or near "DEFAULT" +LINE 1: ...ing_test ATTACH PARTITION partitioning_test_default DEFAULT; + ^ +END; +-- see data is in the table, but some moved out from default partition +SELECT * FROM partitioning_test WHERE id > 20; + id | time +----+------ +(0 rows) + +SELECT * FROM partitioning_test_default; +ERROR: relation "partitioning_test_default" does not exist +LINE 1: SELECT * FROM partitioning_test_default; + ^ -- test master_modify_multiple_shards -- master_modify_multiple_shards on partitioned table SELECT master_modify_multiple_shards('UPDATE partitioning_test SET time = time + INTERVAL ''1 day'''); @@ -471,8 +611,26 @@ WHERE partitioning_test_2009 | partitioning_2009_primary | PRIMARY KEY (1 row) +-- however, you can add primary key if it contains both distribution and partition key +ALTER TABLE partitioning_hash_test ADD CONSTRAINT partitioning_hash_primary PRIMARY KEY (id, subid); +ERROR: relation "partitioning_hash_test" does not exist +-- see PRIMARY KEY is created +SELECT + table_name, + constraint_name, + constraint_type +FROM + information_schema.table_constraints +WHERE + table_name LIKE 'partitioning_hash_test%' AND + constraint_type = 'PRIMARY KEY' +ORDER BY 1; + table_name | constraint_name | constraint_type +------------+-----------------+----------------- +(0 rows) + -- test ADD FOREIGN CONSTRAINT --- add FOREIGN CONSTRAINT to partitioned table -- this will error out +-- add FOREIGN CONSTRAINT to partitioned table -- this will error out (it is a self reference) ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_foreign FOREIGN KEY (id) REFERENCES partitioning_test_2009 (id); ERROR: foreign key constraints are not supported on partitioned tables LINE 1: ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_fo... @@ -511,6 +669,46 @@ SELECT * FROM partitioning_test WHERE time >= '2009-01-01' AND time < '2010-01-0 ----+------+------------ (0 rows) +-- delete from default partition +DELETE FROM partitioning_test WHERE time >= '2015-01-01'; +SELECT * FROM partitioning_test_default; +ERROR: relation "partitioning_test_default" does not exist +LINE 1: SELECT * FROM partitioning_test_default; + ^ +-- create a reference table for foreign key test +CREATE TABLE partitioning_test_reference(id int PRIMARY KEY, subid int); +INSERT INTO partitioning_test_reference SELECT a, a FROM generate_series(1, 50) a; +SELECT create_reference_table('partitioning_test_reference'); +NOTICE: Copying data from local table... + create_reference_table +------------------------ + +(1 row) + +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_reference_fkey FOREIGN KEY (id) REFERENCES partitioning_test_reference(id) ON DELETE CASCADE; +ERROR: foreign key constraints are not supported on partitioned tables +LINE 1: ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_re... + ^ +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + id | time | new_column +----+------------+------------ + 11 | 01-02-2011 | + 11 | 01-02-2011 | + 12 | 01-02-2012 | + 12 | 01-02-2012 | +(4 rows) + +DELETE FROM partitioning_test_reference WHERE id = 11 or id = 12; +-- see data is deleted from referencing table +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + id | time | new_column +----+------------+------------ + 11 | 01-02-2011 | + 11 | 01-02-2011 | + 12 | 01-02-2012 | + 12 | 01-02-2012 | +(4 rows) + -- -- Transaction tests -- @@ -662,6 +860,7 @@ SELECT * FROM partitioning_test WHERE time >= '2010-01-01' AND time < '2011-01-0 -- test DROP partitioned table DROP TABLE partitioning_test; +DROP TABLE partitioning_test_reference; -- dropping the parent should CASCADE to the children as well SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'partitioning_test%' ORDER BY 1; table_name @@ -912,7 +1111,7 @@ INSERT INTO multi_column_partitioning VALUES(1, 1); INSERT INTO multi_column_partitioning_0_0_10_0 VALUES(5, -5); -- test INSERT to multi-column partitioned table where no suitable partition exists INSERT INTO multi_column_partitioning VALUES(10, 1); -ERROR: no partition of relation "multi_column_partitioning_1660068" found for row +ERROR: no partition of relation "multi_column_partitioning_1660073" found for row DETAIL: Partition key of the failing row contains (c1, c2) = (10, 1). CONTEXT: while executing command on localhost:57637 -- test with MINVALUE/MAXVALUE @@ -922,7 +1121,7 @@ INSERT INTO multi_column_partitioning VALUES(11, -11); INSERT INTO multi_column_partitioning_10_max_20_min VALUES(19, -19); -- test INSERT to multi-column partitioned table where no suitable partition exists INSERT INTO multi_column_partitioning VALUES(20, -20); -ERROR: no partition of relation "multi_column_partitioning_1660068" found for row +ERROR: no partition of relation "multi_column_partitioning_1660073" found for row DETAIL: Partition key of the failing row contains (c1, c2) = (20, -20). CONTEXT: while executing command on localhost:57637 -- see data is loaded to multi-column partitioned table @@ -1236,6 +1435,79 @@ ORDER BY (12 rows) COMMIT; +-- test partition-wise join +CREATE TABLE partitioning_hash_join_test(id int, subid int) PARTITION BY HASH(subid); +ERROR: unrecognized partitioning strategy "hash" +CREATE TABLE partitioning_hash_join_test_0 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +ERROR: syntax error at or near "WITH" +LINE 1: ...RTITION OF partitioning_hash_join_test FOR VALUES WITH (MODU... + ^ +CREATE TABLE partitioning_hash_join_test_1 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +ERROR: syntax error at or near "WITH" +LINE 1: ...RTITION OF partitioning_hash_join_test FOR VALUES WITH (MODU... + ^ +CREATE TABLE partitioning_hash_join_test_2 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 2); +ERROR: syntax error at or near "WITH" +LINE 1: ...RTITION OF partitioning_hash_join_test FOR VALUES WITH (MODU... + ^ +SELECT create_distributed_table('partitioning_hash_join_test', 'id'); +ERROR: relation "partitioning_hash_join_test" does not exist +LINE 1: SELECT create_distributed_table('partitioning_hash_join_test... + ^ +-- see the query plan without partition-wise join +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); +ERROR: relation "partitioning_hash_test" does not exist +LINE 2: SELECT * FROM partitioning_hash_test JOIN partitioning_hash_... + ^ +-- set partition-wise join on +SELECT success FROM run_command_on_workers('alter system set enable_partitionwise_join to on'); + success +--------- + f + f +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------- + t + t +(2 rows) + +SET enable_partitionwise_join TO on; +ERROR: unrecognized configuration parameter "enable_partitionwise_join" +-- see the new query plan +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); +ERROR: relation "partitioning_hash_test" does not exist +LINE 2: SELECT * FROM partitioning_hash_test JOIN partitioning_hash_... + ^ +-- note that partition-wise joins only work when partition key is in the join +-- following join does not have that, therefore join will not be pushed down to +-- partitions +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id); +ERROR: relation "partitioning_hash_test" does not exist +LINE 2: SELECT * FROM partitioning_hash_test JOIN partitioning_hash_... + ^ +-- reset partition-wise join +SELECT success FROM run_command_on_workers('reset enable_partitionwise_join'); + success +--------- + f + f +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------- + t + t +(2 rows) + +RESET enable_partitionwise_join; +ERROR: unrecognized configuration parameter "enable_partitionwise_join" DROP TABLE IF EXISTS partitioning_test_2009, diff --git a/src/test/regress/expected/multi_partitioning_1.out b/src/test/regress/expected/multi_partitioning_1.out index 48909e0f8..7a5111a4a 100644 --- a/src/test/regress/expected/multi_partitioning_1.out +++ b/src/test/regress/expected/multi_partitioning_1.out @@ -21,7 +21,10 @@ CREATE TABLE partitioning_test(id int, time date) PARTITION BY RANGE (time); ERROR: syntax error at or near "PARTITION" LINE 1: CREATE TABLE partitioning_test(id int, time date) PARTITION ... ^ - +CREATE TABLE partitioning_hash_test(id int, subid int) PARTITION BY HASH(subid); +ERROR: syntax error at or near "PARTITION" +LINE 1: ...E TABLE partitioning_hash_test(id int, subid int) PARTITION ... + ^ -- create its partitions CREATE TABLE partitioning_test_2009 PARTITION OF partitioning_test FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); ERROR: syntax error at or near "PARTITION" @@ -31,6 +34,14 @@ CREATE TABLE partitioning_test_2010 PARTITION OF partitioning_test FOR VALUES FR ERROR: syntax error at or near "PARTITION" LINE 1: CREATE TABLE partitioning_test_2010 PARTITION OF partitionin... ^ +CREATE TABLE partitioning_hash_test_0 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_hash_test_0 PARTITION OF partition... + ^ +CREATE TABLE partitioning_hash_test_1 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_hash_test_1 PARTITION OF partition... + ^ -- load some data and distribute tables INSERT INTO partitioning_test VALUES (1, '2009-06-06'); ERROR: relation "partitioning_test" does not exist @@ -48,16 +59,40 @@ INSERT INTO partitioning_test_2010 VALUES (4, '2010-03-03'); ERROR: relation "partitioning_test_2010" does not exist LINE 1: INSERT INTO partitioning_test_2010 VALUES (4, '2010-03-03'); ^ +INSERT INTO partitioning_hash_test VALUES (1, 2); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (1, 2); + ^ +INSERT INTO partitioning_hash_test VALUES (2, 13); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (2, 13); + ^ +INSERT INTO partitioning_hash_test VALUES (3, 7); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (3, 7); + ^ +INSERT INTO partitioning_hash_test VALUES (4, 4); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (4, 4); + ^ -- distribute partitioned table SELECT create_distributed_table('partitioning_test', 'id'); ERROR: relation "partitioning_test" does not exist LINE 1: SELECT create_distributed_table('partitioning_test', 'id'); ^ +SELECT create_distributed_table('partitioning_hash_test', 'id'); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: SELECT create_distributed_table('partitioning_hash_test', 'i... + ^ -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; ERROR: relation "partitioning_test" does not exist LINE 1: SELECT * FROM partitioning_test ORDER BY 1; ^ +SELECT * FROM partitioning_hash_test ORDER BY 1; +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: SELECT * FROM partitioning_hash_test ORDER BY 1; + ^ -- see partitioned table and its partitions are distributed SELECT logicalrelid @@ -80,6 +115,27 @@ ORDER BY ERROR: relation "partitioning_test" does not exist LINE 4: WHERE logicalrelid IN ('partitioning_test', 'partitioning_t... ^ +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +ORDER BY 1; +ERROR: relation "partitioning_hash_test" does not exist +LINE 6: logicalrelid IN ('partitioning_hash_test', 'partitioning_ha... + ^ +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +GROUP BY + logicalrelid +ORDER BY + 1,2; +ERROR: relation "partitioning_hash_test" does not exist +LINE 4: WHERE logicalrelid IN ('partitioning_hash_test', 'partition... + ^ -- 2-) Creating partition of a distributed table CREATE TABLE partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01'); ERROR: syntax error at or near "PARTITION" @@ -138,11 +194,35 @@ ORDER BY ERROR: relation "partitioning_test" does not exist LINE 4: WHERE logicalrelid IN ('partitioning_test', 'partitioning_t... ^ +-- try to insert a new data to hash partitioned table +-- no partition is defined for value 5 +INSERT INTO partitioning_hash_test VALUES (8, 5); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (8, 5); + ^ +INSERT INTO partitioning_hash_test VALUES (9, 12); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (9, 12); + ^ +CREATE TABLE partitioning_hash_test_2 (id int, subid int); +INSERT INTO partitioning_hash_test_2 VALUES (8, 5); +ALTER TABLE partitioning_hash_test ATTACH PARTITION partitioning_hash_test_2 FOR VALUES WITH (MODULUS 3, REMAINDER 2); +ERROR: syntax error at or near "ATTACH" +LINE 1: ALTER TABLE partitioning_hash_test ATTACH PARTITION partitio... + ^ +INSERT INTO partitioning_hash_test VALUES (9, 12); +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: INSERT INTO partitioning_hash_test VALUES (9, 12); + ^ -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; ERROR: relation "partitioning_test" does not exist LINE 1: SELECT * FROM partitioning_test ORDER BY 1; ^ +SELECT * FROM partitioning_hash_test ORDER BY 1; +ERROR: relation "partitioning_hash_test" does not exist +LINE 1: SELECT * FROM partitioning_hash_test ORDER BY 1; + ^ -- 4-) Attaching distributed table to distributed table CREATE TABLE partitioning_test_2013(id int, time date); SELECT create_distributed_table('partitioning_test_2013', 'id'); @@ -366,6 +446,61 @@ SELECT * FROM partitioning_test WHERE id = 9 OR id = 10 ORDER BY 1; ERROR: relation "partitioning_test" does not exist LINE 1: SELECT * FROM partitioning_test WHERE id = 9 OR id = 10 ORDE... ^ +-- create default partition +CREATE TABLE partitioning_test_default PARTITION OF partitioning_test DEFAULT; +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_test_default PARTITION OF partitio... + ^ +\d+ partitioning_test +INSERT INTO partitioning_test VALUES(21, '2014-02-02'); +ERROR: relation "partitioning_test" does not exist +LINE 1: INSERT INTO partitioning_test VALUES(21, '2014-02-02'); + ^ +INSERT INTO partitioning_test VALUES(22, '2015-04-02'); +ERROR: relation "partitioning_test" does not exist +LINE 1: INSERT INTO partitioning_test VALUES(22, '2015-04-02'); + ^ +-- see they are inserted into default partition +SELECT * FROM partitioning_test WHERE id > 20; +ERROR: relation "partitioning_test" does not exist +LINE 1: SELECT * FROM partitioning_test WHERE id > 20; + ^ +SELECT * FROM partitioning_test_default; +ERROR: relation "partitioning_test_default" does not exist +LINE 1: SELECT * FROM partitioning_test_default; + ^ +-- create a new partition (will fail) +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_test_2014 PARTITION OF partitionin... + ^ +BEGIN; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_default; +ERROR: syntax error at or near "DETACH" +LINE 1: ALTER TABLE partitioning_test DETACH PARTITION partitioning_... + ^ +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_test_2014 PARTITION OF partitionin... + ^ +INSERT INTO partitioning_test SELECT * FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +ERROR: current transaction is aborted, commands ignored until end of transaction block +DELETE FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +ERROR: current transaction is aborted, commands ignored until end of transaction block +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_default DEFAULT; +ERROR: syntax error at or near "ATTACH" +LINE 1: ALTER TABLE partitioning_test ATTACH PARTITION partitioning_... + ^ +END; +-- see data is in the table, but some moved out from default partition +SELECT * FROM partitioning_test WHERE id > 20; +ERROR: relation "partitioning_test" does not exist +LINE 1: SELECT * FROM partitioning_test WHERE id > 20; + ^ +SELECT * FROM partitioning_test_default; +ERROR: relation "partitioning_test_default" does not exist +LINE 1: SELECT * FROM partitioning_test_default; + ^ -- test master_modify_multiple_shards -- master_modify_multiple_shards on partitioned table SELECT master_modify_multiple_shards('UPDATE partitioning_test SET time = time + INTERVAL ''1 day'''); @@ -443,8 +578,26 @@ WHERE ------------+-----------------+----------------- (0 rows) +-- however, you can add primary key if it contains both distribution and partition key +ALTER TABLE partitioning_hash_test ADD CONSTRAINT partitioning_hash_primary PRIMARY KEY (id, subid); +ERROR: relation "partitioning_hash_test" does not exist +-- see PRIMARY KEY is created +SELECT + table_name, + constraint_name, + constraint_type +FROM + information_schema.table_constraints +WHERE + table_name LIKE 'partitioning_hash_test%' AND + constraint_type = 'PRIMARY KEY' +ORDER BY 1; + table_name | constraint_name | constraint_type +------------+-----------------+----------------- +(0 rows) + -- test ADD FOREIGN CONSTRAINT --- add FOREIGN CONSTRAINT to partitioned table -- this will error out +-- add FOREIGN CONSTRAINT to partitioned table -- this will error out (it is a self reference) ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_foreign FOREIGN KEY (id) REFERENCES partitioning_test_2009 (id); ERROR: relation "partitioning_test" does not exist -- add FOREIGN CONSTRAINT to partition @@ -498,6 +651,37 @@ SELECT * FROM partitioning_test WHERE time >= '2009-01-01' AND time < '2010-01-0 ERROR: relation "partitioning_test" does not exist LINE 1: SELECT * FROM partitioning_test WHERE time >= '2009-01-01' A... ^ +-- delete from default partition +DELETE FROM partitioning_test WHERE time >= '2015-01-01'; +ERROR: relation "partitioning_test" does not exist +LINE 1: DELETE FROM partitioning_test WHERE time >= '2015-01-01'; + ^ +SELECT * FROM partitioning_test_default; +ERROR: relation "partitioning_test_default" does not exist +LINE 1: SELECT * FROM partitioning_test_default; + ^ +-- create a reference table for foreign key test +CREATE TABLE partitioning_test_reference(id int PRIMARY KEY, subid int); +INSERT INTO partitioning_test_reference SELECT a, a FROM generate_series(1, 50) a; +SELECT create_reference_table('partitioning_test_reference'); +NOTICE: Copying data from local table... + create_reference_table +------------------------ + +(1 row) + +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_reference_fkey FOREIGN KEY (id) REFERENCES partitioning_test_reference(id) ON DELETE CASCADE; +ERROR: relation "partitioning_test" does not exist +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; +ERROR: relation "partitioning_test" does not exist +LINE 1: SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + ^ +DELETE FROM partitioning_test_reference WHERE id = 11 or id = 12; +-- see data is deleted from referencing table +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; +ERROR: relation "partitioning_test" does not exist +LINE 1: SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + ^ -- -- Transaction tests -- @@ -638,6 +822,7 @@ LINE 1: SELECT * FROM partitioning_test WHERE time >= '2010-01-01' A... -- test DROP partitioned table DROP TABLE partitioning_test; ERROR: table "partitioning_test" does not exist +DROP TABLE partitioning_test_reference; -- dropping the parent should CASCADE to the children as well SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'partitioning_test%' ORDER BY 1; table_name @@ -1121,6 +1306,81 @@ ORDER BY 1, 2, 3; ERROR: current transaction is aborted, commands ignored until end of transaction block COMMIT; +-- test partition-wise join +CREATE TABLE partitioning_hash_join_test(id int, subid int) PARTITION BY HASH(subid); +ERROR: syntax error at or near "PARTITION" +LINE 1: ...LE partitioning_hash_join_test(id int, subid int) PARTITION ... + ^ +CREATE TABLE partitioning_hash_join_test_0 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_hash_join_test_0 PARTITION OF part... + ^ +CREATE TABLE partitioning_hash_join_test_1 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_hash_join_test_1 PARTITION OF part... + ^ +CREATE TABLE partitioning_hash_join_test_2 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 2); +ERROR: syntax error at or near "PARTITION" +LINE 1: CREATE TABLE partitioning_hash_join_test_2 PARTITION OF part... + ^ +SELECT create_distributed_table('partitioning_hash_join_test', 'id'); +ERROR: relation "partitioning_hash_join_test" does not exist +LINE 1: SELECT create_distributed_table('partitioning_hash_join_test... + ^ +-- see the query plan without partition-wise join +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); +ERROR: relation "partitioning_hash_test" does not exist +LINE 2: SELECT * FROM partitioning_hash_test JOIN partitioning_hash_... + ^ +-- set partition-wise join on +SELECT success FROM run_command_on_workers('alter system set enable_partitionwise_join to on'); + success +--------- + f + f +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------- + t + t +(2 rows) + +SET enable_partitionwise_join TO on; +ERROR: unrecognized configuration parameter "enable_partitionwise_join" +-- see the new query plan +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); +ERROR: relation "partitioning_hash_test" does not exist +LINE 2: SELECT * FROM partitioning_hash_test JOIN partitioning_hash_... + ^ +-- note that partition-wise joins only work when partition key is in the join +-- following join does not have that, therefore join will not be pushed down to +-- partitions +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id); +ERROR: relation "partitioning_hash_test" does not exist +LINE 2: SELECT * FROM partitioning_hash_test JOIN partitioning_hash_... + ^ +-- reset partition-wise join +SELECT success FROM run_command_on_workers('reset enable_partitionwise_join'); + success +--------- + f + f +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------- + t + t +(2 rows) + +RESET enable_partitionwise_join; +ERROR: unrecognized configuration parameter "enable_partitionwise_join" DROP TABLE IF EXISTS partitioning_test_2009, diff --git a/src/test/regress/sql/multi_partitioning.sql b/src/test/regress/sql/multi_partitioning.sql index 48d35ffc4..f96952558 100644 --- a/src/test/regress/sql/multi_partitioning.sql +++ b/src/test/regress/sql/multi_partitioning.sql @@ -17,11 +17,16 @@ SELECT substring(:'server_version', '\d+')::int AS server_version; -- 1-) Distributing partitioned table -- create partitioned table CREATE TABLE partitioning_test(id int, time date) PARTITION BY RANGE (time); - + +CREATE TABLE partitioning_hash_test(id int, subid int) PARTITION BY HASH(subid); + -- create its partitions CREATE TABLE partitioning_test_2009 PARTITION OF partitioning_test FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); CREATE TABLE partitioning_test_2010 PARTITION OF partitioning_test FOR VALUES FROM ('2010-01-01') TO ('2011-01-01'); +CREATE TABLE partitioning_hash_test_0 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +CREATE TABLE partitioning_hash_test_1 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); + -- load some data and distribute tables INSERT INTO partitioning_test VALUES (1, '2009-06-06'); INSERT INTO partitioning_test VALUES (2, '2010-07-07'); @@ -29,12 +34,21 @@ INSERT INTO partitioning_test VALUES (2, '2010-07-07'); INSERT INTO partitioning_test_2009 VALUES (3, '2009-09-09'); INSERT INTO partitioning_test_2010 VALUES (4, '2010-03-03'); +INSERT INTO partitioning_hash_test VALUES (1, 2); +INSERT INTO partitioning_hash_test VALUES (2, 13); +INSERT INTO partitioning_hash_test VALUES (3, 7); +INSERT INTO partitioning_hash_test VALUES (4, 4); + -- distribute partitioned table SELECT create_distributed_table('partitioning_test', 'id'); +SELECT create_distributed_table('partitioning_hash_test', 'id'); + -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; +SELECT * FROM partitioning_hash_test ORDER BY 1; + -- see partitioned table and its partitions are distributed SELECT logicalrelid @@ -53,6 +67,23 @@ GROUP BY ORDER BY 1,2; +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +ORDER BY 1; + +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +GROUP BY + logicalrelid +ORDER BY + 1,2; + -- 2-) Creating partition of a distributed table CREATE TABLE partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01'); @@ -101,9 +132,23 @@ GROUP BY ORDER BY 1,2; +-- try to insert a new data to hash partitioned table +-- no partition is defined for value 5 +INSERT INTO partitioning_hash_test VALUES (8, 5); +INSERT INTO partitioning_hash_test VALUES (9, 12); + +CREATE TABLE partitioning_hash_test_2 (id int, subid int); +INSERT INTO partitioning_hash_test_2 VALUES (8, 5); + +ALTER TABLE partitioning_hash_test ATTACH PARTITION partitioning_hash_test_2 FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +INSERT INTO partitioning_hash_test VALUES (9, 12); + -- see the data is loaded to shards SELECT * FROM partitioning_test ORDER BY 1; +SELECT * FROM partitioning_hash_test ORDER BY 1; + -- 4-) Attaching distributed table to distributed table CREATE TABLE partitioning_test_2013(id int, time date); SELECT create_distributed_table('partitioning_test_2013', 'id'); @@ -239,6 +284,33 @@ DELETE FROM partitioning_test_2010 WHERE id = 10; -- see the data is deleted SELECT * FROM partitioning_test WHERE id = 9 OR id = 10 ORDER BY 1; +-- create default partition +CREATE TABLE partitioning_test_default PARTITION OF partitioning_test DEFAULT; + +\d+ partitioning_test + +INSERT INTO partitioning_test VALUES(21, '2014-02-02'); +INSERT INTO partitioning_test VALUES(22, '2015-04-02'); + +-- see they are inserted into default partition +SELECT * FROM partitioning_test WHERE id > 20; +SELECT * FROM partitioning_test_default; + +-- create a new partition (will fail) +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); + +BEGIN; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_default; +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +INSERT INTO partitioning_test SELECT * FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +DELETE FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_default DEFAULT; +END; + +-- see data is in the table, but some moved out from default partition +SELECT * FROM partitioning_test WHERE id > 20; +SELECT * FROM partitioning_test_default; + -- test master_modify_multiple_shards -- master_modify_multiple_shards on partitioned table SELECT master_modify_multiple_shards('UPDATE partitioning_test SET time = time + INTERVAL ''1 day'''); @@ -302,8 +374,23 @@ WHERE table_name = 'partitioning_test_2009' AND constraint_name = 'partitioning_2009_primary'; +-- however, you can add primary key if it contains both distribution and partition key +ALTER TABLE partitioning_hash_test ADD CONSTRAINT partitioning_hash_primary PRIMARY KEY (id, subid); + +-- see PRIMARY KEY is created +SELECT + table_name, + constraint_name, + constraint_type +FROM + information_schema.table_constraints +WHERE + table_name LIKE 'partitioning_hash_test%' AND + constraint_type = 'PRIMARY KEY' +ORDER BY 1; + -- test ADD FOREIGN CONSTRAINT --- add FOREIGN CONSTRAINT to partitioned table -- this will error out +-- add FOREIGN CONSTRAINT to partitioned table -- this will error out (it is a self reference) ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_foreign FOREIGN KEY (id) REFERENCES partitioning_test_2009 (id); -- add FOREIGN CONSTRAINT to partition @@ -329,6 +416,24 @@ ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009; -- see DETACHed partitions content is not accessible from partitioning_test; SELECT * FROM partitioning_test WHERE time >= '2009-01-01' AND time < '2010-01-01' ORDER BY 1; +-- delete from default partition +DELETE FROM partitioning_test WHERE time >= '2015-01-01'; +SELECT * FROM partitioning_test_default; + + +-- create a reference table for foreign key test +CREATE TABLE partitioning_test_reference(id int PRIMARY KEY, subid int); +INSERT INTO partitioning_test_reference SELECT a, a FROM generate_series(1, 50) a; + +SELECT create_reference_table('partitioning_test_reference'); + +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_reference_fkey FOREIGN KEY (id) REFERENCES partitioning_test_reference(id) ON DELETE CASCADE; + +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; +DELETE FROM partitioning_test_reference WHERE id = 11 or id = 12; +-- see data is deleted from referencing table +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + -- -- Transaction tests -- @@ -438,6 +543,7 @@ SELECT * FROM partitioning_test WHERE time >= '2010-01-01' AND time < '2011-01-0 -- test DROP partitioned table DROP TABLE partitioning_test; +DROP TABLE partitioning_test_reference; -- dropping the parent should CASCADE to the children as well SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'partitioning_test%' ORDER BY 1; @@ -809,6 +915,41 @@ ORDER BY 1, 2, 3; COMMIT; +-- test partition-wise join + +CREATE TABLE partitioning_hash_join_test(id int, subid int) PARTITION BY HASH(subid); +CREATE TABLE partitioning_hash_join_test_0 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +CREATE TABLE partitioning_hash_join_test_1 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +CREATE TABLE partitioning_hash_join_test_2 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +SELECT create_distributed_table('partitioning_hash_join_test', 'id'); + +-- see the query plan without partition-wise join +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); + +-- set partition-wise join on +SELECT success FROM run_command_on_workers('alter system set enable_partitionwise_join to on'); +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + +SET enable_partitionwise_join TO on; + +-- see the new query plan +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); + +-- note that partition-wise joins only work when partition key is in the join +-- following join does not have that, therefore join will not be pushed down to +-- partitions +EXPLAIN +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id); + +-- reset partition-wise join +SELECT success FROM run_command_on_workers('reset enable_partitionwise_join'); +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + +RESET enable_partitionwise_join; + DROP TABLE IF EXISTS partitioning_test_2009,