技術約12分で読めます

PostgresをAIでRustに書き直したpgrustと、Zig作者のBun移植批判が同じ日にHNフロントページに載った

いけさん目次

米国時間2026年7月9日、Hacker Newsのフロントページに「Postgres rewritten in Rust, now passing 100% of the Postgres regression tests」(807ポイント)と、Zig作者Andrew Kelleyの「My Thoughts on the Bun Rust Rewrite」(783ポイント)が同時に載った。
前日にはBun公式ブログ「Rewriting Bun in Rust」(777ポイント)が出たばかりで、AIによる大規模書き直しのスレッドが24時間に3本立った。ポイントはHN読者による賛成投票の数で、pgrustの807はこの日のトップだった。

5月に書いたBunの100万行Rust移植の記事の続きとして、PostgresのRust書き直し「pgrust」の中身と、Bun側が泥仕合になっていった経緯を整理してみる。

日付(米国時間)スレッドポイント
7/8Rewriting Bun in Rust(Bun公式ブログ)777
7/9Postgres rewritten in Rust(pgrustリポジトリ)807
7/9My Thoughts on the Bun Rust Rewrite(Andrew Kelley)783
graph TD
    subgraph pg[pgrust側]
        A[4/20 pgrust公開<br/>250k行・回帰テスト1/3通過] --> B[4/28 67%通過]
        B --> C[6/25 回帰テスト100%通過<br/>Show HNは6ポイントで不発]
    end
    subgraph bz[BunとZig側]
        D[5/14 BunのRust移植<br/>100万行がmainへ] --> E[5月末 ZigがLLM貢献の<br/>受け入れ禁止を明文化]
        E --> F[7/8 Sumnerが公式ブログ<br/>Rewriting Bun in Rustを公開]
    end
    C --> G[7/9 HNフロントページで衝突<br/>pgrust 807pt / Kelley批判 783pt]
    F --> G

pgrustは2人の個人プロジェクト

pgrustはMichael MalisがJason Seibelと2人で作っている個人プロジェクトで、企業のプロダクトではない。
MalisはHeapで1ペタバイト規模のPostgresクラスタを運用していた元インフラエンジニアで、自分のブログにPostgresの内部構造の記事を長年書いてきた人物だ。

作業は4月上旬に始まった。CodexエージェントにPostgresのCソースを読ませてサブシステムを説明させ、対応する最小限のRust実装を書かせる方式で、git worktreeベースのオーケストレータConductorを併用して手元のCPUが飽和する17並列まで増やした。
4月20日の公開時点で250,000行、Postgresの回帰テストの約3分の1が通っていた。この時点の記事でMalisは「もうコードのほとんどを読んでいない」と書いている。

6月に作り方を変えた。ゼロから書く実装を捨て、c2rustでPostgres本体のCをunsafe Rustへ機械変換し(Cのコンパイル単位ごとに1クレート、約1,000クレート)、そこからクレート単位でsafeなRustに書き換える方式にした。
書き換えはClaudeに持たせたスキル3本(次のクレートを選ぶ、クレートを書き換える、書き換えを監査する)で回している。旧実装はarchiveブランチに退避された。

6月25日、PostgreSQL 18.3の回帰テスト46,000本超を100%通過、アイソレーションテストも通過、既存のPostgres 18.3のデータディレクトリからそのまま起動できる、と発表した。
本人のShow HNは6ポイントで沈み、2週間後に第三者が再投稿して807ポイントまで伸びた。

READMEとブログには、本番利用できる段階ではない、性能最適化もまだ、既存のPostgres拡張とは非互換、と明記されている。ライセンスはAGPL-3.0で、ここが論争となっている。
AGPLはGPLの公開義務をネットワーク越しの利用まで広げたライセンスで、改変版を配布しなくても、サービスとして動かしてユーザーに使わせた時点でソース公開義務がかかる。通常のGPLの義務は配布時にしか発生しない。
データベースは配布されずにSaaSの内部で動くことが多いので、AGPLだとクラウド業者にも公開義務が及ぶ。MinIOやMongoDB(SSPL移行前)がクラウド業者への対抗に使ってきた系統で、HNでも「データベースとAGPLは組み合わせが悪い」という反応が出ていた。

回帰テスト100%が保証する範囲

