PostgreSQL の SEQUENCE に値を設定するには ALTER SEQUENCE と setval() の 2 つの方法があります。
さらに setval() には 引数が 2 つのものと 3 つのものがあります。 それぞれの実行結果を見ていきます。
まず ALTER SEQUENCE 。
db=# ALTER SEQUENCE test_sequence RESTART WITH 1;
このとき、内部の値は次のようになっています。
db=# SELECT last_value, is_called FROM test_sequence; -[ RECORD 1 ]-- last_value | 1 is_called | f
last_value が RESTART WITH で設定した 1 になり、 is_called が f (偽) になります。
is_called というのは last_value が既に呼ばれたかどうかのフラグで is_called が偽であれば まだ呼ばれていないので nextval() したときに last_value の 1 を返します。
次に 引数が 2 つの setval() です。
db=# SELECT setval('test_sequence', 1);
このとき、内部の値は次のようになっています。
db=# SELECT last_value, is_called FROM test_sequence; -[ RECORD 1 ]-- last_value | 1 is_called | t
引数が 2 つの setval() では last_value は同じですが is_called が t (真) になりました。 last_value の 1 は既に呼ばれているという内容なので この場合 nextval() したときに 1 + increment_by (デフォルト 1) を返します。
同じように 1 を設定しても ALTER SEQUENCE と 引数が 2 つの setval() では 次に返す値が変わってしまいます。
そこで 引数が 3 つの setval() の出番になります。
db=# SELECT setval('test_sequence', 1, false);
上のように 引数が 3 つの setval() では 第三引数で is_called の値を指定することができます。
これで ALTER SEQUENCE したときと同じになります。
db=# SELECT last_value, is_called FROM test_sequence; -[ RECORD 1 ]-- last_value | 1 is_called | f
SEQUENCE はデータの一意性を守ってくれる大事な機能なので 移行時などにずれてしまわないよう注意が必要です。