# LogicTest: default parallel-stmts distsql

# Transaction involving schema changes.
statement ok
BEGIN TRANSACTION

statement ok
CREATE TABLE kv (
  k CHAR PRIMARY KEY,
  v CHAR
)

statement ok
INSERT INTO kv (k,v) VALUES ('a', 'b')

query TT
SELECT * FROM kv
----
a b

statement ok
COMMIT TRANSACTION

# A transaction to update kv.

statement ok
BEGIN TRANSACTION

statement ok
UPDATE kv SET v = 'c' WHERE k in ('a')

query TT
SELECT * FROM kv
----
a c

statement ok
COMMIT TRANSACTION

query TT
SELECT * FROM kv
----
a c

# Rollback a transaction before committing.

statement ok
BEGIN TRANSACTION

statement ok
UPDATE kv SET v = 'b' WHERE k in ('a')

query TT
SELECT * FROM kv
----
a b

statement ok
ROLLBACK TRANSACTION

query TT
SELECT * FROM kv
----
a c

# Statement execution should not depend on request boundaries.

statement ok
BEGIN TRANSACTION; UPDATE kv SET v = 'b' WHERE k in ('a')

query TT
SELECT * FROM kv
----
a b

query TT
SELECT * FROM kv; COMMIT; BEGIN; UPDATE kv SET v = 'd' WHERE k in ('a')
----
a b

query TT
SELECT * FROM kv; UPDATE kv SET v = 'c' WHERE k in ('a'); COMMIT
----
a d

query TT
SELECT * FROM kv
----
a c

# Abort transaction with a syntax error, and ignore statements until the end of the transaction block

statement ok
BEGIN

query error syntax error at or near ","
SELECT COUNT(*, 1) FROM kv

statement error pgcode 25P02 current transaction is aborted, commands ignored until end of transaction block
UPDATE kv SET v = 'b' WHERE k in ('a')

statement ok
ROLLBACK

query TT
SELECT * FROM kv
----
a c

# Abort transaction with a problematic statement, and ignore statements until
# the end of the transaction block (a COMMIT/ROLLBACK statement as the first
# statement in a batch).

statement ok
BEGIN

statement error duplicate key value \(k\)=\('a'\) violates unique constraint "primary"
INSERT INTO kv VALUES('unique_key', 'some value');
INSERT INTO kv VALUES('a', 'c');
INSERT INTO kv VALUES('unique_key2', 'some value');
COMMIT

# Txn is still aborted.
statement error current transaction is aborted, commands ignored until end of transaction block
UPDATE kv SET v = 'b' WHERE k in ('a')

# Txn is still aborted.
statement error current transaction is aborted, commands ignored until end of transaction block
UPDATE kv SET v = 'b' WHERE k in ('a')

# Now the transaction will be ended. After that, statements execute.
statement ok
COMMIT;
INSERT INTO kv VALUES('x', 'y')

query TT rowsort
SELECT * FROM kv
----
a c
x y

# BEGIN in the middle of a transaction is an error.

statement ok
BEGIN TRANSACTION

statement ok
UPDATE kv SET v = 'b' WHERE k in ('a')

statement error there is already a transaction in progress
BEGIN TRANSACTION

statement error current transaction is aborted, commands ignored until end of transaction block
SELECT * FROM kv
----

statement ok
ROLLBACK TRANSACTION

# An empty transaction is allowed.

statement ok
BEGIN; COMMIT

# END is same as commit
statement ok
BEGIN; END

# COMMIT/ROLLBACK without a transaction are errors.

statement error there is no transaction in progress
COMMIT TRANSACTION

statement error there is no transaction in progress
ROLLBACK TRANSACTION

# Set isolation level without a transaction is an error.

statement error there is no transaction in progress
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

statement ok
BEGIN TRANSACTION ISOLATION LEVEL SNAPSHOT; COMMIT

statement ok
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; COMMIT

statement ok
BEGIN TRANSACTION; SET TRANSACTION ISOLATION LEVEL SNAPSHOT; COMMIT

statement ok
BEGIN TRANSACTION; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; COMMIT

# It is an error to change the isolation level of a running transaction.

statement ok
BEGIN TRANSACTION

statement ok
UPDATE kv SET v = 'b' WHERE k in ('a')

statement error cannot change the isolation level of a running transaction
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

statement ok
ROLLBACK

statement ok
BEGIN TRANSACTION

statement ok
UPDATE kv SET v = 'b' WHERE k in ('a')

statement error cannot change the isolation level of a running transaction
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

statement ok
ROLLBACK

# Transactions default to serializable.

statement ok
BEGIN TRANSACTION

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SERIALIZABLE

statement ok
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

statement ok
COMMIT

# We can explicitly start a transaction in snapshot isolation.

statement ok
BEGIN TRANSACTION ISOLATION LEVEL SNAPSHOT

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

statement ok
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SERIALIZABLE

statement ok
COMMIT

# user priority

statement error there is no transaction in progress
SET TRANSACTION PRIORITY LOW

statement ok
BEGIN TRANSACTION PRIORITY LOW; COMMIT

statement ok
BEGIN TRANSACTION PRIORITY NORMAL; COMMIT

statement ok
BEGIN TRANSACTION PRIORITY HIGH; COMMIT

statement ok
BEGIN TRANSACTION; SET TRANSACTION PRIORITY LOW; COMMIT

statement ok
BEGIN TRANSACTION; SET TRANSACTION PRIORITY NORMAL; COMMIT

statement ok
BEGIN TRANSACTION; SET TRANSACTION PRIORITY HIGH; COMMIT

# It is an error to change the user priority of a running transaction.

statement ok
BEGIN TRANSACTION

statement ok
UPDATE kv SET v = 'b' WHERE k in ('a')

statement error cannot change the user priority of a running transaction
SET TRANSACTION PRIORITY NORMAL

statement ok
ROLLBACK

statement ok
BEGIN TRANSACTION

statement ok
UPDATE kv SET v = 'b' WHERE k in ('a')

statement error cannot change the user priority of a running transaction
SET TRANSACTION PRIORITY HIGH

statement ok
ROLLBACK

# User priority default to normal

statement ok
BEGIN TRANSACTION

query T
SHOW TRANSACTION PRIORITY
----
NORMAL

statement ok
SET TRANSACTION PRIORITY HIGH

query T
SHOW TRANSACTION PRIORITY
----
HIGH

statement ok
COMMIT

# We can explicitly start a transaction in low user priority.

statement ok
BEGIN TRANSACTION PRIORITY LOW

query T
SHOW TRANSACTION PRIORITY
----
LOW

statement ok
SET TRANSACTION PRIORITY NORMAL

query T
SHOW TRANSACTION PRIORITY
----
NORMAL

statement ok
COMMIT

# We can specify both isolation level and user priority.

statement ok
BEGIN TRANSACTION ISOLATION LEVEL SNAPSHOT, PRIORITY LOW; COMMIT

statement ok
BEGIN TRANSACTION PRIORITY LOW, ISOLATION LEVEL SNAPSHOT; COMMIT

# We can explicitly start a transaction in snapshot isolation level and low user priority.

statement ok
BEGIN TRANSACTION ISOLATION LEVEL SNAPSHOT, PRIORITY LOW

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

query T
SHOW TRANSACTION PRIORITY
----
LOW

statement ok
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, PRIORITY HIGH

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SERIALIZABLE

query T
SHOW TRANSACTION PRIORITY
----
HIGH

statement ok
SET TRANSACTION PRIORITY NORMAL, ISOLATION LEVEL SNAPSHOT

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

query T
SHOW TRANSACTION PRIORITY
----
NORMAL

statement ok
COMMIT

statement ok
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SNAPSHOT

query T
SHOW DEFAULT_TRANSACTION_ISOLATION
----
SNAPSHOT

# SHOW without a transaction should create an auto-transaction with the default level
query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

statement ok
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE

query T
SHOW DEFAULT_TRANSACTION_ISOLATION
----
SERIALIZABLE

statement ok
SET DEFAULT_TRANSACTION_ISOLATION TO 'SNAPSHOT'

