Repository navigation
Ship transaction-free bundles by default - #4
Merged
lemuelroberto merged 4 commits intoSep 30, 2026
Merged
Conversation
cel4postgres 0.0.2 ships its plain bundle without transaction control, so the vendored file can sit inside a transaction the caller owns -- the property fga4postgres's own bundles are about to need. The file is the published release asset, byte for byte: its sha256 matches the release's SHA256SUMS.
Every sql/ script opened and committed its own transaction, so the all-in bundle carried one BEGIN;/COMMIT; pair per script -- forty with the vendored cel4postgres. Embedding it in a migration tool, which runs each migration inside a transaction it owns, therefore failed in the worst way: the first COMMIT; ended the migration's transaction and the rest ran in autocommit, so a failure halfway left half an engine behind. pg_tle had the same problem, which is why pgtle-wrap.sh grepped those lines out. The sources now carry no transaction control and the plain artifacts are what the sources say. The caller picks the boundary: psql -1, a migration's transaction, or CREATE EXTENSION. Each artifact gets a -tx twin with exactly one BEGIN; and one COMMIT; around the whole file, for a bare psql -f that should still be all or nothing. The per-file install loops (initdb, the bench's persistent volume, the CI reinstall) now pass --single-transaction so each file stays atomic as before, and the bench loader already gets that from the simple protocol's implicit transaction. build-release.sh refuses a BEGIN; or COMMIT; line in sql/ or the vendored bundle. scripts/smoke-artifacts.sh, run by CI and by the release, installs each plain artifact between BEGIN and ROLLBACK and asserts nothing survives, which a stray COMMIT; would break; it replaces release-engine-initdb.sh.
The artifact set changed shape: plain files lost their transaction control and -tx twins were added. A consumer pinning 0.0.1 must not receive files that behave differently under the same name.
The sql/ naming section justified plain concatenation by every script opening its own BEGIN;/COMMIT;. That is no longer true, and a contributor following it would reintroduce exactly the lines that stop a bundle being embedded in a caller's transaction. State the new contract and what enforces it, and point the by-hand install and the vendoring decision at cel4postgres 0.0.2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The all-in bundle carried one
BEGIN;/COMMIT;pair per script — 40including the vendored cel4postgres. Embedded in a migration tool
(Kysely, Flyway, Liquibase…), which runs each migration inside its own
transaction, the first
COMMIT;ended that transaction and the restran in autocommit: a failure halfway left half an engine installed.
pgtle-wrap.shalready grepped the lines out forCREATE EXTENSION.What changes
bundle has no transaction control. The file is the published release
asset; sha256
b6de8556…matches itsSHA256SUMS.sql/carries no transaction control. Plain artifacts run inside thecaller's transaction; each gets a
-txtwin with exactly oneBEGIN;and oneCOMMIT;around the whole file.build-release.shrefuses aBEGIN;/COMMIT;line insql/or thevendored bundle.
scripts/smoke-artifacts.sh, run by CI and the release: eachplain artifact installs between
BEGINandROLLBACKand must leaveno
fga/celschema (a strayCOMMIT;fails it), then with--single-transaction; each-txartifact installs with a barepsql -f; engine-only files over the vendored cel. Replacesrelease-engine-initdb.sh.docker/000_install.sh, CI reinstall) use--single-transaction, so each file stays atomic — it matters on thebench's persistent volume.
bench/loader.goalready gets that fromthe simple protocol's implicit transaction (comment updated).
pgtle-wrap.shwraps plain files unchanged and refuses-txinput.docs/INSTALL.md/ README: both shapes,psql -1, and an "Inside amigration tool" section.
CLAUDE.md'ssql/contract updated in itsown commit. Version 0.0.2.
Verified locally
docker compose up -d --waitinstalls through the new initdb loop.go vet ./...,go build ./...,TestLoadAndCheck(bench loader),TestEngineVersion+TestCheckCorpus(149 subtests pass; skips arethe named skip list). Full suite left to CI per CLAUDE.md.
smoke-artifacts.sh: all four artifacts ok. With a top-levelCOMMIT;injected into the plain bundle it fails with "committed onits own"; a
BEGIN;added tosql/makesbuild-release.shrefuse.shellcheck scripts/*.sh docker/*.sh: clean.