3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # May you do good and not evil.
7 # May you find forgiveness for yourself and forgive others.
8 # May you share freely, never taking more than you give.
10 #***********************************************************************
12 # Tests for the sessions module. Specifically, that a changeset can
13 # be applied after ALTER TABLE ADD COLUMN has been used to add
17 if {![info exists testdir]} {
18 set testdir [file join [file dirname [info script]] .. .. test]
20 source [file join [file dirname [info script]] session_common.tcl]
21 source $testdir/tester.tcl
22 ifcapable !session {finish_test; return}
23 set testprefix sessionat
25 # If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
26 ifcapable !altertable {
34 proc log {code msg} { lappend ::log $code $msg }
39 forcedelete test.db test.db2
45 # Run all tests in this file twice. Once with "WITHOUT ROWID", and once
46 # with regular rowid tables.
48 # ?.1.*: Test that PK inconsistencies are detected if one or more of the PK
49 # columns are not present in the changeset.
51 # ?.2.*: Test that it is not possible to apply a changeset with N columns
52 # to a db with fewer than N columns.
54 # ?.3.*: Test some INSERT, UPDATE and DELETE operations that do not
55 # require conflict handling.
57 # ?.4.*: Test some INSERT, UPDATE and DELETE operations that do require
60 # ?.5.*: Test that attempting to concat two changesets with different
61 # numbers of columns for the same table is an error.
63 foreach {tn trailing} {
65 sessionat-wor " WITHOUT ROWID "
67 eval [string map [list %WR% $trailing] {
70 #-----------------------------------------------------------------------
71 do_execsql_test $tn.1.0 {
72 CREATE TABLE t1(a, b, PRIMARY KEY(a)) %WR%;
74 do_execsql_test -db db2 $tn.1.1 {
75 CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c)) %WR%;
79 do_then_apply_sql { INSERT INTO t1 VALUES('one', 'two') }
82 SQLITE_SCHEMA {sqlite3changeset_apply(): primary key mismatch for table t1}
84 do_execsql_test $tn.1.3 { SELECT * FROM t1 } {one two}
85 do_execsql_test -db db2 $tn.1.4 { SELECT * FROM t1 } {}
87 #-----------------------------------------------------------------------
88 do_execsql_test $tn.2.0 {
89 CREATE TABLE t2(x, y, z, PRIMARY KEY(x)) %WR%;
91 do_execsql_test -db db2 $tn.2.1 {
92 CREATE TABLE t2(x, y, PRIMARY KEY(x)) %WR%;
97 do_then_apply_sql { INSERT INTO t2 VALUES(1, 2, 3) }
99 } [list SQLITE_SCHEMA \
100 {sqlite3changeset_apply(): table t2 has 2 columns, expected 3 or more}
102 do_execsql_test $tn.2.3 { SELECT * FROM t2 } {1 2 3}
103 do_execsql_test -db db2 $tn.2.4 { SELECT * FROM t2 } {}
105 #-----------------------------------------------------------------------
106 do_execsql_test $tn.3.0 {
107 CREATE TABLE t3(a, b, PRIMARY KEY(b)) %WR%;
109 do_execsql_test -db db2 $tn.3.1 {
110 CREATE TABLE t3(a, b, c DEFAULT 'D', PRIMARY KEY(b)) %WR%;
113 do_then_apply_sql -ignorenoop {
114 INSERT INTO t3 VALUES(1, 2);
115 INSERT INTO t3 VALUES(3, 4);
116 INSERT INTO t3 VALUES(5, 6);
118 db2 eval {SELECT * FROM t3}
119 } {1 2 D 3 4 D 5 6 D}
121 do_then_apply_sql -ignorenoop {
122 UPDATE t3 SET a=45 WHERE b=4;
123 DELETE FROM t3 WHERE a=5;
125 db2 eval {SELECT * FROM t3}
128 #-----------------------------------------------------------------------
129 # 4.1: INSERT statements
130 # 4.2: DELETE statements
131 # 4.3: UPDATE statements
133 do_execsql_test $tn.4.1.0 {
134 CREATE TABLE t4(x INTEGER PRIMARY KEY, y) %WR%;
136 do_execsql_test -db db2 $tn.4.1.1 {
137 CREATE TABLE t4(x INTEGER PRIMARY KEY, y, z) %WR%;
138 INSERT INTO t4 VALUES(1, 2, 3);
139 INSERT INTO t4 VALUES(4, 5, 6);
141 do_conflict_test $tn.4.1.2 -tables t4 -sql {
142 INSERT INTO t4 VALUES(10, 20);
143 INSERT INTO t4 VALUES(4, 11);
145 {INSERT t4 CONFLICT {i 4 i 11} {i 4 i 5}}
147 do_execsql_test -db db2 $tn.4.1.3 {
148 SELECT * FROM t4 ORDER BY x
149 } {1 2 3 4 5 6 10 20 {}}
150 do_conflict_test $tn.4.1.4 -policy REPLACE -tables t4 -sql {
151 INSERT INTO t4 VALUES(1, 11);
153 {INSERT t4 CONFLICT {i 1 i 11} {i 1 i 2}}
155 do_execsql_test -db db2 $tn.4.1.5 {
156 SELECT * FROM t4 ORDER BY x
157 } {1 11 {} 4 5 6 10 20 {}}
159 do_execsql_test $tn.4.2.0 {
161 INSERT INTO t4 VALUES(1, 'A');
162 INSERT INTO t4 VALUES(2, 'B');
163 INSERT INTO t4 VALUES(3, 'C');
164 INSERT INTO t4 VALUES(4, 'D');
166 do_execsql_test -db db2 $tn.4.2.1 {
168 INSERT INTO t4 VALUES(1, 'A', 'a');
169 INSERT INTO t4 VALUES(3, 'C', 'c');
170 INSERT INTO t4 VALUES(4, 'E', 'd');
172 do_conflict_test $tn.4.2.2 -tables t4 -sql {
173 DELETE FROM t4 WHERE x=2;
174 DELETE FROM t4 WHERE x=4;
176 {DELETE t4 NOTFOUND {i 2 t B}}
177 {DELETE t4 DATA {i 4 t D} {i 4 t E}}
180 do_execsql_test $tn.4.3.0 {
181 CREATE TABLE t5(a, b, c PRIMARY KEY) %WR%;
182 INSERT INTO t5 VALUES(1,1,1), (2,2,2), (3,3,3), (4,4,4);
184 do_execsql_test -db db2 $tn.4.3.1 {
185 CREATE TABLE t5(a, b, c PRIMARY KEY, d CHECK(b!=10)) %WR%;
186 INSERT INTO t5 VALUES (2,2,2,2), (3,8,3,3), (4,4,4,4);
188 do_conflict_test $tn.4.3.2 -tables t5 -sql {
189 UPDATE t5 SET a=4 WHERE c=1;
190 UPDATE t5 SET b=9 WHERE c=3;
191 UPDATE t5 SET b=10 WHERE c=2;
193 {UPDATE t5 NOTFOUND {i 1 {} {} i 1} {i 4 {} {} {} {}}}
194 {UPDATE t5 DATA {{} {} i 3 i 3} {{} {} i 9 {} {}} {i 3 i 8 i 3}}
195 {UPDATE t5 CONSTRAINT {{} {} i 2 i 2} {{} {} i 10 {} {}}}
198 #-----------------------------------------------------------------------
199 do_execsql_test $tn.5.0 {
200 CREATE TABLE t6(a, b, c, PRIMARY KEY(a, b)) %WR%;
202 do_execsql_test -db db2 $tn.5.1 {
203 CREATE TABLE t6(a, b, c, d, e, PRIMARY KEY(a, b)) %WR%;
206 set c1 [sql_exec_changeset db {
207 INSERT INTO t6 VALUES(1, 1, 1);
208 INSERT INTO t6 VALUES(2, 2, 2);
210 set c2 [sql_exec_changeset db2 {
211 INSERT INTO t6 VALUES(3, 3, 3, 3, 3);
212 INSERT INTO t6 VALUES(4, 4, 4, 4, 4);
214 list [catch { sqlite3changeset_concat $c1 $c2} msg] $msg
217 #-----------------------------------------------------------------------
220 do_execsql_test $tn.6.0 {
221 CREATE TABLE t7(a INTEGER PRIMARY KEY, b) %WR%;
222 INSERT INTO t7 VALUES(1, 1);
223 INSERT INTO t7 VALUES(2, 2);
224 INSERT INTO t7 VALUES(3, 3);
228 set c1 [sql_exec_changeset db {
229 INSERT INTO t7 VALUES(4, 4);
230 DELETE FROM t7 WHERE a=1;
231 UPDATE t7 SET b=222 WHERE a=2;
233 set cinv [sqlite3changeset_invert $c1]
234 execsql { SELECT * FROM t7 }
237 do_execsql_test -db db2 $tn.6.2 {
238 ALTER TABLE t7 ADD COLUMN c DEFAULT 'ccc'
241 proc xConfict {args} { return "OMIT" }
243 sqlite3changeset_apply db $cinv xConflict
244 execsql { SELECT * FROM t7 }
245 } {1 1 ccc 2 2 ccc 3 3 ccc}
247 #-----------------------------------------------------------------------
249 do_execsql_test $tn.7.0 {
250 CREATE TABLE t8(a PRIMARY KEY, b, c);
252 do_execsql_test -db db2 $tn.7.1 {
253 CREATE TABLE t8(a PRIMARY KEY, b, c, d DEFAULT 'D', e DEFAULT 'E');
256 do_then_apply_sql -ignorenoop {
257 INSERT INTO t8 VALUES(1, 2, 3);
258 INSERT INTO t8 VALUES(4, 5, 6);
260 do_execsql_test $tn.7.2.1 {
263 do_execsql_test -db db2 $tn.7.2.2 {
265 } {1 2 3 D E 4 5 6 D E}
267 do_then_apply_sql -ignorenoop {
268 UPDATE t8 SET c=45 WHERE a=4;
270 do_execsql_test $tn.7.3.1 {
273 do_execsql_test -db db2 $tn.7.3.2 {
275 } {1 2 3 D E 4 5 45 D E}
277 #-----------------------------------------------------------------------
279 do_execsql_test $tn.8.0 {
280 CREATE TABLE t9(a PRIMARY KEY, b, c, d, e, f, g, h);
282 do_execsql_test -db db2 $tn.8.1 {
283 CREATE TABLE t9(a PRIMARY KEY, b, c, d, e, f, g, h, i, j, k, l);
285 do_then_apply_sql -ignorenoop {
286 INSERT INTO t9 VALUES(1, 2, 3, 4, 5, 6, 7, 8);
289 UPDATE t9 SET h=450 WHERE a=1
291 do_execsql_test -db db2 $tn.8.2 {
293 } {1 2 3 4 5 6 7 450 {} {} {} {}}
294 do_then_apply_sql -ignorenoop {
297 do_execsql_test -db db2 $tn.8.2 {
299 } {1 2 3 4 5 6 7 {} {} {} {} {}}