raahii.meのブログのロゴ画像

ウェブログ

Vim ALE と sql-formatter で SQL を整形する

最近データベーススペシャリストの勉強をしながら SQL を書いている中で、フォーマッタがほしいなと思ったので色々調査していた。Vim に ALE というリンタプラグインがあるが、公式でサポートしている SQL 向けのフォーマットは下記の 4 つだ(2022/09 時点)。

ale/ale-sql.txt · dense-analysis/ale

一通り使ってみた中では pgformatter が良かった。設定が豊富で、それらを ~/.pg_format で管理することもできる。特に、コンマを行頭に持ってこれる整形オプションが好きで、こんな SQL が、

SELECT po.id product_order_id, p.id product_id, p.name product_name, po.num_orders
FROM product_order po
JOIN product p ON p.id = po.product_id
WHERE p.is_set_product = TRUE

こんな風にフォーマットされて良い。

SELECT
    po.id product_order_id
    , p.id product_id
    , p.name product_name
    , po.num_orders
FROM
    product_order po
    JOIN product p ON p.id = po.product_id
WHERE
    p.is_set_product = TRUE

ところが、使っている中でコメント周りやサブクエリ周りの整形が微妙なことがわかったのと、pgformatter は PostgreSQL 向けなのに対し、私は MySQL 向けの SQL を書くことが多いので、代替を探していた。

すると、巷では明らかに sql-formatter-org/sql-formatter が使われているようだった。例えばcoc-sql も採用している。サポートしているクエリ言語も手広いので、これを採用して ALE に組み込むことにした。

ALE では次のように任意のコマンドを組み込める。-l の言語指定はお好みで。

let g:ale_fixers = {
  ...
  \ 'sql': [
  \   { buffer -> {
  \       'command': 'sql-formatter -l mysql'
  \   }},
  \ ]
\}

これでめっちゃ快適に SQL を書けるようになった。

余談だが、仕事でもクエリを管理するためのレポがあって、DB オペの度にそこでレビュー受けてから実行するような運用なのだけれど、書き方が結構バラバラなので導入してみようかな。そういうチョットしたものでも、フォーマッタがある方が書く側もレビューする側も余計な時間を使わずに済んで良い。

あと、LSP があるのでなぜ未だに ALE つかっているの?と思う人もいるかも知れない。私は coc.nvim を使っているが、フォーマッタは自由に選んで差し替えられるようにしたいので、フォーマッタだけ ALE を使う運用を続けている。coc でフォーマットもやる場合は何もかもプラグインの実装次第なのだが、大体フォーマッタが無くて足したいとか、別のものを使いたいとか、そいつだけ無効にしたい、となり、でも設定が提供されていないとそこで詰むという感じで柔軟性に欠けるので止めた、という経緯です。