query T
SHOW DEFAULT_TRANSACTION_ISOLATION
----
SNAPSHOT

# Without the isolation level specified, BEGIN should use the default

statement ok
BEGIN

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

statement ok
COMMIT

# setting user priority without isolation level should not change isolation level.

statement ok
BEGIN TRANSACTION

statement ok
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

statement ok
SET TRANSACTION PRIORITY HIGH

query T
SHOW TRANSACTION ISOLATION LEVEL
----
SNAPSHOT

statement ok
COMMIT

# SHOW TRANSACTION STATUS

query T
SHOW TRANSACTION STATUS
----
NoTxn

statement ok
BEGIN

query T
SHOW TRANSACTION STATUS
----
Open

statement ok
COMMIT

query T
SHOW TRANSACTION STATUS
----
NoTxn

statement ok
BEGIN

query error pq: database "t" does not exist
SELECT a FROM t.b

query T
SHOW TRANSACTION STATUS
----
Aborted

statement ok
ROLLBACK

query T
SHOW TRANSACTION STATUS
----
NoTxn

# CommitWait state
statement ok
BEGIN;SAVEPOINT cockroach_restart

statement ok
RELEASE SAVEPOINT cockroach_restart

query T
SHOW TRANSACTION STATUS
----
CommitWait

statement ok
COMMIT

# RestartWait state
statement ok
BEGIN TRANSACTION; SAVEPOINT cockroach_restart

query error restart transaction: HandledRetryableTxnError: forced by crdb_internal.force_retry()
SELECT CRDB_INTERNAL.FORCE_RETRY('1s':::INTERVAL)

query T
SHOW TRANSACTION STATUS
----
RestartWait

statement ok
ROLLBACK TO SAVEPOINT cockroach_restart

query T
SHOW TRANSACTION STATUS
----
Open

statement ok
COMMIT

# General savepoints
statement ok
BEGIN TRANSACTION

statement error SAVEPOINT not supported except for COCKROACH_RESTART
SAVEPOINT other

statement ok
ROLLBACK

statement ok
BEGIN TRANSACTION

statement error SAVEPOINT not supported except for COCKROACH_RESTART
RELEASE SAVEPOINT other

statement ok
ROLLBACK

statement ok
BEGIN TRANSACTION

statement error SAVEPOINT not supported except for COCKROACH_RESTART
ROLLBACK TO SAVEPOINT other

statement ok
ROLLBACK

# Savepoint must be first statement in a transaction.
statement ok
BEGIN TRANSACTION; UPSERT INTO kv VALUES('savepoint', 'true')

statement error SAVEPOINT COCKROACH_RESTART needs to be the first statement in a transaction
SAVEPOINT cockroach_restart

statement ok
ROLLBACK

# Can rollback to a savepoint if no statements have been executed.
statement ok
BEGIN TRANSACTION; SAVEPOINT cockroach_restart

statement ok
ROLLBACK TO SAVEPOINT cockroach_restart

# Can do it twice in a row.
statement ok
ROLLBACK TO SAVEPOINT cockroach_restart

# Can rollback after a transactional write, even if not in a retryable state.
statement ok
UPSERT INTO kv VALUES('savepoint', 'true')

statement ok
ROLLBACK TO SAVEPOINT cockroach_restart

statement ok
COMMIT

# Because we rolled back, the 'savepoint' insert will not have been committed.
query I
SELECT COUNT(*) FROM kv WHERE k = 'savepoint'
----
0

# Test READ ONLY/WRITE syntax.

statement ok
BEGIN

statement error read mode specified multiple times
SET TRANSACTION READ ONLY, READ WRITE

statement ok
ROLLBACK

statement ok
BEGIN READ WRITE; COMMIT

statement error read only not supported
BEGIN READ ONLY

statement error read mode specified multiple times
BEGIN READ WRITE, READ ONLY

statement error user priority specified multiple times
BEGIN PRIORITY LOW, PRIORITY HIGH

statement error isolation level specified multiple times
BEGIN ISOLATION LEVEL SERIALIZABLE, ISOLATION LEVEL SERIALIZABLE
