4 # The author disclaims copyright to this source code. In place of
5 # a legal notice, here is a blessing:
7 # May you do good and not evil.
8 # May you find forgiveness for yourself and forgive others.
9 # May you share freely, never taking more than you give.
11 #***********************************************************************
12 # This file implements regression tests for SQLite library.
14 # This file implements tests for the conflict resolution extension
17 # $Id: conflict.test,v 1.19 2003/08/05 13:13:39 drh Exp $
19 set testdir [file dirname $argv0]
20 source $testdir/tester.tcl
22 # Create tables for the first group of tests.
24 do_test conflict-1.0 {
26 CREATE TABLE t1(a, b, c, UNIQUE(a,b));
28 SELECT c FROM t1 ORDER BY c;
32 # Six columns of configuration data as follows:
34 # i The reference number of the test
35 # conf The conflict resolution algorithm on the BEGIN statement
36 # cmd An INSERT or REPLACE command to execute against table t1
37 # t0 True if there is an error from $cmd
38 # t1 Content of "c" column of t1 assuming no error in $cmd
39 # t2 Content of "x" column of t2
41 foreach {i conf cmd t0 t1 t2} {
43 2 {} {INSERT OR IGNORE} 0 3 1
44 3 {} {INSERT OR REPLACE} 0 4 1
46 5 {} {INSERT OR FAIL} 1 {} 1
47 6 {} {INSERT OR ABORT} 1 {} 1
48 7 {} {INSERT OR ROLLBACK} 1 {} {}
50 9 IGNORE {INSERT OR IGNORE} 0 3 1
51 10 IGNORE {INSERT OR REPLACE} 0 4 1
52 11 IGNORE REPLACE 0 4 1
53 12 IGNORE {INSERT OR FAIL} 1 {} 1
54 13 IGNORE {INSERT OR ABORT} 1 {} 1
55 14 IGNORE {INSERT OR ROLLBACK} 1 {} {}
56 15 REPLACE INSERT 0 4 1
58 17 ABORT INSERT 1 {} 1
59 18 ROLLBACK INSERT 1 {} {}
61 do_test conflict-1.$i {
62 if {$conf!=""} {set conf "ON CONFLICT $conf"}
63 set r0 [catch {execsql [subst {
66 INSERT INTO t1 VALUES(1,2,3);
68 INSERT INTO t2 VALUES(1);
69 $cmd INTO t1 VALUES(1,2,4);
71 catch {execsql {COMMIT}}
72 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
73 set r2 [execsql {SELECT x FROM t2}]
78 # Create tables for the first group of tests.
80 do_test conflict-2.0 {
84 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(a,b));
86 SELECT c FROM t1 ORDER BY c;
90 # Six columns of configuration data as follows:
92 # i The reference number of the test
93 # conf The conflict resolution algorithm on the BEGIN statement
94 # cmd An INSERT or REPLACE command to execute against table t1
95 # t0 True if there is an error from $cmd
96 # t1 Content of "c" column of t1 assuming no error in $cmd
97 # t2 Content of "x" column of t2
99 foreach {i conf cmd t0 t1 t2} {
101 2 {} {INSERT OR IGNORE} 0 3 1
102 3 {} {INSERT OR REPLACE} 0 4 1
104 5 {} {INSERT OR FAIL} 1 {} 1
105 6 {} {INSERT OR ABORT} 1 {} 1
106 7 {} {INSERT OR ROLLBACK} 1 {} {}
107 8 IGNORE INSERT 0 3 1
108 9 IGNORE {INSERT OR IGNORE} 0 3 1
109 10 IGNORE {INSERT OR REPLACE} 0 4 1
110 11 IGNORE REPLACE 0 4 1
111 12 IGNORE {INSERT OR FAIL} 1 {} 1
112 13 IGNORE {INSERT OR ABORT} 1 {} 1
113 14 IGNORE {INSERT OR ROLLBACK} 1 {} {}
114 15 REPLACE INSERT 0 4 1
115 16 FAIL INSERT 1 {} 1
116 17 ABORT INSERT 1 {} 1
117 18 ROLLBACK INSERT 1 {} {}
119 do_test conflict-2.$i {
120 if {$conf!=""} {set conf "ON CONFLICT $conf"}
121 set r0 [catch {execsql [subst {
124 INSERT INTO t1 VALUES(1,2,3);
126 INSERT INTO t2 VALUES(1);
127 $cmd INTO t1 VALUES(1,2,4);
129 catch {execsql {COMMIT}}
130 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
131 set r2 [execsql {SELECT x FROM t2}]
136 # Create tables for the first group of tests.
138 do_test conflict-3.0 {
142 CREATE TABLE t1(a, b, c INTEGER, PRIMARY KEY(c), UNIQUE(a,b));
144 SELECT c FROM t1 ORDER BY c;
148 # Six columns of configuration data as follows:
150 # i The reference number of the test
151 # conf The conflict resolution algorithm on the BEGIN statement
152 # cmd An INSERT or REPLACE command to execute against table t1
153 # t0 True if there is an error from $cmd
154 # t1 Content of "c" column of t1 assuming no error in $cmd
155 # t2 Content of "x" column of t2
157 foreach {i conf cmd t0 t1 t2} {
159 2 {} {INSERT OR IGNORE} 0 3 1
160 3 {} {INSERT OR REPLACE} 0 4 1
162 5 {} {INSERT OR FAIL} 1 {} 1
163 6 {} {INSERT OR ABORT} 1 {} 1
164 7 {} {INSERT OR ROLLBACK} 1 {} {}
165 8 IGNORE INSERT 0 3 1
166 9 IGNORE {INSERT OR IGNORE} 0 3 1
167 10 IGNORE {INSERT OR REPLACE} 0 4 1
168 11 IGNORE REPLACE 0 4 1
169 12 IGNORE {INSERT OR FAIL} 1 {} 1
170 13 IGNORE {INSERT OR ABORT} 1 {} 1
171 14 IGNORE {INSERT OR ROLLBACK} 1 {} {}
172 15 REPLACE INSERT 0 4 1
173 16 FAIL INSERT 1 {} 1
174 17 ABORT INSERT 1 {} 1
175 18 ROLLBACK INSERT 1 {} {}
177 do_test conflict-3.$i {
178 if {$conf!=""} {set conf "ON CONFLICT $conf"}
179 set r0 [catch {execsql [subst {
182 INSERT INTO t1 VALUES(1,2,3);
184 INSERT INTO t2 VALUES(1);
185 $cmd INTO t1 VALUES(1,2,4);
187 catch {execsql {COMMIT}}
188 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
189 set r2 [execsql {SELECT x FROM t2}]
194 do_test conflict-4.0 {
202 # Six columns of configuration data as follows:
204 # i The reference number of the test
205 # conf1 The conflict resolution algorithm on the UNIQUE constraint
206 # conf2 The conflict resolution algorithm on the BEGIN statement
207 # cmd An INSERT or REPLACE command to execute against table t1
208 # t0 True if there is an error from $cmd
209 # t1 Content of "c" column of t1 assuming no error in $cmd
210 # t2 Content of "x" column of t2
212 foreach {i conf1 conf2 cmd t0 t1 t2} {
213 1 {} {} INSERT 1 {} 1
214 2 REPLACE {} INSERT 0 4 1
215 3 IGNORE {} INSERT 0 3 1
216 4 FAIL {} INSERT 1 {} 1
217 5 ABORT {} INSERT 1 {} 1
218 6 ROLLBACK {} INSERT 1 {} {}
219 7 REPLACE {} {INSERT OR IGNORE} 0 3 1
220 8 IGNORE {} {INSERT OR REPLACE} 0 4 1
221 9 FAIL {} {INSERT OR IGNORE} 0 3 1
222 10 ABORT {} {INSERT OR REPLACE} 0 4 1
223 11 ROLLBACK {} {INSERT OR IGNORE } 0 3 1
224 12 REPLACE IGNORE INSERT 0 3 1
225 13 IGNORE REPLACE INSERT 0 4 1
226 14 FAIL IGNORE INSERT 0 3 1
227 15 ABORT REPLACE INSERT 0 4 1
228 16 ROLLBACK IGNORE INSERT 0 3 1
229 12 IGNORE REPLACE INSERT 0 4 1
230 13 IGNORE FAIL INSERT 1 {} 1
231 14 IGNORE ABORT INSERT 1 {} 1
232 15 IGNORE ROLLBACK INSERT 1 {} {}
234 do_test conflict-4.$i {
235 if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
236 if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
237 set r0 [catch {execsql [subst {
239 CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
241 INSERT INTO t1 VALUES(1,2,3);
243 INSERT INTO t2 VALUES(1);
244 $cmd INTO t1 VALUES(1,2,4);
246 catch {execsql {COMMIT}}
247 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
248 set r2 [execsql {SELECT x FROM t2}]
253 do_test conflict-5.0 {
261 # Six columns of configuration data as follows:
263 # i The reference number of the test
264 # conf1 The conflict resolution algorithm on the NOT NULL constraint
265 # conf2 The conflict resolution algorithm on the BEGIN statement
266 # cmd An INSERT or REPLACE command to execute against table t1
267 # t0 True if there is an error from $cmd
268 # t1 Content of "c" column of t1 assuming no error in $cmd
269 # t2 Content of "x" column of t2
271 foreach {i conf1 conf2 cmd t0 t1 t2} {
272 1 {} {} INSERT 1 {} 1
273 2 REPLACE {} INSERT 0 5 1
274 3 IGNORE {} INSERT 0 {} 1
275 4 FAIL {} INSERT 1 {} 1
276 5 ABORT {} INSERT 1 {} 1
277 6 ROLLBACK {} INSERT 1 {} {}
278 7 REPLACE {} {INSERT OR IGNORE} 0 {} 1
279 8 IGNORE {} {INSERT OR REPLACE} 0 5 1
280 9 FAIL {} {INSERT OR IGNORE} 0 {} 1
281 10 ABORT {} {INSERT OR REPLACE} 0 5 1
282 11 ROLLBACK {} {INSERT OR IGNORE} 0 {} 1
283 12 {} {} {INSERT OR IGNORE} 0 {} 1
284 13 {} {} {INSERT OR REPLACE} 0 5 1
285 14 {} {} {INSERT OR FAIL} 1 {} 1
286 15 {} {} {INSERT OR ABORT} 1 {} 1
287 16 {} {} {INSERT OR ROLLBACK} 1 {} {}
288 17 {} IGNORE INSERT 0 {} 1
289 18 {} REPLACE INSERT 0 5 1
290 19 {} FAIL INSERT 1 {} 1
291 20 {} ABORT INSERT 1 {} 1
292 21 {} ROLLBACK INSERT 1 {} {}
293 22 REPLACE FAIL INSERT 1 {} 1
294 23 IGNORE ROLLBACK INSERT 1 {} {}
296 if {$t0} {set t1 {t1.c may not be NULL}}
297 do_test conflict-5.$i {
298 if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
299 if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
300 set r0 [catch {execsql [subst {
302 CREATE TABLE t1(a,b,c NOT NULL $conf1 DEFAULT 5);
305 INSERT INTO t2 VALUES(1);
306 $cmd INTO t1 VALUES(1,2,NULL);
308 catch {execsql {COMMIT}}
309 if {!$r0} {set r1 [execsql {SELECT c FROM t1}]}
310 set r2 [execsql {SELECT x FROM t2}]
315 do_test conflict-6.0 {
318 CREATE TABLE t2(a,b,c);
319 INSERT INTO t2 VALUES(1,2,1);
320 INSERT INTO t2 VALUES(2,3,2);
321 INSERT INTO t2 VALUES(3,4,1);
322 INSERT INTO t2 VALUES(4,5,4);
323 SELECT c FROM t2 ORDER BY b;
325 INSERT INTO t3 VALUES(1);
329 # Six columns of configuration data as follows:
331 # i The reference number of the test
332 # conf1 The conflict resolution algorithm on the UNIQUE constraint
333 # conf2 The conflict resolution algorithm on the BEGIN statement
334 # cmd An UPDATE command to execute against table t1
335 # t0 True if there is an error from $cmd
336 # t1 Content of "b" column of t1 assuming no error in $cmd
337 # t2 Content of "x" column of t3
339 foreach {i conf1 conf2 cmd t0 t1 t2} {
340 1 {} {} UPDATE 1 {6 7 8 9} 1
341 2 REPLACE {} UPDATE 0 {7 6 9} 1
342 3 IGNORE {} UPDATE 0 {6 7 3 9} 1
343 4 FAIL {} UPDATE 1 {6 7 3 4} 1
344 5 ABORT {} UPDATE 1 {1 2 3 4} 1
345 6 ROLLBACK {} UPDATE 1 {1 2 3 4} 0
346 7 REPLACE {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
347 8 IGNORE {} {UPDATE OR REPLACE} 0 {7 6 9} 1
348 9 FAIL {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
349 10 ABORT {} {UPDATE OR REPLACE} 0 {7 6 9} 1
350 11 ROLLBACK {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
351 12 {} {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
352 13 {} {} {UPDATE OR REPLACE} 0 {7 6 9} 1
353 14 {} {} {UPDATE OR FAIL} 1 {6 7 3 4} 1
354 15 {} {} {UPDATE OR ABORT} 1 {1 2 3 4} 1
355 16 {} {} {UPDATE OR ROLLBACK} 1 {1 2 3 4} 0
356 17 {} IGNORE UPDATE 0 {6 7 3 9} 1
357 18 {} REPLACE UPDATE 0 {7 6 9} 1
358 19 {} FAIL UPDATE 1 {6 7 3 4} 1
359 20 {} ABORT UPDATE 1 {1 2 3 4} 1
360 21 {} ROLLBACK UPDATE 1 {1 2 3 4} 0
361 22 REPLACE IGNORE UPDATE 0 {6 7 3 9} 1
362 23 IGNORE REPLACE UPDATE 0 {7 6 9} 1
363 24 REPLACE FAIL UPDATE 1 {6 7 3 4} 1
364 25 IGNORE ABORT UPDATE 1 {1 2 3 4} 1
365 26 REPLACE ROLLBACK UPDATE 1 {1 2 3 4} 0
367 if {$t0} {set t1 {column a is not unique}}
368 do_test conflict-6.$i {
369 if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
370 if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
371 set r0 [catch {execsql [subst {
373 CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
374 INSERT INTO t1 SELECT * FROM t2;
381 catch {execsql {COMMIT}}
382 if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
383 set r2 [execsql {SELECT x FROM t3}]
388 # Test to make sure a lot of IGNOREs don't cause a stack overflow
390 do_test conflict-7.1 {
395 CREATE TABLE t1(a unique, b);
397 for {set i 1} {$i<=50} {incr i} {
398 execsql "INSERT into t1 values($i,[expr {$i+1}]);"
401 SELECT count(*), min(a), max(b) FROM t1;
404 do_test conflict-7.2 {
406 PRAGMA count_changes=on;
407 UPDATE OR IGNORE t1 SET a=1000;
410 do_test conflict-7.2.1 {
413 do_test conflict-7.3 {
415 SELECT b FROM t1 WHERE a=1000;
418 do_test conflict-7.4 {
420 SELECT count(*) FROM t1;
423 do_test conflict-7.5 {
425 PRAGMA count_changes=on;
426 UPDATE OR REPLACE t1 SET a=1001;
429 do_test conflict-7.5.1 {
432 do_test conflict-7.6 {
434 SELECT b FROM t1 WHERE a=1001;
437 do_test conflict-7.7 {
439 SELECT count(*) FROM t1;
442 do_test conflict-7.7.1 {
446 # Make sure the row count is right for rows that are ignored on
449 do_test conflict-8.1 {
452 INSERT INTO t1 VALUES(1,2);
455 INSERT OR IGNORE INTO t1 VALUES(2,3);
458 do_test conflict-8.1.1 {
461 do_test conflict-8.2 {
463 INSERT OR IGNORE INTO t1 VALUES(2,4);
466 do_test conflict-8.2.1 {
469 do_test conflict-8.3 {
471 INSERT OR REPLACE INTO t1 VALUES(2,4);
474 do_test conflict-8.3.1 {
477 do_test conflict-8.4 {
479 INSERT OR IGNORE INTO t1 SELECT * FROM t1;
482 do_test conflict-8.4.1 {
485 do_test conflict-8.5 {
487 INSERT OR IGNORE INTO t1 SELECT a+2,b+2 FROM t1;
490 do_test conflict-8.5.1 {
493 do_test conflict-8.6 {
495 INSERT OR IGNORE INTO t1 SELECT a+3,b+3 FROM t1;
498 do_test conflict-8.6.1 {
502 integrity_check conflict-8.99
504 do_test conflict-9.1 {
506 PRAGMA count_changes=0;
508 a INTEGER UNIQUE ON CONFLICT IGNORE,
509 b INTEGER UNIQUE ON CONFLICT FAIL,
510 c INTEGER UNIQUE ON CONFLICT REPLACE,
511 d INTEGER UNIQUE ON CONFLICT ABORT,
512 e INTEGER UNIQUE ON CONFLICT ROLLBACK
515 INSERT INTO t3 VALUES(1);
519 do_test conflict-9.2 {
521 INSERT INTO t2 VALUES(1,1,1,1,1);
522 INSERT INTO t2 VALUES(2,2,2,2,2);
525 } {0 {1 1 1 1 1 2 2 2 2 2}}
526 do_test conflict-9.3 {
528 INSERT INTO t2 VALUES(1,3,3,3,3);
531 } {0 {1 1 1 1 1 2 2 2 2 2}}
532 do_test conflict-9.4 {
534 UPDATE t2 SET a=a+1 WHERE a=1;
537 } {0 {1 1 1 1 1 2 2 2 2 2}}
538 do_test conflict-9.5 {
540 INSERT INTO t2 VALUES(3,1,3,3,3);
543 } {1 {column b is not unique}}
544 do_test conflict-9.6 {
546 UPDATE t2 SET b=b+1 WHERE b=1;
549 } {1 {column b is not unique}}
550 do_test conflict-9.7 {
554 INSERT INTO t2 VALUES(3,1,3,3,3);
557 } {1 {column b is not unique}}
558 do_test conflict-9.8 {
560 execsql {SELECT * FROM t3}
562 do_test conflict-9.9 {
566 UPDATE t2 SET b=b+1 WHERE b=1;
569 } {1 {column b is not unique}}
570 do_test conflict-9.10 {
572 execsql {SELECT * FROM t3}
574 do_test conflict-9.11 {
576 INSERT INTO t2 VALUES(3,3,3,1,3);
579 } {1 {column d is not unique}}
580 do_test conflict-9.12 {
582 UPDATE t2 SET d=d+1 WHERE d=1;
585 } {1 {column d is not unique}}
586 do_test conflict-9.13 {
590 INSERT INTO t2 VALUES(3,3,3,1,3);
593 } {1 {column d is not unique}}
594 do_test conflict-9.14 {
596 execsql {SELECT * FROM t3}
598 do_test conflict-9.15 {
602 UPDATE t2 SET d=d+1 WHERE d=1;
605 } {1 {column d is not unique}}
606 do_test conflict-9.16 {
608 execsql {SELECT * FROM t3}
610 do_test conflict-9.17 {
612 INSERT INTO t2 VALUES(3,3,3,3,1);
615 } {1 {column e is not unique}}
616 do_test conflict-9.18 {
618 UPDATE t2 SET e=e+1 WHERE e=1;
621 } {1 {column e is not unique}}
622 do_test conflict-9.19 {
626 INSERT INTO t2 VALUES(3,3,3,3,1);
629 } {1 {column e is not unique}}
630 do_test conflict-9.20 {
631 catch {execsql {COMMIT}}
632 execsql {SELECT * FROM t3}
634 do_test conflict-9.21 {
638 UPDATE t2 SET e=e+1 WHERE e=1;
641 } {1 {column e is not unique}}
642 do_test conflict-9.22 {
643 catch {execsql {COMMIT}}
644 execsql {SELECT * FROM t3}
646 do_test conflict-9.23 {
648 INSERT INTO t2 VALUES(3,3,1,3,3);
651 } {0 {2 2 2 2 2 3 3 1 3 3}}
652 do_test conflict-9.24 {
654 UPDATE t2 SET c=c-1 WHERE c=2;
658 do_test conflict-9.25 {
662 INSERT INTO t2 VALUES(3,3,1,3,3);
666 do_test conflict-9.26 {
667 catch {execsql {COMMIT}}
668 execsql {SELECT * FROM t3}
671 do_test conflict-10.1 {
674 BEGIN ON CONFLICT ROLLBACK;
675 INSERT INTO t1 VALUES(1,2);
676 INSERT INTO t1 VALUES(1,3);
679 execsql {SELECT * FROM t1}
681 do_test conflict-10.2 {
684 CREATE UNIQUE INDEX t4x ON t4(x);
685 BEGIN ON CONFLICT ROLLBACK;
686 INSERT INTO t4 VALUES(1);
687 INSERT INTO t4 VALUES(1);
690 execsql {SELECT * FROM t4}
693 integrity_check conflict-99.0