Repository navigation
Conversation
PostgreSQL refuses every CONCURRENTLY form inside an explicit block, so a script that wraps one in BEGIN ... COMMIT fails at that statement and rolls back. Lint now tracks the block a script opens and reports the operation as concurrent-in-transaction, an error, with how to fix it. statement.TransactionControlOf reads BEGIN, COMMIT, and their variants from the parse tree. The lint report moves to format_version 3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Explicitly disabled REINDEX concurrency incorrectly triggers the new transaction error.
1 open issue
What changed in this PR
Adds script-level transaction tracking to pg-sprite lint so concurrent operations inside explicit transaction blocks produce an error.
Changes:
- Parses transaction controls and emits
concurrent-in-transactionfindings. - Adds unit, renderer, and PostgreSQL integration tests.
- Updates the lint report to version 3, documentation, and demo assertions.
| File | Description |
|---|---|
| pkg/statement/transaction.go | Parses transaction-control effects. |
| pkg/statement/transaction_test.go | Tests transaction-control classification. |
| pkg/lint/transaction_integration_test.go | Checks PostgreSQL refusal of concurrent operations. |
| pkg/lint/lint.go | Tracks blocks and emits the new diagnostic. |
| pkg/lint/lint_test.go | Tests block tracking and report version. |
| internal/cli/lint_text.go | Renders diagnostic explanation and help. |
| internal/cli/lint_test.go | Tests diagnostic text output. |
| docs/postgres-online-ddl-reference.md | Explains the new diagnostic. |
| docs/lint-report.md | Documents version 3 and the new code. |
| docs/cli-output-examples.md | Updates the JSON example version. |
| demo/tour.sh | Expects lint report version 3. |
Review effort: Balanced
REINDEX (CONCURRENTLY false) and (CONCURRENTLY 0) rebuild with the blocking lock, which PostgreSQL runs inside a transaction block, but the parser counted any CONCURRENTLY option as concurrent. Lint flagged them as concurrent-in-transaction, and the concurrent rewrite appended a second CONCURRENTLY option the server refuses as conflicting. The option's value is now read as the server's defGetBoolean reads it, through one helper that replaces the duplicate in ops.go, and the rewrite replaces a disabled option instead of adding one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
aparajon
marked this pull request as ready for review
October 17, 2026 16:13
aparajon
requested review from
JashLal,
Kiran01bm,
eeSeeGee,
jayjanssen,
jemiahw and
morgo
as code owners
October 17, 2026 16:13
…t-in-transaction # Conflicts: # pkg/lint/lint.go # pkg/lint/lint_test.go # pkg/statement/rewrite.go
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
PostgreSQL refuses every
CONCURRENTLYform inside an explicit transaction block. Many schema change tools wrap each file inBEGIN … COMMIT, so a file that adds an index the safe way still fails at that statement and rolls back. Lint flaggedBEGINandCOMMITas unrecognized, but said nothing about the statement that actually breaks.What
CONCURRENTLYoperation inside it asconcurrent-in-transaction, an error. That coversCREATE INDEX,DROP INDEX,REINDEX, andDETACH PARTITION.COMMIT AND CHAINthat opens the next block at once, keeps the script inside its block.COMMIT,ROLLBACK, andPREPARE TRANSACTIONclose it.statement.TransactionControlOfreads those statements from the parse tree, so lint never matches on text.format_version3, since a new code is a contract change.docs/lint-report.mdand the reference doc describe the code.active_sql_transaction.New text output
Before this change the same statement printed no finding; only
BEGINandCOMMITwere flagged, as unrecognized operations.🤖 Generated with Claude Code