Allow COPY after a multi-shard command

This change removes the XactModificationLevel check at the start of COPY
that was made redundant by consistently using GetPlacementConnection.
pull/1441/head
Marco Slot 2017-06-06 18:05:25 +02:00
parent 50501227e9
commit 70abfd29d2
4 changed files with 43 additions and 50 deletions

View File

@ -734,14 +734,6 @@ OpenCopyConnections(CopyStmt *copyStatement, ShardConnections *shardConnections,
MemoryContextSwitchTo(oldContext);
if (XactModificationLevel > XACT_MODIFICATION_DATA)
{
ereport(ERROR, (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
errmsg("distributed copy operations must not appear in "
"transaction blocks containing other distributed "
"modifications")));
}
foreach(placementCell, finalizedPlacementList)
{
ShardPlacement *placement = (ShardPlacement *) lfirst(placementCell);

View File

@ -1634,8 +1634,6 @@ ROLLBACK;
BEGIN;
INSERT INTO raw_events_first SELECT * FROM raw_events_second;
COPY raw_events_first (user_id, value_1) FROM STDIN DELIMITER ',';
ERROR: distributed copy operations must not appear in transaction blocks containing other distributed modifications
CONTEXT: COPY raw_events_first, line 1: "102,102"
ROLLBACK;
BEGIN;
INSERT INTO raw_events_first SELECT * FROM raw_events_second WHERE user_id = 100;

View File

@ -202,6 +202,20 @@ BEGIN;
INSERT INTO labs VALUES (6, 'Bell Labs');
\copy labs from stdin delimiter ','
COMMIT;
-- COPY cannot be performed if multiple shards were modified over the same connection
BEGIN;
INSERT INTO researchers VALUES (2, 1, 'Knuth Donald');
INSERT INTO researchers VALUES (10, 6, 'Lamport Leslie');
\copy researchers from stdin delimiter ','
ERROR: cannot establish new placement connection when DML has been executed on existing placement connection
CONTEXT: COPY researchers, line 2: "10,6,Lesport Lampie"
ROLLBACK;
-- after a COPY you can modify multiple shards, since they'll use different connections
BEGIN;
\copy researchers from stdin delimiter ','
INSERT INTO researchers VALUES (2, 1, 'Knuth Donald');
INSERT INTO researchers VALUES (10, 6, 'Lamport Leslie');
ROLLBACK;
-- COPY can happen before single row INSERT
BEGIN;
\copy labs from stdin delimiter ','
@ -369,41 +383,17 @@ ORDER BY nodeport;
localhost | 57638 | t | DROP FUNCTION
(2 rows)
-- finally, ALTER and copy aren't compatible
-- ALTER TABLE and COPY are compatible if ALTER TABLE precedes COPY
BEGIN;
ALTER TABLE labs ADD COLUMN motto text;
\copy labs from stdin delimiter ','
ERROR: distributed copy operations must not appear in transaction blocks containing other distributed modifications
CONTEXT: COPY labs, line 1: "12,fsociety,lol"
COMMIT;
-- but the DDL should correctly roll back
\d labs
Table "public.labs"
Column | Type | Modifiers
--------+--------+-----------
id | bigint | not null
name | text | not null
-- and if the copy is before the ALTER...
ROLLBACK;
-- but not if COPY precedes ALTER TABLE
BEGIN;
\copy labs from stdin delimiter ','
ALTER TABLE labs ADD COLUMN motto text;
ERROR: distributed DDL commands must not appear within transaction blocks containing single-shard data modifications
COMMIT;
-- the DDL fails, but copy persists
\d labs
Table "public.labs"
Column | Type | Modifiers
--------+--------+-----------
id | bigint | not null
name | text | not null
SELECT * FROM labs WHERE id = 12;
id | name
----+----------
12 | fsociety
(1 row)
ROLLBACK;
-- multi-shard operations can co-exist with DDL in a transactional way
BEGIN;
ALTER TABLE labs ADD COLUMN motto text;

View File

@ -162,6 +162,26 @@ INSERT INTO labs VALUES (6, 'Bell Labs');
\.
COMMIT;
-- COPY cannot be performed if multiple shards were modified over the same connection
BEGIN;
INSERT INTO researchers VALUES (2, 1, 'Knuth Donald');
INSERT INTO researchers VALUES (10, 6, 'Lamport Leslie');
\copy researchers from stdin delimiter ','
3,1,Duth Knonald
10,6,Lesport Lampie
\.
ROLLBACK;
-- after a COPY you can modify multiple shards, since they'll use different connections
BEGIN;
\copy researchers from stdin delimiter ','
3,1,Duth Knonald
10,6,Lesport Lampie
\.
INSERT INTO researchers VALUES (2, 1, 'Knuth Donald');
INSERT INTO researchers VALUES (10, 6, 'Lamport Leslie');
ROLLBACK;
-- COPY can happen before single row INSERT
BEGIN;
\copy labs from stdin delimiter ','
@ -269,28 +289,21 @@ ORDER BY nodeport, shardid;
SELECT * FROM run_command_on_workers('drop function reject_large_id()')
ORDER BY nodeport;
-- finally, ALTER and copy aren't compatible
-- ALTER TABLE and COPY are compatible if ALTER TABLE precedes COPY
BEGIN;
ALTER TABLE labs ADD COLUMN motto text;
\copy labs from stdin delimiter ','
12,fsociety,lol
\.
COMMIT;
ROLLBACK;
-- but the DDL should correctly roll back
\d labs
-- and if the copy is before the ALTER...
-- but not if COPY precedes ALTER TABLE
BEGIN;
\copy labs from stdin delimiter ','
12,fsociety
\.
ALTER TABLE labs ADD COLUMN motto text;
COMMIT;
-- the DDL fails, but copy persists
\d labs
SELECT * FROM labs WHERE id = 12;
ROLLBACK;
-- multi-shard operations can co-exist with DDL in a transactional way
BEGIN;
@ -930,4 +943,4 @@ DROP TABLE reference_modifying_xacts, hash_modifying_xacts, hash_modifying_xacts
reference_failure_test, numbers_hash_failure_test;
SELECT * FROM run_command_on_workers('DROP USER test_user');
DROP USER test_user;
DROP USER test_user;