Skip to content

Preserve hint block spacing in fmt-sql output#10

Merged
tomoemon merged 2 commits into
mainfrom
fix/fmt-sql-hint-spacing
Apr 10, 2026
Merged

Preserve hint block spacing in fmt-sql output#10
tomoemon merged 2 commits into
mainfrom
fix/fmt-sql-hint-spacing

Conversation

@tomoemon

Copy link
Copy Markdown
Owner

Summary

  • fmt-sqlFROM Table@{FORCE_INDEX=Idx}FROM Table @ { FORCE_INDEX = Idx } のように展開されてしまう不具合を修正
  • formatTokens() にヒントブロック専用の状態 (hintDepth) を追加し、@{...} 内部のトークンをスペースなしで連結する
  • ヒント内部は upper(t) ではなく t.raw を使用し、ユーザが書いた大小文字を保持する
  • テーブルヒント、ステートメントヒント、JOIN ヒント、複数レコード、ソース側の余計な空白の正規化、大小文字保持を含む5ケースのテストを追加

設計の背景

memefish lexer はヒント構文 @{FORCE_INDEX=SingersByName}@, {, FORCE_INDEX, =, SingersByName, } のように複数トークンに分割する。既存の needsSpace() はこれらの記号を考慮していないため、各トークン間にスペースが挿入されていた。

@<param> 形式のクエリパラメータは memefish が単一トークンとして返すため、@ 単独トークンの直後に { が続くケースは常にヒント導入子と判断できる。この前提のもと、hintDepth カウンタで @{...} の開閉を追跡し、内部ではスペース抑制と , での record 区切りのみを行う方針とした (memefish の Hint.SQL() 出力と一致)。

検討した代替案

  1. noSpaceBefore / noSpaceAfter マップに @, {, }, = を追加する案。却下理由: これらの記号はヒント外部 (比較演算子 =, JSON 風リテラルなど将来の構文) では通常のスペーシングが必要で、単純なマップでは文脈依存の規則を表現できない。
  2. memefish の AST から Hint ノードを取り出して Hint.SQL() で再構築する案。却下理由: formatter.go 全体がトークンベース設計であり、AST ベース処理を混在させると整合性が崩れる。トークンレベルで解決可能なうちは現行設計を維持する方が望ましい。

Test plan

  • go test ./... -run TestFormatSQL で既存ケースと追加5ケースが全て PASS
  • table hint FORCE_INDEX, table hint with whitespace in source, table hint multiple records, statement hint preserves casing, join hint の各ケースで期待フォーマットを確認
  • @param クエリパラメータを含む既存テスト (simple select) が regression しないことを確認

🤖 Generated with Claude Code

tomoemon and others added 2 commits April 10, 2026 17:54
memefish lexer splits `@{FORCE_INDEX=...}` into separate tokens, which
the token-based formatter rewrote as `@ { FORCE_INDEX = ... }`. Track a
hint depth and reassemble tokens inside `@{...}` without spaces, keeping
only `, ` between records to match memefish's Hint.SQL() output. Use the
raw token text so user-provided casing is preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
testdata/test.ddl gained an OrderItem table in 72101cc but the
TestParseDDL/tables_parsed expectations were not updated, leaving CI
red on main. Update the expected table count and name list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tomoemon
tomoemon merged commit 33067ad into main Apr 10, 2026
2 checks passed
@tomoemon
tomoemon deleted the fix/fmt-sql-hint-spacing branch April 10, 2026 09:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant