mirror of
https://github.com/postgres/postgres.git
synced 2025-12-21 05:21:08 +03:00
Support COPY TO for partitioned tables.
Previously, COPY TO command didn't support directly specifying partitioned tables so users had to use COPY (SELECT ...) TO variant. This commit adds direct COPY TO support for partitioned tables, improving both usability and performance. Performance tests show it's faster than the COPY (SELECT ...) TO variant as it avoids the overheads of query processing and sending results to the COPY TO command. When used with partitioned tables, COPY TO copies the same rows as SELECT * FROM table. Row-level security policies of the partitioned table are applied in the same way as when executing COPY TO on a plain table. Author: jian he <jian.universality@gmail.com> Reviewed-by: vignesh C <vignesh21@gmail.com> Reviewed-by: David Rowley <dgrowleyml@gmail.com> Reviewed-by: Melih Mutlu <m.melihmutlu@gmail.com> Reviewed-by: Kirill Reshke <reshkekirill@gmail.com> Reviewed-by: Atsushi Torikoshi <torikoshia@oss.nttdata.com> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Discussion: https://postgr.es/m/CACJufxEZt%2BG19Ors3bQUq-42-61__C%3Dy5k2wk%3DsHEFRusu7%3DiQ%40mail.gmail.com
This commit is contained in:
@@ -373,3 +373,23 @@ COPY copytest_mv(id) TO stdout WITH (header);
|
||||
id
|
||||
1
|
||||
DROP MATERIALIZED VIEW copytest_mv;
|
||||
-- Tests for COPY TO with partitioned tables.
|
||||
-- The child table pp_2 has a different column order than the root table pp.
|
||||
-- Check if COPY TO exports tuples as the root table's column order.
|
||||
CREATE TABLE pp (id int,val int) PARTITION BY RANGE (id);
|
||||
CREATE TABLE pp_1 (val int, id int) PARTITION BY RANGE (id);
|
||||
CREATE TABLE pp_2 (id int, val int) PARTITION BY RANGE (id);
|
||||
ALTER TABLE pp ATTACH PARTITION pp_1 FOR VALUES FROM (1) TO (5);
|
||||
ALTER TABLE pp ATTACH PARTITION pp_2 FOR VALUES FROM (5) TO (10);
|
||||
CREATE TABLE pp_15 PARTITION OF pp_1 FOR VALUES FROM (1) TO (5);
|
||||
CREATE TABLE pp_510 PARTITION OF pp_2 FOR VALUES FROM (5) TO (10);
|
||||
INSERT INTO pp SELECT g, 10 + g FROM generate_series(1,6) g;
|
||||
COPY pp TO stdout(header);
|
||||
id val
|
||||
1 11
|
||||
2 12
|
||||
3 13
|
||||
4 14
|
||||
5 15
|
||||
6 16
|
||||
DROP TABLE PP;
|
||||
|
||||
@@ -986,6 +986,11 @@ NOTICE: f_leak => my first satire
|
||||
9 | 11 | 1 | regress_rls_dave | awesome science fiction
|
||||
(4 rows)
|
||||
|
||||
COPY part_document TO stdout WITH (DELIMITER ',');
|
||||
1,11,1,regress_rls_bob,my first novel
|
||||
6,11,1,regress_rls_carol,great science fiction
|
||||
9,11,1,regress_rls_dave,awesome science fiction
|
||||
4,55,1,regress_rls_bob,my first satire
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------
|
||||
@@ -1028,6 +1033,17 @@ NOTICE: f_leak => awesome technology book
|
||||
10 | 99 | 2 | regress_rls_dave | awesome technology book
|
||||
(10 rows)
|
||||
|
||||
COPY part_document TO stdout WITH (DELIMITER ',');
|
||||
1,11,1,regress_rls_bob,my first novel
|
||||
2,11,2,regress_rls_bob,my second novel
|
||||
6,11,1,regress_rls_carol,great science fiction
|
||||
9,11,1,regress_rls_dave,awesome science fiction
|
||||
4,55,1,regress_rls_bob,my first satire
|
||||
8,55,2,regress_rls_carol,great satire
|
||||
3,99,2,regress_rls_bob,my science textbook
|
||||
5,99,2,regress_rls_bob,my history book
|
||||
7,99,2,regress_rls_carol,great technology book
|
||||
10,99,2,regress_rls_dave,awesome technology book
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------
|
||||
@@ -1058,6 +1074,11 @@ NOTICE: f_leak => awesome science fiction
|
||||
9 | 11 | 1 | regress_rls_dave | awesome science fiction
|
||||
(4 rows)
|
||||
|
||||
COPY part_document TO stdout WITH (DELIMITER ',');
|
||||
1,11,1,regress_rls_bob,my first novel
|
||||
2,11,2,regress_rls_bob,my second novel
|
||||
6,11,1,regress_rls_carol,great science fiction
|
||||
9,11,1,regress_rls_dave,awesome science fiction
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
|
||||
QUERY PLAN
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
@@ -405,3 +405,17 @@ COPY copytest_mv(id) TO stdout WITH (header);
|
||||
REFRESH MATERIALIZED VIEW copytest_mv;
|
||||
COPY copytest_mv(id) TO stdout WITH (header);
|
||||
DROP MATERIALIZED VIEW copytest_mv;
|
||||
|
||||
-- Tests for COPY TO with partitioned tables.
|
||||
-- The child table pp_2 has a different column order than the root table pp.
|
||||
-- Check if COPY TO exports tuples as the root table's column order.
|
||||
CREATE TABLE pp (id int,val int) PARTITION BY RANGE (id);
|
||||
CREATE TABLE pp_1 (val int, id int) PARTITION BY RANGE (id);
|
||||
CREATE TABLE pp_2 (id int, val int) PARTITION BY RANGE (id);
|
||||
ALTER TABLE pp ATTACH PARTITION pp_1 FOR VALUES FROM (1) TO (5);
|
||||
ALTER TABLE pp ATTACH PARTITION pp_2 FOR VALUES FROM (5) TO (10);
|
||||
CREATE TABLE pp_15 PARTITION OF pp_1 FOR VALUES FROM (1) TO (5);
|
||||
CREATE TABLE pp_510 PARTITION OF pp_2 FOR VALUES FROM (5) TO (10);
|
||||
INSERT INTO pp SELECT g, 10 + g FROM generate_series(1,6) g;
|
||||
COPY pp TO stdout(header);
|
||||
DROP TABLE PP;
|
||||
|
||||
@@ -362,16 +362,19 @@ SELECT * FROM pg_policies WHERE schemaname = 'regress_rls_schema' AND tablename
|
||||
SET SESSION AUTHORIZATION regress_rls_bob;
|
||||
SET row_security TO ON;
|
||||
SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did;
|
||||
COPY part_document TO stdout WITH (DELIMITER ',');
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
|
||||
|
||||
-- viewpoint from regress_rls_carol
|
||||
SET SESSION AUTHORIZATION regress_rls_carol;
|
||||
SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did;
|
||||
COPY part_document TO stdout WITH (DELIMITER ',');
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
|
||||
|
||||
-- viewpoint from regress_rls_dave
|
||||
SET SESSION AUTHORIZATION regress_rls_dave;
|
||||
SELECT * FROM part_document WHERE f_leak(dtitle) ORDER BY did;
|
||||
COPY part_document TO stdout WITH (DELIMITER ',');
|
||||
EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle);
|
||||
|
||||
-- pp1 ERROR
|
||||
|
||||
Reference in New Issue
Block a user