2 #pragma ident "%Z%%M% %I% %E% SMI"
6 # The author disclaims copyright to this source code. In place of
7 # a legal notice, here is a blessing:
9 # May you do good and not evil.
10 # May you find forgiveness for yourself and forgive others.
11 # May you share freely, never taking more than you give.
13 #***********************************************************************
14 # This file implements regression tests for SQLite library.
16 # This file implements tests for the conflict resolution extension
19 # $Id: conflict.test,v 1.19 2003/08/05 13:13:39 drh Exp $
21 set testdir [file dirname $argv0]
22 source $testdir/tester.tcl
24 # Create tables for the first group of tests.
26 do_test conflict-1.0 {
28 CREATE TABLE t1(a, b, c, UNIQUE(a,b));
30 SELECT c FROM t1 ORDER BY c;
34 # Six columns of configuration data as follows:
36 # i The reference number of the test
37 # conf The conflict resolution algorithm on the BEGIN statement
38 # cmd An INSERT or REPLACE command to execute against table t1
39 # t0 True if there is an error from $cmd
40 # t1 Content of "c" column of t1 assuming no error in $cmd
41 # t2 Content of "x" column of t2
43 foreach {i conf cmd t0 t1 t2} {
45 2 {} {INSERT OR IGNORE} 0 3 1
46 3 {} {INSERT OR REPLACE} 0 4 1
48 5 {} {INSERT OR FAIL} 1 {} 1
49 6 {} {INSERT OR ABORT} 1 {} 1
50 7 {} {INSERT OR ROLLBACK} 1 {} {}
52 9 IGNORE {INSERT OR IGNORE} 0 3 1
53 10 IGNORE {INSERT OR REPLACE} 0 4 1
54 11 IGNORE REPLACE 0 4 1
55 12 IGNORE {INSERT OR FAIL} 1 {} 1
56 13 IGNORE {INSERT OR ABORT} 1 {} 1
57 14 IGNORE {INSERT OR ROLLBACK} 1 {} {}
58 15 REPLACE INSERT 0 4 1
60 17 ABORT INSERT 1 {} 1
61 18 ROLLBACK INSERT 1 {} {}
63 do_test conflict-1.$i {
64 if {$conf!=""} {set conf "ON CONFLICT $conf"}
65 set r0 [catch {execsql [subst {
68 INSERT INTO t1 VALUES(1,2,3);
70 INSERT INTO t2 VALUES(1);
71 $cmd INTO t1 VALUES(1,2,4);
73 catch {execsql {COMMIT}}
74 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
75 set r2 [execsql {SELECT x FROM t2}]
80 # Create tables for the first group of tests.
82 do_test conflict-2.0 {
86 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(a,b));
88 SELECT c FROM t1 ORDER BY c;
92 # Six columns of configuration data as follows:
94 # i The reference number of the test
95 # conf The conflict resolution algorithm on the BEGIN statement
96 # cmd An INSERT or REPLACE command to execute against table t1
97 # t0 True if there is an error from $cmd
98 # t1 Content of "c" column of t1 assuming no error in $cmd
99 # t2 Content of "x" column of t2
101 foreach {i conf cmd t0 t1 t2} {
103 2 {} {INSERT OR IGNORE} 0 3 1
104 3 {} {INSERT OR REPLACE} 0 4 1
106 5 {} {INSERT OR FAIL} 1 {} 1
107 6 {} {INSERT OR ABORT} 1 {} 1
108 7 {} {INSERT OR ROLLBACK} 1 {} {}
109 8 IGNORE INSERT 0 3 1
110 9 IGNORE {INSERT OR IGNORE} 0 3 1
111 10 IGNORE {INSERT OR REPLACE} 0 4 1
112 11 IGNORE REPLACE 0 4 1
113 12 IGNORE {INSERT OR FAIL} 1 {} 1
114 13 IGNORE {INSERT OR ABORT} 1 {} 1
115 14 IGNORE {INSERT OR ROLLBACK} 1 {} {}
116 15 REPLACE INSERT 0 4 1
117 16 FAIL INSERT 1 {} 1
118 17 ABORT INSERT 1 {} 1
119 18 ROLLBACK INSERT 1 {} {}
121 do_test conflict-2.$i {
122 if {$conf!=""} {set conf "ON CONFLICT $conf"}
123 set r0 [catch {execsql [subst {
126 INSERT INTO t1 VALUES(1,2,3);
128 INSERT INTO t2 VALUES(1);
129 $cmd INTO t1 VALUES(1,2,4);
131 catch {execsql {COMMIT}}
132 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
133 set r2 [execsql {SELECT x FROM t2}]
138 # Create tables for the first group of tests.
140 do_test conflict-3.0 {
144 CREATE TABLE t1(a, b, c INTEGER, PRIMARY KEY(c), UNIQUE(a,b));
146 SELECT c FROM t1 ORDER BY c;
150 # Six columns of configuration data as follows:
152 # i The reference number of the test
153 # conf The conflict resolution algorithm on the BEGIN statement
154 # cmd An INSERT or REPLACE command to execute against table t1
155 # t0 True if there is an error from $cmd
156 # t1 Content of "c" column of t1 assuming no error in $cmd
157 # t2 Content of "x" column of t2
159 foreach {i conf cmd t0 t1 t2} {
161 2 {} {INSERT OR IGNORE} 0 3 1
162 3 {} {INSERT OR REPLACE} 0 4 1
164 5 {} {INSERT OR FAIL} 1 {} 1
165 6 {} {INSERT OR ABORT} 1 {} 1
166 7 {} {INSERT OR ROLLBACK} 1 {} {}
167 8 IGNORE INSERT 0 3 1
168 9 IGNORE {INSERT OR IGNORE} 0 3 1
169 10 IGNORE {INSERT OR REPLACE} 0 4 1
170 11 IGNORE REPLACE 0 4 1
171 12 IGNORE {INSERT OR FAIL} 1 {} 1
172 13 IGNORE {INSERT OR ABORT} 1 {} 1
173 14 IGNORE {INSERT OR ROLLBACK} 1 {} {}
174 15 REPLACE INSERT 0 4 1
175 16 FAIL INSERT 1 {} 1
176 17 ABORT INSERT 1 {} 1
177 18 ROLLBACK INSERT 1 {} {}
179 do_test conflict-3.$i {
180 if {$conf!=""} {set conf "ON CONFLICT $conf"}
181 set r0 [catch {execsql [subst {
184 INSERT INTO t1 VALUES(1,2,3);
186 INSERT INTO t2 VALUES(1);
187 $cmd INTO t1 VALUES(1,2,4);
189 catch {execsql {COMMIT}}
190 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
191 set r2 [execsql {SELECT x FROM t2}]
196 do_test conflict-4.0 {
204 # Six columns of configuration data as follows:
206 # i The reference number of the test
207 # conf1 The conflict resolution algorithm on the UNIQUE constraint
208 # conf2 The conflict resolution algorithm on the BEGIN statement
209 # cmd An INSERT or REPLACE command to execute against table t1
210 # t0 True if there is an error from $cmd
211 # t1 Content of "c" column of t1 assuming no error in $cmd
212 # t2 Content of "x" column of t2
214 foreach {i conf1 conf2 cmd t0 t1 t2} {
215 1 {} {} INSERT 1 {} 1
216 2 REPLACE {} INSERT 0 4 1
217 3 IGNORE {} INSERT 0 3 1
218 4 FAIL {} INSERT 1 {} 1
219 5 ABORT {} INSERT 1 {} 1
220 6 ROLLBACK {} INSERT 1 {} {}
221 7 REPLACE {} {INSERT OR IGNORE} 0 3 1
222 8 IGNORE {} {INSERT OR REPLACE} 0 4 1
223 9 FAIL {} {INSERT OR IGNORE} 0 3 1
224 10 ABORT {} {INSERT OR REPLACE} 0 4 1
225 11 ROLLBACK {} {INSERT OR IGNORE } 0 3 1
226 12 REPLACE IGNORE INSERT 0 3 1
227 13 IGNORE REPLACE INSERT 0 4 1
228 14 FAIL IGNORE INSERT 0 3 1
229 15 ABORT REPLACE INSERT 0 4 1
230 16 ROLLBACK IGNORE INSERT 0 3 1
231 12 IGNORE REPLACE INSERT 0 4 1
232 13 IGNORE FAIL INSERT 1 {} 1
233 14 IGNORE ABORT INSERT 1 {} 1
234 15 IGNORE ROLLBACK INSERT 1 {} {}
236 do_test conflict-4.$i {
237 if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
238 if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
239 set r0 [catch {execsql [subst {
241 CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
243 INSERT INTO t1 VALUES(1,2,3);
245 INSERT INTO t2 VALUES(1);
246 $cmd INTO t1 VALUES(1,2,4);
248 catch {execsql {COMMIT}}
249 if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
250 set r2 [execsql {SELECT x FROM t2}]
255 do_test conflict-5.0 {
263 # Six columns of configuration data as follows:
265 # i The reference number of the test
266 # conf1 The conflict resolution algorithm on the NOT NULL constraint
267 # conf2 The conflict resolution algorithm on the BEGIN statement
268 # cmd An INSERT or REPLACE command to execute against table t1
269 # t0 True if there is an error from $cmd
270 # t1 Content of "c" column of t1 assuming no error in $cmd
271 # t2 Content of "x" column of t2
273 foreach {i conf1 conf2 cmd t0 t1 t2} {
274 1 {} {} INSERT 1 {} 1
275 2 REPLACE {} INSERT 0 5 1
276 3 IGNORE {} INSERT 0 {} 1
277 4 FAIL {} INSERT 1 {} 1
278 5 ABORT {} INSERT 1 {} 1
279 6 ROLLBACK {} INSERT 1 {} {}
280 7 REPLACE {} {INSERT OR IGNORE} 0 {} 1
281 8 IGNORE {} {INSERT OR REPLACE} 0 5 1
282 9 FAIL {} {INSERT OR IGNORE} 0 {} 1
283 10 ABORT {} {INSERT OR REPLACE} 0 5 1
284 11 ROLLBACK {} {INSERT OR IGNORE} 0 {} 1
285 12 {} {} {INSERT OR IGNORE} 0 {} 1
286 13 {} {} {INSERT OR REPLACE} 0 5 1
287 14 {} {} {INSERT OR FAIL} 1 {} 1
288 15 {} {} {INSERT OR ABORT} 1 {} 1
289 16 {} {} {INSERT OR ROLLBACK} 1 {} {}
290 17 {} IGNORE INSERT 0 {} 1
291 18 {} REPLACE INSERT 0 5 1
292 19 {} FAIL INSERT 1 {} 1
293 20 {} ABORT INSERT 1 {} 1
294 21 {} ROLLBACK INSERT 1 {} {}
295 22 REPLACE FAIL INSERT 1 {} 1
296 23 IGNORE ROLLBACK INSERT 1 {} {}
298 if {$t0} {set t1 {t1.c may not be NULL}}
299 do_test conflict-5.$i {
300 if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
301 if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
302 set r0 [catch {execsql [subst {
304 CREATE TABLE t1(a,b,c NOT NULL $conf1 DEFAULT 5);
307 INSERT INTO t2 VALUES(1);
308 $cmd INTO t1 VALUES(1,2,NULL);
310 catch {execsql {COMMIT}}
311 if {!$r0} {set r1 [execsql {SELECT c FROM t1}]}
312 set r2 [execsql {SELECT x FROM t2}]
317 do_test conflict-6.0 {
320 CREATE TABLE t2(a,b,c);
321 INSERT INTO t2 VALUES(1,2,1);
322 INSERT INTO t2 VALUES(2,3,2);
323 INSERT INTO t2 VALUES(3,4,1);
324 INSERT INTO t2 VALUES(4,5,4);
325 SELECT c FROM t2 ORDER BY b;
327 INSERT INTO t3 VALUES(1);
331 # Six columns of configuration data as follows:
333 # i The reference number of the test
334 # conf1 The conflict resolution algorithm on the UNIQUE constraint
335 # conf2 The conflict resolution algorithm on the BEGIN statement
336 # cmd An UPDATE command to execute against table t1
337 # t0 True if there is an error from $cmd
338 # t1 Content of "b" column of t1 assuming no error in $cmd
339 # t2 Content of "x" column of t3
341 foreach {i conf1 conf2 cmd t0 t1 t2} {
342 1 {} {} UPDATE 1 {6 7 8 9} 1
343 2 REPLACE {} UPDATE 0 {7 6 9} 1
344 3 IGNORE {} UPDATE 0 {6 7 3 9} 1
345 4 FAIL {} UPDATE 1 {6 7 3 4} 1
346 5 ABORT {} UPDATE 1 {1 2 3 4} 1
347 6 ROLLBACK {} UPDATE 1 {1 2 3 4} 0
348 7 REPLACE {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
349 8 IGNORE {} {UPDATE OR REPLACE} 0 {7 6 9} 1
350 9 FAIL {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
351 10 ABORT {} {UPDATE OR REPLACE} 0 {7 6 9} 1
352 11 ROLLBACK {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
353 12 {} {} {UPDATE OR IGNORE} 0 {6 7 3 9} 1
354 13 {} {} {UPDATE OR REPLACE} 0 {7 6 9} 1
355 14 {} {} {UPDATE OR FAIL} 1 {6 7 3 4} 1
356 15 {} {} {UPDATE OR ABORT} 1 {1 2 3 4} 1
357 16 {} {} {UPDATE OR ROLLBACK} 1 {1 2 3 4} 0
358 17 {} IGNORE UPDATE 0 {6 7 3 9} 1
359 18 {} REPLACE UPDATE 0 {7 6 9} 1
360 19 {} FAIL UPDATE 1 {6 7 3 4} 1
361 20 {} ABORT UPDATE 1 {1 2 3 4} 1
362 21 {} ROLLBACK UPDATE 1 {1 2 3 4} 0
363 22 REPLACE IGNORE UPDATE 0 {6 7 3 9} 1
364 23 IGNORE REPLACE UPDATE 0 {7 6 9} 1
365 24 REPLACE FAIL UPDATE 1 {6 7 3 4} 1
366 25 IGNORE ABORT UPDATE 1 {1 2 3 4} 1
367 26 REPLACE ROLLBACK UPDATE 1 {1 2 3 4} 0
369 if {$t0} {set t1 {column a is not unique}}
370 do_test conflict-6.$i {
371 if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
372 if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
373 set r0 [catch {execsql [subst {
375 CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
376 INSERT INTO t1 SELECT * FROM t2;
383 catch {execsql {COMMIT}}
384 if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
385 set r2 [execsql {SELECT x FROM t3}]
390 # Test to make sure a lot of IGNOREs don't cause a stack overflow
392 do_test conflict-7.1 {
397 CREATE TABLE t1(a unique, b);
399 for {set i 1} {$i<=50} {incr i} {
400 execsql "INSERT into t1 values($i,[expr {$i+1}]);"
403 SELECT count(*), min(a), max(b) FROM t1;
406 do_test conflict-7.2 {
408 PRAGMA count_changes=on;
409 UPDATE OR IGNORE t1 SET a=1000;
412 do_test conflict-7.2.1 {
415 do_test conflict-7.3 {
417 SELECT b FROM t1 WHERE a=1000;
420 do_test conflict-7.4 {
422 SELECT count(*) FROM t1;
425 do_test conflict-7.5 {
427 PRAGMA count_changes=on;
428 UPDATE OR REPLACE t1 SET a=1001;
431 do_test conflict-7.5.1 {
434 do_test conflict-7.6 {
436 SELECT b FROM t1 WHERE a=1001;
439 do_test conflict-7.7 {
441 SELECT count(*) FROM t1;
444 do_test conflict-7.7.1 {
448 # Make sure the row count is right for rows that are ignored on
451 do_test conflict-8.1 {
454 INSERT INTO t1 VALUES(1,2);
457 INSERT OR IGNORE INTO t1 VALUES(2,3);
460 do_test conflict-8.1.1 {
463 do_test conflict-8.2 {
465 INSERT OR IGNORE INTO t1 VALUES(2,4);
468 do_test conflict-8.2.1 {
471 do_test conflict-8.3 {
473 INSERT OR REPLACE INTO t1 VALUES(2,4);
476 do_test conflict-8.3.1 {
479 do_test conflict-8.4 {
481 INSERT OR IGNORE INTO t1 SELECT * FROM t1;
484 do_test conflict-8.4.1 {
487 do_test conflict-8.5 {
489 INSERT OR IGNORE INTO t1 SELECT a+2,b+2 FROM t1;
492 do_test conflict-8.5.1 {
495 do_test conflict-8.6 {
497 INSERT OR IGNORE INTO t1 SELECT a+3,b+3 FROM t1;
500 do_test conflict-8.6.1 {
504 integrity_check conflict-8.99
506 do_test conflict-9.1 {
508 PRAGMA count_changes=0;
510 a INTEGER UNIQUE ON CONFLICT IGNORE,
511 b INTEGER UNIQUE ON CONFLICT FAIL,
512 c INTEGER UNIQUE ON CONFLICT REPLACE,
513 d INTEGER UNIQUE ON CONFLICT ABORT,
514 e INTEGER UNIQUE ON CONFLICT ROLLBACK
517 INSERT INTO t3 VALUES(1);
521 do_test conflict-9.2 {
523 INSERT INTO t2 VALUES(1,1,1,1,1);
524 INSERT INTO t2 VALUES(2,2,2,2,2);
527 } {0 {1 1 1 1 1 2 2 2 2 2}}
528 do_test conflict-9.3 {
530 INSERT INTO t2 VALUES(1,3,3,3,3);
533 } {0 {1 1 1 1 1 2 2 2 2 2}}
534 do_test conflict-9.4 {
536 UPDATE t2 SET a=a+1 WHERE a=1;
539 } {0 {1 1 1 1 1 2 2 2 2 2}}
540 do_test conflict-9.5 {
542 INSERT INTO t2 VALUES(3,1,3,3,3);
545 } {1 {column b is not unique}}
546 do_test conflict-9.6 {
548 UPDATE t2 SET b=b+1 WHERE b=1;
551 } {1 {column b is not unique}}
552 do_test conflict-9.7 {
556 INSERT INTO t2 VALUES(3,1,3,3,3);
559 } {1 {column b is not unique}}
560 do_test conflict-9.8 {
562 execsql {SELECT * FROM t3}
564 do_test conflict-9.9 {
568 UPDATE t2 SET b=b+1 WHERE b=1;
571 } {1 {column b is not unique}}
572 do_test conflict-9.10 {
574 execsql {SELECT * FROM t3}
576 do_test conflict-9.11 {
578 INSERT INTO t2 VALUES(3,3,3,1,3);
581 } {1 {column d is not unique}}
582 do_test conflict-9.12 {
584 UPDATE t2 SET d=d+1 WHERE d=1;
587 } {1 {column d is not unique}}
588 do_test conflict-9.13 {
592 INSERT INTO t2 VALUES(3,3,3,1,3);
595 } {1 {column d is not unique}}
596 do_test conflict-9.14 {
598 execsql {SELECT * FROM t3}
600 do_test conflict-9.15 {
604 UPDATE t2 SET d=d+1 WHERE d=1;
607 } {1 {column d is not unique}}
608 do_test conflict-9.16 {
610 execsql {SELECT * FROM t3}
612 do_test conflict-9.17 {
614 INSERT INTO t2 VALUES(3,3,3,3,1);
617 } {1 {column e is not unique}}
618 do_test conflict-9.18 {
620 UPDATE t2 SET e=e+1 WHERE e=1;
623 } {1 {column e is not unique}}
624 do_test conflict-9.19 {
628 INSERT INTO t2 VALUES(3,3,3,3,1);
631 } {1 {column e is not unique}}
632 do_test conflict-9.20 {
633 catch {execsql {COMMIT}}
634 execsql {SELECT * FROM t3}
636 do_test conflict-9.21 {
640 UPDATE t2 SET e=e+1 WHERE e=1;
643 } {1 {column e is not unique}}
644 do_test conflict-9.22 {
645 catch {execsql {COMMIT}}
646 execsql {SELECT * FROM t3}
648 do_test conflict-9.23 {
650 INSERT INTO t2 VALUES(3,3,1,3,3);
653 } {0 {2 2 2 2 2 3 3 1 3 3}}
654 do_test conflict-9.24 {
656 UPDATE t2 SET c=c-1 WHERE c=2;
660 do_test conflict-9.25 {
664 INSERT INTO t2 VALUES(3,3,1,3,3);
668 do_test conflict-9.26 {
669 catch {execsql {COMMIT}}
670 execsql {SELECT * FROM t3}
673 do_test conflict-10.1 {
676 BEGIN ON CONFLICT ROLLBACK;
677 INSERT INTO t1 VALUES(1,2);
678 INSERT INTO t1 VALUES(1,3);
681 execsql {SELECT * FROM t1}
683 do_test conflict-10.2 {
686 CREATE UNIQUE INDEX t4x ON t4(x);
687 BEGIN ON CONFLICT ROLLBACK;
688 INSERT INTO t4 VALUES(1);
689 INSERT INTO t4 VALUES(1);
692 execsql {SELECT * FROM t4}
695 integrity_check conflict-99.0