fkey6.test 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. # 2013-07-11
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library.
  12. #
  13. # This file tests the PRAGMA defer_foreign_keys and
  14. # SQLITE_DBSTATUS_DEFERRED_FKS
  15. #
  16. # EVIDENCE-OF: R-18981-16292 When the defer_foreign_keys PRAGMA is on,
  17. # enforcement of all foreign key constraints is delayed until the
  18. # outermost transaction is committed.
  19. #
  20. # EVIDENCE-OF: R-28911-57501 The defer_foreign_keys pragma defaults to
  21. # OFF so that foreign key constraints are only deferred if they are
  22. # created as "DEFERRABLE INITIALLY DEFERRED".
  23. set testdir [file dirname $argv0]
  24. source $testdir/tester.tcl
  25. ifcapable {!foreignkey} {
  26. finish_test
  27. return
  28. }
  29. do_execsql_test fkey6-1.0 {
  30. PRAGMA defer_foreign_keys;
  31. } {0}
  32. do_execsql_test fkey6-1.1 {
  33. PRAGMA foreign_keys=ON;
  34. CREATE TABLE t1(x INTEGER PRIMARY KEY);
  35. CREATE TABLE t2(y INTEGER PRIMARY KEY,
  36. z INTEGER REFERENCES t1(x) DEFERRABLE INITIALLY DEFERRED);
  37. CREATE INDEX t2z ON t2(z);
  38. CREATE TABLE t3(u INTEGER PRIMARY KEY, v INTEGER REFERENCES t1(x));
  39. CREATE INDEX t3v ON t3(v);
  40. INSERT INTO t1 VALUES(1),(2),(3),(4),(5);
  41. INSERT INTO t2 VALUES(1,1),(2,2);
  42. INSERT INTO t3 VALUES(3,3),(4,4);
  43. } {}
  44. do_test fkey6-1.2 {
  45. catchsql {DELETE FROM t1 WHERE x=2;}
  46. } {1 {foreign key constraint failed}}
  47. do_test fkey6-1.3 {
  48. sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
  49. } {0 0 0}
  50. do_test fkey6-1.4 {
  51. execsql {
  52. BEGIN;
  53. DELETE FROM t1 WHERE x=1;
  54. }
  55. } {}
  56. do_test fkey6-1.5.1 {
  57. sqlite3_db_status db DBSTATUS_DEFERRED_FKS 1
  58. } {0 1 0}
  59. do_test fkey6-1.5.2 {
  60. sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
  61. } {0 1 0}
  62. do_test fkey6-1.6 {
  63. execsql {
  64. ROLLBACK;
  65. }
  66. } {}
  67. do_test fkey6-1.7 {
  68. sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
  69. } {0 0 0}
  70. do_test fkey6-1.8 {
  71. execsql {
  72. PRAGMA defer_foreign_keys=ON;
  73. BEGIN;
  74. DELETE FROM t1 WHERE x=3;
  75. }
  76. } {}
  77. do_test fkey6-1.9 {
  78. sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
  79. } {0 1 0}
  80. # EVIDENCE-OF: R-21752-26913 The defer_foreign_keys pragma is
  81. # automatically switched off at each COMMIT or ROLLBACK. Hence, the
  82. # defer_foreign_keys pragma must be separately enabled for each
  83. # transaction.
  84. do_execsql_test fkey6-1.10.1 {
  85. PRAGMA defer_foreign_keys;
  86. ROLLBACK;
  87. PRAGMA defer_foreign_keys;
  88. BEGIN;
  89. PRAGMA defer_foreign_keys=ON;
  90. PRAGMA defer_foreign_keys;
  91. COMMIT;
  92. PRAGMA defer_foreign_keys;
  93. BEGIN;
  94. } {1 0 1 0}
  95. do_test fkey6-1.10.2 {
  96. catchsql {DELETE FROM t1 WHERE x=3}
  97. } {1 {foreign key constraint failed}}
  98. db eval {ROLLBACK}
  99. do_test fkey6-1.20 {
  100. execsql {
  101. BEGIN;
  102. DELETE FROM t1 WHERE x=1;
  103. }
  104. sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
  105. } {0 1 0}
  106. do_test fkey6-1.21 {
  107. execsql {
  108. DELETE FROM t2 WHERE y=1;
  109. }
  110. sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
  111. } {0 0 0}
  112. do_test fkey6-1.22 {
  113. execsql {
  114. COMMIT;
  115. }
  116. } {}
  117. do_execsql_test fkey6-2.1 {
  118. CREATE TABLE p1(a PRIMARY KEY);
  119. INSERT INTO p1 VALUES('one'), ('two');
  120. CREATE TABLE c1(x REFERENCES p1);
  121. INSERT INTO c1 VALUES('two'), ('one');
  122. }
  123. do_execsql_test fkey6-2.2 {
  124. BEGIN;
  125. PRAGMA defer_foreign_keys = 1;
  126. DELETE FROM p1;
  127. ROLLBACK;
  128. PRAGMA defer_foreign_keys;
  129. } {0}
  130. do_execsql_test fkey6-2.3 {
  131. BEGIN;
  132. PRAGMA defer_foreign_keys = 1;
  133. DROP TABLE p1;
  134. PRAGMA vdbe_trace = 0;
  135. ROLLBACK;
  136. PRAGMA defer_foreign_keys;
  137. } {0}
  138. do_execsql_test fkey6-2.4 {
  139. BEGIN;
  140. PRAGMA defer_foreign_keys = 1;
  141. DELETE FROM p1;
  142. DROP TABLE c1;
  143. COMMIT;
  144. PRAGMA defer_foreign_keys;
  145. } {0}
  146. do_execsql_test fkey6-2.5 {
  147. DROP TABLE p1;
  148. CREATE TABLE p1(a PRIMARY KEY);
  149. INSERT INTO p1 VALUES('one'), ('two');
  150. CREATE TABLE c1(x REFERENCES p1);
  151. INSERT INTO c1 VALUES('two'), ('one');
  152. }
  153. do_execsql_test fkey6-2.6 {
  154. BEGIN;
  155. PRAGMA defer_foreign_keys = 1;
  156. INSERT INTO c1 VALUES('three');
  157. DROP TABLE c1;
  158. COMMIT;
  159. PRAGMA defer_foreign_keys;
  160. } {0}
  161. finish_test