Merge pull request #31 from yuzupy/def_part

Add a hypothetical default partition feature
This commit is contained in:
Julien Rouhaud 2018-11-07 08:11:05 +01:00 committed by GitHub
commit 6ee1a7894a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 217 additions and 63 deletions

View file

@ -42,6 +42,7 @@ CREATE TABLE part_multi_2_q1 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-0
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_2_def PARTITION OF part_multi_2 DEFAULT;
CREATE TABLE part_multi_1 PARTITION OF part_multi FOR VALUES IN (1) PARTITION BY RANGE(dt);
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$$);
@ -49,12 +50,20 @@ CREATE TABLE part_multi_1_q4 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-1
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_b PARTITION OF part_multi_1_q1 FOR VALUES FROM ($$2015-02-01$$) TO ($$2015-04-01$$);
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_def PARTITION OF part_multi_1 DEFAULT;
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;
CREATE TABLE part_multi_3_def PARTITION OF part_multi_3 DEFAULT;
CREATE TABLE part_multi_def PARTITION OF part_multi DEFAULT PARTITION BY RANGE(dt);
CREATE TABLE part_multi_def_q1 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$);
CREATE TABLE part_multi_def_q2 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
CREATE TABLE part_multi_def_q3 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
CREATE TABLE part_multi_def_q4 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
CREATE TABLE part_multi_def_def PARTITION OF part_multi_def DEFAULT;
INSERT INTO part_multi select (i%4)+1, '2015-01-01'::date + interval '1 day' * (i%500), 'val ' || i FROM generate_series(1,50000) i;
-- Hypothetical tables
-- -------------------
-- 0. Dropping any hypothetical object
@ -197,7 +206,7 @@ SELECT tablename FROM hypopg_add_partition('hypo_part_hash_0', 'PARTITION OF hyp
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;
INSERT INTO hypo_part_multi select (i%4)+1, '2015-01-01'::date + interval '1 day' * (i%500), 'val ' || i FROM generate_series(1,50000) i;
SELECT * FROM hypopg_partition_table('hypo_part_multi', 'PARTITION BY LIST (dpt)');
hypopg_partition_table
------------------------
@ -234,6 +243,12 @@ SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_q4', 'PARTITION OF
hypo_part_multi_2_q4
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_2_def', 'PARTITION OF hypo_part_multi_2 DEFAULT');
tablename
-----------------------
hypo_part_multi_2_def
(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
-------------------
@ -276,6 +291,12 @@ SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1_a', 'PARTITION
hypo_part_multi_1_q1_a
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_def', 'PARTITION OF hypo_part_multi_1 DEFAULT');
tablename
-----------------------
hypo_part_multi_1_def
(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
-------------------
@ -306,6 +327,48 @@ SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_q4', 'PARTITION OF
hypo_part_multi_3_q4
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_def', 'PARTITION OF hypo_part_multi_3 DEFAULT');
tablename
-----------------------
hypo_part_multi_3_def
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def', 'PARTITION OF hypo_part_multi DEFAULT' ,'PARTITION BY RANGE(dt)');
tablename
---------------------
hypo_part_multi_def
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q1', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)');
tablename
------------------------
hypo_part_multi_def_q1
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q2', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
tablename
------------------------
hypo_part_multi_def_q2
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q3', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
tablename
------------------------
hypo_part_multi_def_q3
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q4', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
tablename
------------------------
hypo_part_multi_def_q4
(1 row)
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_def', 'PARTITION OF hypo_part_multi_def DEFAULT');
tablename
-------------------------
hypo_part_multi_def_def
(1 row)
-- Maintenance
-- -----------
VACUUM ANALYZE;
@ -376,6 +439,7 @@ FROM hypopg_table();
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_2_def | f | t | | DEFAULT
f | hypo_part_multi_1 | f | t | PARTITION BY RANGE (dt) | FOR VALUES IN ('1')
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')
@ -383,12 +447,20 @@ FROM hypopg_table();
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_b | f | t | | FOR VALUES FROM ('02-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_def | f | t | | DEFAULT
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)
f | hypo_part_multi_3_def | f | t | | DEFAULT
f | hypo_part_multi_def | f | t | PARTITION BY RANGE (dt) | DEFAULT
f | hypo_part_multi_def_q1 | f | t | | FOR VALUES FROM ('01-01-2015') TO ('04-01-2015')
f | hypo_part_multi_def_q2 | f | t | | FOR VALUES FROM ('04-01-2015') TO ('07-01-2015')
f | hypo_part_multi_def_q3 | f | t | | FOR VALUES FROM ('07-01-2015') TO ('10-01-2015')
f | hypo_part_multi_def_q4 | f | t | | FOR VALUES FROM ('10-01-2015') TO ('01-01-2016')
f | hypo_part_multi_def_def | f | t | | DEFAULT
(46 rows)
-- Test hypothetical partitioning behavior
-- =======================================
@ -529,27 +601,35 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_hash WHERE id < 15000;
-- 4. Multi level range
EXPLAIN (COSTS OFF) SELECT * FROM part_multi;
QUERY PLAN
-------------------------------------
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_1_def
-> 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_2_def
-> 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)
-> Seq Scan on part_multi_3_def
-> Seq Scan on part_multi_def_q1
-> Seq Scan on part_multi_def_q2
-> Seq Scan on part_multi_def_q3
-> Seq Scan on part_multi_def_q4
-> Seq Scan on part_multi_def_def
(22 rows)
EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dpt = 2;
QUERY PLAN
-----------------------------------
QUERY PLAN
------------------------------------
Append
-> Seq Scan on part_multi_2_q1
Filter: (dpt = 2)
@ -559,7 +639,9 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dpt = 2;
Filter: (dpt = 2)
-> Seq Scan on part_multi_2_q4
Filter: (dpt = 2)
(9 rows)
-> Seq Scan on part_multi_2_def
Filter: (dpt = 2)
(11 rows)
EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dt >= '2015-01-05' AND dt < '2015-01-10';
QUERY PLAN
@ -567,11 +649,21 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_multi WHERE dt >= '2015-01-05' AND dt < '
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_1_def
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_2_def
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)
-> Seq Scan on part_multi_3_def
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
-> Seq Scan on part_multi_def_q1
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
-> Seq Scan on part_multi_def_def
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
(17 rows)
-- Hypothetical tables
-- -------------------
@ -708,27 +800,35 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash WHERE id < 15000;
-- 4. Multi level range
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi;
QUERY PLAN
----------------------------------------------------------
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_1_def
-> 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_2_def
-> 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)
-> Seq Scan on hypo_part_multi hypo_part_multi_3_def
-> Seq Scan on hypo_part_multi hypo_part_multi_def_q1
-> Seq Scan on hypo_part_multi hypo_part_multi_def_q2
-> Seq Scan on hypo_part_multi hypo_part_multi_def_q3
-> Seq Scan on hypo_part_multi hypo_part_multi_def_q4
-> Seq Scan on hypo_part_multi hypo_part_multi_def_def
(22 rows)
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dpt = 2;
QUERY PLAN
--------------------------------------------------------
QUERY PLAN
---------------------------------------------------------
Append
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q1
Filter: (dpt = 2)
@ -738,7 +838,9 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dpt = 2;
Filter: (dpt = 2)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q4
Filter: (dpt = 2)
(9 rows)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_def
Filter: (dpt = 2)
(11 rows)
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dt >= '2015-01-05' AND dt < '2015-01-10';
QUERY PLAN
@ -746,11 +848,21 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi WHERE dt >= '2015-01-05' AND d
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_1_def
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_2_def
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)
-> Seq Scan on hypo_part_multi hypo_part_multi_3_def
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
-> Seq Scan on hypo_part_multi hypo_part_multi_def_q1
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
-> Seq Scan on hypo_part_multi hypo_part_multi_def_def
Filter: ((dt >= '01-05-2015'::date) AND (dt < '01-10-2015'::date))
(17 rows)
-- Join queries
-- ------------
@ -822,8 +934,8 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_hash t1, part_hash t2 WHERE t1.id = t2.id
(25 rows)
EXPLAIN (COSTS OFF) SELECT * FROM part_multi t1, part_multi t2 WHERE t1.dpt = t2.dpt and t1.dpt = 2;
QUERY PLAN
----------------------------------------------------
QUERY PLAN
-----------------------------------------------------
Nested Loop
-> Append
-> Seq Scan on part_multi_2_q1 t1
@ -834,6 +946,8 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_multi t1, part_multi t2 WHERE t1.dpt = t2
Filter: (dpt = 2)
-> Seq Scan on part_multi_2_q4 t1_3
Filter: (dpt = 2)
-> Seq Scan on part_multi_2_def t1_4
Filter: (dpt = 2)
-> Materialize
-> Append
-> Seq Scan on part_multi_2_q1 t2
@ -844,7 +958,9 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_multi t1, part_multi t2 WHERE t1.dpt = t2
Filter: (dpt = 2)
-> Seq Scan on part_multi_2_q4 t2_3
Filter: (dpt = 2)
(20 rows)
-> Seq Scan on part_multi_2_def t2_4
Filter: (dpt = 2)
(24 rows)
-- 2. Hypothetical tables
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_range t1, hypo_part_range t2 WHERE t1.id = t2.id and t1.id < 15000;
@ -912,8 +1028,8 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_hash t1, hypo_part_hash t2 WHERE t1.
(25 rows)
EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi t1, hypo_part_multi t2 WHERE t1.dpt = t2.dpt and t1.dpt = 2;
QUERY PLAN
----------------------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------------------
Nested Loop
-> Append
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q1
@ -924,6 +1040,8 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi t1, hypo_part_multi t2 WHERE t
Filter: (dpt = 2)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q4
Filter: (dpt = 2)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_def
Filter: (dpt = 2)
-> Materialize
-> Append
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q1_1
@ -934,7 +1052,9 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi t1, hypo_part_multi t2 WHERE t
Filter: (dpt = 2)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q4_1
Filter: (dpt = 2)
(20 rows)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_def_1
Filter: (dpt = 2)
(24 rows)
-- 3. Real tables and hypothetical tables
EXPLAIN (COSTS OFF) SELECT * FROM part_range t1, hypo_part_range t2 WHERE t1.id = t2.id and t1.id < 15000;
@ -1002,8 +1122,8 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_hash t1, hypo_part_hash t2 WHERE t1.id =
(25 rows)
EXPLAIN (COSTS OFF) SELECT * FROM part_multi t1, hypo_part_multi t2 WHERE t1.dpt = t2.dpt and t1.dpt = 2;
QUERY PLAN
--------------------------------------------------------------------
QUERY PLAN
---------------------------------------------------------------------
Nested Loop
-> Append
-> Seq Scan on part_multi_2_q1 t1
@ -1014,6 +1134,8 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_multi t1, hypo_part_multi t2 WHERE t1.dpt
Filter: (dpt = 2)
-> Seq Scan on part_multi_2_q4 t1_3
Filter: (dpt = 2)
-> Seq Scan on part_multi_2_def t1_4
Filter: (dpt = 2)
-> Materialize
-> Append
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q1
@ -1024,7 +1146,9 @@ EXPLAIN (COSTS OFF) SELECT * FROM part_multi t1, hypo_part_multi t2 WHERE t1.dpt
Filter: (dpt = 2)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_q4
Filter: (dpt = 2)
(20 rows)
-> Seq Scan on hypo_part_multi hypo_part_multi_2_def
Filter: (dpt = 2)
(24 rows)
-- Partitionwise joins
-- -------------------

