PostgreSQL 8.3 から型チェックが厳密になっている件

PostgreSQL 8.3 からは、自動キャストがなくなり、SQLにおける型チェックが厳密化されたようです。
理由は、下記のように説明されています。

この変更の理由は自動キャストによって驚くような振舞いを引き起していたためです。

http://osb.sra.co.jp/technology/postgresql/8.3/

そして、この変更は、下位のバージョンとの互換性が無い変更のため、注意が必要となります。

具体例

下記のようなテーブルに、

sample-# \d users
            Table "public.users"
 Column   | Type                  | Modifiers
                                                                                          • -
id | integer | not null name | character varying(32) | not null

下記のようなSQL(文字型のカラムに対して数字型で条件指定)を実行すると、型エラー(operator does not exist・・)のメッセージが出力されます。

sample=# select count(1) from users where name = 2;
ERROR:  operator does not exist: character varying = integer
LINE 1: select count(1) from users where name = 2;
                                              ^
HINT:  No operator matches the given name and argument type(s).
You might need to add explicit type casts.

もちろん、ちゃんと「'」をつければ、正常に実行可能です。

sample=# select count(1) from users where name = '2';
 count
            • -
0 (1 row)

互換性問題に対する回避策的なもの

もちろん、一番確実な対応方法は、型を厳密に扱うようアプリケーションやSQLを書き換えることですが、アプリケーションの規模が大きかったり、そもそも書き換えができないケースもあるのではないかと思います。できれば、せっかく高速化された 8.3 へはバージョンアップしたいですし、互換性を保つ手軽な方法は何か無いでしょうか?

キャストを追加してバージョン互換性を保つには | Let's Postgres

上記以外の理由でも、PostgreSQLを前提としたパッケージを導入している場合にも、利用できるかもしれません。
まあ、その場合は、バージョンアップしないという選択肢もあると思いますが、性能的に8.3以降を利用したいという要望がある場合など。

具体的な方法については、上記のリンク先に詳しく記載されていますので、ここでは、簡単に紹介だけしておきます。

  • どうしてもアプリケーション側の改修が困難であれば、
  • 自分で型変換関数を定義(CREATE FUNCTION)
  • その関数を使う暗黙的キャストを定義 (CREATE CAST)
  • 要は、無くなったなら、自分で暗黙的キャストを作っちゃえ!ということでしょうか。

ちなみに

運用作業として、SQLを不用意に実行すると、うっかりエラーが出て、サーバー監視でエラーメールなんか出ちゃうと恥ずかしいから、注意ですな。


ツール*1経由でやれば?みたいな話もあがるけど、危険性を少しだけ回避できるくらいじゃないかな。生のSQLも実行できちゃうわけだから、文法エラーには注意しなきゃいかんのは同じだし。


それより、開発環境で検証したSQLしか、本番環境には流さない習慣のほうが大事だよな。


まあ、DBサーバログは(operator does not existが含まれる場合は)監視無視して、アプリケーションの不具合などでこんなSQLを発行してしまったら、それはそれでアプリケーション側で検知できるから、アプリログに出力して、それでサーバー監視に引っかかればいいじゃんという判断もいいけど、微妙ですよね。
PostgreSQL自身の不具合に気付けなかったみたいなことが起こりそうだし。

*1:使うならphppgadminがいいと思います。phpPgAdmin:Web開発者向けのPostgresクライアントツール (1/5) - ITmedia エンタープライズ デモサイトもあるので使ってみるといいかもしれません。phpPgAdmin - start