Repository navigation
Description
Origin
smugglr, bp 019fb06d-6e38 / signal 019fb06d-fa4c (2026-07-30): S6.2.1's MUST fixes execution ORDER for non-atomic batches but says nothing about whether the statements share a CONNECTION. A server that runs them one at a time, in array order, each on a fresh pooled connection, conforms to every word of 6.2.1. The consumer pattern at risk is statement-0-as-precondition: connection-scoped-but-not-transaction-scoped state that survives autocommit and dies only on a connection swap.
The two unconfounded cases from the report:
PRAGMA foreign_keys = ONas statement 0. Survives autocommit (proven incidentally by smugglr's FK test); on a pooled server it reverts to SQLite's default OFF mid-batch and FK enforcement silently vanishes. No error in either direction.CREATE TEMP TABLEas statement 0, read by later statements. Becomes "no such table" on a swap.
The ask: is session continuity across the statements of a non-atomic batch guaranteed, denied, or undefined? Silence is the only answer a consumer cannot build on.
Ruling: not guaranteed, and the spec must say so
Session continuity across the statements of a non-atomic batch is NOT guaranteed. The spec should state the non-guarantee normatively rather than leave it to silence. Grounds:
- The D1 reference server is the existence proof. Its non-atomic path is a loop of independent
db.prepare().all()calls (examples/cloudflare-worker-to-d1/src/index.ts:99-108). Each statement is its own round trip to D1, and the D1 binding offers no session pinning. A continuity guarantee would make a reference implementation non-conforming on day one -- the same trap class the statementIndex MUST scoping (spec: define non-atomic batch failure behavior #9) was designed around. - Stateless, edge-friendly is the spec's identity. Many target backends (D1, HTTP-based SQL services) have no connection concept the server could pin even if it wanted to. Guaranteeing affinity excludes exactly the deployment class this spec exists for.
- Transport, not policy (S10.1). A session is the beginning of server-side state between statements; granting one changes what the protocol is.
"Undefined" is rejected too: undefined is silence with a label. The buildable form is an explicit client-side MUST NOT plus a server-side MAY.
Proposed spec text (S6.2.1 addition)
http-sql defines no session. Servers MAY execute each statement of a non-atomic batch on a different database connection or session. Clients MUST NOT rely on connection-scoped state -- temporary tables, session-scoped PRAGMAs or variables, deferred-constraint modes -- established by one statement of a non-atomic batch being visible to any later statement. Each statement of a non-atomic batch MUST be self-contained.
Non-normative note to accompany it:
An atomic batch executes inside a single transaction (section 4.2), and a transaction is bound to a single connection in every known engine, so connection-scoped state established inside an atomic batch survives for the batch's duration in practice. That is a consequence of the transaction obligation, not a session grant: http-sql still defines no session semantics. A client that needs cross-statement session state should send
atomic: trueor restructure its statements to be self-contained.
Client conformance (S10.2) gains: treat each statement of a non-atomic batch as self-contained (section 6.2.1).
Conformance
No black-box case can verify the absence of a guarantee, and under this ruling a connection-pooling server that passes B-3/B-4/B-5 is conforming, not a gap. conformance/README.md gets a prose note: the B cases do not probe session continuity, and neither servers nor clients may infer a continuity guarantee from a passing run.
Versioning
Additive clarification of previously-undefined behavior; rides the next minor wave alongside #25.
Activity
ssilvius commentedon Aug 29, 2026
Closed by operator ruling (2026-08-29): this is not a transport-spec question. Whether statements of a batch share a connection is the concern of a client that chooses to rely on connection-scoped state, and of the server it talks to, not of the wire format. The proposed MUST NOT would also have specialized a protocol meant for any SQL database to the limits of its SQLite-backed reference servers. Not written into the spec.