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