mirror of
https://github.com/postgres/postgres.git
synced 2025-11-28 11:44:57 +03:00
Allow batching of inserts during cross-partition updates.
Commit927f453a9disallowed batching added by commitb663a4136to be used for the inserts performed as part of cross-partition updates of partitioned tables, mainly because the previous code in nodeModifyTable.c couldn't handle pending inserts into foreign-table partitions that are also UPDATE target partitions. But we don't have such a limitation anymore (cf. commitffbb7e65a), so let's allow for this by removing from execPartition.c the restriction added by commit927f453a9that batching is only allowed if the query command type is CMD_INSERT. In postgres_fdw, since commit86dc90056changed it to effectively disable cross-partition updates in the case where a foreign-table partition chosen to insert rows into is also an UPDATE target partition, allow batching in the case where a foreign-table partition chosen to do so is *not* also an UPDATE target partition. This is enabled by the "batch_size" option added by commitb663a4136, which is disabled by default. This patch also adjusts the test case added by commit927f453a9to confirm that the inserts performed as part of a cross-partition update of a partitioned table indeed uses batching. Amit Langote, reviewed and/or tested by Georgios Kokolatos, Zhihong Yu, Bharath Rupireddy, Hou Zhijie, Vignesh C, and me. Discussion: http://postgr.es/m/CA%2BHiwqH1Lz1yJmPs%3DaD-pzd_HLLynLHvq5iYeT9mB0bBV7oJ6w%40mail.gmail.com
This commit is contained in:
@@ -3329,8 +3329,13 @@ CREATE TABLE batch_table_p2
|
||||
INSERT INTO batch_table SELECT * FROM generate_series(1, 66) i;
|
||||
SELECT COUNT(*) FROM batch_table;
|
||||
|
||||
-- Check that enabling batched inserts doesn't interfere with cross-partition
|
||||
-- updates
|
||||
-- Clean up
|
||||
DROP TABLE batch_table;
|
||||
DROP TABLE batch_table_p0;
|
||||
DROP TABLE batch_table_p1;
|
||||
|
||||
-- Check that batched mode also works for some inserts made during
|
||||
-- cross-partition updates
|
||||
CREATE TABLE batch_cp_upd_test (a int) PARTITION BY LIST (a);
|
||||
CREATE TABLE batch_cp_upd_test1 (LIKE batch_cp_upd_test);
|
||||
CREATE FOREIGN TABLE batch_cp_upd_test1_f
|
||||
@@ -3338,16 +3343,50 @@ CREATE FOREIGN TABLE batch_cp_upd_test1_f
|
||||
FOR VALUES IN (1)
|
||||
SERVER loopback
|
||||
OPTIONS (table_name 'batch_cp_upd_test1', batch_size '10');
|
||||
CREATE TABLE batch_cp_up_test1 PARTITION OF batch_cp_upd_test
|
||||
CREATE TABLE batch_cp_upd_test2 PARTITION OF batch_cp_upd_test
|
||||
FOR VALUES IN (2);
|
||||
INSERT INTO batch_cp_upd_test VALUES (1), (2);
|
||||
CREATE TABLE batch_cp_upd_test3 (LIKE batch_cp_upd_test);
|
||||
CREATE FOREIGN TABLE batch_cp_upd_test3_f
|
||||
PARTITION OF batch_cp_upd_test
|
||||
FOR VALUES IN (3)
|
||||
SERVER loopback
|
||||
OPTIONS (table_name 'batch_cp_upd_test3', batch_size '1');
|
||||
|
||||
-- The following moves a row from the local partition to the foreign one
|
||||
UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a;
|
||||
SELECT tableoid::regclass, * FROM batch_cp_upd_test;
|
||||
-- Create statement triggers on remote tables that "log" any INSERTs
|
||||
-- performed on them.
|
||||
CREATE TABLE cmdlog (cmd text);
|
||||
CREATE FUNCTION log_stmt() RETURNS TRIGGER LANGUAGE plpgsql AS $$
|
||||
BEGIN INSERT INTO public.cmdlog VALUES (TG_OP || ' on ' || TG_RELNAME); RETURN NULL; END;
|
||||
$$;
|
||||
CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test1
|
||||
FOR EACH STATEMENT EXECUTE FUNCTION log_stmt();
|
||||
CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test3
|
||||
FOR EACH STATEMENT EXECUTE FUNCTION log_stmt();
|
||||
|
||||
-- This update moves rows from the local partition 'batch_cp_upd_test2' to the
|
||||
-- foreign partition 'batch_cp_upd_test1', one that has insert batching
|
||||
-- enabled, so a single INSERT for both rows.
|
||||
INSERT INTO batch_cp_upd_test VALUES (2), (2);
|
||||
UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2;
|
||||
|
||||
-- This one moves rows from the local partition 'batch_cp_upd_test2' to the
|
||||
-- foreign partition 'batch_cp_upd_test2', one that has insert batching
|
||||
-- disabled, so separate INSERTs for the two rows.
|
||||
INSERT INTO batch_cp_upd_test VALUES (2), (2);
|
||||
UPDATE batch_cp_upd_test t SET a = 3 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2;
|
||||
|
||||
SELECT tableoid::regclass, * FROM batch_cp_upd_test ORDER BY 1;
|
||||
|
||||
-- Should see 1 INSERT on batch_cp_upd_test1 and 2 on batch_cp_upd_test3 as
|
||||
-- described above.
|
||||
SELECT * FROM cmdlog ORDER BY 1;
|
||||
|
||||
-- Clean up
|
||||
DROP TABLE batch_table, batch_cp_upd_test, batch_table_p0, batch_table_p1 CASCADE;
|
||||
DROP TABLE batch_cp_upd_test;
|
||||
DROP TABLE batch_cp_upd_test1;
|
||||
DROP TABLE batch_cp_upd_test3;
|
||||
DROP TABLE cmdlog;
|
||||
DROP FUNCTION log_stmt();
|
||||
|
||||
-- Use partitioning
|
||||
ALTER SERVER loopback OPTIONS (ADD batch_size '10');
|
||||
|
||||
Reference in New Issue
Block a user