SQLite仮想テーブルの括弧なしパターンに対するスキーマダンプの修正
VIRTUAL_TABLE_REGEX の正規表現を .+ から .* に修正することで、引数を持たない SQLite 仮想テーブルの schema.rb 生成が正常に動作するようになりました。
背景
SQLite の仮想テーブルには、USING module() のように括弧内が空になるケースが存在します。SpatiaLite 拡張を GpkgMode で使用し InitSpatialMetadata(1) を実行すると、このパターンの仮想テーブルが作成されます。#56969 では、この状態で ActiveRecord::SchemaDumper.dump を実行すると不正な schema.rb が生成される問題が報告されました。
問題の原因は、VIRTUAL_TABLE_REGEX が USING\s+(\w+)\s*\((.+)\) と定義されており、.+(1文字以上)により括弧内が空の () にマッチしない点にありました。CREATE VIRTUAL TABLE foo USING bar() のような SQL 文に対してこの正規表現が一致しないため、仮想テーブルの検出に失敗し、スキーマダンプ処理が壊れた出力を生成していました。
技術的な変更
activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb の正規表現を1文字修正することで問題を解消しています。
変更前:
VIRTUAL_TABLE_REGEX = /USING\s+(\w+)\s*\((.+)\)/i
変更後:
VIRTUAL_TABLE_REGEX = /USING\s+(\w+)\s*\((.*)\)/i
.+(1文字以上)を .*(0文字以上)に変更したことで、括弧内が空の仮想テーブルの SQL 文にもマッチするようになります。これに合わせて activerecord/test/cases/adapters/sqlite3/virtual_table_test.rb にテストケースが追加されました。CREATE VIRTUAL TABLE foo USING bar() に対してマッチすること、モジュール名のキャプチャグループが "bar"、引数のキャプチャグループが "" になることを検証しています。
設計判断
最小限の変更で問題を解消する方針 が採用されています。正規表現の1文字変更のみで対応しており、virtual_tables メソッドや呼び出し側のロジックには手を加えていません。引数が空の場合にキャプチャグループが空文字列になることは呼び出し側が許容できる状態であり、変更箇所を最小に抑えつつ問題を修正できています。
まとめ
.+ から .* への1文字の修正は、正規表現における「1文字以上」と「0文字以上」の違いが実際のバグに直結する典型的な事例です。SpatiaLite のような外部拡張が作成する仮想テーブルを含む環境でも schema.rb が正しく生成されるようになり、Rails と SQLite エコシステムの互換性が改善されました。