From e9cbdb064538f2fc2b7c017bdd589f5220e260e3 Mon Sep 17 00:00:00 2001 From: Julien Rouhaud Date: Sun, 4 Nov 2018 13:42:07 +0100 Subject: [PATCH] Add a hypopg_drop_table(oid) wrapper. The underlying C function was already existing, I just forgot to add the SQL wrapper. The C function is modified to add an error if the function is called on a non hypothetically partitioned table instead of silently doing nothing, and add regression tests. --- expected/hypo_table.out | 78 ++++++++++++++++++++++++++++++++++++++++- hypopg--2.0.0dev.sql | 5 +++ hypopg_table.c | 4 +++ test/sql/hypo_table.sql | 28 ++++++++++++++- 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/expected/hypo_table.out b/expected/hypo_table.out index c81a055..0e58990 100644 --- a/expected/hypo_table.out +++ b/expected/hypo_table.out @@ -1411,7 +1411,7 @@ SELECT * FROM hypopg_reset(); (1 row) -DROP TABLE part_multi CASCADE; +DROP TABLE part_multi; CREATE TABLE part_multi(dpt smallint, dt date, val text) PARTITION BY LIST (dpt); SELECT * FROM hypopg_partition_table('hypo_part_multi', 'PARTITION BY LIST (dpt)'); hypopg_partition_table @@ -1475,3 +1475,79 @@ EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; -> Seq Scan on hypo_part_multi hypo_part_multi_2_q1 (2 rows) +-- removing hypothetical partitions +-- ================================ +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$$); +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_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) + +DROP TABLE part_multi_1_q1_a; +SELECT hypopg_drop_table(relid) FROM hypopg_table() WHERE tablename = 'hypo_part_multi_1_q1_a'; + hypopg_drop_table +------------------- + +(1 row) + +EXPLAIN (COSTS OFF) SELECT * FROM part_multi; + QUERY PLAN +------------------------------------- + Append + -> Seq Scan on part_multi_1_q1_b + -> Seq Scan on part_multi_2_q1 +(3 rows) + +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; + QUERY PLAN +---------------------------------------------------------- + Append + -> Seq Scan on hypo_part_multi hypo_part_multi_1_q1_b + -> Seq Scan on hypo_part_multi hypo_part_multi_2_q1 +(3 rows) + +DROP TABLE part_multi_1; +SELECT hypopg_drop_table(relid) FROM hypopg_table() WHERE tablename = 'hypo_part_multi_1'; + hypopg_drop_table +------------------- + +(1 row) + +EXPLAIN (COSTS OFF) SELECT * FROM part_multi; + QUERY PLAN +----------------------------------- + Append + -> Seq Scan on part_multi_2_q1 +(2 rows) + +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; + QUERY PLAN +-------------------------------------------------------- + Append + -> Seq Scan on hypo_part_multi hypo_part_multi_2_q1 +(2 rows) + +SELECT hypopg_drop_table(relid) FROM hypopg_table() WHERE tablename = 'hypo_part_multi'; + hypopg_drop_table +------------------- + +(1 row) + +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; + QUERY PLAN +----------------------------- + Seq Scan on hypo_part_multi +(1 row) + +SELECT hypopg_drop_table(oid) FROM pg_class WHERE relname = 'pg_class'; +ERROR: hypopg: Oid 1259 is not a hypothetically partitioned table +SELECT hypopg_drop_table(1); +ERROR: hypopg: Oid 1 is not a hypothetically partitioned table diff --git a/hypopg--2.0.0dev.sql b/hypopg--2.0.0dev.sql index a9823a4..67443ee 100644 --- a/hypopg--2.0.0dev.sql +++ b/hypopg--2.0.0dev.sql @@ -92,6 +92,11 @@ CREATE FUNCTION hypopg_reset_table() LANGUAGE C VOLATILE COST 100 AS '$libdir/hypopg', 'hypopg_reset_table'; +CREATE FUNCTION hypopg_drop_table(IN relid oid) + RETURNS void + LANGUAGE C VOLATILE COST 100 +AS '$libdir/hypopg', 'hypopg_drop_table'; + CREATE FUNCTION hypopg_table(OUT relid oid, OUT tablename text, OUT parentid oid, OUT rootid oid, OUT partition_by_clause text, OUT partition_bounds text) diff --git a/hypopg_table.c b/hypopg_table.c index 29a9468..3c149f2 100644 --- a/hypopg_table.c +++ b/hypopg_table.c @@ -3210,6 +3210,10 @@ HYPO_PARTITION_NOT_SUPPORTED(); /* Process any pending invalidation */ hypo_process_inval(); + if (!hypo_table_oid_is_hypothetical(tableid)) + elog(ERROR, "hypopg: Oid %d is not a hypothetically partitioned table", + tableid); + PG_RETURN_BOOL(hypo_table_remove(tableid, true)); #endif } diff --git a/test/sql/hypo_table.sql b/test/sql/hypo_table.sql index 66ba065..845e026 100644 --- a/test/sql/hypo_table.sql +++ b/test/sql/hypo_table.sql @@ -266,7 +266,7 @@ EXPLAIN (COSTS OFF) WITH s AS (DELETE FROM foo USING part_range WHERE foo.id = p -- childless partitioning -- ====================== SELECT * FROM hypopg_reset(); -DROP TABLE part_multi CASCADE; +DROP TABLE part_multi; CREATE TABLE part_multi(dpt smallint, dt date, val text) PARTITION BY LIST (dpt); SELECT * FROM hypopg_partition_table('hypo_part_multi', 'PARTITION BY LIST (dpt)'); @@ -285,3 +285,29 @@ SELECT tablename FROM hypopg_add_partition('hypo_part_multi_1_q1', 'PARTITION OF EXPLAIN (COSTS OFF) SELECT * FROM part_multi; EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; + +-- removing hypothetical partitions +-- ================================ +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$$); +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$$)'); + +DROP TABLE part_multi_1_q1_a; +SELECT hypopg_drop_table(relid) FROM hypopg_table() WHERE tablename = 'hypo_part_multi_1_q1_a'; + +EXPLAIN (COSTS OFF) SELECT * FROM part_multi; +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; + +DROP TABLE part_multi_1; +SELECT hypopg_drop_table(relid) FROM hypopg_table() WHERE tablename = 'hypo_part_multi_1'; + +EXPLAIN (COSTS OFF) SELECT * FROM part_multi; +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; + +SELECT hypopg_drop_table(relid) FROM hypopg_table() WHERE tablename = 'hypo_part_multi'; + +EXPLAIN (COSTS OFF) SELECT * FROM hypo_part_multi; + +SELECT hypopg_drop_table(oid) FROM pg_class WHERE relname = 'pg_class'; +SELECT hypopg_drop_table(1);