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