implicit cast
alias: 暗黙的キャスト
context: PostgreSQLでtotalをdecimalに変更する作業中に質問
今回の件ってアプリ側は相変わらずintegerで投げてくるんだけど投げる先がdecimalのカラムの場合はpostgreSQL側が勝手に変換してくれる機能があるという理解でいいのかな?mtane0412.icon
Claude.icon
その理解で正しいです。アプリが整数で投げてきても、書き込み先が numeric カラムなら PostgreSQL が自動で変換して受け取ります。
仕組みとしては「カラムが変換する」というより、書き込む値の側を、カラムの型に合わせて暗黙の型変換(implicit cast)するという動きです。
PostgreSQL は内部に「どの型からどの型へ、どういう文脈で自動変換してよいか」という登録表(pg_cast)を持っていて、integer → numeric はそこに「暗黙変換OK」として登録されています。
だから明示的なキャストを書かなくても勝手に通ります。
そしてこの方向の変換は**完全に安全(ロスレス)**です。
整数は必ず numeric にぴったり収まるので、丸めも誤差も起きません。
3850 を投げれば numeric(15,2) のカラムには 3850.00 として格納されます(小数部はゼロ埋めされるだけ)。
前回「後方互換なので旧コードのままで大丈夫」と言えたのは、まさにこの暗黙変換のおかげです。旧コードが integer を投げ続けても、DB 側が黙って吸収してくれます。
逆向き(numeric → integer)だと話が違って、小数部が落ちる可能性があるため暗黙変換は許されず、明示的なキャストが要求されます。
「整数→numeric は勝手にやってくれるが、numeric→整数はやってくれない」という非対称性があると覚えておくと役立ちます。
唯一の注意点として、桁あふれだけは起こりうることだけ頭の隅に置いておくとよいです。
numeric(15,2) は「全体15桁・小数2桁」なので、整数部に使えるのは13桁までです。
元が普通の integer(最大約21億=10桁)なら余裕で収まるので今回は問題になりませんが、もし将来 bigint 級の巨大な値を投げると numeric field overflow エラーになります。