PostgreSQL の最低サポートバージョンを 10.0 に引き上げ
Rails の PostgreSQL アダプターが要求する最低バージョンが 9.3 から 10.0 に引き上げられました。これにより、PostgreSQL 18 との互換性が確保されるとともに、バージョン分岐のためのコードが整理されています。
背景
PostgreSQL 18 がキャンセルリクエストキーのフォーマットを変更したことで、Rails の既存テストが失敗するようになったことがこの変更の直接の引き金です。postgres/postgres の a460251 で導入された変更により、プロトコルバージョン 3.2 以降では 32 ビット固定だったキャンセルリクエストキーが最大 256 バイトの可変長に変更されました。この変更は総当たりによるクエリキャンセルへの耐性向上を目的としています。
この影響を受け、ActiveRecord::PostgresqlTransactionTest#test_raises_Interrupt_when_canceling_statement_via_interrupt が pg gem 1.5.9 と PostgreSQL 18 beta1 の組み合わせで失敗するようになりました。新しいキャンセル関数への対応は ged/ruby-pg#614 で PG::CancelConnection クラスとして実装され、pg gem v1.6.0 に含まれています。
一方、pg gem v1.6 は ged/ruby-pg#606 で PostgreSQL 9.x のサポートを打ち切り、最低サポートバージョンを 10 に引き上げました。Rails 側が引き続き 9.3 以上を宣言したままでは pg gem v1.6 との整合性が取れないため、Rails の最低サポートバージョンも 10.0 に揃える必要が生じました。
技術的な変更
バージョン条件分岐の削除と、それに伴う非推奨化の追加が変更の中心です。
バージョン条件分岐の削除として、postgresql_adapter.rb では database_version を参照していた複数のバージョンガードが true に置き換えられました。
変更前:
def supports_insert_on_conflict?
database_version >= 9_05_00 # >= 9.5
end
def supports_identity_columns? # :nodoc:
database_version >= 10_00_00 # >= 10.0
end
def supports_native_partitioning? # :nodoc:
database_version >= 10_00_00 # >= 10.0
end
変更後:
def supports_insert_on_conflict?
true
end
def supports_identity_columns? # :nodoc:
true
end
def supports_native_partitioning? # :nodoc:
true
end
同様に schema_statements.rb では、シーケンスの最小値取得クエリでバージョンによって pg_sequence ビューと min_value カラムを切り替えていた分岐が削除され、PostgreSQL 10 以降の pg_sequence ビューを用いた書き方に一本化されました。また rename_enum_value メソッドでも「PostgreSQL 10 以降でのみサポート」という旨のガード節が不要になり削除されています。
非推奨化として、supports_pgcrypto_uuid? メソッドが非推奨になりました。pgcrypto が gen_random_uuid() を提供するのは PostgreSQL 9.4 以降であり、最低バージョンが 10.0 になった以上このメソッドは常に true を返すだけで実質的な意味を持たなくなるためです。
def supports_pgcrypto_uuid?
true
end
deprecate :supports_pgcrypto_uuid?, deprecator: ActiveRecord.deprecator
テストコードでも同様の整理が行われています。uuid_test.rb では supports_pgcrypto_uuid? を参照していた条件分岐と uuid_function / uuid_default ヘルパーメソッドが削除され、gen_random_uuid() を直接使用するよう変更されました。また schema_test.rb では DROP COLUMN IF EXISTS が「9.X のみの構文」として避けられていたコメントが削除され、素直に使用するよう修正されています。
設計判断
バージョンガードを削除して定数 true を返す方式が採用されました。database_version >= N という条件を true に置き換えることで、サポートバージョンの実態をメソッドの戻り値から読み取りやすくしています。将来的に PostgreSQL 15 以降向けの分岐(例: supports_nulls_not_distinct? など)が残っている箇所は引き続きバージョンチェックを維持しており、変更の対象は最低バージョン引き上げで常時 true になるものに限定されています。
supports_pgcrypto_uuid? を即座に削除するのではなく 非推奨(deprecate) とした点も設計上の判断です。外部から呼び出しているコードとの後方互換性を一定期間維持しつつ、メソッド自体を段階的に廃止する方針が取られています。
まとめ
PostgreSQL 18 のプロトコル変更を起点に、Rails の PostgreSQL アダプターが要求する最低バージョンが 9.3 から 10.0 に引き上げられました。バージョン条件分岐の撤廃により、アダプターのコードはシンプルになり、pg gem v1.6 との依存関係の整合性も確保されています。