Skip to content

fix(ast): separate ALTER TABLE actions with commas in SQL() [W5-02b] - #907

Merged
ajitpratap0 merged 4 commits into
mainfrom
fix/w5-02b-alter-table-sql-commas
Oct 31, 2026
Merged

ajitpratap0 merged 4 commits into
mainfrom
fix/w5-02b-alter-table-sql-commas

Conversation

@ajitpratap0

Copy link
Copy Markdown
Owner

Summary

Correctness fix W5-02b from the 2026-11 performance audit. The FMT-1 verifier found it while routing statements through SQL(). Codex implemented it; Opus reviewed it and ran the full gate.

AlterTableStatement.SQL() separated multiple actions with spaces only, for example ALTER TABLE t ADD COLUMN a INT DROP COLUMN b, so its output re-parsed as different SQL or failed to parse. It now writes , between actions. That matches the formatter's compact visitor output: ALTER TABLE t ADD COLUMN a INT, DROP COLUMN b. Single-action statements are unchanged.

This PR is ready for review, not a draft, because it is a bug fix independent of the perf gate. Once it lands, AlterTable can join the compact SQL() fast path in #904 in a follow-up.

Test Plan

  • New tests in pkg/sql/ast/alter_table_sql_test.go:
    • reproduce the missing commas in all 11 parser dialects;
    • cover mixed and single actions.
  • Differential checks require SQL() to equal the compact formatter output and to round-trip through a re-parse:
    • 152 ALTER TABLE statements from testdata/realworld/* and testdata/corpus/*;
    • 1,083 accepted input/dialect combinations from the parser tests.
  • Gate, run outside the Codex sandbox:
Check Result
go run honnef.co/go/tools/cmd/staticcheck@latest ./pkg/sql/ast/... ✅
task check ✅
task test:cbinding ✅
go test -count=1 ./pkg/compatibility/... ✅

Breaking Changes

None to the API. SQL() output for multi-action ALTER TABLE changes from invalid spacing to comma-separated actions, as recorded in the CHANGELOG under Fixed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2

AlterTableStatement.SQL() wrote multiple actions separated only by spaces
("ALTER TABLE t ADD COLUMN a INT DROP COLUMN b"), so the output re-parsed
differently or not at all. It now writes ", " between actions, matching
the compact formatter's visitor renderer. Found by the audit's FMT-1
verifier, which keeps AlterTable off the compact SQL() fast path until
this lands.

Tests reproduce the bug in all 11 parser dialects; differential checks
compare SQL() with the compact formatter output and a re-parse round trip
for 152 ALTER TABLE statements from the real-world corpora and 1,083
accepted parser-test input/dialect combinations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DnbRnTFErhoMJdAjVEeCg2
@vercel

vercel Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
gosqlx-website Ignored Ignored Preview Oct 31, 2026 8:46pm UTC

@github-actions github-actions Bot added documentation Improvements or additions to documentation ast AST node changes labels Oct 31, 2026
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Claude finished @ajitpratap0's task in 22s —— View job


Review of PR #907: comma-separated ALTER TABLE actions in SQL()

The fix is correct, minimal, and safe to merge. I have a few notes on the tests and the PR description. I read the diff but did not run the tests.

The change (pkg/sql/ast/sql.go:1676)

  • The i > 0 check writes "," before the existing " ". That gives a, b and leaves a single action and an empty action list unchanged.
  • The action := action copy is kept, so there is no behavior change beyond the separator.
  • The CHANGELOG entry is under [Unreleased] → Fixed, as CLAUDE.md requires.

Test coverage: worth a closer look

  1. The tests that exercise the changed code are in TestAlterTableSQLSeparators.
    • Only that test builds the legacy AlterTableStatement by hand, which is the node this PR changes.
    • The parser produces AlterStatement (the file's own comment says so). So TestAlterTableSQLDialectActions, the corpus test and the parser-inputs test check AlterStatement.SQL(), not the line that changed.
    • Those three tests are still good guards for the follow-up fast-path work, but the PR text overstates them. "Reproduce the missing commas in all 11 dialects" and "152 + 1,083 differential checks" don't show that this fix was needed. I'd reword the summary, or confirm that AlterStatement.SQL() already handled commas before this PR.
  2. The dialect loop in TestAlterTableSQLSeparators multiplies cases without adding coverage. SQL() doesn't depend on dialect, so the want assertion repeats 11 times. Only the round-trip and visitor comparison use the dialect. That is harmless, but you could assert SQL() once and loop over dialects only for checkAlterSQL.
  3. Round-trip can't run for hand-built nodes with unknown dialect rules. The roundtrip flag is len(actions) > 0. If a dialect rejects ADD COLUMN a INT, DROP COLUMN b, the test fails on a parse error rather than a SQL() bug. Oracle and SQL Server use different ADD syntax, so confirm that CI is green across all 11 dialects.
  4. Robustness of TestAlterTableSQLParserInputs.
    • It scans Go string literals from the parser tests for ALTER and TABLE, then runs t.Run for each accepted input across 11 dialects. That makes subtest names long and the run slower (about 1,000 parses).
    • count is incremented inside the closure passed to goast.Inspect, not inside the subtest, so it is fine.
    • The count == 0 guard is good.
    • Because the test is coupled to the parser test files' contents, a refactor of those tests (for example, moving to testdata files) could silently lower coverage. Consider logging a minimum threshold, such as count > 100.
  5. The benchmark is fine, but nothing asserts on it. It is optional.

Nits

  • The //nolint:staticcheck comments are appropriate given that the node is deprecated.
  • The test file is about 240 lines for a 3-line fix. That is acceptable for the differential value, but it duplicates some of what the formatter tests probably cover.

Security / performance: nothing to flag. The change adds one extra WriteString per additional action to a pooled buffer.

Verdict: approve with the description and test-scoping notes above. They are non-blocking.
· branch fix/w5-02b-alter-table-sql-commas

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Claude finished @ajitpratap0's task in 14s —— View job


Review of PR #907: comma-separated ALTER TABLE actions in SQL()

I read the diff against origin/main but did not run the tests.

The fix is correct and minimal. In pkg/sql/ast/sql.go:1676, AlterTableStatement.SQL() now writes , before the existing space for every action after the first. Single-action and empty-action statements are unchanged. The CHANGELOG entry is under [Unreleased] → Fixed. I found no security or performance concerns: the change adds one WriteString per extra action to a pooled buffer.

Test scoping (non-blocking)

  • Only TestAlterTableSQLSeparators exercises the changed line. It builds the legacy AlterTableStatement by hand. The other three tests (dialect actions, corpus, parser inputs) type-assert on *ast.AlterStatement, which is what the parser produces. They don't cover this fix. They are still useful guards for the follow-up fast-path work.
  • The PR description overstates the evidence. The "11 dialects" and "152 + 1,083 differential checks" claims don't show this bug. I'd reword it, or say that AlterStatement.SQL() already handled commas.
  • The dialect loop in TestAlterTableSQLSeparators repeats the SQL() assertion 11 times. SQL() doesn't depend on dialect. You could assert it once and loop over dialects only for the round-trip check.
  • TestAlterTableSQLParserInputs depends on the parser tests' contents. It scans Go string literals in those test files. A refactor, such as moving the inputs to testdata, could silently lower coverage. The count == 0 guard only catches total loss, so a minimum threshold (for example count > 100) would help.
  • Round-trip failures on dialect-specific ADD syntax would show up as parse errors, not SQL() bugs. That would be most likely on Oracle and SQL Server. Please confirm CI is green across all dialects.

Verdict

Approve from my side. The code change is good, and the notes above are about the tests and the PR text.
· branch fix/w5-02b-alter-table-sql-commas

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Claude finished @ajitpratap0's task in 13s —— View job


Review of PR #907: comma-separated ALTER TABLE actions in SQL()

I read the diff against origin/main. I did not run the tests.

The fix is correct and minimal.

  • In pkg/sql/ast/sql.go:1676, AlterTableStatement.SQL() now writes , before the existing space for every action after the first.
  • Single-action and empty-action statements are unchanged.
  • The CHANGELOG entry is under [Unreleased] → Fixed, as CLAUDE.md requires.
  • I found no security or performance concerns. The change adds one WriteString per extra action to a pooled buffer.

Non-blocking notes

These repeat the earlier reviews on this PR. Nothing in the diff has changed them.

  1. Only TestAlterTableSQLSeparators exercises the changed line. It builds the legacy AlterTableStatement by hand. The parser produces AlterStatement, so the dialect, corpus and parser-input tests don't cover this fix. They are still useful guards for the compact fast-path follow-up.
  2. The PR description overstates the evidence. The "11 dialects" and "152 + 1,083 differential checks" claims don't show this bug. Either reword it or say that AlterStatement.SQL() already handled commas.
  3. The dialect loop in TestAlterTableSQLSeparators repeats the same SQL() assertion 11 times, because SQL() doesn't depend on dialect. Assert it once and loop over dialects only for the round-trip check.
  4. TestAlterTableSQLParserInputs depends on the parser tests' contents. It scans Go string literals in those files, so a refactor could silently lower coverage. A minimum-count guard such as count > 100 would catch that. The current count == 0 guard only catches total loss.
  5. Dialect-specific ADD syntax (Oracle, SQL Server) could fail the round-trip with parse errors that aren't SQL() bugs. Please confirm CI is green across all dialects.

Verdict

Approve from my side. The code change is good, and the notes above are about the tests and the PR text.
· branch fix/w5-02b-alter-table-sql-commas

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Claude finished @ajitpratap0's task in 13s —— View job


Review of PR #907: comma-separated ALTER TABLE actions in SQL()

I read the diff against origin/main. I did not run the tests.

The fix is correct and minimal.

  • In pkg/sql/ast/sql.go:1676, AlterTableStatement.SQL() now writes , before the existing space for every action after the first.
  • Single-action and empty-action statements are unchanged.
  • The CHANGELOG entry is under [Unreleased] → Fixed, as CLAUDE.md requires.
  • I found no security or performance concerns. The change adds one WriteString per extra action to a pooled buffer.

Non-blocking notes

These repeat the earlier reviews on this PR. Nothing in the diff has changed them.

  1. Only TestAlterTableSQLSeparators exercises the changed line. It builds the legacy AlterTableStatement by hand. The parser produces AlterStatement, so the dialect, corpus and parser-input tests don't cover this fix. They are still useful guards for the compact fast-path follow-up.
  2. The PR description overstates the evidence. The "11 dialects" and "152 + 1,083 differential checks" claims don't show this bug. Either reword it or say that AlterStatement.SQL() already handled commas.
  3. The dialect loop in TestAlterTableSQLSeparators repeats the same SQL() assertion 11 times, because SQL() doesn't depend on dialect. Assert it once and loop over dialects only for the round-trip check.
  4. TestAlterTableSQLParserInputs depends on the parser tests' contents. It scans Go string literals in those files, so a refactor could silently lower coverage. A minimum-count guard such as count > 100 would catch that. The current count == 0 guard only catches total loss.
  5. Dialect-specific ADD syntax (Oracle, SQL Server) could fail the round-trip with parse errors that aren't SQL() bugs. Please confirm CI is green across all dialects.

Verdict

The code change is good, so I'd approve it. I can't submit a formal approval. The notes above are about the tests and the PR text.
· branch fix/w5-02b-alter-table-sql-commas

@ajitpratap0
ajitpratap0 merged commit 4def1cb into main Oct 31, 2026
43 checks passed
@ajitpratap0
ajitpratap0 deleted the fix/w5-02b-alter-table-sql-commas branch October 31, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ast AST node changes documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant