cockroachdb / cockroachdb/cockroach

pgwire: persist a list of portals when creating a `SAVEPOINT` in a transaction

Open
#99,170 0 comments 0 reactions 0 assignees View on GitHub
A-pausable-portals C-bug T-sql-queries
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

Ran the following pgwire tests against postgres. From this experiment, it seems that PG behaves like this:

1. When a `SAVEPOINT` is created, keep a list of existing portals (In the following example, `plst0 = {p0, p1}`)
2. When rolling back to this save point, get the current list of portals (e.g. `plst1 = {p1, p2}`)
3. The valid portals now are `plst0 ∩ plst1 = {p1}`

However, notice that after rolling back and re-executing `p1`, the returned row continues from the execution AFTER the savepoint's creation.

```

send
Query {"String": "BEGIN"}
Parse {"Name": "q0", "Query": "SELECT * FROM generate_series(1,20)"}
Bind {"DestinationPortal": "p0", "PreparedStatement": "q0"}
Parse {"Name": "q1", "Query": "SELECT * FROM generate_series(1,20)"}
Bind {"DestinationPortal": "p1", "PreparedStatement": "q1"}
Execute {"Portal": "p1", "MaxRows": 1}
Query {"String": "SAVEPOINT my_savepoint;"}
Execute {"Portal": "p1", "MaxRows": 1}
Execute {"Portal": "p1", "MaxRows": 1}
Parse {"Name": "q2", "Query": "SELECT * FROM generate_series(8,100) LIMIT 5"}
Bind {"DestinationPortal": "p2", "PreparedStatement": "q2"}
Execute {"Portal": "p2", "MaxRows": 1}
Close {"ObjectType": "P", "Name": "p0"}
Query {"String": "ROLLBACK TO SAVEPOINT my_savepoint;"}
Execute {"Portal": "p1", "MaxRows": 1}
Execute {"Portal": "p0", "MaxRows": 1}
Execute {"Portal": "p2", "MaxRows": 1}
Sync
----

until noncrdb_only keepErrMessage
ReadyForQuery
ReadyForQuery
ReadyForQuery
ErrorResponse
ReadyForQuery
----
{"Type":"CommandComplete","CommandTag":"BEGIN"}
{"Type":"ReadyForQuery","TxStatus":"T"}
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"DataRow","Values":[{"text":"1"}]}
{"Type":"PortalSuspended"}
{"Type":"CommandComplete","CommandTag":"SAVEPOINT"}
{"Type":"ReadyForQuery","TxStatus":"T"}
{"Type":"DataRow","Values":[{"text":"2"}]}
{"Type":"PortalSuspended"}
{"Type":"DataRow","Values":[{"text":"3"}]}
{"Type":"PortalSuspended"}
{"Type":"ParseComplete"}
{"Type":"BindComplete"}
{"Type":"DataRow","Values":[{"text":"8"}]}
{"Type":"PortalSuspended"}
{"Type":"CloseComplete"}
{"Type":"CommandComplete","CommandTag":"ROLLBACK"}
{"Type":"ReadyForQuery","TxStatus":"T"}
{"Type":"DataRow","Values":[{"text":"4"}]}
{"Type":"PortalSuspended"}
{"Type":"ErrorResponse","Code":"34000","Message":"portal \"p0\" does not exist"}
{"Type":"ReadyForQuery","TxStatus":"E"}
```

Jira issue: CRDB-25731

Epic CRDB-25183

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.