3 min read

Rust で SQL Compiler を作ってる

sqlc がとても素敵だなと思っており、自社では sqlc (go の pgx/v5) を採用している。ただ sqlc の開発が不安定だったり、TypeScript 版がメンテナンスが止まってしまったり、migrate や formatter が付いていたら ... という気持ちがあったので、いい機会なので作る事にした。

また、最近は Rust の難しい部分を LLM が吸収してしまうことや、Tokio が本当に素晴らしい事もあり Rust でのウェブアプリも現実的なのでは?と考えているため、まずは Rust の tokio-postgres 向けで試してみることにした。うまくいったら Go の pgx/v5 向けも追加する感じで。

製品名

自社は昔 Lua 向けの Linter を作っていたのだが、その名前にあやかって ruri とすることにした。名前大事。ここからは ruri == SQL Compilerと思って読んで欲しい。

Compiler 設計方針

基本的には sqlc と同じく SQL をコンパイルして Rust のコードを生成するだけ。ただ sqlc が頑張れていなかった部分は積極的に対応していく。また複数データベースへの対応はメンテナンスが厳しいため Postgres のみ対応とすることにした。将来的に SQLite や DuckDB といった自社が利用しているデータベースに対応してもいいかもしれないが、正直あまりメリットはないと考えている。

もちろん libpg_query.rs を利用する。Postgres 17 対応。

Migarte 設計方針

sqlc の不満の1つがマイグレーションツールがなかったこと、SQL Compiler にマイグレーションツールが付いていたらなぁ ... ってずっと思っていた。

またマイグレーションも sqldefpg-schema-diff のように変更差分をうまく吸収して最新の Schema だけ管理すれば良いという仕組みを使いたかったのだが、細かい部分で不安が多かったので、丁寧に対応することにした。ruri migrate コマンドを作る。

pg-chema-diffsqldef を参考にして実際の Postgres に接続して plan を立てて apply するという仕組みを採用する事にした。独自性を出すメリットはない。

Formatter 設計方針

色々フォーマッターはあるが、個人的に使ってて違和感が少なかった pgFormatter 互換を目指すことにした。難しく考えず ruri fmt で使えるだけ。設定ファイルは用意しない。ただここをミスると死ぬので死ぬほど丁寧に実装する。

Go への対応

基本は Rust の tokio-postgres での利用を想定しているが、Go の pgx/v5 でも利用できるようになっている。

Insta を利用したスナップショットテスト

テストには schema.sql / query.sql を用意して、スナップショットテストをすることで生成される Rust コードを保証する。

スナップショットテスト(承認テストとも呼ばれます)は、 値を基準値(スナップショット)と比較するタイプのテストです。 これはassert_eq!で値を基準値と比較するのと似ていますが、 単純な文字列比較とは異なり、スナップショットテストでは複雑なデータ構造に対しても テストを実施できます。 値を比較し、変更内容を詳細に確認できる包括的なツール群を備えています。
GitHub - mitsuhiko/insta: A snapshot testing library for rust
A snapshot testing library for rust. Contribute to mitsuhiko/insta development by creating an account on GitHub.

SQL Compiler はスナップショットテストとの相性が本当に良い。大量の SQL テストとスナップショットを書いている。

ruri の現状

LLM を使って Gist に 2026 年 2 月時点でのまとめたので興味ある人は見てみてほしい。雰囲気がわかってもらえると思う。

ruri.md
GitHub Gist: instantly share code, notes, and snippets.

まとめ

結局アプリを作るには RDB (というかトランザクション) が必要なので、SQL はまだまだ利用される。そうであれば使いやすい SQL からのコード生成、SQL マイグレーション、SQL フォーマッターを徹底的なテストにより実現したツールを作るのは今の時点では悪くないと判断した。

SQLite が大量のテストをしているように、ruri も大量のテストをしている。今後もテストは増えていく予定だ。

Go への対応とSQL フォーマッターも一段落しそうなので、次は Playground (つまり Wasm) を使ってブラウザですぐに確認できる仕組みも準備していきたい。

まずは社内で利用して、商用製品として展開できるのが理想だと思っている。