pg_regressはクエリの出力テキストを期待値ファイル(expected)とdiff比較する仕組みで、46,000本はそのクエリ数だ。並行トランザクションの直列化を検証するアイソレーションテストも通っている。
一方、クラッシュからの復旧を検証するリカバリテスト(TAP形式のスイート)は移植時点で47本中34本しか通っておらず(本人が立てたissue #10)、sqllogictestやJepsenのような外部テストは「まだ大きなものは何もない」と本人がHNで答えている。

HNの議論はこの100%が何を意味するかに集中した。回帰テストの通過は「その回帰が存在しない」ことしか証明しない、という原則論に加えて、「このテストが落ちるので直して」のループでLLMを回すと、テストを特殊ケース分岐で通す書き方が混ざりうるという指摘が出た。テストが目標になると指標として機能しなくなる、というグッドハートの法則の懸念だ。
pgrust最大の変更であるプロセス毎接続からスレッド毎接続への切り替えについては、プロセスモデル前提で書かれた既存テストがそこを検証しないという指摘があり、PgDog作者のlevkkは「一応確認だけど、fsyncはオンになってる?」と聞いていた。pg_regressはI/Oパターンの正しさまでは測れない。

比較対象としてはSQLiteが繰り返し引き合いに出た。SQLiteは製品コード1に対してテストコード約590という比率を公開していて、回帰テスト100%という一つの数字とはテストの規模の桁が違う。

SQLsmithの作者が数日でセグフォを出した

Postgres本体のバグを多数見つけてきたクエリファザー「SQLsmith」の作者Andreas Seltenreichが、7月9日からpgrustにファジングをかけてissueを連投した。

SELECT numrange_subdiff(1,1); の1行でセグメンテーションフォールト(シグナル11、issue #23)。Postgres 18.3では0が返るクエリで、メモリ安全を掲げた書き直しがCでは落ちないクエリで落ちた。
ほかにMERGE文で内部エラー(#22)、プランナの内部不変条件が崩れる系のエラーが複数(#17、#21、#28)、byteaリテラルの検証が丸ごと欠けている報告(#13)も出ている。

副産物として、AIが書いた説明文がそのまま実行時エラーとして外に出てくる例もある。issue #20では「SubLink::clone: subselect is an embedded owned Query whose children are context-allocated; …」という開発メモのような長文が、クエリのERRORメッセージとして返ってきた。

前提として、pg_regress自体がカバレッジ100%を目的に作られていない。make checkは速く終わることを優先していて、SQLsmithのようなファジングはPostgresの開発プロセスの側に人間の運用として組み込まれている。変換で手に入るのはコードのスナップショットだけで、この運用は含まれない。
HNのevil-oliveはこれを「静的なスナップショットを別の静的なスナップショットに変換したことには意味がない。14を実装して、データを保持したまま15、16、17、18と上げてみせろ」と表現していた。

公開版の実測はむしろ遅い

READMEには未公開の新バージョンについて、トランザクション処理でPostgresより50%速い、分析クエリで約300倍速い(ClickBenchでClickHouseの2倍遅い)という更新が載っている。この数字は第三者には検証できない。
公開版を実測した人はいて、issue #31のpgbenchではバニラのPostgres 18.4に対してTPSが約9分の1(728対6,365)、初期化は約11倍遅かった。負荷をかけるとOOMで落ちる報告(#30)もある。

Malis自身は素朴な変換が速くならないことを認めていて、Bunのスレッドで「新しいRustコードは元のCコードにかなり忠実だったが、それでも8倍遅かった」とコメントしている。
300倍の方にはHNで「ACID保証の同期機構を壊さない限りありえない数字だ」という反応がついたが、これ自体も根拠を示さない推測で、カラム型の実行に切り替えていれば正当に出うる範囲ではある。公開されるまで判定できない。

コードを読んだ側の指摘としては、HNで数えた人によるとunsafeブロック2,664箇所とunsafe関数1,835本があり、Malisは「大半はc2rustで機械変換したパーサに閉じている。Postgresのパーサ自体がyacc/bisonの生成物なので、そこは意図的に機械的な移植のままにした」と答えている。
エラーハンドリングがCの返り値の構造をそのまま写していて、Result型と真偽値の二重チェックになっている箇所を挙げた人もいた。

同じ朝に出たZig作者のBun批判

pgrustのスレッドが伸びたのと同じ7月9日の朝、Andrew Kelleyが「My Thoughts on the Bun Rust Rewrite」を公開した。前日にJarred Sumnerが出した公式ブログへの反論として書かれている。

Sumner側のブログによると、移植は11日間、6,502コミット、ピークで64並列のClaudeエージェントを実装役とレビュー役のペアで走らせ、未キャッシュの入力59億トークンと出力6.9億トークンを消費した。API料金換算で約16.5万ドル。
モデルはリリース前のClaude Fable 5で、「エンジニア3人で1年ほどかかる仕事」という見積もりが添えられている。検証の判定基準はBun自身が持つ約100万アサーションのテストスイートだった。
Rust版Bunは6月17日リリースのClaude Code v2.1.181から本体のランタイムとして使われている。

Kelleyの記事は技術批判と個人攻撃が地続きに書かれていて、反応も真っ二つに割れた。
雇用主としてのSumnerについて「Jarredはひどいマネージャだった。コミュニケーション不全、非現実的な期待、共感の欠如、経験なし」と元従業員からの伝聞を載せ、「JarredはLLMに触る前からslopを書いていた」と続け、Anthropicには「このブログ記事は見事に書けている。まるで1兆ドル企業のマーケティング部門が、この記事に大金を賭けているかのようだ」と皮肉を向けた。
SumnerがZig Software Foundationに年間6万ドルを寄付していたが、買収後に黙って止まった、という経緯もこの記事で明かされている。

技術面でKelleyが突いたのはテストスイートの整合性だ。100万行の未レビューコードを出荷する根拠がテストスイートなら、なぜZig版には厄介なバグが多かったと言えるのか。Zigコードのバグを拾えなかったテストスイートが、100万行の未レビューコードのバグなら拾えるのか。
ほかにも、バイナリサイズ削減に使われたLTOはZigでも最初から使えた、ブログはファジングをやっていたように読めるが打ち合わせではファジングしていないと聞いていた、といった指摘もある。

そしてこの記事は公開後に書き換えられた。現行版の結論部には「処理しきれていない恨みの感情があって、読者には明白だったのに自分には見えていなかった。内省してこの結論セクションを更新した」という断り書きがあり、「1兆ドル企業が先に撃ったことを考えれば、多少の猶予をもらえるとうれしい」と続く。
初版にあったファジングのくだりを「真っ赤な捏造」と呼ぶ表現はHNコメントの引用にだけ残っていて、現行版では「〜と示唆している」に弱められている。

X側では、Dagster作者のNick Schrockが「プログラミング言語に積極的に失敗してほしいと思ったことはなかったが、Kelleyの下劣で常軌を逸した記事のおかげでそこに到達した。すべてのプロジェクトをZigからRustに移植しろ」と書き、「企業の行動規範を10層通したフィルタ越しでない人格で意見を言って何が悪い」という擁護も出た。
Sumner本人はこの記事を書いている時点(7月12日)でKelleyに直接応答していない。Kelley側は2023年にTwitterとRedditをやめていてXにいないので、応酬は双方の支持者の間で続く形になった。

残っている論点

テストスイートは仕様の代わりになるか。これが両案件に共通する問いで、5月の記事では「同じテストとベンチを通す」という機械判定可能なゴールがあるとAIの生成→検証ループが回しやすくなる、と書いた。今回はその成功例と、限界を示す例が同時に出ている。
Bunは自前の100万アサーションを、それを書いたメンテナ本人が回した。pgrustは他人のテストスイートを外から借りて、SQLsmithが数日でその外側を示した。

ZigとRustの言語間対立として読まれた側面もある。Zigは5月末にLLM生成コードの貢献を受け付けないポリシーを明文化していて、報道の中でKelleyはLLM貢献を「例外なくゴミ」と呼んでいる。BunはAI生成の変更をZigツールチェーンの本家に送れなくなり、フォークを維持することになった。
Zig最大の実用プロジェクトだったBunがAnthropic傘下でRustに移り、その批判記事への反発で「ZigからRustへ全部移植しろ」が伸びる、という順番で燃え広がった。

ライセンスの議論も続いていて、対象はpgrustが寛容なPostgreSQLライセンスのコードを機械変換してAGPL-3.0で再ライセンスした点だ。機械変換は派生物なので元のライセンスを外せないのではという指摘と、AI生成コードにはそもそも著作権が発生しないのではという指摘が同居していて、決着はない。
SQLiteをGoに機械翻訳したncrucesのプロジェクトが、変換後も元プロジェクトの著作権表記を保持しているのが対比として挙がっていた。

先行の書き直しと比べる

Turso(旧Limbo)のSQLite書き直しは、初日から決定論的シミュレーションテストとファジングを組み込んで、SQLite本体との差分比較で正しさを判定する構成にした。SQLite本体のテストスイートが非公開で、借りられるテストが存在しない前提からの設計だった。
fish shellのC++からRustへの移植は人間主導で、数年かけてコンポーネント単位に置き換え、途中のどの時点でも動くシェルであり続ける方式を取った。今回の2件はどちらの手順も踏んでいない。かかった期間は、fishの数年に対してBunが11日、pgrustが3か月弱だ。

「AIにやらせるな」という反発の背景には、書き直し以前からの蓄積もある。curlがAIスロップ報告への対応でバグバウンティを廃止したのは今年2月で、LinuxカーネルはソースツリーにAIコーディングアシスタントの利用ポリシーを入れた
pgrustのリポジトリにも「これは真面目なプロジェクトなのか、ただのAIスロップなのか」というissue(#24)が立った。そこで返ってきた答えの一つが、正当性は継続的なメンテナンスで測られる、Bunの書き直しはBunのメンテナ自身がやったもので部外者の投げ込みとは別物だ、というものだった。

未解決の問いは具体的な形で残っている。50%速い・300倍速いは公開されて初めて検証できる。スレッド毎接続でアイソレーションテストの通過が維持されるか、リカバリテストの残り13本がどうなるかも公開待ちだ。
HNのaeonfoxは、AI書き直しの品質指標として「Postgres本体と突き合わせる差分ファジングで、ずれが出るまでに通ったクエリ数のlog10」を提案していた。log10は常用対数で、10万クエリまで一致し続ければ5、100万なら6という桁のスコアになる。この数字なら、公開されているビルドでも今日から測れる。

参考