Repository navigation
fix(linter): report L006 column as a byte offset; tighten comment span test - #840
Conversation
…n test L006 (column alignment) compared indentation with a tab counted as 4 columns and then reported Location.Column as that tab-expanded width + 1, so a column indented with two tabs was reported at column 9 instead of 3. Indentation is still compared with tab = 4, but the reported column is now the 1-based byte column of the first non-whitespace character, matching the byte columns documented on models.Location (#797, #826). Also strengthen TestTokenPositions_CommentsKeepOwnPositions to assert the token after a comment starts at or after the comment's End (line, then column) and that no token overlaps the comment span, with a multi-line comment case. Refs #830 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9
|
Claude finished @ajitpratap0's task in 19s —— View job Review of PR #840Verdict: looks good, with only minor nits.
Correctness
Nits
Performance, security, tests
The user-visible column change for tab-indented lines is clearly noted in the PR description and the docs. I'd also add the release note to |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @ajitpratap0's task in 12s —— View job Review of PR #840Verdict: looks good. The only thing I'd add is a changelog entry. I read the diff for Correctness
Nits (non-blocking)
Changelog
Performance and security
Tests
|
* chore(parser): remove stray parser.go-e backup with conflict markers [vercel skip] The sed backup file was committed by accident in #791. It is not compiled but ships in the module zip. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * chore(release): bump version to 1.16.0 [vercel skip] gosqlx.Version and the CLI version were still 1.14.0 (v1.15.0 shipped with them), so gosqlx --version, the MCP server info and /health reported 1.14.0. Also bumps the VS Code extension, Claude Code plugin and marketplace, glama, performance baseline label, llms.txt and the site's release badge. pygosqlx __version__ now matches pyproject (0.2.0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * docs(changelog): finalize 1.16.0 release notes [vercel skip] Turns [Unreleased] into [1.16.0] - 2026-10-21, adds the missing entries for #734, #735, #780, #786, #789, #790, #791, #826, #835, #836, #837, #840, #841, #843 and #844, updates the MCP and composite-field entries amended by #841 and #843, adds PR refs, and adds the compare links. The VS Code extension gets a 1.16.0 entry, and split-changelog.js generates the /changelog page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * docs: v1.15 to v1.16 migration guide and release doc fixes [vercel skip] MIGRATION gains a v1.15.0 -> v1.16.0 section with a behaviour-change checklist. ERROR_CODES documents E4001 dialect gating and the 11 dialect names. CLI_GUIDE lists --dialect on format, parse, analyze and lint and all 11 dialects. SQL_COMPATIBILITY marks Oracle CONNECT BY/PRIOR and SQL Server PIVOT as parsed. api/mcp.md matches the current Config and middleware API, api/models.md drops the nonexistent Location.Offset and documents byte columns, and HIGHLIGHTING notes ANSI control-character neutralization. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * chore(website): regenerate sample AST and changelog pages The website build rewrote both files on main: sample-ast.json gains the WithOrdinality and ColumnAliases fields from #843, and v1-9-1.md drops the emoji the changelog splitter strips. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * docs(release): correct allocation claim, plugin history, E4001 and LoadConfig errors Address review notes on #845: the lead paragraph understated the perf audit's allocation cuts, the MIGRATION table listed a v1.15.0 plugin that never shipped, E4001 also covers LIMIT under SQL Server, and LoadConfig rejects more trusted-proxy misconfigurations than the API doc listed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * docs(release): make glama.json match the MCP server List all 11 validate_sql dialects, describe lint_sql as the 10 rules it runs (L001-L010; the CLI and SDK have 30), sync tool descriptions with pkg/mcp/server.go, and drop the unsourced 1.38M ops/sec claim in favour of a link to the benchmarks page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * docs(release): add #846-#851 to the v1.16.0 CHANGELOG and migration guide Record the pygosqlx 0.3.0 API and wheels, the gosqlx_version double free, LSP serverInfo/CLI version reporting, the Python CI and release workflows and the #848 docs. MIGRATION companion table lists pygosqlx 0.3.0, libgosqlx exports and the LSP serverInfo version, with matching behaviour-change notes. Regenerate the v1.16.0 blog page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * docs(release): address v1.16.0 release review; add #852 - Release date 2026-10-22 in CHANGELOG, MIGRATION, the extension changelog and the generated blog post (re-stamp at tag time if it slips). - vscode-extension CHANGELOG: Fixed entry for the #846 version reporting. - CHANGELOG: keep the Behavior changes list tight; name TranspileError and the LintResult/SecurityScanResult types in the pygosqlx 0.3.0 entry. - MIGRATION: PyPI wheels row is conditional on the pygosqlx-v0.3.0 tag. - Add #852 (sdist builds fail without libgosqlx; release tag lookup skips v1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * build(release): replace deprecated goreleaser keys (formats, version_template) goreleaser check (v2.12.7) flagged archives.format, format_overrides.format and snapshot.name_template as deprecated; release.yml runs goreleaser 'latest'. Snapshot release dry-run builds all six archives. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * docs(release): add #853 to the v1.16.0 CHANGELOG Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 * feat(python): version pygosqlx in lockstep with GoSQLX (1.16.0) pygosqlx wheels bundle libgosqlx built from the same commit, so its version now matches the GoSQLX release. The first PyPI release is 1.16.0 (it was 0.2.0, never published); no older versions are backfilled. - pygosqlx-release.yml also publishes on GoSQLX 'vX.Y.Z' tags (the floating 'v1' tag does not match); 'pygosqlx-v*' stays for Python-only .postN releases. Both must match pyproject.toml and be on main. - pyproject.toml / __version__ 1.16.0; the version test now asserts __version__ equals the bundled library's version(). - CHANGELOG, MIGRATION and python/README describe the lockstep scheme. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9 --------- Co-authored-by: Ajit Pratap Singh <ajitpratapsingh@Ajits-Mac-mini-2655.local> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Summary
This PR finishes the remaining items of #830, the column follow-ups from the review of #826 (refs #797).
b3c85948).readQuotedIdentifierSlowbuilds its newline-branch error fromt.toSQLPosition(startPos), the same as the EOF branch, andStringLiteralReaderfollows the same byte-column rule. I checked this onorigin/mainwith the issue's repro,x\t/* c */ é\t"ab\nc". It reportsE1002 at line 1, column 14, which is the byte column of the opening quote. This PR does not change it.pkg/linter/rules/style/column_alignment.gostill compares indentation widths with tab = 4. It now reportsLocation.Columnas the 1-based byte column of the column's first non-whitespace character, where a tab is one byte.TestTokenPositions_CommentsKeepOwnPositions): the test now assertstokens[2].Start >= Comments[0].End(line first, then column) and checks that no token overlaps the comment's half-open span. A multi-line block comment case covers the line comparison.docs/LINTING_RULES.mdnow explains how L006 counts tabs and reports columns.Root cause / design
getIndentSizereturns a tab-expanded width (space = 1, tab = 4). L006 compared those widths, which is correct. It then reportedColumn: indent + 1, so the width was being used as if it were a position. Examples of wrong columns before this fix:\t\td\td\t dThe fix keeps two parallel values for each SELECT column:
indents: the tab-expanded width. It is used for the mode/alignment comparison and is unchanged, so a tab still aligns with 4 spaces and the set of violations does not change.cols:leadingWhitespaceBytes(line) + 1, the 1-based byte column of the first non-whitespace character. It is used only for the reportedLocation.leadingWhitespaceBytesis a new byte loop over leading' '/'\t'.getIndentSizeis unchanged; I only updated its doc comment to say the result is a width, not a position.Other linter rules audited for the same bug. I checked every rule that sets a non-constant
Location.Column:strings.Index/strings.LastIndex+ 1len(strings.TrimRight(...)) + 1range+ regex byte offsetsrangebyte index + 1MaxLength + 1overlen(line)Column: 1L006 was the only rule that turned an indentation width into a reported column. The
[]runeloop inkeyword_case.fixLinerewrites text and never produces a column.I left one pre-existing quirk alone: the
SELECT DISTINCTfirst-column branch in L006 can never run, because the enclosingifexcludes DISTINCT. It only affects the first column, which is never reported, so I kept it out of scope.Test Plan
gofmt -l pkg/linter pkg/sql/tokenizer: no output.go vet ./pkg/linter/... ./pkg/sql/tokenizer/: clean.golangci-lint run ./pkg/linter/... ./pkg/sql/tokenizer/...:0 issues.go test -race -timeout 180s ./pkg/linter/... ./pkg/sql/tokenizer/... ./cmd/gosqlx/... ./pkg/lsp/... ./pkg/gosqlx/...: allok.go test -race -timeout 180s ./pkg/sql/tokenizer/ ./pkg/sql/ast/ ./pkg/compatibility/(literal/SQL golden tests): allok.go build ./...: ok. The pre-commit hook (go fmt,go vet,go test -short ./...) passed.TestColumnAlignmentRule_TabColumnIsByteOffsethas 6 cases: a tab aligned with 4 spaces, two tabs, a single tab, mixed spaces/tab/spaces, spaces against a tab majority, and a tab+space outlier with a multi-byte name. Each case checks the exact(line, column)and that the column points at the first non-whitespace byte.TestLeadingWhitespaceBytesis a table test.TestTokenPositions_CommentsKeepOwnPositionshas single-line and multi-line comment subtests.column_alignment.go, 4 of the 6 new L006 cases fail, reporting the old tab-expanded columns (for examplegot [{4 9}], want [{4 3}]). The two cases with no tab in the reported line pass on both versions, as expected.intper SELECT column line.Breaking Changes
None to the API. L006 now reports a different
Location.Columnfor misaligned columns indented with tabs. Space-indented lines report the same column as before, and the set of violations is unchanged.Release note
Closes #830
🤖 Generated with Claude Code
https://claude.ai/code/session_01RkzVu3JY9Y6BRWfjesWts9