cockroachdb / cockroachdb/cockroach
pgwire: persist a list of portals when creating a `SAVEPOINT` in a transaction
- 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
Assessment
This issue has not been assessed yet.