diff --git a/src/backend/distributed/commands/multi_copy.c b/src/backend/distributed/commands/multi_copy.c index a0e1f0b65..ba7ff8b8b 100644 --- a/src/backend/distributed/commands/multi_copy.c +++ b/src/backend/distributed/commands/multi_copy.c @@ -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); diff --git a/src/test/regress/expected/multi_insert_select.out b/src/test/regress/expected/multi_insert_select.out index 72962f0a7..123d833d1 100644 --- a/src/test/regress/expected/multi_insert_select.out +++ b/src/test/regress/expected/multi_insert_select.out @@ -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; diff --git a/src/test/regress/expected/multi_modifying_xacts.out b/src/test/regress/expected/multi_modifying_xacts.out index 191e8f948..f4d953c66 100644 --- a/src/test/regress/expected/multi_modifying_xacts.out +++ b/src/test/regress/expected/multi_modifying_xacts.out @@ -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; diff --git a/src/test/regress/sql/multi_modifying_xacts.sql b/src/test/regress/sql/multi_modifying_xacts.sql index 949f8949a..e5d9ddc71 100644 --- a/src/test/regress/sql/multi_modifying_xacts.sql +++ b/src/test/regress/sql/multi_modifying_xacts.sql @@ -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; \ No newline at end of file +DROP USER test_user;