Summary
SetSerializableTransactionSnapshot (crates/backend/storage/lmgr/predicate/src/engine.rs:648-660) handles establishing a SERIALIZABLE transaction's snapshot when a snapshot is being imported (SET TRANSACTION SNAPSHOT '...') rather than freshly taken. After checking the parallel-worker case and the READ ONLY DEFERRABLE incompatibility, the actual import path is a hard panic:
panic!("predicate.c SetSerializableTransactionSnapshot: snapshot import into a serializable transaction is not ported");
The comment directly above the function confirms this is a known, deliberate gap:
// SetSerializableTransactionSnapshot (predicate.c): in a parallel worker the
// leader's SERIALIZABLEXACT arrives via AttachSerializableXact, so there is
// nothing to do here. The snapshot-import arm (SET TRANSACTION SNAPSHOT,
// GetSerializableTransactionSnapshotInt's sourcevxid path) is unported.
Why this matters
SET TRANSACTION SNAPSHOT combined with SERIALIZABLE is valid, standard PostgreSQL syntax with real use cases — most notably tools that need multiple sessions/connections to observe an identical consistent view of the database (e.g. custom parallel dump/export tooling, or application code doing manual snapshot-sharing across connections for consistent reporting). PostgreSQL's own pg_dump/pg_restore --jobs machinery relies on the closely related pg_export_snapshot()/import flow, though typically at REPEATABLE READ rather than SERIALIZABLE — but nothing in SQL prevents a user from requesting SET TRANSACTION ISOLATION LEVEL SERIALIZABLE, SNAPSHOT '...' and hitting this panic.
This crashes the backend rather than returning an error, which is a correctness/availability concern for any code path that reaches it.
Reproduction sketch
-- Session A
BEGIN ISOLATION LEVEL SERIALIZABLE;
SELECT pg_export_snapshot(); -- returns e.g. '00000003-00000001-1'
-- Session B
BEGIN ISOLATION LEVEL SERIALIZABLE;
SET TRANSACTION SNAPSHOT '00000003-00000001-1'; -- panics here
Suggested scope for a fix
Port GetSerializableTransactionSnapshotInt's sourcevxid/snapshot-import arm from predicate.c, wiring SetSerializableTransactionSnapshot to actually attach to the imported snapshot's SERIALIZABLEXACT state (including whatever conflict/RW-tracking bookkeeping the imported transaction needs to participate correctly in SSI) instead of panicking. At minimum, until ported, consider returning a normal ERRCODE_FEATURE_NOT_SUPPORTED error instead of a hard panic, consistent with how the adjacent READ ONLY DEFERRABLE case in the same function already does (engine.rs:658-660).
Environment / where found
Found via static source review of a fresh clone of this repo (part of a broader MVCC/procarray/SSI review — the core SSI dangerous-structure detection and write-skew handling were found to be genuinely and faithfully ported and tested under real concurrent threads). Have not attempted to build/run pgrust myself to runtime-confirm the panic; based on reading crates/backend/storage/lmgr/predicate/src/engine.rs directly.
Related: #61 (a separate unported pg_serial SLRU/SERIALIZABLEXACT-slot-exhaustion panic in the same file).
Summary
SetSerializableTransactionSnapshot(crates/backend/storage/lmgr/predicate/src/engine.rs:648-660) handles establishing a SERIALIZABLE transaction's snapshot when a snapshot is being imported (SET TRANSACTION SNAPSHOT '...') rather than freshly taken. After checking the parallel-worker case and the READ ONLY DEFERRABLE incompatibility, the actual import path is a hard panic:The comment directly above the function confirms this is a known, deliberate gap:
Why this matters
SET TRANSACTION SNAPSHOTcombined withSERIALIZABLEis valid, standard PostgreSQL syntax with real use cases — most notably tools that need multiple sessions/connections to observe an identical consistent view of the database (e.g. custom parallel dump/export tooling, or application code doing manual snapshot-sharing across connections for consistent reporting). PostgreSQL's ownpg_dump/pg_restore--jobsmachinery relies on the closely relatedpg_export_snapshot()/import flow, though typically at REPEATABLE READ rather than SERIALIZABLE — but nothing in SQL prevents a user from requestingSET TRANSACTION ISOLATION LEVEL SERIALIZABLE, SNAPSHOT '...'and hitting this panic.This crashes the backend rather than returning an error, which is a correctness/availability concern for any code path that reaches it.
Reproduction sketch
Suggested scope for a fix
Port
GetSerializableTransactionSnapshotInt'ssourcevxid/snapshot-import arm frompredicate.c, wiringSetSerializableTransactionSnapshotto actually attach to the imported snapshot'sSERIALIZABLEXACTstate (including whatever conflict/RW-tracking bookkeeping the imported transaction needs to participate correctly in SSI) instead of panicking. At minimum, until ported, consider returning a normalERRCODE_FEATURE_NOT_SUPPORTEDerror instead of a hard panic, consistent with how the adjacent READ ONLY DEFERRABLE case in the same function already does (engine.rs:658-660).Environment / where found
Found via static source review of a fresh clone of this repo (part of a broader MVCC/procarray/SSI review — the core SSI dangerous-structure detection and write-skew handling were found to be genuinely and faithfully ported and tested under real concurrent threads). Have not attempted to build/run pgrust myself to runtime-confirm the panic; based on reading
crates/backend/storage/lmgr/predicate/src/engine.rsdirectly.Related: #61 (a separate unported
pg_serialSLRU/SERIALIZABLEXACT-slot-exhaustion panic in the same file).