genfkey.test 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. package require sqlite3
  2. proc do_test {name cmd expected} {
  3. puts -nonewline "$name ..."
  4. set res [uplevel $cmd]
  5. if {$res eq $expected} {
  6. puts Ok
  7. } else {
  8. puts Error
  9. puts " Got: $res"
  10. puts " Expected: $expected"
  11. exit
  12. }
  13. }
  14. proc execsql {sql} {
  15. uplevel [list db eval $sql]
  16. }
  17. proc catchsql {sql} {
  18. set rc [catch {uplevel [list db eval $sql]} msg]
  19. list $rc $msg
  20. }
  21. file delete -force test.db test.db.journal
  22. sqlite3 db test.db
  23. # The following tests - genfkey-1.* - test RESTRICT foreign keys.
  24. #
  25. do_test genfkey-1.1 {
  26. execsql {
  27. CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
  28. CREATE TABLE t2(e REFERENCES t1, f);
  29. CREATE TABLE t3(g, h, i, FOREIGN KEY (h, i) REFERENCES t1(b, c));
  30. }
  31. } {}
  32. do_test genfkey-1.2 {
  33. execsql [exec ./sqlite3 test.db .genfkey]
  34. } {}
  35. do_test genfkey-1.3 {
  36. catchsql { INSERT INTO t2 VALUES(1, 2) }
  37. } {1 {constraint failed}}
  38. do_test genfkey-1.4 {
  39. execsql {
  40. INSERT INTO t1 VALUES(1, 2, 3);
  41. INSERT INTO t2 VALUES(1, 2);
  42. }
  43. } {}
  44. do_test genfkey-1.5 {
  45. execsql { INSERT INTO t2 VALUES(NULL, 3) }
  46. } {}
  47. do_test genfkey-1.6 {
  48. catchsql { UPDATE t2 SET e = 5 WHERE e IS NULL }
  49. } {1 {constraint failed}}
  50. do_test genfkey-1.7 {
  51. execsql { UPDATE t2 SET e = 1 WHERE e IS NULL }
  52. } {}
  53. do_test genfkey-1.8 {
  54. execsql { UPDATE t2 SET e = NULL WHERE f = 3 }
  55. } {}
  56. do_test genfkey-1.9 {
  57. catchsql { UPDATE t1 SET a = 10 }
  58. } {1 {constraint failed}}
  59. do_test genfkey-1.9a {
  60. catchsql { UPDATE t1 SET a = NULL }
  61. } {1 {datatype mismatch}}
  62. do_test genfkey-1.10 {
  63. catchsql { DELETE FROM t1 }
  64. } {1 {constraint failed}}
  65. do_test genfkey-1.11 {
  66. execsql { UPDATE t2 SET e = NULL }
  67. } {}
  68. do_test genfkey-1.12 {
  69. execsql {
  70. UPDATE t1 SET a = 10 ;
  71. DELETE FROM t1;
  72. DELETE FROM t2;
  73. }
  74. } {}
  75. do_test genfkey-1.13 {
  76. execsql {
  77. INSERT INTO t3 VALUES(1, NULL, NULL);
  78. INSERT INTO t3 VALUES(1, 2, NULL);
  79. INSERT INTO t3 VALUES(1, NULL, 3);
  80. }
  81. } {}
  82. do_test genfkey-1.14 {
  83. catchsql { INSERT INTO t3 VALUES(3, 1, 4) }
  84. } {1 {constraint failed}}
  85. do_test genfkey-1.15 {
  86. execsql {
  87. INSERT INTO t1 VALUES(1, 1, 4);
  88. INSERT INTO t3 VALUES(3, 1, 4);
  89. }
  90. } {}
  91. do_test genfkey-1.16 {
  92. catchsql { DELETE FROM t1 }
  93. } {1 {constraint failed}}
  94. do_test genfkey-1.17 {
  95. catchsql { UPDATE t1 SET b = 10}
  96. } {1 {constraint failed}}
  97. do_test genfkey-1.18 {
  98. execsql { UPDATE t1 SET a = 10}
  99. } {}
  100. do_test genfkey-1.19 {
  101. catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3}
  102. } {1 {constraint failed}}
  103. do_test genfkey-1.X {
  104. execsql {
  105. DROP TABLE t1;
  106. DROP TABLE t2;
  107. DROP TABLE t3;
  108. }
  109. } {}
  110. # The following tests - genfkey-2.* - test CASCADE foreign keys.
  111. #
  112. do_test genfkey-2.1 {
  113. execsql {
  114. CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
  115. CREATE TABLE t2(e REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE, f);
  116. CREATE TABLE t3(g, h, i,
  117. FOREIGN KEY (h, i)
  118. REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE
  119. );
  120. }
  121. } {}
  122. do_test genfkey-2.2 {
  123. execsql [exec ./sqlite3 test.db .genfkey]
  124. } {}
  125. do_test genfkey-2.3 {
  126. execsql {
  127. INSERT INTO t1 VALUES(1, 2, 3);
  128. INSERT INTO t1 VALUES(4, 5, 6);
  129. INSERT INTO t2 VALUES(1, 'one');
  130. INSERT INTO t2 VALUES(4, 'four');
  131. }
  132. } {}
  133. do_test genfkey-2.4 {
  134. execsql {
  135. UPDATE t1 SET a = 2 WHERE a = 1;
  136. SELECT * FROM t2;
  137. }
  138. } {2 one 4 four}
  139. do_test genfkey-2.5 {
  140. execsql {
  141. DELETE FROM t1 WHERE a = 4;
  142. SELECT * FROM t2;
  143. }
  144. } {2 one}
  145. do_test genfkey-2.6 {
  146. execsql {
  147. INSERT INTO t3 VALUES('hello', 2, 3);
  148. UPDATE t1 SET c = 2;
  149. SELECT * FROM t3;
  150. }
  151. } {hello 2 2}
  152. do_test genfkey-2.7 {
  153. execsql {
  154. DELETE FROM t1;
  155. SELECT * FROM t3;
  156. }
  157. } {}
  158. do_test genfkey-2.X {
  159. execsql {
  160. DROP TABLE t1;
  161. DROP TABLE t2;
  162. DROP TABLE t3;
  163. }
  164. } {}
  165. # The following tests - genfkey-3.* - test SET NULL foreign keys.
  166. #
  167. do_test genfkey-3.1 {
  168. execsql {
  169. CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(c, b));
  170. CREATE TABLE t2(e REFERENCES t1 ON UPDATE SET NULL ON DELETE SET NULL, f);
  171. CREATE TABLE t3(g, h, i,
  172. FOREIGN KEY (h, i)
  173. REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL
  174. );
  175. }
  176. } {}
  177. do_test genfkey-3.2 {
  178. execsql [exec ./sqlite3 test.db .genfkey]
  179. } {}
  180. do_test genfkey-3.3 {
  181. execsql {
  182. INSERT INTO t1 VALUES(1, 2, 3);
  183. INSERT INTO t1 VALUES(4, 5, 6);
  184. INSERT INTO t2 VALUES(1, 'one');
  185. INSERT INTO t2 VALUES(4, 'four');
  186. }
  187. } {}
  188. do_test genfkey-3.4 {
  189. execsql {
  190. UPDATE t1 SET a = 2 WHERE a = 1;
  191. SELECT * FROM t2;
  192. }
  193. } {{} one 4 four}
  194. do_test genfkey-3.5 {
  195. execsql {
  196. DELETE FROM t1 WHERE a = 4;
  197. SELECT * FROM t2;
  198. }
  199. } {{} one {} four}
  200. do_test genfkey-3.6 {
  201. execsql {
  202. INSERT INTO t3 VALUES('hello', 2, 3);
  203. UPDATE t1 SET c = 2;
  204. SELECT * FROM t3;
  205. }
  206. } {hello {} {}}
  207. do_test genfkey-2.7 {
  208. execsql {
  209. UPDATE t3 SET h = 2, i = 2;
  210. DELETE FROM t1;
  211. SELECT * FROM t3;
  212. }
  213. } {hello {} {}}
  214. do_test genfkey-3.X {
  215. execsql {
  216. DROP TABLE t1;
  217. DROP TABLE t2;
  218. DROP TABLE t3;
  219. }
  220. } {}
  221. # The following tests - genfkey-4.* - test that errors in the schema
  222. # are detected correctly.
  223. #
  224. do_test genfkey-4.1 {
  225. execsql {
  226. CREATE TABLE t1(a REFERENCES nosuchtable, b);
  227. CREATE TABLE t2(a REFERENCES t1, b);
  228. CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b));
  229. CREATE TABLE t4(a, b, c, FOREIGN KEY(c, b) REFERENCES t3);
  230. CREATE TABLE t5(a REFERENCES t4(d), b, c);
  231. CREATE TABLE t6(a REFERENCES t4(a), b, c);
  232. CREATE TABLE t7(a REFERENCES t3(a), b, c);
  233. CREATE TABLE t8(a REFERENCES nosuchtable(a), b, c);
  234. }
  235. } {}
  236. do_test genfkey-4.X {
  237. set rc [catch {exec ./sqlite3 test.db .genfkey} msg]
  238. list $rc $msg
  239. } "1 {[string trim {
  240. Error in table t5: foreign key columns do not exist
  241. Error in table t8: foreign key columns do not exist
  242. Error in table t4: implicit mapping to composite primary key
  243. Error in table t1: implicit mapping to non-existant primary key
  244. Error in table t2: implicit mapping to non-existant primary key
  245. Error in table t6: foreign key is not unique
  246. Error in table t7: foreign key is not unique
  247. }]}"
  248. # Test that ticket #3800 has been resolved.
  249. #
  250. do_test genfkey-5.1 {
  251. execsql {
  252. DROP TABLE t1; DROP TABLE t2; DROP TABLE t3;
  253. DROP TABLE t4; DROP TABLE t5; DROP TABLE t6;
  254. DROP TABLE t7; DROP TABLE t8;
  255. }
  256. } {}
  257. do_test genfkey-5.2 {
  258. execsql {
  259. CREATE TABLE "t.3" (c1 PRIMARY KEY);
  260. CREATE TABLE t13 (c1, foreign key(c1) references "t.3"(c1));
  261. }
  262. } {}
  263. do_test genfkey-5.3 {
  264. set rc [catch {exec ./sqlite3 test.db .genfkey} msg]
  265. } {0}
  266. do_test genfkey-5.4 {
  267. db eval $msg
  268. } {}
  269. do_test genfkey-5.5 {
  270. catchsql { INSERT INTO t13 VALUES(1) }
  271. } {1 {constraint failed}}
  272. do_test genfkey-5.5 {
  273. catchsql {
  274. INSERT INTO "t.3" VALUES(1);
  275. INSERT INTO t13 VALUES(1);
  276. }
  277. } {0 {}}
  278. # Test also column names that require quoting.
  279. do_test genfkey-6.1 {
  280. execsql {
  281. DROP TABLE "t.3";
  282. DROP TABLE t13;
  283. CREATE TABLE p(
  284. "a.1 first", "b.2 second",
  285. UNIQUE("a.1 first", "b.2 second")
  286. );
  287. CREATE TABLE c(
  288. "c.1 I", "d.2 II",
  289. FOREIGN KEY("c.1 I", "d.2 II")
  290. REFERENCES p("a.1 first", "b.2 second")
  291. ON UPDATE CASCADE ON DELETE CASCADE
  292. );
  293. }
  294. } {}
  295. do_test genfkey-6.2 {
  296. set rc [catch {exec ./sqlite3 test.db .genfkey} msg]
  297. } {0}
  298. do_test genfkey-6.3 {
  299. execsql $msg
  300. execsql {
  301. INSERT INTO p VALUES('A', 'B');
  302. INSERT INTO p VALUES('C', 'D');
  303. INSERT INTO c VALUES('A', 'B');
  304. INSERT INTO c VALUES('C', 'D');
  305. UPDATE p SET "a.1 first" = 'X' WHERE rowid = 1;
  306. DELETE FROM p WHERE rowid = 2;
  307. }
  308. execsql { SELECT * FROM c }
  309. } {X B}
  310. do_test genfkey-6.4 {
  311. execsql {
  312. DROP TABLE p;
  313. DROP TABLE c;
  314. CREATE TABLE parent("a.1", PRIMARY KEY("a.1"));
  315. CREATE TABLE child("b.2", FOREIGN KEY("b.2") REFERENCES parent("a.1"));
  316. }
  317. set rc [catch {exec ./sqlite3 test.db .genfkey} msg]
  318. } {0}
  319. do_test genfkey-6.5 {
  320. execsql $msg
  321. execsql {
  322. INSERT INTO parent VALUES(1);
  323. INSERT INTO child VALUES(1);
  324. }
  325. catchsql { UPDATE parent SET "a.1"=0 }
  326. } {1 {constraint failed}}
  327. do_test genfkey-6.6 {
  328. catchsql { UPDATE child SET "b.2"=7 }
  329. } {1 {constraint failed}}
  330. do_test genfkey-6.7 {
  331. execsql {
  332. SELECT * FROM parent;
  333. SELECT * FROM child;
  334. }
  335. } {1 1}