コアテクノロジーグループの山田です。
先日、新しいSQLフォーマッターであるuroboroSQL-fmtをリリースしました 🎉
このツールは弊社が公開しているPostgreSQL向けのSQLコーディング規約に基づき、SQL文をフォーマットするツールです。
弊社でのSQLフォーマッター開発の取り組み
元々弊社ではuroboroSQL Formatter(以下uroboroSQL Formatterを旧版、uroboroSQL-fmtを新版と呼ぶ)というSQLフォーマッターを公開していました。旧版は
- 字句解析して得られたトークンを基にフォーマットするという設計になっていたため、SELECT句のエイリアス補完といった文法を考慮する必要のある機能の追加が困難
- Pythonで書かれておりVSCodeの拡張機能として動作させるのが難しい
という課題を抱えており、それを解消するため新たなSQLフォーマッターを開発していました。
ANTLR+TypeScriptによるSQLフォーマッターの開発
Engineer Camp2020でANTLRとTypeScriptによるSQLフォーマッターを開発しました。インターンシップ中にSQLがフォーマットできるようになり、この方向性で旧版が抱えていた課題は解決できそうに思えましたが、SQLの構文解析が著しく遅いという問題点がありました。弊社太田がANTLRのJavaScript runtimeの不具合を発見し、かなり高速化されたものの実用的な速さにはならなかったこともありANTLRを用いたSQLフォーマッターの開発はストップしました。
インターンシップで行ったことについては以下の記事をご覧ください。
RustによるSQLフォーマッターの開発
旧版の課題を解決しつつ十分な速さでフォーマット可能なSQLフォーマッターを開発するため、Engineer Camp2022でRustによるSQLフォーマッターの開発を開始しました。インターンシップ終了時点で簡単なSQLのフォーマットが可能になり、その後もアルバイトとしてSQLフォーマッター開発に参画していただき、旧版のフォーマッターでは実現できなかったSELECT句のエイリアス補完等の機能、vscode拡張化、wasm化を実現しリリースに至りました。
インターンシップで行ったことや開発の過程で調査したことは以下の記事をご覧ください。
- Engineer Camp2022 RustでSQLフォーマッタ作成(前編)
- Engineer Camp2022 RustでSQLフォーマッタ作成(後編)
- Language Server Protocolを用いたVSCode拡張機能開発 (前編)
- Language Server Protocolを用いたVSCode拡張機能開発 (後編)
- Rust製SQLフォーマッタをnapi-rsを利用してVSCode拡張機能化
- C/C++を呼び出しているRustのWASM化
旧版と新版の比較
処理時間比較
新しく開発したSQLフォーマッターでは処理時間が大幅に向上しています!
巨大なSQLファイルと小さなSQLファイルをフォーマットしたときの処理時間を比較しました。
内容によってフォーマットにかかる時間は変わって変わるため、あくまで一例ですが概ね5-500倍ほど性能改善しています。
旧版 | 新版 | |
---|---|---|
3985行のINSERT-SELECT文 | 1m53.651s | 0m0.194s |
6行のSELECT文 | 0m0.357s | 0m0.054s |
機能比較
字句解析ベースから構文解析ベースになったことで、下記のような構文を意識した補完やauto fixができるようになっています。
カラムのAS補完
フォーマット前
SELECT |
フォーマット後
SELECT |
カラムエイリアス補完
フォーマット前
SELECT |
フォーマット後
SELECT |
長い関数呼出の折返し
フォーマット前
select |
フォーマット後
max_char_per_lineの設定は関数呼出の長さの上限を表し、デフォルトが50になっています。
この例ではlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongは50文字超のため変数ごとに折返され、short_funcは引数入れても50文字以内のためワンライン化されています。
where句にあってもいい感じに折り返され、横スクロールが発生しにくいようになっています。
longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglongは50文字超のため変数ごとに折返され、short_funcは引数入れても50文字以内のためワンライン化されています。
where句にあってもいい感じに折り返され、横スクロールが発生しにくいようになっています。
select |
新旧の機能比較
その他新旧の機能比較は下記です。
テーブルのAS除去や::によるキャストをCASTに変換などPostgreSQL限定構文は等価の標準SQLに変換する機能を入れています。
旧版 | 新版 | |
---|---|---|
対応SQL | 全て | PostgreSQL |
タブサイズの設定 | o | o |
予約語、識別子の変換 | 大文字化、小文字化 | 大文字化、小文字化、変換なし |
エイリアス補完 | - | o |
outer補完 | - | o |
カラムのAS補完 | - | o |
テーブルのAS除去 | - | o |
バインドパラメータの余計な空白除去 | - | o |
冗長な空白除去 | - | o |
1行の最大長指定 | - | o |
SQL ID補完 | ||
::によるキャストをCASTに変換 | - | o |
<>を!=に変換 | - | o |
ディレクトリ内のファイルを一括フォーマット | o | - |
予約語をファイルで指定 | o | - |
vscode拡張 | - | o |
wasm | - | o |
Eclipse plugin | o | - |
IntelliJ plugin | o | - |
SublimeText3 plugin | o | - |
exe版 | o | - |
2way-sql | uroborosql、doma | uroborosql、go-twowaysql、doma |
選択範囲フォーマット | - | o vscode拡張版のみ |
- PostgreSQL以外のSQLには対応していないため、PostgreSQL以外のSQLのフォーマットには旧版の使用をお勧めしています。
- Eclipse pluginとexe版は現在は用意できていないのですが、将来的には作成する予定です!
使い方
方法1:wasm版を試してみる
wasm版はこちらのデモでお試しできます。
使い方についてはデモページ内の説明をご参照ください。
wasm版の実行イメージ
方法2:vscode拡張として使用する
まず、他の拡張機能と同様にuroborosql-fmt - Visual Studio Marketplaceをvscodeにインストールしてください。
settings.jsonに以下の設定を入れてください
{
"[sql]": {
"editor.defaultFormatter": "Future.uroborosql-fmt"
}
}SQLファイルを開き、コマンドパレットから
Format Document
か、format sql
を実行してください
format sql
では選択範囲のフォーマットをサポートしています
フォーマットの設定方法
フォーマットの各種設定を記載したファイルのパスを指定できます。
指定されなかった場合にはデフォルトのパスにある ./.uroborosqlfmtrc.json
を読み込みます。
設定ファイルが存在しなかった場合、デフォルト値でフォーマットされます。
※ 現状は設定ファイルのパスしかできませんが、個々の設定の変更もvscodeの設定画面から出来るようにする予定です。
設定ファイルは以下のような内容です。
個々の設定についてはuroborosql-fmt - Visual Studio Marketplaceをご参照ください。
{ |
vscode拡張版の実行イメージ
方法3:cliで使用する
- Rustの環境を構築
cargo install --git https://github.com/future-architect/uroborosql-fmt
でuroborosql-fmt-cli
をインストールuroborosql-fmt-cli input.sql
でinput.sql
をフォーマットした結果が標準出力に出力されます。uroborosql-fmt-cli input.sql result.sql
のように第2引数を渡すと、第2引数で指定したファイルにフォーマット結果が格納されます
チーム開発で使用する場合
.vscode/settings.json
を作成し、以下のようにuroborosql-fmt.configurationFilePath
の設定を記載してください{
"uroborosql-fmt.configurationFilePath": "./.uroborosqlfmtrc.json"
}チームで使用したいフォーマットの設定を
.uroborosqlfmtrc.json
に記載し、リポジトリ直下に配置してください
最後に
まだまだ枯れておらずフォーマットできないことも多いです。元のSQLを壊していないか検証するロジックは入っていますが、意図しない変更が入っていないか確認お願いします。不具合や要望等ございましたらお気軽にissueやPRいただければと思います。
※ ライセンスはBSLですが競合会社含め開発環境での利用は自由ですので、お気軽に使用ください