HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

シーケンスの情報の取得

ふと、PostgreSQLでシーケンスの情報を取得する必要ができたので調べてみたらしい。

そもそもPostgreSQLにおけるシーケンスは、CREATE SEQUENCE文を使って自分で定義するか、SERIAL(SERIAL4)型やBIGSERIAL(SERIAL8)型の列を含むテーブルの作成によって自動的に生成される。
いずれにしても、シーケンスの現在の値を知りたいといった場合によく出てくるのが、nextval、currval、setvalの各関数である。
しかし、currval関数は「そのセッション内で」「最後に生成された値」を取得するもので、nextvalがそのセッション内で呼び出されていないと使えない。が、そんなことのためにシーケンスの値は更新したくない。

ということで、それらの関数に依存しないものについて。

実際の確認のための事前準備

まず、以下のようなSQL文を実行し、テーブルとシーケンスを準備する。

-- SERIAL型の列の定義によって自動生成されるシーケンス
CREATE TABLE hoge(id SERIAL PRIMARY KEY, name CHAR(4) NOT NULL)
CREATE TABLE foo(id SERIAL PRIMARY KEY, name CHAR(4) NOT NULL)
SELECT setval('foo_id_seq', 2147483646)
SELECT nextval('foo_id_seq')
SELECT nextval('foo_id_seq')
-- 自前で作るシーケンス
CREATE SEQUENCE seq0
CREATE SEQUENCE seq1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE START WITH 1 CACHE 1 NO CYCLE
CREATE SEQUENCE seq2 INCREMENT BY 3 MINVALUE -2147483648 MAXVALUE 2147483647 START WITH 5 CACHE 3 CYCLE
SELECT setval('seq0', 2147483646)
SELECT nextval('seq0')
SELECT nextval('seq0')

seq0 と seq1 は内容的にはまったく同じもので、各設定値を明示したかしないかだけの違いである。

psqlのコマンド

psqlの「\d」コマンド。

postgres=# \d hoge_id_seq
Sequence "public.hoge_id_seq"
    Column     |  Type
---------------+---------
 sequence_name | name
 last_value    | bigint
 increment_by  | bigint
 max_value     | bigint
 min_value     | bigint
 cache_value   | bigint
 log_cnt       | bigint
 is_cycled     | boolean
 is_called     | boolean

うーん、役に立たない。せいぜい、シーケンスが生成する数値は常にBIGINTの範囲になっていそうだということと、シーケンスが持つ属性が分かる程度である。

シーケンスに対してSELECT

ふとしたことで知ったのだが、実はPostgreSQLのドキュメントに書いてあったらしい。「これ(SELECT * FROM name)を使用すると、シーケンスのパラメータと現在の状態を確認することができます。」

SELECT * FROM hoge_id_seq
UNION
SELECT * FROM foo_id_seq
UNION
SELECT * FROM seq0
UNION
SELECT * FROM seq1
UNION
SELECT * FROM seq2

ためしに実行してみると、次のような出力が得られる。

 sequence_name | last_value | increment_by |      max_value      |  min_value  | cache_value | log_cnt | is_cycled | is_called
---------------+------------+--------------+---------------------+-------------+-------------+---------+-----------+-----------
 foo_id_seq    | 2147483648 |            1 | 9223372036854775807 |           1 |           1 |      31 | f         | t
 hoge_id_seq   |          1 |            1 | 9223372036854775807 |           1 |           1 |       1 | f         | f
 seq0          | 2147483648 |            1 | 9223372036854775807 |           1 |           1 |      31 | f         | t
 seq1          |          1 |            1 | 9223372036854775807 |           1 |           1 |       1 | f         | f
 seq2          |          5 |            3 |          2147483647 | -2147483648 |           3 |       1 | t         | f
(5 rows)

情報スキーマからの取得

v8.2以降では、シーケンスが生成する値の型とかの情報は次のクエリでも取得できる。

SELECT * FROM information_schema.sequences WHERE sequence_name IN ('hoge_id_seq', 'foo_id_seq', 'seq0', 'seq1', 'seq2')

これで得られる情報は次のとおり。

 sequence_catalog | sequence_schema | sequence_name | data_type | numeric_precision | numeric_precision_radix | numeric_scale | maximum_value | minimum_value | increment | cycle_option
------------------+-----------------+---------------+-----------+-------------------+-------------------------+---------------+---------------+---------------+-----------+--------------
 postgres         | public          | hoge_id_seq   | bigint    |                64 |                       2 |             0 |               |               |           |
 postgres         | public          | foo_id_seq    | bigint    |                64 |                       2 |             0 |               |               |           |
 postgres         | public          | seq0          | bigint    |                64 |                       2 |             0 |               |               |           |
 postgres         | public          | seq1          | bigint    |                64 |                       2 |             0 |               |               |           |
 postgres         | public          | seq2          | bigint    |                64 |                       2 |             0 |               |               |           |
(5 rows)

あまり有益な情報ではないかな。せいぜい、シーケンスが生成するデータの型が分かるという程度。