xref: /titanic_52/usr/src/lib/libsqlite/test/conflict.test (revision c5c4113dfcabb1eed3d4bdf7609de5170027a794)
1*c5c4113dSnw141292
2*c5c4113dSnw141292#pragma ident	"%Z%%M%	%I%	%E% SMI"
3*c5c4113dSnw141292
4*c5c4113dSnw141292# 2002 January 29
5*c5c4113dSnw141292#
6*c5c4113dSnw141292# The author disclaims copyright to this source code.  In place of
7*c5c4113dSnw141292# a legal notice, here is a blessing:
8*c5c4113dSnw141292#
9*c5c4113dSnw141292#    May you do good and not evil.
10*c5c4113dSnw141292#    May you find forgiveness for yourself and forgive others.
11*c5c4113dSnw141292#    May you share freely, never taking more than you give.
12*c5c4113dSnw141292#
13*c5c4113dSnw141292#***********************************************************************
14*c5c4113dSnw141292# This file implements regression tests for SQLite library.
15*c5c4113dSnw141292#
16*c5c4113dSnw141292# This file implements tests for the conflict resolution extension
17*c5c4113dSnw141292# to SQLite.
18*c5c4113dSnw141292#
19*c5c4113dSnw141292# $Id: conflict.test,v 1.19 2003/08/05 13:13:39 drh Exp $
20*c5c4113dSnw141292
21*c5c4113dSnw141292set testdir [file dirname $argv0]
22*c5c4113dSnw141292source $testdir/tester.tcl
23*c5c4113dSnw141292
24*c5c4113dSnw141292# Create tables for the first group of tests.
25*c5c4113dSnw141292#
26*c5c4113dSnw141292do_test conflict-1.0 {
27*c5c4113dSnw141292  execsql {
28*c5c4113dSnw141292    CREATE TABLE t1(a, b, c, UNIQUE(a,b));
29*c5c4113dSnw141292    CREATE TABLE t2(x);
30*c5c4113dSnw141292    SELECT c FROM t1 ORDER BY c;
31*c5c4113dSnw141292  }
32*c5c4113dSnw141292} {}
33*c5c4113dSnw141292
34*c5c4113dSnw141292# Six columns of configuration data as follows:
35*c5c4113dSnw141292#
36*c5c4113dSnw141292#   i      The reference number of the test
37*c5c4113dSnw141292#   conf   The conflict resolution algorithm on the BEGIN statement
38*c5c4113dSnw141292#   cmd    An INSERT or REPLACE command to execute against table t1
39*c5c4113dSnw141292#   t0     True if there is an error from $cmd
40*c5c4113dSnw141292#   t1     Content of "c" column of t1 assuming no error in $cmd
41*c5c4113dSnw141292#   t2     Content of "x" column of t2
42*c5c4113dSnw141292#
43*c5c4113dSnw141292foreach {i conf cmd t0 t1 t2} {
44*c5c4113dSnw141292  1 {}       INSERT                  1 {}  1
45*c5c4113dSnw141292  2 {}       {INSERT OR IGNORE}      0 3   1
46*c5c4113dSnw141292  3 {}       {INSERT OR REPLACE}     0 4   1
47*c5c4113dSnw141292  4 {}       REPLACE                 0 4   1
48*c5c4113dSnw141292  5 {}       {INSERT OR FAIL}        1 {}  1
49*c5c4113dSnw141292  6 {}       {INSERT OR ABORT}       1 {}  1
50*c5c4113dSnw141292  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
51*c5c4113dSnw141292  8 IGNORE   INSERT                  0 3   1
52*c5c4113dSnw141292  9 IGNORE   {INSERT OR IGNORE}      0 3   1
53*c5c4113dSnw141292 10 IGNORE   {INSERT OR REPLACE}     0 4   1
54*c5c4113dSnw141292 11 IGNORE   REPLACE                 0 4   1
55*c5c4113dSnw141292 12 IGNORE   {INSERT OR FAIL}        1 {}  1
56*c5c4113dSnw141292 13 IGNORE   {INSERT OR ABORT}       1 {}  1
57*c5c4113dSnw141292 14 IGNORE   {INSERT OR ROLLBACK}    1 {}  {}
58*c5c4113dSnw141292 15 REPLACE  INSERT                  0 4   1
59*c5c4113dSnw141292 16 FAIL     INSERT                  1 {}  1
60*c5c4113dSnw141292 17 ABORT    INSERT                  1 {}  1
61*c5c4113dSnw141292 18 ROLLBACK INSERT                  1 {}  {}
62*c5c4113dSnw141292} {
63*c5c4113dSnw141292  do_test conflict-1.$i {
64*c5c4113dSnw141292    if {$conf!=""} {set conf "ON CONFLICT $conf"}
65*c5c4113dSnw141292    set r0 [catch {execsql [subst {
66*c5c4113dSnw141292      DELETE FROM t1;
67*c5c4113dSnw141292      DELETE FROM t2;
68*c5c4113dSnw141292      INSERT INTO t1 VALUES(1,2,3);
69*c5c4113dSnw141292      BEGIN $conf;
70*c5c4113dSnw141292      INSERT INTO t2 VALUES(1);
71*c5c4113dSnw141292      $cmd INTO t1 VALUES(1,2,4);
72*c5c4113dSnw141292    }]} r1]
73*c5c4113dSnw141292    catch {execsql {COMMIT}}
74*c5c4113dSnw141292    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
75*c5c4113dSnw141292    set r2 [execsql {SELECT x FROM t2}]
76*c5c4113dSnw141292    list $r0 $r1 $r2
77*c5c4113dSnw141292  } [list $t0 $t1 $t2]
78*c5c4113dSnw141292}
79*c5c4113dSnw141292
80*c5c4113dSnw141292# Create tables for the first group of tests.
81*c5c4113dSnw141292#
82*c5c4113dSnw141292do_test conflict-2.0 {
83*c5c4113dSnw141292  execsql {
84*c5c4113dSnw141292    DROP TABLE t1;
85*c5c4113dSnw141292    DROP TABLE t2;
86*c5c4113dSnw141292    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(a,b));
87*c5c4113dSnw141292    CREATE TABLE t2(x);
88*c5c4113dSnw141292    SELECT c FROM t1 ORDER BY c;
89*c5c4113dSnw141292  }
90*c5c4113dSnw141292} {}
91*c5c4113dSnw141292
92*c5c4113dSnw141292# Six columns of configuration data as follows:
93*c5c4113dSnw141292#
94*c5c4113dSnw141292#   i      The reference number of the test
95*c5c4113dSnw141292#   conf   The conflict resolution algorithm on the BEGIN statement
96*c5c4113dSnw141292#   cmd    An INSERT or REPLACE command to execute against table t1
97*c5c4113dSnw141292#   t0     True if there is an error from $cmd
98*c5c4113dSnw141292#   t1     Content of "c" column of t1 assuming no error in $cmd
99*c5c4113dSnw141292#   t2     Content of "x" column of t2
100*c5c4113dSnw141292#
101*c5c4113dSnw141292foreach {i conf cmd t0 t1 t2} {
102*c5c4113dSnw141292  1 {}       INSERT                  1 {}  1
103*c5c4113dSnw141292  2 {}       {INSERT OR IGNORE}      0 3   1
104*c5c4113dSnw141292  3 {}       {INSERT OR REPLACE}     0 4   1
105*c5c4113dSnw141292  4 {}       REPLACE                 0 4   1
106*c5c4113dSnw141292  5 {}       {INSERT OR FAIL}        1 {}  1
107*c5c4113dSnw141292  6 {}       {INSERT OR ABORT}       1 {}  1
108*c5c4113dSnw141292  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
109*c5c4113dSnw141292  8 IGNORE   INSERT                  0 3   1
110*c5c4113dSnw141292  9 IGNORE   {INSERT OR IGNORE}      0 3   1
111*c5c4113dSnw141292 10 IGNORE   {INSERT OR REPLACE}     0 4   1
112*c5c4113dSnw141292 11 IGNORE   REPLACE                 0 4   1
113*c5c4113dSnw141292 12 IGNORE   {INSERT OR FAIL}        1 {}  1
114*c5c4113dSnw141292 13 IGNORE   {INSERT OR ABORT}       1 {}  1
115*c5c4113dSnw141292 14 IGNORE   {INSERT OR ROLLBACK}    1 {}  {}
116*c5c4113dSnw141292 15 REPLACE  INSERT                  0 4   1
117*c5c4113dSnw141292 16 FAIL     INSERT                  1 {}  1
118*c5c4113dSnw141292 17 ABORT    INSERT                  1 {}  1
119*c5c4113dSnw141292 18 ROLLBACK INSERT                  1 {}  {}
120*c5c4113dSnw141292} {
121*c5c4113dSnw141292  do_test conflict-2.$i {
122*c5c4113dSnw141292    if {$conf!=""} {set conf "ON CONFLICT $conf"}
123*c5c4113dSnw141292    set r0 [catch {execsql [subst {
124*c5c4113dSnw141292      DELETE FROM t1;
125*c5c4113dSnw141292      DELETE FROM t2;
126*c5c4113dSnw141292      INSERT INTO t1 VALUES(1,2,3);
127*c5c4113dSnw141292      BEGIN $conf;
128*c5c4113dSnw141292      INSERT INTO t2 VALUES(1);
129*c5c4113dSnw141292      $cmd INTO t1 VALUES(1,2,4);
130*c5c4113dSnw141292    }]} r1]
131*c5c4113dSnw141292    catch {execsql {COMMIT}}
132*c5c4113dSnw141292    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
133*c5c4113dSnw141292    set r2 [execsql {SELECT x FROM t2}]
134*c5c4113dSnw141292    list $r0 $r1 $r2
135*c5c4113dSnw141292  } [list $t0 $t1 $t2]
136*c5c4113dSnw141292}
137*c5c4113dSnw141292
138*c5c4113dSnw141292# Create tables for the first group of tests.
139*c5c4113dSnw141292#
140*c5c4113dSnw141292do_test conflict-3.0 {
141*c5c4113dSnw141292  execsql {
142*c5c4113dSnw141292    DROP TABLE t1;
143*c5c4113dSnw141292    DROP TABLE t2;
144*c5c4113dSnw141292    CREATE TABLE t1(a, b, c INTEGER, PRIMARY KEY(c), UNIQUE(a,b));
145*c5c4113dSnw141292    CREATE TABLE t2(x);
146*c5c4113dSnw141292    SELECT c FROM t1 ORDER BY c;
147*c5c4113dSnw141292  }
148*c5c4113dSnw141292} {}
149*c5c4113dSnw141292
150*c5c4113dSnw141292# Six columns of configuration data as follows:
151*c5c4113dSnw141292#
152*c5c4113dSnw141292#   i      The reference number of the test
153*c5c4113dSnw141292#   conf   The conflict resolution algorithm on the BEGIN statement
154*c5c4113dSnw141292#   cmd    An INSERT or REPLACE command to execute against table t1
155*c5c4113dSnw141292#   t0     True if there is an error from $cmd
156*c5c4113dSnw141292#   t1     Content of "c" column of t1 assuming no error in $cmd
157*c5c4113dSnw141292#   t2     Content of "x" column of t2
158*c5c4113dSnw141292#
159*c5c4113dSnw141292foreach {i conf cmd t0 t1 t2} {
160*c5c4113dSnw141292  1 {}       INSERT                  1 {}  1
161*c5c4113dSnw141292  2 {}       {INSERT OR IGNORE}      0 3   1
162*c5c4113dSnw141292  3 {}       {INSERT OR REPLACE}     0 4   1
163*c5c4113dSnw141292  4 {}       REPLACE                 0 4   1
164*c5c4113dSnw141292  5 {}       {INSERT OR FAIL}        1 {}  1
165*c5c4113dSnw141292  6 {}       {INSERT OR ABORT}       1 {}  1
166*c5c4113dSnw141292  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
167*c5c4113dSnw141292  8 IGNORE   INSERT                  0 3   1
168*c5c4113dSnw141292  9 IGNORE   {INSERT OR IGNORE}      0 3   1
169*c5c4113dSnw141292 10 IGNORE   {INSERT OR REPLACE}     0 4   1
170*c5c4113dSnw141292 11 IGNORE   REPLACE                 0 4   1
171*c5c4113dSnw141292 12 IGNORE   {INSERT OR FAIL}        1 {}  1
172*c5c4113dSnw141292 13 IGNORE   {INSERT OR ABORT}       1 {}  1
173*c5c4113dSnw141292 14 IGNORE   {INSERT OR ROLLBACK}    1 {}  {}
174*c5c4113dSnw141292 15 REPLACE  INSERT                  0 4   1
175*c5c4113dSnw141292 16 FAIL     INSERT                  1 {}  1
176*c5c4113dSnw141292 17 ABORT    INSERT                  1 {}  1
177*c5c4113dSnw141292 18 ROLLBACK INSERT                  1 {}  {}
178*c5c4113dSnw141292} {
179*c5c4113dSnw141292  do_test conflict-3.$i {
180*c5c4113dSnw141292    if {$conf!=""} {set conf "ON CONFLICT $conf"}
181*c5c4113dSnw141292    set r0 [catch {execsql [subst {
182*c5c4113dSnw141292      DELETE FROM t1;
183*c5c4113dSnw141292      DELETE FROM t2;
184*c5c4113dSnw141292      INSERT INTO t1 VALUES(1,2,3);
185*c5c4113dSnw141292      BEGIN $conf;
186*c5c4113dSnw141292      INSERT INTO t2 VALUES(1);
187*c5c4113dSnw141292      $cmd INTO t1 VALUES(1,2,4);
188*c5c4113dSnw141292    }]} r1]
189*c5c4113dSnw141292    catch {execsql {COMMIT}}
190*c5c4113dSnw141292    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
191*c5c4113dSnw141292    set r2 [execsql {SELECT x FROM t2}]
192*c5c4113dSnw141292    list $r0 $r1 $r2
193*c5c4113dSnw141292  } [list $t0 $t1 $t2]
194*c5c4113dSnw141292}
195*c5c4113dSnw141292
196*c5c4113dSnw141292do_test conflict-4.0 {
197*c5c4113dSnw141292  execsql {
198*c5c4113dSnw141292    DROP TABLE t2;
199*c5c4113dSnw141292    CREATE TABLE t2(x);
200*c5c4113dSnw141292    SELECT x FROM t2;
201*c5c4113dSnw141292  }
202*c5c4113dSnw141292} {}
203*c5c4113dSnw141292
204*c5c4113dSnw141292# Six columns of configuration data as follows:
205*c5c4113dSnw141292#
206*c5c4113dSnw141292#   i      The reference number of the test
207*c5c4113dSnw141292#   conf1  The conflict resolution algorithm on the UNIQUE constraint
208*c5c4113dSnw141292#   conf2  The conflict resolution algorithm on the BEGIN statement
209*c5c4113dSnw141292#   cmd    An INSERT or REPLACE command to execute against table t1
210*c5c4113dSnw141292#   t0     True if there is an error from $cmd
211*c5c4113dSnw141292#   t1     Content of "c" column of t1 assuming no error in $cmd
212*c5c4113dSnw141292#   t2     Content of "x" column of t2
213*c5c4113dSnw141292#
214*c5c4113dSnw141292foreach {i conf1 conf2 cmd t0 t1 t2} {
215*c5c4113dSnw141292  1 {}       {}       INSERT                  1 {}  1
216*c5c4113dSnw141292  2 REPLACE  {}       INSERT                  0 4   1
217*c5c4113dSnw141292  3 IGNORE   {}       INSERT                  0 3   1
218*c5c4113dSnw141292  4 FAIL     {}       INSERT                  1 {}  1
219*c5c4113dSnw141292  5 ABORT    {}       INSERT                  1 {}  1
220*c5c4113dSnw141292  6 ROLLBACK {}       INSERT                  1 {}  {}
221*c5c4113dSnw141292  7 REPLACE  {}       {INSERT OR IGNORE}      0 3   1
222*c5c4113dSnw141292  8 IGNORE   {}       {INSERT OR REPLACE}     0 4   1
223*c5c4113dSnw141292  9 FAIL     {}       {INSERT OR IGNORE}      0 3   1
224*c5c4113dSnw141292 10 ABORT    {}       {INSERT OR REPLACE}     0 4   1
225*c5c4113dSnw141292 11 ROLLBACK {}       {INSERT OR IGNORE }     0 3   1
226*c5c4113dSnw141292 12 REPLACE  IGNORE   INSERT                  0 3   1
227*c5c4113dSnw141292 13 IGNORE   REPLACE  INSERT                  0 4   1
228*c5c4113dSnw141292 14 FAIL     IGNORE   INSERT                  0 3   1
229*c5c4113dSnw141292 15 ABORT    REPLACE  INSERT                  0 4   1
230*c5c4113dSnw141292 16 ROLLBACK IGNORE   INSERT                  0 3   1
231*c5c4113dSnw141292 12 IGNORE   REPLACE  INSERT                  0 4   1
232*c5c4113dSnw141292 13 IGNORE   FAIL     INSERT                  1 {}  1
233*c5c4113dSnw141292 14 IGNORE   ABORT    INSERT                  1 {}  1
234*c5c4113dSnw141292 15 IGNORE   ROLLBACK INSERT                  1 {}  {}
235*c5c4113dSnw141292} {
236*c5c4113dSnw141292  do_test conflict-4.$i {
237*c5c4113dSnw141292    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
238*c5c4113dSnw141292    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
239*c5c4113dSnw141292    set r0 [catch {execsql [subst {
240*c5c4113dSnw141292      DROP TABLE t1;
241*c5c4113dSnw141292      CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
242*c5c4113dSnw141292      DELETE FROM t2;
243*c5c4113dSnw141292      INSERT INTO t1 VALUES(1,2,3);
244*c5c4113dSnw141292      BEGIN $conf2;
245*c5c4113dSnw141292      INSERT INTO t2 VALUES(1);
246*c5c4113dSnw141292      $cmd INTO t1 VALUES(1,2,4);
247*c5c4113dSnw141292    }]} r1]
248*c5c4113dSnw141292    catch {execsql {COMMIT}}
249*c5c4113dSnw141292    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
250*c5c4113dSnw141292    set r2 [execsql {SELECT x FROM t2}]
251*c5c4113dSnw141292    list $r0 $r1 $r2
252*c5c4113dSnw141292  } [list $t0 $t1 $t2]
253*c5c4113dSnw141292}
254*c5c4113dSnw141292
255*c5c4113dSnw141292do_test conflict-5.0 {
256*c5c4113dSnw141292  execsql {
257*c5c4113dSnw141292    DROP TABLE t2;
258*c5c4113dSnw141292    CREATE TABLE t2(x);
259*c5c4113dSnw141292    SELECT x FROM t2;
260*c5c4113dSnw141292  }
261*c5c4113dSnw141292} {}
262*c5c4113dSnw141292
263*c5c4113dSnw141292# Six columns of configuration data as follows:
264*c5c4113dSnw141292#
265*c5c4113dSnw141292#   i      The reference number of the test
266*c5c4113dSnw141292#   conf1  The conflict resolution algorithm on the NOT NULL constraint
267*c5c4113dSnw141292#   conf2  The conflict resolution algorithm on the BEGIN statement
268*c5c4113dSnw141292#   cmd    An INSERT or REPLACE command to execute against table t1
269*c5c4113dSnw141292#   t0     True if there is an error from $cmd
270*c5c4113dSnw141292#   t1     Content of "c" column of t1 assuming no error in $cmd
271*c5c4113dSnw141292#   t2     Content of "x" column of t2
272*c5c4113dSnw141292#
273*c5c4113dSnw141292foreach {i conf1 conf2 cmd t0 t1 t2} {
274*c5c4113dSnw141292  1 {}       {}       INSERT                  1 {}  1
275*c5c4113dSnw141292  2 REPLACE  {}       INSERT                  0 5   1
276*c5c4113dSnw141292  3 IGNORE   {}       INSERT                  0 {}  1
277*c5c4113dSnw141292  4 FAIL     {}       INSERT                  1 {}  1
278*c5c4113dSnw141292  5 ABORT    {}       INSERT                  1 {}  1
279*c5c4113dSnw141292  6 ROLLBACK {}       INSERT                  1 {}  {}
280*c5c4113dSnw141292  7 REPLACE  {}       {INSERT OR IGNORE}      0 {}  1
281*c5c4113dSnw141292  8 IGNORE   {}       {INSERT OR REPLACE}     0 5   1
282*c5c4113dSnw141292  9 FAIL     {}       {INSERT OR IGNORE}      0 {}  1
283*c5c4113dSnw141292 10 ABORT    {}       {INSERT OR REPLACE}     0 5   1
284*c5c4113dSnw141292 11 ROLLBACK {}       {INSERT OR IGNORE}      0 {}  1
285*c5c4113dSnw141292 12 {}       {}       {INSERT OR IGNORE}      0 {}  1
286*c5c4113dSnw141292 13 {}       {}       {INSERT OR REPLACE}     0 5   1
287*c5c4113dSnw141292 14 {}       {}       {INSERT OR FAIL}        1 {}  1
288*c5c4113dSnw141292 15 {}       {}       {INSERT OR ABORT}       1 {}  1
289*c5c4113dSnw141292 16 {}       {}       {INSERT OR ROLLBACK}    1 {}  {}
290*c5c4113dSnw141292 17 {}       IGNORE   INSERT                  0 {}  1
291*c5c4113dSnw141292 18 {}       REPLACE  INSERT                  0 5   1
292*c5c4113dSnw141292 19 {}       FAIL     INSERT                  1 {}  1
293*c5c4113dSnw141292 20 {}       ABORT    INSERT                  1 {}  1
294*c5c4113dSnw141292 21 {}       ROLLBACK INSERT                  1 {}  {}
295*c5c4113dSnw141292 22 REPLACE  FAIL     INSERT                  1 {}  1
296*c5c4113dSnw141292 23 IGNORE   ROLLBACK INSERT                  1 {}  {}
297*c5c4113dSnw141292} {
298*c5c4113dSnw141292  if {$t0} {set t1 {t1.c may not be NULL}}
299*c5c4113dSnw141292  do_test conflict-5.$i {
300*c5c4113dSnw141292    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
301*c5c4113dSnw141292    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
302*c5c4113dSnw141292    set r0 [catch {execsql [subst {
303*c5c4113dSnw141292      DROP TABLE t1;
304*c5c4113dSnw141292      CREATE TABLE t1(a,b,c NOT NULL $conf1 DEFAULT 5);
305*c5c4113dSnw141292      DELETE FROM t2;
306*c5c4113dSnw141292      BEGIN $conf2;
307*c5c4113dSnw141292      INSERT INTO t2 VALUES(1);
308*c5c4113dSnw141292      $cmd INTO t1 VALUES(1,2,NULL);
309*c5c4113dSnw141292    }]} r1]
310*c5c4113dSnw141292    catch {execsql {COMMIT}}
311*c5c4113dSnw141292    if {!$r0} {set r1 [execsql {SELECT c FROM t1}]}
312*c5c4113dSnw141292    set r2 [execsql {SELECT x FROM t2}]
313*c5c4113dSnw141292    list $r0 $r1 $r2
314*c5c4113dSnw141292  } [list $t0 $t1 $t2]
315*c5c4113dSnw141292}
316*c5c4113dSnw141292
317*c5c4113dSnw141292do_test conflict-6.0 {
318*c5c4113dSnw141292  execsql {
319*c5c4113dSnw141292    DROP TABLE t2;
320*c5c4113dSnw141292    CREATE TABLE t2(a,b,c);
321*c5c4113dSnw141292    INSERT INTO t2 VALUES(1,2,1);
322*c5c4113dSnw141292    INSERT INTO t2 VALUES(2,3,2);
323*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,4,1);
324*c5c4113dSnw141292    INSERT INTO t2 VALUES(4,5,4);
325*c5c4113dSnw141292    SELECT c FROM t2 ORDER BY b;
326*c5c4113dSnw141292    CREATE TABLE t3(x);
327*c5c4113dSnw141292    INSERT INTO t3 VALUES(1);
328*c5c4113dSnw141292  }
329*c5c4113dSnw141292} {1 2 1 4}
330*c5c4113dSnw141292
331*c5c4113dSnw141292# Six columns of configuration data as follows:
332*c5c4113dSnw141292#
333*c5c4113dSnw141292#   i      The reference number of the test
334*c5c4113dSnw141292#   conf1  The conflict resolution algorithm on the UNIQUE constraint
335*c5c4113dSnw141292#   conf2  The conflict resolution algorithm on the BEGIN statement
336*c5c4113dSnw141292#   cmd    An UPDATE command to execute against table t1
337*c5c4113dSnw141292#   t0     True if there is an error from $cmd
338*c5c4113dSnw141292#   t1     Content of "b" column of t1 assuming no error in $cmd
339*c5c4113dSnw141292#   t2     Content of "x" column of t3
340*c5c4113dSnw141292#
341*c5c4113dSnw141292foreach {i conf1 conf2 cmd t0 t1 t2} {
342*c5c4113dSnw141292  1 {}       {}       UPDATE                  1 {6 7 8 9}  1
343*c5c4113dSnw141292  2 REPLACE  {}       UPDATE                  0 {7 6 9}    1
344*c5c4113dSnw141292  3 IGNORE   {}       UPDATE                  0 {6 7 3 9}  1
345*c5c4113dSnw141292  4 FAIL     {}       UPDATE                  1 {6 7 3 4}  1
346*c5c4113dSnw141292  5 ABORT    {}       UPDATE                  1 {1 2 3 4}  1
347*c5c4113dSnw141292  6 ROLLBACK {}       UPDATE                  1 {1 2 3 4}  0
348*c5c4113dSnw141292  7 REPLACE  {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
349*c5c4113dSnw141292  8 IGNORE   {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
350*c5c4113dSnw141292  9 FAIL     {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
351*c5c4113dSnw141292 10 ABORT    {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
352*c5c4113dSnw141292 11 ROLLBACK {}       {UPDATE OR IGNORE}      0 {6 7 3 9}   1
353*c5c4113dSnw141292 12 {}       {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
354*c5c4113dSnw141292 13 {}       {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
355*c5c4113dSnw141292 14 {}       {}       {UPDATE OR FAIL}        1 {6 7 3 4}  1
356*c5c4113dSnw141292 15 {}       {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1
357*c5c4113dSnw141292 16 {}       {}       {UPDATE OR ROLLBACK}    1 {1 2 3 4}  0
358*c5c4113dSnw141292 17 {}       IGNORE   UPDATE                  0 {6 7 3 9}  1
359*c5c4113dSnw141292 18 {}       REPLACE  UPDATE                  0 {7 6 9}    1
360*c5c4113dSnw141292 19 {}       FAIL     UPDATE                  1 {6 7 3 4}  1
361*c5c4113dSnw141292 20 {}       ABORT    UPDATE                  1 {1 2 3 4}  1
362*c5c4113dSnw141292 21 {}       ROLLBACK UPDATE                  1 {1 2 3 4}  0
363*c5c4113dSnw141292 22 REPLACE  IGNORE   UPDATE                  0 {6 7 3 9}  1
364*c5c4113dSnw141292 23 IGNORE   REPLACE  UPDATE                  0 {7 6 9}    1
365*c5c4113dSnw141292 24 REPLACE  FAIL     UPDATE                  1 {6 7 3 4}  1
366*c5c4113dSnw141292 25 IGNORE   ABORT    UPDATE                  1 {1 2 3 4}  1
367*c5c4113dSnw141292 26 REPLACE  ROLLBACK UPDATE                  1 {1 2 3 4}  0
368*c5c4113dSnw141292} {
369*c5c4113dSnw141292  if {$t0} {set t1 {column a is not unique}}
370*c5c4113dSnw141292  do_test conflict-6.$i {
371*c5c4113dSnw141292    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
372*c5c4113dSnw141292    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
373*c5c4113dSnw141292    set r0 [catch {execsql [subst {
374*c5c4113dSnw141292      DROP TABLE t1;
375*c5c4113dSnw141292      CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
376*c5c4113dSnw141292      INSERT INTO t1 SELECT * FROM t2;
377*c5c4113dSnw141292      UPDATE t3 SET x=0;
378*c5c4113dSnw141292      BEGIN $conf2;
379*c5c4113dSnw141292      $cmd t3 SET x=1;
380*c5c4113dSnw141292      $cmd t1 SET b=b*2;
381*c5c4113dSnw141292      $cmd t1 SET a=c+5;
382*c5c4113dSnw141292    }]} r1]
383*c5c4113dSnw141292    catch {execsql {COMMIT}}
384*c5c4113dSnw141292    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
385*c5c4113dSnw141292    set r2 [execsql {SELECT x FROM t3}]
386*c5c4113dSnw141292    list $r0 $r1 $r2
387*c5c4113dSnw141292  } [list $t0 $t1 $t2]
388*c5c4113dSnw141292}
389*c5c4113dSnw141292
390*c5c4113dSnw141292# Test to make sure a lot of IGNOREs don't cause a stack overflow
391*c5c4113dSnw141292#
392*c5c4113dSnw141292do_test conflict-7.1 {
393*c5c4113dSnw141292  execsql {
394*c5c4113dSnw141292    DROP TABLE t1;
395*c5c4113dSnw141292    DROP TABLE t2;
396*c5c4113dSnw141292    DROP TABLE t3;
397*c5c4113dSnw141292    CREATE TABLE t1(a unique, b);
398*c5c4113dSnw141292  }
399*c5c4113dSnw141292  for {set i 1} {$i<=50} {incr i} {
400*c5c4113dSnw141292    execsql "INSERT into t1 values($i,[expr {$i+1}]);"
401*c5c4113dSnw141292  }
402*c5c4113dSnw141292  execsql {
403*c5c4113dSnw141292    SELECT count(*), min(a), max(b) FROM t1;
404*c5c4113dSnw141292  }
405*c5c4113dSnw141292} {50 1 51}
406*c5c4113dSnw141292do_test conflict-7.2 {
407*c5c4113dSnw141292  execsql {
408*c5c4113dSnw141292    PRAGMA count_changes=on;
409*c5c4113dSnw141292    UPDATE OR IGNORE t1 SET a=1000;
410*c5c4113dSnw141292  }
411*c5c4113dSnw141292} {1}
412*c5c4113dSnw141292do_test conflict-7.2.1 {
413*c5c4113dSnw141292  db changes
414*c5c4113dSnw141292} {1}
415*c5c4113dSnw141292do_test conflict-7.3 {
416*c5c4113dSnw141292  execsql {
417*c5c4113dSnw141292    SELECT b FROM t1 WHERE a=1000;
418*c5c4113dSnw141292  }
419*c5c4113dSnw141292} {2}
420*c5c4113dSnw141292do_test conflict-7.4 {
421*c5c4113dSnw141292  execsql {
422*c5c4113dSnw141292    SELECT count(*) FROM t1;
423*c5c4113dSnw141292  }
424*c5c4113dSnw141292} {50}
425*c5c4113dSnw141292do_test conflict-7.5 {
426*c5c4113dSnw141292  execsql {
427*c5c4113dSnw141292    PRAGMA count_changes=on;
428*c5c4113dSnw141292    UPDATE OR REPLACE t1 SET a=1001;
429*c5c4113dSnw141292  }
430*c5c4113dSnw141292} {50}
431*c5c4113dSnw141292do_test conflict-7.5.1 {
432*c5c4113dSnw141292  db changes
433*c5c4113dSnw141292} {50}
434*c5c4113dSnw141292do_test conflict-7.6 {
435*c5c4113dSnw141292  execsql {
436*c5c4113dSnw141292    SELECT b FROM t1 WHERE a=1001;
437*c5c4113dSnw141292  }
438*c5c4113dSnw141292} {51}
439*c5c4113dSnw141292do_test conflict-7.7 {
440*c5c4113dSnw141292  execsql {
441*c5c4113dSnw141292    SELECT count(*) FROM t1;
442*c5c4113dSnw141292  }
443*c5c4113dSnw141292} {1}
444*c5c4113dSnw141292do_test conflict-7.7.1 {
445*c5c4113dSnw141292  db changes
446*c5c4113dSnw141292} {0}
447*c5c4113dSnw141292
448*c5c4113dSnw141292# Make sure the row count is right for rows that are ignored on
449*c5c4113dSnw141292# an insert.
450*c5c4113dSnw141292#
451*c5c4113dSnw141292do_test conflict-8.1 {
452*c5c4113dSnw141292  execsql {
453*c5c4113dSnw141292    DELETE FROM t1;
454*c5c4113dSnw141292    INSERT INTO t1 VALUES(1,2);
455*c5c4113dSnw141292  }
456*c5c4113dSnw141292  execsql {
457*c5c4113dSnw141292    INSERT OR IGNORE INTO t1 VALUES(2,3);
458*c5c4113dSnw141292  }
459*c5c4113dSnw141292} {1}
460*c5c4113dSnw141292do_test conflict-8.1.1 {
461*c5c4113dSnw141292  db changes
462*c5c4113dSnw141292} {1}
463*c5c4113dSnw141292do_test conflict-8.2 {
464*c5c4113dSnw141292  execsql {
465*c5c4113dSnw141292    INSERT OR IGNORE INTO t1 VALUES(2,4);
466*c5c4113dSnw141292  }
467*c5c4113dSnw141292} {0}
468*c5c4113dSnw141292do_test conflict-8.2.1 {
469*c5c4113dSnw141292  db changes
470*c5c4113dSnw141292} {0}
471*c5c4113dSnw141292do_test conflict-8.3 {
472*c5c4113dSnw141292  execsql {
473*c5c4113dSnw141292    INSERT OR REPLACE INTO t1 VALUES(2,4);
474*c5c4113dSnw141292  }
475*c5c4113dSnw141292} {1}
476*c5c4113dSnw141292do_test conflict-8.3.1 {
477*c5c4113dSnw141292  db changes
478*c5c4113dSnw141292} {1}
479*c5c4113dSnw141292do_test conflict-8.4 {
480*c5c4113dSnw141292  execsql {
481*c5c4113dSnw141292    INSERT OR IGNORE INTO t1 SELECT * FROM t1;
482*c5c4113dSnw141292  }
483*c5c4113dSnw141292} {0}
484*c5c4113dSnw141292do_test conflict-8.4.1 {
485*c5c4113dSnw141292  db changes
486*c5c4113dSnw141292} {0}
487*c5c4113dSnw141292do_test conflict-8.5 {
488*c5c4113dSnw141292  execsql {
489*c5c4113dSnw141292    INSERT OR IGNORE INTO t1 SELECT a+2,b+2 FROM t1;
490*c5c4113dSnw141292  }
491*c5c4113dSnw141292} {2}
492*c5c4113dSnw141292do_test conflict-8.5.1 {
493*c5c4113dSnw141292  db changes
494*c5c4113dSnw141292} {2}
495*c5c4113dSnw141292do_test conflict-8.6 {
496*c5c4113dSnw141292  execsql {
497*c5c4113dSnw141292    INSERT OR IGNORE INTO t1 SELECT a+3,b+3 FROM t1;
498*c5c4113dSnw141292  }
499*c5c4113dSnw141292} {3}
500*c5c4113dSnw141292do_test conflict-8.6.1 {
501*c5c4113dSnw141292  db changes
502*c5c4113dSnw141292} {3}
503*c5c4113dSnw141292
504*c5c4113dSnw141292integrity_check conflict-8.99
505*c5c4113dSnw141292
506*c5c4113dSnw141292do_test conflict-9.1 {
507*c5c4113dSnw141292  execsql {
508*c5c4113dSnw141292    PRAGMA count_changes=0;
509*c5c4113dSnw141292    CREATE TABLE t2(
510*c5c4113dSnw141292      a INTEGER UNIQUE ON CONFLICT IGNORE,
511*c5c4113dSnw141292      b INTEGER UNIQUE ON CONFLICT FAIL,
512*c5c4113dSnw141292      c INTEGER UNIQUE ON CONFLICT REPLACE,
513*c5c4113dSnw141292      d INTEGER UNIQUE ON CONFLICT ABORT,
514*c5c4113dSnw141292      e INTEGER UNIQUE ON CONFLICT ROLLBACK
515*c5c4113dSnw141292    );
516*c5c4113dSnw141292    CREATE TABLE t3(x);
517*c5c4113dSnw141292    INSERT INTO t3 VALUES(1);
518*c5c4113dSnw141292    SELECT * FROM t3;
519*c5c4113dSnw141292  }
520*c5c4113dSnw141292} {1}
521*c5c4113dSnw141292do_test conflict-9.2 {
522*c5c4113dSnw141292  catchsql {
523*c5c4113dSnw141292    INSERT INTO t2 VALUES(1,1,1,1,1);
524*c5c4113dSnw141292    INSERT INTO t2 VALUES(2,2,2,2,2);
525*c5c4113dSnw141292    SELECT * FROM t2;
526*c5c4113dSnw141292  }
527*c5c4113dSnw141292} {0 {1 1 1 1 1 2 2 2 2 2}}
528*c5c4113dSnw141292do_test conflict-9.3 {
529*c5c4113dSnw141292  catchsql {
530*c5c4113dSnw141292    INSERT INTO t2 VALUES(1,3,3,3,3);
531*c5c4113dSnw141292    SELECT * FROM t2;
532*c5c4113dSnw141292  }
533*c5c4113dSnw141292} {0 {1 1 1 1 1 2 2 2 2 2}}
534*c5c4113dSnw141292do_test conflict-9.4 {
535*c5c4113dSnw141292  catchsql {
536*c5c4113dSnw141292    UPDATE t2 SET a=a+1 WHERE a=1;
537*c5c4113dSnw141292    SELECT * FROM t2;
538*c5c4113dSnw141292  }
539*c5c4113dSnw141292} {0 {1 1 1 1 1 2 2 2 2 2}}
540*c5c4113dSnw141292do_test conflict-9.5 {
541*c5c4113dSnw141292  catchsql {
542*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,1,3,3,3);
543*c5c4113dSnw141292    SELECT * FROM t2;
544*c5c4113dSnw141292  }
545*c5c4113dSnw141292} {1 {column b is not unique}}
546*c5c4113dSnw141292do_test conflict-9.6 {
547*c5c4113dSnw141292  catchsql {
548*c5c4113dSnw141292    UPDATE t2 SET b=b+1 WHERE b=1;
549*c5c4113dSnw141292    SELECT * FROM t2;
550*c5c4113dSnw141292  }
551*c5c4113dSnw141292} {1 {column b is not unique}}
552*c5c4113dSnw141292do_test conflict-9.7 {
553*c5c4113dSnw141292  catchsql {
554*c5c4113dSnw141292    BEGIN;
555*c5c4113dSnw141292    UPDATE t3 SET x=x+1;
556*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,1,3,3,3);
557*c5c4113dSnw141292    SELECT * FROM t2;
558*c5c4113dSnw141292  }
559*c5c4113dSnw141292} {1 {column b is not unique}}
560*c5c4113dSnw141292do_test conflict-9.8 {
561*c5c4113dSnw141292  execsql {COMMIT}
562*c5c4113dSnw141292  execsql {SELECT * FROM t3}
563*c5c4113dSnw141292} {2}
564*c5c4113dSnw141292do_test conflict-9.9 {
565*c5c4113dSnw141292  catchsql {
566*c5c4113dSnw141292    BEGIN;
567*c5c4113dSnw141292    UPDATE t3 SET x=x+1;
568*c5c4113dSnw141292    UPDATE t2 SET b=b+1 WHERE b=1;
569*c5c4113dSnw141292    SELECT * FROM t2;
570*c5c4113dSnw141292  }
571*c5c4113dSnw141292} {1 {column b is not unique}}
572*c5c4113dSnw141292do_test conflict-9.10 {
573*c5c4113dSnw141292  execsql {COMMIT}
574*c5c4113dSnw141292  execsql {SELECT * FROM t3}
575*c5c4113dSnw141292} {3}
576*c5c4113dSnw141292do_test conflict-9.11 {
577*c5c4113dSnw141292  catchsql {
578*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,3,3,1,3);
579*c5c4113dSnw141292    SELECT * FROM t2;
580*c5c4113dSnw141292  }
581*c5c4113dSnw141292} {1 {column d is not unique}}
582*c5c4113dSnw141292do_test conflict-9.12 {
583*c5c4113dSnw141292  catchsql {
584*c5c4113dSnw141292    UPDATE t2 SET d=d+1 WHERE d=1;
585*c5c4113dSnw141292    SELECT * FROM t2;
586*c5c4113dSnw141292  }
587*c5c4113dSnw141292} {1 {column d is not unique}}
588*c5c4113dSnw141292do_test conflict-9.13 {
589*c5c4113dSnw141292  catchsql {
590*c5c4113dSnw141292    BEGIN;
591*c5c4113dSnw141292    UPDATE t3 SET x=x+1;
592*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,3,3,1,3);
593*c5c4113dSnw141292    SELECT * FROM t2;
594*c5c4113dSnw141292  }
595*c5c4113dSnw141292} {1 {column d is not unique}}
596*c5c4113dSnw141292do_test conflict-9.14 {
597*c5c4113dSnw141292  execsql {COMMIT}
598*c5c4113dSnw141292  execsql {SELECT * FROM t3}
599*c5c4113dSnw141292} {4}
600*c5c4113dSnw141292do_test conflict-9.15 {
601*c5c4113dSnw141292  catchsql {
602*c5c4113dSnw141292    BEGIN;
603*c5c4113dSnw141292    UPDATE t3 SET x=x+1;
604*c5c4113dSnw141292    UPDATE t2 SET d=d+1 WHERE d=1;
605*c5c4113dSnw141292    SELECT * FROM t2;
606*c5c4113dSnw141292  }
607*c5c4113dSnw141292} {1 {column d is not unique}}
608*c5c4113dSnw141292do_test conflict-9.16 {
609*c5c4113dSnw141292  execsql {COMMIT}
610*c5c4113dSnw141292  execsql {SELECT * FROM t3}
611*c5c4113dSnw141292} {5}
612*c5c4113dSnw141292do_test conflict-9.17 {
613*c5c4113dSnw141292  catchsql {
614*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,3,3,3,1);
615*c5c4113dSnw141292    SELECT * FROM t2;
616*c5c4113dSnw141292  }
617*c5c4113dSnw141292} {1 {column e is not unique}}
618*c5c4113dSnw141292do_test conflict-9.18 {
619*c5c4113dSnw141292  catchsql {
620*c5c4113dSnw141292    UPDATE t2 SET e=e+1 WHERE e=1;
621*c5c4113dSnw141292    SELECT * FROM t2;
622*c5c4113dSnw141292  }
623*c5c4113dSnw141292} {1 {column e is not unique}}
624*c5c4113dSnw141292do_test conflict-9.19 {
625*c5c4113dSnw141292  catchsql {
626*c5c4113dSnw141292    BEGIN;
627*c5c4113dSnw141292    UPDATE t3 SET x=x+1;
628*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,3,3,3,1);
629*c5c4113dSnw141292    SELECT * FROM t2;
630*c5c4113dSnw141292  }
631*c5c4113dSnw141292} {1 {column e is not unique}}
632*c5c4113dSnw141292do_test conflict-9.20 {
633*c5c4113dSnw141292  catch {execsql {COMMIT}}
634*c5c4113dSnw141292  execsql {SELECT * FROM t3}
635*c5c4113dSnw141292} {5}
636*c5c4113dSnw141292do_test conflict-9.21 {
637*c5c4113dSnw141292  catchsql {
638*c5c4113dSnw141292    BEGIN;
639*c5c4113dSnw141292    UPDATE t3 SET x=x+1;
640*c5c4113dSnw141292    UPDATE t2 SET e=e+1 WHERE e=1;
641*c5c4113dSnw141292    SELECT * FROM t2;
642*c5c4113dSnw141292  }
643*c5c4113dSnw141292} {1 {column e is not unique}}
644*c5c4113dSnw141292do_test conflict-9.22 {
645*c5c4113dSnw141292  catch {execsql {COMMIT}}
646*c5c4113dSnw141292  execsql {SELECT * FROM t3}
647*c5c4113dSnw141292} {5}
648*c5c4113dSnw141292do_test conflict-9.23 {
649*c5c4113dSnw141292  catchsql {
650*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,3,1,3,3);
651*c5c4113dSnw141292    SELECT * FROM t2;
652*c5c4113dSnw141292  }
653*c5c4113dSnw141292} {0 {2 2 2 2 2 3 3 1 3 3}}
654*c5c4113dSnw141292do_test conflict-9.24 {
655*c5c4113dSnw141292  catchsql {
656*c5c4113dSnw141292    UPDATE t2 SET c=c-1 WHERE c=2;
657*c5c4113dSnw141292    SELECT * FROM t2;
658*c5c4113dSnw141292  }
659*c5c4113dSnw141292} {0 {2 2 1 2 2}}
660*c5c4113dSnw141292do_test conflict-9.25 {
661*c5c4113dSnw141292  catchsql {
662*c5c4113dSnw141292    BEGIN;
663*c5c4113dSnw141292    UPDATE t3 SET x=x+1;
664*c5c4113dSnw141292    INSERT INTO t2 VALUES(3,3,1,3,3);
665*c5c4113dSnw141292    SELECT * FROM t2;
666*c5c4113dSnw141292  }
667*c5c4113dSnw141292} {0 {3 3 1 3 3}}
668*c5c4113dSnw141292do_test conflict-9.26 {
669*c5c4113dSnw141292  catch {execsql {COMMIT}}
670*c5c4113dSnw141292  execsql {SELECT * FROM t3}
671*c5c4113dSnw141292} {6}
672*c5c4113dSnw141292
673*c5c4113dSnw141292do_test conflict-10.1 {
674*c5c4113dSnw141292  catchsql {
675*c5c4113dSnw141292    DELETE FROM t1;
676*c5c4113dSnw141292    BEGIN ON CONFLICT ROLLBACK;
677*c5c4113dSnw141292    INSERT INTO t1 VALUES(1,2);
678*c5c4113dSnw141292    INSERT INTO t1 VALUES(1,3);
679*c5c4113dSnw141292    COMMIT;
680*c5c4113dSnw141292  }
681*c5c4113dSnw141292  execsql {SELECT * FROM t1}
682*c5c4113dSnw141292} {}
683*c5c4113dSnw141292do_test conflict-10.2 {
684*c5c4113dSnw141292  catchsql {
685*c5c4113dSnw141292    CREATE TABLE t4(x);
686*c5c4113dSnw141292    CREATE UNIQUE INDEX t4x ON t4(x);
687*c5c4113dSnw141292    BEGIN ON CONFLICT ROLLBACK;
688*c5c4113dSnw141292    INSERT INTO t4 VALUES(1);
689*c5c4113dSnw141292    INSERT INTO t4 VALUES(1);
690*c5c4113dSnw141292    COMMIT;
691*c5c4113dSnw141292  }
692*c5c4113dSnw141292  execsql {SELECT * FROM t4}
693*c5c4113dSnw141292} {}
694*c5c4113dSnw141292
695*c5c4113dSnw141292integrity_check conflict-99.0
696*c5c4113dSnw141292
697*c5c4113dSnw141292finish_test
698