1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Rails schema.rbのenable_extension plpgsqlとpg_catalogの違い

1
Posted at

背景

Railsアップグレード作業中に db:migrate を実行したら、schema.rb の差分にこんな変更が出てきた

# before
enable_extension "plpgsql"

# after
enable_extension "pg_catalog.plpgsql"

pg_catalog って何?壊れた?」と思ったので調べた

結論

機能的な変更はゼロ。そのままコミットして問題ない

Rails 7.2 以降、schema.rb のダンプ時に拡張のスキーマ名を含めた完全修飾名(スキーマ名.拡張名)で出力するようになっただけ

そもそも plpgsql とは

plpgsql(PL/pgSQL) は、SQLに手続き的な制御構文(if / loop / 変数)を追加する言語拡張。PostgreSQLがトリガーやストアドファンクション等の内部機能を動かすためにデフォルトで有効にしている

ポイントは、Railsが plpgsql を有効化しているわけではないということ。PostgreSQLがDB作成時にデフォルトで有効にしている plpgsql の状態を、schema.rb に記録しているだけ

pg_catalog とは

pg_catalog は、PostgreSQLのシステム情報が格納されている特別なスキーマ(名前空間)

Railsで例えると:

PostgreSQL Railsでのイメージ
public スキーマ app/ 配下(自分のコード)
pg_catalog スキーマ Rails gem の内部コード

つまり pg_catalog.plpgsql は「pg_catalog スキーマにインストールされている plpgsql 拡張」を完全修飾名で表現したもの

なぜ完全修飾名に変わったのか

この変更の本来の目的は、Heroku等で拡張が heroku_ext スキーマにインストールされるケースへの対応

# Herokuだとこういう差分が出る
enable_extension "heroku_ext.pgcrypto"

Herokuでは拡張が public ではなく heroku_ext という独自スキーマにインストールされる。スキーマ名を含めずにダンプすると、環境ごとの差異を正しく表現できない

Rails の該当CHANGELOGにはこう書かれている:

Include schema name in enable_extension statements in db/schema.rb

pg_catalog.plpgsql への変更はこの対応の副産物で、plpgsql がたまたま pg_catalog スキーマに入っているからそう出力されるようになっただけ

PostgreSQL Extension について補足

PostgreSQL Extension はPostgreSQLに機能を追加するプラグインの仕組みで、Rubyでいう Gem のようなもの

-- 拡張の一覧を確認するSQL
SELECT extname, nspname
FROM pg_extension
JOIN pg_namespace ON pg_namespace.oid = extnamespace;

-- 結果例
--  extname | nspname
-- ---------+------------
--  plpgsql | pg_catalog

このクエリを実行すると、plpgsql が pg_catalog スキーマに所属していることが確認できる

感想

  • Heroku対応が本来の目的で、plpgsql の表記変更はその副産物というのが面白い
  • こういう「機能は変わってないけど出力が変わる」系の差分は、理由がわからないと不安

参考URL

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?