mirror of
https://github.com/HypoPG/hypopg
synced 2026-05-24 09:38:21 +00:00
Start adding some regression test for hypothetical partitioning.
This will fail on pg10- servers, but since hypothetical partitioning has some feature not covered by regression tests, a full coverage of hypopg for all pg versions will be done in other commit(s).
This commit is contained in:
parent
4a9adb9ca3
commit
37d6cb56ce
7 changed files with 938 additions and 30 deletions
5
Makefile
5
Makefile
|
|
@ -1,7 +1,10 @@
|
|||
EXTENSION = hypopg
|
||||
EXTVERSION = $(shell grep default_version $(EXTENSION).control | sed -e "s/default_version[[:space:]]*=[[:space:]]*'\([^']*\)'/\1/")
|
||||
TESTS = $(wildcard test/sql/*.sql)
|
||||
REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS))
|
||||
REGRESS = hypo_setup \
|
||||
hypo_index \
|
||||
hypo_table
|
||||
|
||||
REGRESS_OPTS = --inputdir=test
|
||||
|
||||
PG_CONFIG ?= pg_config
|
||||
|
|
|
|||
|
|
@ -1,17 +1,4 @@
|
|||
-- SETUP
|
||||
CREATE OR REPLACE FUNCTION do_explain(stmt text) RETURNS table(a text) AS
|
||||
$_$
|
||||
DECLARE
|
||||
ret text;
|
||||
BEGIN
|
||||
FOR ret IN EXECUTE format('EXPLAIN (FORMAT text) %s', stmt) LOOP
|
||||
a := ret;
|
||||
RETURN next ;
|
||||
END LOOP;
|
||||
END;
|
||||
$_$
|
||||
LANGUAGE plpgsql;
|
||||
CREATE EXTENSION hypopg;
|
||||
-- Hypothetical index tests
|
||||
CREATE TABLE hypo (id integer, val text);
|
||||
INSERT INTO hypo SELECT i, 'line ' || i
|
||||
FROM generate_series(1,100000) f(i);
|
||||
16
expected/hypo_setup.out
Normal file
16
expected/hypo_setup.out
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
-- General setup
|
||||
-- Create extension
|
||||
CREATE EXTENSION hypopg;
|
||||
-- Create do_explain function
|
||||
CREATE OR REPLACE FUNCTION do_explain(stmt text) RETURNS table(a text) AS
|
||||
$_$
|
||||
DECLARE
|
||||
ret text;
|
||||
BEGIN
|
||||
FOR ret IN EXECUTE format('EXPLAIN (FORMAT text) %s', stmt) LOOP
|
||||
a := ret;
|
||||
RETURN next ;
|
||||
END LOOP;
|
||||
END;
|
||||
$_$
|
||||
LANGUAGE plpgsql;
|
||||
726
expected/hypo_table.out
Normal file
726
expected/hypo_table.out
Normal file
|
|
@ -0,0 +1,726 @@
|
|||
-- Creating real and hypothetical tables"
|
||||
-- ====================================="
|
||||
-- Real tables
|
||||
-- -----------
|
||||
-- 1. Range partition
|
||||
DROP TABLE IF EXISTS part_range;
|
||||
NOTICE: table "part_range" does not exist, skipping
|
||||
CREATE TABLE part_range (id integer, val text) PARTITION BY RANGE (id);
|
||||
CREATE TABLE part_range_1_10000 PARTITION OF part_range FOR VALUES FROM (1) TO (10000);
|
||||
CREATE TABLE part_range_10000_20000 PARTITION OF part_range FOR VALUES FROM (10000) TO (20000);
|
||||
CREATE TABLE part_range_20000_30000 PARTITION OF part_range FOR VALUES FROM (20000) TO (30000);
|
||||
INSERT INTO part_range SELECT i, 'line ' || i FROM generate_series(1, 29999) i;
|
||||
-- 2. List partitioning
|
||||
DROP TABLE IF EXISTS part_list;
|
||||
NOTICE: table "part_list" does not exist, skipping
|
||||
CREATE TABLE part_list (id integer, id_key integer, val text) PARTITION BY LIST (id_key);
|
||||
CREATE TABLE part_list_1_2_3 PARTITION OF part_list FOR VALUES IN (1, 2, 3);
|
||||
CREATE TABLE part_list_4_5_6_8_10 PARTITION OF part_list FOR VALUES IN (4, 5, 6, 8, 10);
|
||||
CREATE TABLE part_list_7_9 PARTITION OF part_list FOR VALUES IN (7, 9);
|
||||
INSERT INTO part_list SELECT i, (i % 9) + 1, 'line ' || i FROM generate_series(1, 50000) i;
|
||||
-- 3. Hash partitioning
|
||||
DROP TABLE IF EXISTS part_hash;
|
||||
NOTICE: table "part_hash" does not exist, skipping
|
||||
CREATE TABLE part_hash (id integer, val text) PARTITION BY HASH (id);
|
||||
CREATE TABLE part_hash_0 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 0);
|
||||
CREATE TABLE part_hash_1 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 1);
|
||||
CREATE TABLE part_hash_2 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 2);
|
||||
CREATE TABLE part_hash_3 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 3);
|
||||
CREATE TABLE part_hash_4 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 4);
|
||||
CREATE TABLE part_hash_5 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 5);
|
||||
CREATE TABLE part_hash_6 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 6);
|
||||
CREATE TABLE part_hash_7 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 7);
|
||||
CREATE TABLE part_hash_8 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 8);
|
||||
CREATE TABLE part_hash_9 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 9);
|
||||
INSERT INTO part_hash SELECT i, 'line ' || i FROM generate_series(1, 90000) i;
|
||||
-- 4. Multi level range
|
||||
DROP TABLE IF EXISTS part_multi;
|
||||
NOTICE: table "part_multi" does not exist, skipping
|
||||
CREATE TABLE part_multi(dpt smallint, dt date, val text) PARTITION BY LIST (dpt);
|
||||
CREATE TABLE part_multi_1 PARTITION OF part_multi FOR VALUES IN (1) PARTITION BY RANGE(dt);
|
||||
CREATE TABLE part_multi_1_q1 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$) PARTITION BY RANGE (dt);
|
||||
CREATE TABLE part_multi_1_q1_a PARTITION OF part_multi_1_q1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-02-01$$);
|
||||
CREATE TABLE part_multi_1_q1_b PARTITION OF part_multi_1_q1 FOR VALUES FROM ($$2015-02-01$$) TO ($$2015-04-01$$);
|
||||
CREATE TABLE part_multi_1_q2 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
|
||||
CREATE TABLE part_multi_1_q3 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
|
||||
CREATE TABLE part_multi_1_q4 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
|
||||
CREATE TABLE part_multi_2 PARTITION OF part_multi FOR VALUES IN (2) PARTITION BY RANGE(dt);
|
||||
CREATE TABLE part_multi_2_q1 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$);
|
||||
CREATE TABLE part_multi_2_q2 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
|
||||
CREATE TABLE part_multi_2_q3 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
|
||||
CREATE TABLE part_multi_2_q4 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
|
||||
CREATE TABLE part_multi_3 PARTITION OF part_multi FOR VALUES IN (3) PARTITION BY RANGE(dt);
|
||||
CREATE TABLE part_multi_3_q1 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$);
|
||||
CREATE TABLE part_multi_3_q2 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
|
||||
CREATE TABLE part_multi_3_q3 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
|
||||
CREATE TABLE part_multi_3_q4 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
|
||||
INSERT INTO part_multi select (i%3)+1, '2015-01-01'::date + interval '1 day' * (i%365), 'val ' || i FROM generate_series(1,10000) i;
|
||||
-- Hypothetical tables
|
||||
-- -------------------
|
||||
-- 0. Dropping any hypothetical object
|
||||
SELECT * FROM hypopg_reset_index();
|
||||
hypopg_reset_index
|
||||
--------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM hypopg_reset_table();
|
||||
hypopg_reset_table
|
||||
--------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- 1. Range partition
|
||||
DROP TABLE IF EXISTS hypo_part_range;
|
||||
NOTICE: table "hypo_part_range" does not exist, skipping
|
||||
CREATE TABLE hypo_part_range (id integer, val text);
|
||||
INSERT INTO hypo_part_range SELECT i, 'line ' || i FROM generate_series(1, 29999) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_range', 'PARTITION BY RANGE (id)');
|
||||
hypopg_partition_table
|
||||
------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_range_1_10000', 'PARTITION OF hypo_part_range FOR VALUES FROM (1) TO (10000)');
|
||||
tablename
|
||||
-------------------------
|
||||
hypo_part_range_1_10000
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_range_10000_20000', 'PARTITION OF hypo_part_range FOR VALUES FROM (10000) TO (20000)');
|
||||
tablename
|
||||
-----------------------------
|
||||
hypo_part_range_10000_20000
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_range_20000_30000', 'PARTITION OF hypo_part_range FOR VALUES FROM (20000) TO (30000)');
|
||||
tablename
|
||||
-----------------------------
|
||||
hypo_part_range_20000_30000
|
||||
(1 row)
|
||||
|
||||
-- 2. List partitioning
|
||||
DROP TABLE IF EXISTS hypo_part_list;
|
||||
NOTICE: table "hypo_part_list" does not exist, skipping
|
||||
CREATE TABLE hypo_part_list (id integer, id_key integer, val text);
|
||||
INSERT INTO hypo_part_list SELECT i, (i % 9) + 1, 'line ' || i FROM generate_series(1, 50000) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_list', 'PARTITION BY LIST (id_key)');
|
||||
hypopg_partition_table
|
||||
------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_list_1_2_3', 'PARTITION OF hypo_part_list FOR VALUES IN (1, 2, 3)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_list_1_2_3
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_list_4_5_6_8_10', 'PARTITION OF hypo_part_list FOR VALUES IN (4, 5, 6, 8, 10)');
|
||||
tablename
|
||||
---------------------------
|
||||
hypo_part_list_4_5_6_8_10
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_list_7_9', 'PARTITION OF hypo_part_list FOR VALUES IN (7, 9)');
|
||||
tablename
|
||||
--------------------
|
||||
hypo_part_list_7_9
|
||||
(1 row)
|
||||
|
||||
-- 3. Hash partitioning
|
||||
DROP TABLE IF EXISTS hypo_part_hash;
|
||||
NOTICE: table "hypo_part_hash" does not exist, skipping
|
||||
CREATE TABLE hypo_part_hash (id integer, val text);
|
||||
INSERT INTO hypo_part_hash SELECT i, 'line ' || i FROM generate_series(1, 90000) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_hash', 'PARTITION BY HASH (id)');
|
||||
hypopg_partition_table
|
||||
------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_0', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 0)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_0
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_1', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 1)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_1
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_2', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 2)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_2
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_3', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 3)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_3
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_4', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 4)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_4
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_5', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 5)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_5
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_6', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 6)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_6
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_7', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 7)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_7
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_8', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 8)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_8
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_9', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 9)');
|
||||
tablename
|
||||
------------------
|
||||
hypo_part_hash_9
|
||||
(1 row)
|
||||
|
||||
-- 4. Multi level range
|
||||
DROP TABLE IF EXISTS hypo_part_multi;
|
||||
NOTICE: table "hypo_part_multi" does not exist, skipping
|
||||
CREATE TABLE hypo_part_multi(dpt smallint, dt date, val text);
|
||||
INSERT INTO hypo_part_multi select (i%3)+1, '2015-01-01'::date + interval '1 day' * (i%365), 'val ' || i FROM generate_series(1,10000) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_multi', 'PARTITION BY LIST (dpt)');
|
||||
hypopg_partition_table
|
||||
------------------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1', 'PARTITION OF hypo_part_multi FOR VALUES IN (1)', 'PARTITION BY RANGE(dt)');
|
||||
tablename
|
||||
-------------------
|
||||
hypo_part_multi_1
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)','PARTITION BY RANGE (dt)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_1_q1
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1_a', 'PARTITION OF hypo_part_multi_1_q1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-02-01$$)');
|
||||
tablename
|
||||
------------------------
|
||||
hypo_part_multi_1_q1_a
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1_b', 'PARTITION OF hypo_part_multi_1_q1 FOR VALUES FROM ($$2015-02-01$$) TO ($$2015-04-01$$)');
|
||||
tablename
|
||||
------------------------
|
||||
hypo_part_multi_1_q1_b
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q2', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_1_q2
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q3', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_1_q3
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q4', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_1_q4
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2', 'PARTITION OF hypo_part_multi FOR VALUES IN (2)', 'PARTITION BY RANGE(dt)');
|
||||
tablename
|
||||
-------------------
|
||||
hypo_part_multi_2
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q1', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_2_q1
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q2', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_2_q2
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q3', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_2_q3
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q4', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_2_q4
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3', 'PARTITION OF hypo_part_multi FOR VALUES IN (3)', 'PARTITION BY RANGE(dt)');
|
||||
tablename
|
||||
-------------------
|
||||
hypo_part_multi_3
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q1', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_3_q1
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q2', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_3_q2
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q3', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_3_q3
|
||||
(1 row)
|
||||
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q4', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
|
||||
tablename
|
||||
----------------------
|
||||
hypo_part_multi_3_q4
|
||||
(1 row)
|
||||
|
||||
-- Maintenance
|
||||
-- -----------
|
||||
VACUUM ANALYZE;
|
||||
-- Test deparsing
|
||||
-- ==============
|
||||
SELECT relid = rootid AS is_root, tablename, parentid IS NULL parentid_is_null,
|
||||
parentid IS NOT NULL AS parentid_is_not_null,
|
||||
partition_by_clause, partition_bounds
|
||||
FROM hypopg_table();
|
||||
is_root | tablename | parentid_is_null | parentid_is_not_null | partition_by_clause | partition_bounds
|
||||
---------+-----------------------------+------------------+----------------------+----------------------------+--------------------------------------------------
|
||||
t | hypo_part_range | t | f | PARTITION BY RANGE (id) |
|
||||
f | hypo_part_range_1_10000 | f | t | | FOR VALUES FROM (1) TO (10000)
|
||||
f | hypo_part_range_10000_20000 | f | t | | FOR VALUES FROM (10000) TO (20000)
|
||||
f | hypo_part_range_20000_30000 | f | t | | FOR VALUES FROM (20000) TO (30000)
|
||||
t | hypo_part_list | t | f | PARTITION BY LIST (id_key) |
|
||||
f | hypo_part_list_1_2_3 | f | t | | FOR VALUES IN (1, 2, 3)
|
||||
f | hypo_part_list_4_5_6_8_10 | f | t | | FOR VALUES IN (4, 5, 6, 8, 10)
|
||||
f | hypo_part_list_7_9 | f | t | | FOR VALUES IN (7, 9)
|
||||
t | hypo_part_hash | t | f | PARTITION BY HASH (id) |
|
||||
f | hypo_part_hash_0 | f | t | | FOR VALUES WITH (modulus 10, remainder 0)
|
||||
f | hypo_part_hash_1 | f | t | | FOR VALUES WITH (modulus 10, remainder 1)
|
||||
f | hypo_part_hash_2 | f | t | | FOR VALUES WITH (modulus 10, remainder 2)
|
||||
f | hypo_part_hash_3 | f | t | | FOR VALUES WITH (modulus 10, remainder 3)
|
||||
f | hypo_part_hash_4 | f | t | | FOR VALUES WITH (modulus 10, remainder 4)
|
||||
f | hypo_part_hash_5 | f | t | | FOR VALUES WITH (modulus 10, remainder 5)
|
||||
f | hypo_part_hash_6 | f | t | | FOR VALUES WITH (modulus 10, remainder 6)
|
||||
f | hypo_part_hash_7 | f | t | | FOR VALUES WITH (modulus 10, remainder 7)
|
||||
f | hypo_part_hash_8 | f | t | | FOR VALUES WITH (modulus 10, remainder 8)
|
||||
f | hypo_part_hash_9 | f | t | | FOR VALUES WITH (modulus 10, remainder 9)
|
||||
t | hypo_part_multi | t | f | PARTITION BY LIST (dpt) |
|
||||
f | hypo_part_multi_1 | f | t | PARTITION BY RANGE (dt) | FOR VALUES IN ('1')
|
||||
f | hypo_part_multi_1_q1 | f | t | PARTITION BY RANGE (dt) | FOR VALUES FROM ('01-01-2015') TO ('04-01-2015')
|
||||
f | hypo_part_multi_1_q1_a | f | t | | FOR VALUES FROM ('01-01-2015') TO ('02-01-2015')
|
||||
f | hypo_part_multi_1_q1_b | f | t | | FOR VALUES FROM ('02-01-2015') TO ('04-01-2015')
|
||||
f | hypo_part_multi_1_q2 | f | t | | FOR VALUES FROM ('04-01-2015') TO ('07-01-2015')
|
||||
f | hypo_part_multi_1_q3 | f | t | | FOR VALUES FROM ('07-01-2015') TO ('10-01-2015')
|
||||
f | hypo_part_multi_1_q4 | f | t | | FOR VALUES FROM ('10-01-2015') TO ('01-01-2016')
|
||||
f | hypo_part_multi_2 | f | t | PARTITION BY RANGE (dt) | FOR VALUES IN ('2')
|
||||
f | hypo_part_multi_2_q1 | f | t | | FOR VALUES FROM ('01-01-2015') TO ('04-01-2015')
|
||||
f | hypo_part_multi_2_q2 | f | t | | FOR VALUES FROM ('04-01-2015') TO ('07-01-2015')
|
||||
f | hypo_part_multi_2_q3 | f | t | | FOR VALUES FROM ('07-01-2015') TO ('10-01-2015')
|
||||
f | hypo_part_multi_2_q4 | f | t | | FOR VALUES FROM ('10-01-2015') TO ('01-01-2016')
|
||||
f | hypo_part_multi_3 | f | t | PARTITION BY RANGE (dt) | FOR VALUES IN ('3')
|
||||
f | hypo_part_multi_3_q1 | f | t | | FOR VALUES FROM ('01-01-2015') TO ('04-01-2015')
|
||||
f | hypo_part_multi_3_q2 | f | t | | FOR VALUES FROM ('04-01-2015') TO ('07-01-2015')
|
||||
f | hypo_part_multi_3_q3 | f | t | | FOR VALUES FROM ('07-01-2015') TO ('10-01-2015')
|
||||
f | hypo_part_multi_3_q4 | f | t | | FOR VALUES FROM ('10-01-2015') TO ('01-01-2016')
|
||||
(37 rows)
|
||||
|
||||
-- Test hypothetical partitioning behavior
|
||||
-- =======================================
|
||||
-- Simple queries
|
||||
-- --------------
|
||||
-- Real tables
|
||||
-- -----------
|
||||
-- 1. Range partition
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_range;
|
||||
QUERY PLAN
|
||||
------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_range_1_10000
|
||||
-> Seq Scan on part_range_10000_20000
|
||||
-> Seq Scan on part_range_20000_30000
|
||||
(4 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id = 42;
|
||||
QUERY PLAN
|
||||
--------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_range_1_10000
|
||||
Filter: (id = 42)
|
||||
(3 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id < 15000;
|
||||
QUERY PLAN
|
||||
------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_range_1_10000
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_range_10000_20000
|
||||
Filter: (id < 15000)
|
||||
(5 rows)
|
||||
|
||||
-- 2. List partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list;
|
||||
QUERY PLAN
|
||||
----------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_list_1_2_3
|
||||
-> Seq Scan on part_list_4_5_6_8_10
|
||||
-> Seq Scan on part_list_7_9
|
||||
(4 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id < 42;
|
||||
QUERY PLAN
|
||||
----------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_list_1_2_3
|
||||
Filter: (id < 42)
|
||||
-> Seq Scan on part_list_4_5_6_8_10
|
||||
Filter: (id < 42)
|
||||
-> Seq Scan on part_list_7_9
|
||||
Filter: (id < 42)
|
||||
(7 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id < 15000;
|
||||
QUERY PLAN
|
||||
----------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_list_1_2_3
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_list_4_5_6_8_10
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_list_7_9
|
||||
Filter: (id < 15000)
|
||||
(7 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id_key < 5;
|
||||
QUERY PLAN
|
||||
----------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_list_1_2_3
|
||||
Filter: (id_key < 5)
|
||||
-> Seq Scan on part_list_4_5_6_8_10
|
||||
Filter: (id_key < 5)
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id_key = 7;
|
||||
QUERY PLAN
|
||||
---------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_list_7_9
|
||||
Filter: (id_key = 7)
|
||||
(3 rows)
|
||||
|
||||
-- 3. Hash partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_hash;
|
||||
QUERY PLAN
|
||||
-------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_hash_0
|
||||
-> Seq Scan on part_hash_1
|
||||
-> Seq Scan on part_hash_2
|
||||
-> Seq Scan on part_hash_3
|
||||
-> Seq Scan on part_hash_4
|
||||
-> Seq Scan on part_hash_5
|
||||
-> Seq Scan on part_hash_6
|
||||
-> Seq Scan on part_hash_7
|
||||
-> Seq Scan on part_hash_8
|
||||
-> Seq Scan on part_hash_9
|
||||
(11 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_hash WHERE id = 42;
|
||||
QUERY PLAN
|
||||
-------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_hash_4
|
||||
Filter: (id = 42)
|
||||
(3 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_hash WHERE id < 15000;
|
||||
QUERY PLAN
|
||||
-------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_hash_0
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_1
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_2
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_3
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_4
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_5
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_6
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_7
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_8
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on part_hash_9
|
||||
Filter: (id < 15000)
|
||||
(21 rows)
|
||||
|
||||
-- 4. Multi level range
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_multi;
|
||||
QUERY PLAN
|
||||
-------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_multi_1_q1_a
|
||||
-> Seq Scan on part_multi_1_q1_b
|
||||
-> Seq Scan on part_multi_1_q2
|
||||
-> Seq Scan on part_multi_1_q3
|
||||
-> Seq Scan on part_multi_1_q4
|
||||
-> Seq Scan on part_multi_2_q1
|
||||
-> Seq Scan on part_multi_2_q2
|
||||
-> Seq Scan on part_multi_2_q3
|
||||
-> Seq Scan on part_multi_2_q4
|
||||
-> Seq Scan on part_multi_3_q1
|
||||
-> Seq Scan on part_multi_3_q2
|
||||
-> Seq Scan on part_multi_3_q3
|
||||
-> Seq Scan on part_multi_3_q4
|
||||
(14 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dpt = 2;
|
||||
QUERY PLAN
|
||||
-----------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_multi_2_q1
|
||||
Filter: (dpt = 2)
|
||||
-> Seq Scan on part_multi_2_q2
|
||||
Filter: (dpt = 2)
|
||||
-> Seq Scan on part_multi_2_q3
|
||||
Filter: (dpt = 2)
|
||||
-> Seq Scan on part_multi_2_q4
|
||||
Filter: (dpt = 2)
|
||||
(9 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dt >= '2015-01-05' AND dt < '2015-01-10';
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on part_multi_1_q1_a
|
||||
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
|
||||
-> Seq Scan on part_multi_2_q1
|
||||
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
|
||||
-> Seq Scan on part_multi_3_q1
|
||||
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
|
||||
(7 rows)
|
||||
|
||||
-- Hypothetical tables
|
||||
-- ------------------"
|
||||
-- 1. Range partition
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_range hypo_part_range_1_10000
|
||||
-> Seq Scan on hypo_part_range hypo_part_range_10000_20000
|
||||
-> Seq Scan on hypo_part_range hypo_part_range_20000_30000
|
||||
(4 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id = 42;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_range hypo_part_range_1_10000
|
||||
Filter: (id = 42)
|
||||
(3 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id < 15000;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_range hypo_part_range_1_10000
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_range hypo_part_range_10000_20000
|
||||
Filter: (id < 15000)
|
||||
(5 rows)
|
||||
|
||||
-- 2. List partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_1_2_3
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_4_5_6_8_10
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_7_9
|
||||
(4 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id < 42;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_1_2_3
|
||||
Filter: (id < 42)
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_4_5_6_8_10
|
||||
Filter: (id < 42)
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_7_9
|
||||
Filter: (id < 42)
|
||||
(7 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id < 15000;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_1_2_3
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_4_5_6_8_10
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_7_9
|
||||
Filter: (id < 15000)
|
||||
(7 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id_key < 5;
|
||||
QUERY PLAN
|
||||
------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_1_2_3
|
||||
Filter: (id_key < 5)
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_4_5_6_8_10
|
||||
Filter: (id_key < 5)
|
||||
(5 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id_key = 7;
|
||||
QUERY PLAN
|
||||
-----------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_list hypo_part_list_7_9
|
||||
Filter: (id_key = 7)
|
||||
(3 rows)
|
||||
|
||||
-- 3. Hash partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_0
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_1
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_2
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_3
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_4
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_5
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_6
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_7
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_8
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_9
|
||||
(11 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash WHERE id = 42;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_4
|
||||
Filter: (id = 42)
|
||||
(3 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash WHERE id < 15000;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_0
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_1
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_2
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_3
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_4
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_5
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_6
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_7
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_8
|
||||
Filter: (id < 15000)
|
||||
-> Seq Scan on hypo_part_hash hypo_part_hash_9
|
||||
Filter: (id < 15000)
|
||||
(21 rows)
|
||||
|
||||
-- 4. Multi level range
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi;
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_1_q1_a
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_1_q1_b
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_1_q2
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_1_q3
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_1_q4
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q1
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q2
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q3
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q4
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_3_q1
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_3_q2
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_3_q3
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_3_q4
|
||||
(14 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dpt = 2;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q1
|
||||
Filter: (dpt = 2)
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q2
|
||||
Filter: (dpt = 2)
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q3
|
||||
Filter: (dpt = 2)
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q4
|
||||
Filter: (dpt = 2)
|
||||
(9 rows)
|
||||
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dt >= '2015-01-05' AND dt < '2015-01-10';
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------
|
||||
Append
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_1_q1_a
|
||||
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q1
|
||||
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
|
||||
-> Seq Scan on hypo_part_multi hypo_part_multi_3_q1
|
||||
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
|
||||
(7 rows)
|
||||
|
||||
|
|
@ -1,18 +1,4 @@
|
|||
-- SETUP
|
||||
CREATE OR REPLACE FUNCTION do_explain(stmt text) RETURNS table(a text) AS
|
||||
$_$
|
||||
DECLARE
|
||||
ret text;
|
||||
BEGIN
|
||||
FOR ret IN EXECUTE format('EXPLAIN (FORMAT text) %s', stmt) LOOP
|
||||
a := ret;
|
||||
RETURN next ;
|
||||
END LOOP;
|
||||
END;
|
||||
$_$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
CREATE EXTENSION hypopg;
|
||||
-- Hypothetical index tests
|
||||
|
||||
CREATE TABLE hypo (id integer, val text);
|
||||
|
||||
18
test/sql/hypo_setup.sql
Normal file
18
test/sql/hypo_setup.sql
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
-- General setup
|
||||
|
||||
-- Create extension
|
||||
CREATE EXTENSION hypopg;
|
||||
|
||||
-- Create do_explain function
|
||||
CREATE OR REPLACE FUNCTION do_explain(stmt text) RETURNS table(a text) AS
|
||||
$_$
|
||||
DECLARE
|
||||
ret text;
|
||||
BEGIN
|
||||
FOR ret IN EXECUTE format('EXPLAIN (FORMAT text) %s', stmt) LOOP
|
||||
a := ret;
|
||||
RETURN next ;
|
||||
END LOOP;
|
||||
END;
|
||||
$_$
|
||||
LANGUAGE plpgsql;
|
||||
172
test/sql/hypo_table.sql
Normal file
172
test/sql/hypo_table.sql
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
-- Creating real and hypothetical tables"
|
||||
-- ====================================="
|
||||
|
||||
-- Real tables
|
||||
-- -----------
|
||||
-- 1. Range partition
|
||||
DROP TABLE IF EXISTS part_range;
|
||||
CREATE TABLE part_range (id integer, val text) PARTITION BY RANGE (id);
|
||||
CREATE TABLE part_range_1_10000 PARTITION OF part_range FOR VALUES FROM (1) TO (10000);
|
||||
CREATE TABLE part_range_10000_20000 PARTITION OF part_range FOR VALUES FROM (10000) TO (20000);
|
||||
CREATE TABLE part_range_20000_30000 PARTITION OF part_range FOR VALUES FROM (20000) TO (30000);
|
||||
INSERT INTO part_range SELECT i, 'line ' || i FROM generate_series(1, 29999) i;
|
||||
-- 2. List partitioning
|
||||
DROP TABLE IF EXISTS part_list;
|
||||
CREATE TABLE part_list (id integer, id_key integer, val text) PARTITION BY LIST (id_key);
|
||||
CREATE TABLE part_list_1_2_3 PARTITION OF part_list FOR VALUES IN (1, 2, 3);
|
||||
CREATE TABLE part_list_4_5_6_8_10 PARTITION OF part_list FOR VALUES IN (4, 5, 6, 8, 10);
|
||||
CREATE TABLE part_list_7_9 PARTITION OF part_list FOR VALUES IN (7, 9);
|
||||
INSERT INTO part_list SELECT i, (i % 9) + 1, 'line ' || i FROM generate_series(1, 50000) i;
|
||||
-- 3. Hash partitioning
|
||||
DROP TABLE IF EXISTS part_hash;
|
||||
CREATE TABLE part_hash (id integer, val text) PARTITION BY HASH (id);
|
||||
CREATE TABLE part_hash_0 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 0);
|
||||
CREATE TABLE part_hash_1 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 1);
|
||||
CREATE TABLE part_hash_2 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 2);
|
||||
CREATE TABLE part_hash_3 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 3);
|
||||
CREATE TABLE part_hash_4 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 4);
|
||||
CREATE TABLE part_hash_5 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 5);
|
||||
CREATE TABLE part_hash_6 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 6);
|
||||
CREATE TABLE part_hash_7 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 7);
|
||||
CREATE TABLE part_hash_8 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 8);
|
||||
CREATE TABLE part_hash_9 PARTITION OF part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 9);
|
||||
INSERT INTO part_hash SELECT i, 'line ' || i FROM generate_series(1, 90000) i;
|
||||
-- 4. Multi level range
|
||||
DROP TABLE IF EXISTS part_multi;
|
||||
CREATE TABLE part_multi(dpt smallint, dt date, val text) PARTITION BY LIST (dpt);
|
||||
CREATE TABLE part_multi_1 PARTITION OF part_multi FOR VALUES IN (1) PARTITION BY RANGE(dt);
|
||||
CREATE TABLE part_multi_1_q1 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$) PARTITION BY RANGE (dt);
|
||||
CREATE TABLE part_multi_1_q1_a PARTITION OF part_multi_1_q1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-02-01$$);
|
||||
CREATE TABLE part_multi_1_q1_b PARTITION OF part_multi_1_q1 FOR VALUES FROM ($$2015-02-01$$) TO ($$2015-04-01$$);
|
||||
CREATE TABLE part_multi_1_q2 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
|
||||
CREATE TABLE part_multi_1_q3 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
|
||||
CREATE TABLE part_multi_1_q4 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
|
||||
CREATE TABLE part_multi_2 PARTITION OF part_multi FOR VALUES IN (2) PARTITION BY RANGE(dt);
|
||||
CREATE TABLE part_multi_2_q1 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$);
|
||||
CREATE TABLE part_multi_2_q2 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
|
||||
CREATE TABLE part_multi_2_q3 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
|
||||
CREATE TABLE part_multi_2_q4 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
|
||||
CREATE TABLE part_multi_3 PARTITION OF part_multi FOR VALUES IN (3) PARTITION BY RANGE(dt);
|
||||
CREATE TABLE part_multi_3_q1 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$);
|
||||
CREATE TABLE part_multi_3_q2 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
|
||||
CREATE TABLE part_multi_3_q3 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
|
||||
CREATE TABLE part_multi_3_q4 PARTITION OF part_multi_3 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
|
||||
INSERT INTO part_multi select (i%3)+1, '2015-01-01'::date + interval '1 day' * (i%365), 'val ' || i FROM generate_series(1,10000) i;
|
||||
|
||||
-- Hypothetical tables
|
||||
-- -------------------
|
||||
-- 0. Dropping any hypothetical object
|
||||
SELECT * FROM hypopg_reset_index();
|
||||
SELECT * FROM hypopg_reset_table();
|
||||
-- 1. Range partition
|
||||
DROP TABLE IF EXISTS hypo_part_range;
|
||||
CREATE TABLE hypo_part_range (id integer, val text);
|
||||
INSERT INTO hypo_part_range SELECT i, 'line ' || i FROM generate_series(1, 29999) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_range', 'PARTITION BY RANGE (id)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_range_1_10000', 'PARTITION OF hypo_part_range FOR VALUES FROM (1) TO (10000)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_range_10000_20000', 'PARTITION OF hypo_part_range FOR VALUES FROM (10000) TO (20000)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_range_20000_30000', 'PARTITION OF hypo_part_range FOR VALUES FROM (20000) TO (30000)');
|
||||
-- 2. List partitioning
|
||||
DROP TABLE IF EXISTS hypo_part_list;
|
||||
CREATE TABLE hypo_part_list (id integer, id_key integer, val text);
|
||||
INSERT INTO hypo_part_list SELECT i, (i % 9) + 1, 'line ' || i FROM generate_series(1, 50000) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_list', 'PARTITION BY LIST (id_key)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_list_1_2_3', 'PARTITION OF hypo_part_list FOR VALUES IN (1, 2, 3)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_list_4_5_6_8_10', 'PARTITION OF hypo_part_list FOR VALUES IN (4, 5, 6, 8, 10)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_list_7_9', 'PARTITION OF hypo_part_list FOR VALUES IN (7, 9)');
|
||||
-- 3. Hash partitioning
|
||||
DROP TABLE IF EXISTS hypo_part_hash;
|
||||
CREATE TABLE hypo_part_hash (id integer, val text);
|
||||
INSERT INTO hypo_part_hash SELECT i, 'line ' || i FROM generate_series(1, 90000) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_hash', 'PARTITION BY HASH (id)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_0', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 0)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_1', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 1)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_2', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 2)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_3', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 3)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_4', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 4)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_5', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 5)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_6', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 6)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_7', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 7)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_8', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 8)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_hash_9', 'PARTITION OF hypo_part_hash FOR VALUES WITH (MODULUS 10, REMAINDER 9)');
|
||||
-- 4. Multi level range
|
||||
DROP TABLE IF EXISTS hypo_part_multi;
|
||||
CREATE TABLE hypo_part_multi(dpt smallint, dt date, val text);
|
||||
INSERT INTO hypo_part_multi select (i%3)+1, '2015-01-01'::date + interval '1 day' * (i%365), 'val ' || i FROM generate_series(1,10000) i;
|
||||
SELECT * FROM hypopg_partition_table('hypo_part_multi', 'PARTITION BY LIST (dpt)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1', 'PARTITION OF hypo_part_multi FOR VALUES IN (1)', 'PARTITION BY RANGE(dt)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)','PARTITION BY RANGE (dt)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1_a', 'PARTITION OF hypo_part_multi_1_q1 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-02-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1_b', 'PARTITION OF hypo_part_multi_1_q1 FOR VALUES FROM ($$2015-02-01$$) TO ($$2015-04-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q2', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q3', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q4', 'PARTITION OF hypo_part_multi_1 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2', 'PARTITION OF hypo_part_multi FOR VALUES IN (2)', 'PARTITION BY RANGE(dt)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q1', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q2', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q3', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q4', 'PARTITION OF hypo_part_multi_2 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3', 'PARTITION OF hypo_part_multi FOR VALUES IN (3)', 'PARTITION BY RANGE(dt)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q1', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q2', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q3', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
|
||||
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q4', 'PARTITION OF hypo_part_multi_3 FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
|
||||
|
||||
-- Maintenance
|
||||
-- -----------
|
||||
VACUUM ANALYZE;
|
||||
|
||||
-- Test deparsing
|
||||
-- ==============
|
||||
SELECT relid = rootid AS is_root, tablename, parentid IS NULL parentid_is_null,
|
||||
parentid IS NOT NULL AS parentid_is_not_null,
|
||||
partition_by_clause, partition_bounds
|
||||
FROM hypopg_table();
|
||||
|
||||
-- Test hypothetical partitioning behavior
|
||||
-- =======================================
|
||||
|
||||
-- Simple queries
|
||||
-- --------------
|
||||
|
||||
-- Real tables
|
||||
-- -----------
|
||||
-- 1. Range partition
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_range;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id = 42;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_range WHERE id < 15000;
|
||||
-- 2. List partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id < 42;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id < 15000;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id_key < 5;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_list WHERE id_key = 7;
|
||||
-- 3. Hash partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_hash;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_hash WHERE id = 42;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_hash WHERE id < 15000;
|
||||
-- 4. Multi level range
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_multi;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dpt = 2;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dt >= '2015-01-05' AND dt < '2015-01-10';
|
||||
|
||||
-- Hypothetical tables
|
||||
-- ------------------"
|
||||
-- 1. Range partition
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id = 42;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range WHERE id < 15000;
|
||||
-- 2. List partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id < 42;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id < 15000;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id_key < 5;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_list WHERE id_key = 7;
|
||||
-- 3. Hash partitioning
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash WHERE id = 42;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash WHERE id < 15000;
|
||||
-- 4. Multi level range
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dpt = 2;
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dt >= '2015-01-05' AND dt < '2015-01-10';
|
||||
Loading…
Reference in a new issue