« なれる!SE11 絶対?管理職宣言 | トップページ | pg_topで遊んでみる »

2014.02.27

シーケンス番号を自在に操りたい!(2)-データ型とシーケンス値

いろいろと罠があるもので……

PostgreSQLでシーケンスを扱う際にはデータ型としてSerial / Bigserialのいずれかを指定してあげれば、自動的にシーケンスオブジェクトが作成され、1番から採番できるように準備される。
ただ、この時の挙動でバグっぽいものを発見した。

Versionは9.1.3/9.1.6(Linux/Win)で再現を確認した。
ひょっとすると9.2.x系や9.1系でももう少し上のバージョンでは直ってるかもしれないと思って、9.1.7~9.1.12のリリースノートをざっと見てみたけど、該当する箇所については対応しているようには見えなかった。
さらに気になったので9.3.3(Win)をインストールしてみたがやっぱり再現した。

で、何を発見したかというとカラムをSerial型で作成した場合のシーケンスオブジェクトの状況である。

CREATE TABLE test_int (seq_int serial, test_int integer);
CREATE TABLE test_big (seq_big bigserial, test_big bigint);

こんな2つのテーブルを作ってみる。

当然ながらtest_int_seq_int_seqとtest_big_seq_big_seqという2つのシーケンスオブジェクトが生成される。
ここで問題なのは、この2つのシーケンスの各種設定値は同一だということだった。

ポイントはMAXVALUEパラメータ。
seq_intのほうはserial型=4バイト整数値なので、値としては2147483647までしか許容されない。しかるにseq_bigのほうはbigserial型=8バイト整数値なので、9223372036854775807までいける。
ところがこのMAXVALUEについては、serial型で定義した場合でもbigserial型で定義した場合でも、ともに9223372036854775807が設定されてしまうのだ。

上記は先ほどCREATE TABLEした直後のseq_intカラムに対応するシーケンスのプロパティである。
もしかしてserail型って実は4バイトじゃなくて8バイト?かと思い、限界値テストを実施してみる。

SELECT setval('test_int_seq_int_seq', 2147483647);
INSERT INTO test_int(test_int) VALUES(0);

ERROR: integer out of range
********** エラー **********
ERROR: integer out of range
SQLステート:22003

ですよねー。

というわけでbigserial型ではなくserial型でカラムを設定する場合はMAXVALUEにはご注意、ということでした。

|

« なれる!SE11 絶対?管理職宣言 | トップページ | pg_topで遊んでみる »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/2022/59206235

この記事へのトラックバック一覧です: シーケンス番号を自在に操りたい!(2)-データ型とシーケンス値:

« なれる!SE11 絶対?管理職宣言 | トップページ | pg_topで遊んでみる »