フューチャー技術ブログ

Pure Rustで生まれ変わったPostgreSQL公式構文準拠SQLフォーマッター「uroborosql-fmt」をリリース🎉

はじめに

コアテクノロジーグループの川渕です。

先日、uroborosql-fmtの新バージョンv1.0.0をリリースしました 🎉

このツールは当社が公開しているPostgreSQL向けのSQLコーディング規約に基づき、SQL文をフォーマットするツールです。

現在、以下の3種類の方法でご利用いただけます。

詳しい利用方法は利用方法の章で説明しています。

※ uroborosql-fmtのライセンスはBUSLですが、競合会社含め開発環境での利用は自由ですのでお気軽にご使用ください

また、今回のアップデートについては、以下のシリーズ記事でも詳しく解説しています。

  • 新パーサーの技術詳細: (近日公開予定!)
  • パーサーの置き換え戦略: (近日公開予定!)

当社のSQLフォーマッター開発の歩みと課題の変遷

当社ではこれまでにもSQLフォーマッターを開発・公開してきました。

それらのフォーマッターにはそれぞれ課題がありましたが、今回の新バージョンではこれまでの課題を全て克服しています。

名前 特徴 課題 関連ブログ
2017 uroboroSQL formatter ・Pythonで開発
・トークンベースで解析(パースなし)
・lexerベースのため複数RDB構文対応といった自由度は高い反面、複雑な構文はサポートが困難 (postgresql以外のRDBを使う方は未だお薦めできます)
・PythonのためVSCode拡張化やwasm化が難しい
SQL開発者を幸せにする!? Sublime Text 3でも使える uroboroSQL Formatter を公開しました | フューチャー技術ブログ
2020 ANTLR+TypeScript版SQLフォーマッター ・TypeScriptで開発(VSCode拡張化が容易)
・ANTLR4のパース結果を利用
・ANTLR4のパーサーが非常に低速なことにより、フォーマッター全体の動作が低速 Engineer Camp2020でSQLフォーマッターを開発しました | フューチャー技術ブログ
2022 uroborosql-fmt v0.1.0 ・Rustで開発(wasm化やVSCode拡張化が可能)
tree-sitter-sqlのパース結果を利用しており高速
tree-sitter-sqlの文法が不完全で、PostgreSQLの追従・修正コストがかかる
・文法を増やすとバイナリサイズが大きくなる
tree-sitter-sqlのC言語依存によりwasm化が複雑
新しいSQLフォーマッターであるuroboroSQL-fmtをリリースしました | フューチャー技術ブログ
2025 uroborosql-fmt v1.0.0 ・Rustで開発(wasm化やVSCode拡張化が可能)
・公式PostgreSQL文法に準拠したパーサー(postgresql-cst-parser)のパース結果を利用しているため、文法の追従コストが低い
・postgresql-cst-parserは十分に高速であり、パーサー自体も高速
・Pure Rustであるため、wasm化が容易

パーサー移行の背景とメリット

uroborosql-fmt v0.1.0ではパーサーとして tree-sitter-sqlを利用していましたが、開発を進めるにつれて以下3点の課題が判明しました。

  • サポートされている文法が少なく、grammarの改善に工数がかかる
    • v0.1.0における新規構文サポートでは、フォーマットプロセスの改善に加えてパースプロセスの改善(grammarの改善)が必要であり、新規構文サポートに工数がかかっていた
  • 対応文法を増やすとパーサーのサイズが大きくなり、結果的にフォーマッターのバイナリサイズも大きくなる
    • フォーク元tree-sitter-sqlでは、PRを全てマージすると83MBになるらしい… (参考issue)
  • tree-sitterは内部的にC言語を利用しているため、wasmにコンパイルする際にwasm-bindgenが利用できず、wasmへのコンパイルが複雑化していた

これらの課題に対応するため、当社の山田がPostgreSQLの公式のパーサーをRustに移植したpostgresql-cst-parserを作成しました。uroborosql-fmt v1.0.0ではそのパーサーを利用するようにしています。

パーサーの変更により、v0.1.0でのパーサー起因の課題が全て解消されました。

  • 公式パーサーから移植しているので、パーサー自体は全てのPostgreSQL文法に対応している
  • 公式の構文定義ファイルからRust製パーサーを自動生成しているため、文法の追従が容易
  • 全てのPostgreSQL文法に対応しているにも関わらず、バイナリサイズが約6MBとコンパクト
  • Pure Rust (C言語を含まない) であるため、wasm-bindgenを用いてwasmにコンパイルすることができる

この変更によって、新規構文サポートのためのパースプロセスの改善工数はゼロになり、フォーマットプロセスの改善のみで新規構文をサポートできるようになりました :tada:

image.png

パーサーの動作は以下のデモページから確認することができます。

image.png

新パーサーの詳細については後日ブログで公開する予定です。

利用方法

現在以下の3種類の方法で利用することができます。

  1. ブラウザツール
  2. VSCode拡張
  3. CLIツール

1. ブラウザツール

デモページからブラウザ上で試すことができます。使い方の詳細はデモページをご覧ください。

image.png

2. VSCode拡張

  1. uroborosql-fmtの拡張機能をインストールしてください

  2. settings.jsonに以下の設定を入れてください

    settings.json
    {
    "[sql]": {
    "editor.defaultFormatter": "Future.uroborosql-fmt"
    }
    }
  3. SQLファイルを開き、コマンドパレットからFormat Documentか、format sqlを実行してください
    format sqlでは選択範囲のフォーマットをサポートしています

image.png

3. CLIツール

  1. Rustをインストールしてください。(インストール方法)

  2. 以下を実行してください

    cargo install --git https://github.com/future-architect/uroborosql-fmt
  3. 以下のようなコマンドでuroborosql-fmtを実行できるようになります (オプションの詳細はCLIツールのREADMEをご覧ください)

    uroborosql-fmt-cli --write target.sql

今後の展望

今後は対応構文の拡張とLinter機能の開発を行う予定です。

Linter機能は具体的に、以下のような警告・エラーをVSCode上で表示する機能を想定しています。

  • 大きすぎるIN句はパフォーマンスに影響を与える可能性があるため警告 (コーディング規約)
  • 存在しないカラム・テーブルを参照している場合はエラー
  • NullableなカラムをINNER JOINしている場合は警告

最後に

まだまだ開発途上であり、フォーマットできない構文も多くあります。
不具合や要望等ございましたらお気軽に以下リポジトリまでissueやPRを頂ければと思います。

後日postgresql-cst-parser開発の話、パーサー移行に伴うフォーマッター移行作業の話の2本の記事を公開予定です。お楽しみに!