[pgsql-jp: 37581] 被外部参照テーブル削除時の制約の遅延について

kishino kishino @ jins.co.jp
2006年 10月 18日 (水) 10:15:21 JST


岸野と申します。

 はじめまして。
 いつもこちらのMLにはお世話になっています。

 さて、テーブルの外部参照に関して、予期しない
 現象が起きているので質問させていただきます。

 使用OS: Windows 2000 SP3
 (ただし、Red Hatでもまったく同じ結果です)
 PostgreSQL 8.1.3

 ----- SQL ここから -----
select version();

create table test (
  id int4 primary key,
  name text
);
create table test_sub (
  id int4 primary key,
  val text,
  constraint test_refer foreign key (id)
    references test (id) on delete restrict
    deferrable initially deferred
);

insert into test values (1,'test');
insert into test_sub values (1,'test too');

begin;
delete from test where id=1;
delete from test_sub where id=1;
commit;
 ----- SQL ここまで -----

 ----- 実行結果ここから -----
                                         version

------------------------------------------------------------------------------------------
 PostgreSQL 8.1.3 on i686-pc-mingw32, compiled by GCC gcc.exe (GCC)
3.4.4 (mingw special)
(1 row)

test=#
test=# create table test (
test(#   id int4 primary key,
test(#   name text
test(# );
test=# create table test_sub (
test(#   id int4 primary key,
test(#   val text,
test(#   constraint test_refer foreign key (id)
test(#     references test (id) on delete restrict
test(#     deferrable initially deferred
test(# );
test=#
test=# insert into test values (1,'test');
INSERT 0 1
test=# insert into test_sub values (1,'test too');
INSERT 0 1
test=#
test=# begin;
BEGIN
test=# delete from test where id=1;
ERROR:  update or delete on "test" violates foreign key constraint
"test_refer" on "test_sub"
DETAIL:  Key (id)=(1) is still referenced from table "test_sub".
test=# delete from test_sub where id=1;
ERROR:  current transaction is aborted, commands ignored until end of
transaction block
test=# commit;
ROLLBACK
 ----- 実行結果ここまで -----
 上記の SQLで、テーブル「test」は「test_sub」
 から参照されています。

 削除時の挙動は「RESTRICT」ですので、「test」
 のデータを削除しようとするとエラーになります。

 が、「DEFERRABLE INITIALLY DEFERRED」 と指定
 してあるので、私の理解では制約の検査はトラン
 ザクションの終了時に行われることを期待してい
 ます。

 つまり上記 SQLは問題なく「commit」される予定
 なのですが、実際には一つ目の「delete」で制約
 のエラーになってしまいます。


 これは正しい動作なのでしょうか。
 私が何か勘違いをしているのでしょうか。

 なにか情報をお持ちの方がいらっしゃいましたら、
 ぜひ、ご教示願います。


 よろしくお願いします。

-- 
岸野 謙一 kishino @ jins.co.jp
(株)ジインズ システムソリューション部
ソフトウェア開発グループ
TEL 055-220-2580 FAX 055-220-2582
URL http://www.jins.co.jp/





pgsql-jp メーリングリストの案内