View file

@ -317,6 +317,8 @@ static void hypo_do_analyze_partition(Relation onerel, Relation pgstats,
* partition
* */
totalrows = SPI_processed * 100 / fraction;
part->tuples = (int) totalrows;
part->set_tuples = true;
/*
* Compute the statistics. Temporary results during the calculations for

View file

@ -2007,9 +2007,12 @@ hypo_injectHypotheticalPartitioning(PlannerInfo *root,
}
/*
* If this rel is a partition, we will estimate pages and tuples according
* to its partition bound and root table's pages and tuples.
* If this rel is a partition, we set rel->pages and rel->tuples.
*
* When hypoTable->set_tuples is true, pages and tuples are set
* according to hypoTable->tuples. Otherwise, we will estimate pages
* and tuples here according to its partition bound and root table's
* pages and tuples as follows:
* In the case of RANGE/LIST partitioning, we will compute selectivity
* according to the partition constraints including its ancestors'.
* On the other hand, in the case of HASH partitioning, we will multiply
@ -2042,18 +2045,6 @@ hypo_injectHypotheticalPartitioning(PlannerInfo *root,
return;
}
/*
* hypo_clauselist_selectivity will retrieve the constraints for this
* partition and all its ancestors
*/
selectivity = hypo_clauselist_selectivity(root, rel, NIL,
part->rootid, part->parentid);
elog(DEBUG1, "hypopg: selectivity for partition \"%s\": %lf",
hypo_find_table(linitial_oid(planner_rt_fetch(rel->relid,
root)->values_lists), false)->tablename,
selectivity);
/*
* Selectivity for hash partitions cannot be done using the standard
* clauselist_selectivity(), because the underlying constraint is using
@ -2078,10 +2069,38 @@ hypo_injectHypotheticalPartitioning(PlannerInfo *root,
elog(DEBUG1, "hypopg: total modulus for partition %s: %d",
part->tablename, total_modulus);
/* compute pages and tuples using selectivity and total_modulus */
pages = ceil(rel->pages * selectivity / total_modulus);
rel->pages = (BlockNumber) pages;
rel->tuples = clamp_row_est(rel->tuples * selectivity / total_modulus);
if (part->set_tuples)
{
/*
* pages and tuples are set according to part->tuples got by
* hypopg_analyze function. But we need compute them again
* using total_modulus for hash partitioning, since hypopg_analyze
* cannot run on hash partitioning
*/
pages = ceil(rel->pages * part->tuples / rel->tuples / total_modulus);
rel->pages = (BlockNumber) pages;
rel->tuples = clamp_row_est(part->tuples / total_modulus);
}
else
{
/*
* hypo_clauselist_selectivity will retrieve the constraints for this
* partition and all its ancestors
*/
selectivity = hypo_clauselist_selectivity(root, rel, NIL,
part->rootid, part->parentid);
elog(DEBUG1, "hypopg: selectivity for partition \"%s\": %lf",
hypo_find_table(linitial_oid(planner_rt_fetch(rel->relid,
root)->values_lists), false)->tablename,
selectivity);
/* compute pages and tuples using selectivity and total_modulus */
pages = ceil(rel->pages * selectivity / total_modulus);
rel->pages = (BlockNumber) pages;
rel->tuples = clamp_row_est(rel->tuples * selectivity / total_modulus);
}
}
/*
@ -2471,25 +2490,17 @@ hypo_get_qual_for_range(hypoTable *parent, PartitionBoundSpec *spec, bool for_de
for (i = 0; i < nparts; i++)
{
Oid inhrelid = inhoids[i]; //is this a parent oid or dummy child oid?
HeapTuple tuple;
Datum datum;
bool isnull;
Oid inhrelid = inhoids[i];
hypoTable *part;
PartitionBoundSpec *bspec;
elog(NOTICE,"inhrelid : %u",inhrelid);
/*
* get each partition's boundspec from hypoTable entry
* instead of catalog
*/
part = hypo_find_table(inhrelid, false);
bspec = part->boundspec;
tuple = SearchSysCache1(RELOID, inhrelid);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", inhrelid);
datum = SysCacheGetAttr(RELOID, tuple,
Anum_pg_class_relpartbound,
&isnull);
Assert(!isnull);
bspec = (PartitionBoundSpec *)
stringToNode(TextDatumGetCString(datum));
if (!IsA(bspec, PartitionBoundSpec))
elog(ERROR, "expected PartitionBoundSpec");
@ -2507,7 +2518,6 @@ hypo_get_qual_for_range(hypoTable *parent, PartitionBoundSpec *spec, bool for_de
? makeBoolExpr(AND_EXPR, part_qual, -1)
: linitial(part_qual));
}
ReleaseSysCache(tuple);
}
if (or_expr_args != NIL)

