# Prepare a statement that will start an explicit transaction.
send
Parse {"Name": "begin_stmt", "Query": "BEGIN"}
Sync
----

# At this point, TxStatus is still "idle" since the BEGIN was not
# executed yet.
until
ReadyForQuery
----
{"Type":"ParseComplete"}
{"Type":"ReadyForQuery","TxStatus":"I"}

# Executing should start the explicit transaction.
send
Bind {"DestinationPortal": "p1", "PreparedStatement": "begin_stmt"}
Execute {"Portal": "p1"}
Sync
----

until
ReadyForQuery
----
{"Type":"BindComplete"}
{"Type":"CommandComplete","CommandTag":"BEGIN"}
{"Type":"ReadyForQuery","TxStatus":"T"}

# Preparing another BEGIN is allowed.
send
Parse {"Name": "another_begin_stmt", "Query": "BEGIN"}
Sync
----

until
ReadyForQuery
----
{"Type":"ParseComplete"}
{"Type":"ReadyForQuery","TxStatus":"T"}

# But we can't execute the other BEGIN.
send
Bind {"DestinationPortal": "p2", "PreparedStatement": "another_begin_stmt"}
Execute {"Portal": "p2"}
Sync
----

# Postgres allows BEGIN inside an explicit transaction, but shows a warning.
until noncrdb_only
ReadyForQuery
----
{"Type":"BindComplete"}
{"Severity":"WARNING","SeverityUnlocalized":"WARNING","Code":"25001","Message":"there is already a transaction in progress","Detail":"","Hint":"","Position":0,"InternalPosition":0,"InternalQuery":"","Where":"","SchemaName":"","TableName":"","ColumnName":"","DataTypeName":"","ConstraintName":"","File":"xact.c","Line":0,"Routine":"BeginTransactionBlock","UnknownFields":null}
{"Type":"CommandComplete","CommandTag":"BEGIN"}
{"Type":"ReadyForQuery","TxStatus":"T"}

until crdb_only
ErrorResponse
ReadyForQuery
----
{"Type":"BindComplete"}
{"Type":"ErrorResponse","Code":"25001"}
{"Type":"ReadyForQuery","TxStatus":"E"}

send
Parse {"Name": "rollback_stmt", "Query": "ROLLBACK"}
Bind {"DestinationPortal": "p3", "PreparedStatement": "rollback_stmt"}
Execute {"Portal": "p3"}
Sync
----

until
ReadyForQuery
----
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"CommandComplete","CommandTag":"ROLLBACK"}
{"Type":"ReadyForQuery","TxStatus":"I"}

# Verify that READ ONLY works on a prepared BEGIN statement.

send
Parse {"Name": "begin_read_only_stmt", "Query": "BEGIN READ ONLY"}
Bind {"DestinationPortal": "p4", "PreparedStatement": "begin_read_only_stmt"}
Execute {"Portal": "p4"}
Sync
----

until
ReadyForQuery
----
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"CommandComplete","CommandTag":"BEGIN"}
{"Type":"ReadyForQuery","TxStatus":"T"}

send
Query {"String": "SHOW transaction_read_only"}
Query {"String": "COMMIT"}
----

until
ReadyForQuery
ReadyForQuery
----
{"Type":"RowDescription","Fields":[{"Name":"transaction_read_only","TableOID":0,"TableAttributeNumber":0,"DataTypeOID":25,"DataTypeSize":-1,"TypeModifier":-1,"Format":0}]}
{"Type":"DataRow","Values":[{"text":"on"}]}
{"Type":"CommandComplete","CommandTag":"SHOW"}
{"Type":"ReadyForQuery","TxStatus":"T"}
{"Type":"CommandComplete","CommandTag":"COMMIT"}
{"Type":"ReadyForQuery","TxStatus":"I"}


# Verify that READ ONLY AS OF SYSTEM TIME works on a prepared BEGIN statement.

let $orig_timestamp
Query {"String": "SELECT now()::TIMESTAMPTZ"}
----

send crdb_only
Parse {"Name": "begin_read_only_aost_stmt", "Query": "BEGIN READ ONLY AS OF SYSTEM TIME '-10s'"}
Bind {"DestinationPortal": "p5", "PreparedStatement": "begin_read_only_aost_stmt"}
Execute {"Portal": "p5"}
Sync
----

until crdb_only
ReadyForQuery
----
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"CommandComplete","CommandTag":"BEGIN"}
{"Type":"ReadyForQuery","TxStatus":"T"}

send crdb_only
Query {"String": "SHOW transaction_read_only"}
Query {"String": "SELECT ('$orig_timestamp'::TIMESTAMPTZ - '9 seconds'::INTERVAL) > now()"}
Query {"String": "COMMIT"}
----

until ignore=RowDescription crdb_only
ReadyForQuery
ReadyForQuery
ReadyForQuery
----
{"Type":"DataRow","Values":[{"text":"on"}]}
{"Type":"CommandComplete","CommandTag":"SHOW"}
{"Type":"ReadyForQuery","TxStatus":"T"}
{"Type":"DataRow","Values":[{"text":"t"}]}
{"Type":"CommandComplete","CommandTag":"SELECT 1"}
{"Type":"ReadyForQuery","TxStatus":"T"}
{"Type":"CommandComplete","CommandTag":"COMMIT"}
{"Type":"ReadyForQuery","TxStatus":"I"}