View file

@ -39,6 +39,7 @@ CREATE TABLE part_multi_2_q1 PARTITION OF part_multi_2 FOR VALUES FROM ($$2015-0
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_2_def PARTITION OF part_multi_2 DEFAULT;
CREATE TABLE part_multi_1 PARTITION OF part_multi FOR VALUES IN (1) PARTITION BY RANGE(dt);
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$$);
@ -46,12 +47,20 @@ CREATE TABLE part_multi_1_q4 PARTITION OF part_multi_1 FOR VALUES FROM ($$2015-1
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_b PARTITION OF part_multi_1_q1 FOR VALUES FROM ($$2015-02-01$$) TO ($$2015-04-01$$);
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_def PARTITION OF part_multi_1 DEFAULT;
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;
CREATE TABLE part_multi_3_def PARTITION OF part_multi_3 DEFAULT;
CREATE TABLE part_multi_def PARTITION OF part_multi DEFAULT PARTITION BY RANGE(dt);
CREATE TABLE part_multi_def_q1 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$);
CREATE TABLE part_multi_def_q2 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$);
CREATE TABLE part_multi_def_q3 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$);
CREATE TABLE part_multi_def_q4 PARTITION OF part_multi_def FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$);
CREATE TABLE part_multi_def_def PARTITION OF part_multi_def DEFAULT;
INSERT INTO part_multi select (i%4)+1, '2015-01-01'::date + interval '1 day' * (i%500), 'val ' || i FROM generate_series(1,50000) i;
-- Hypothetical tables
-- -------------------
@ -91,13 +100,14 @@ SELECT tablename FROM hypopg_add_partition('hypo_part_hash_0', 'PARTITION OF hyp
-- 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;
INSERT INTO hypo_part_multi select (i%4)+1, '2015-01-01'::date + interval '1 day' * (i%500), 'val ' || i FROM generate_series(1,50000) i;
SELECT * FROM hypopg_partition_table('hypo_part_multi', 'PARTITION BY LIST (dpt)');
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_2_def', 'PARTITION OF hypo_part_multi_2 DEFAULT');
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_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$$)');
@ -105,11 +115,19 @@ SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q4', 'PARTITION OF
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_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_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_def', 'PARTITION OF hypo_part_multi_1 DEFAULT');
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$$)');
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_3_def', 'PARTITION OF hypo_part_multi_3 DEFAULT');
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def', 'PARTITION OF hypo_part_multi DEFAULT' ,'PARTITION BY RANGE(dt)');
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q1', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-01-01$$) TO ($$2015-04-01$$)');
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q2', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-04-01$$) TO ($$2015-07-01$$)');
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q3', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-07-01$$) TO ($$2015-10-01$$)');
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_q4', 'PARTITION OF hypo_part_multi_def FOR VALUES FROM ($$2015-10-01$$) TO ($$2016-01-01$$)');
SELECT tablename FROM hypopg_add_partition('hypo_part_multi_def_def', 'PARTITION OF hypo_part_multi_def DEFAULT');
-- Maintenance
-- -----------