Enhance the command-line completion extension to return the names of
[sqlite.git] / ext / session / session5.test
blob9b8f9ffe12f955bccdc0095d2fc0537ab87cf2c7
1 # 2011 April 13
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 #***********************************************************************
11 # This file implements regression tests for the session module. 
12 # Specifically, for the sqlite3changeset_concat() command.
13
15 if {![info exists testdir]} {
16   set testdir [file join [file dirname [info script]] .. .. test]
17
18 source [file join [file dirname [info script]] session_common.tcl]
19 source $testdir/tester.tcl
20 ifcapable !session {finish_test; return}
22 set testprefix session5
24 # Organization of tests:
26 #   session5-1.*: Simple tests to check the concat() function produces 
27 #                 correct results.
29 #   session5-2.*: More complicated tests.
30 #   
31 #   session5-3.*: Schema mismatch errors.
33 #   session5-4.*: Test the concat cases that indicate that the database
34 #                 was modified in between recording of the two changesets
35 #                 being concatenated (i.e. two changesets that INSERT rows
36 #                 with the same PK values).
39 proc do_concat_test {tn args} {
41   set subtest 0
42   foreach sql $args {
43     incr subtest
44     sqlite3session S db main ; S attach *
45     execsql $sql
47     set c [S changeset]
48     if {[info commands s_prev] != ""} {
49       set c_concat [sqlite3changeset_concat $c_prev $c]
50       set c_two [s_prev changeset]
51       s_prev delete
53       set h_concat [changeset_to_list $c_concat]
54       set h_two [changeset_to_list $c_two]
56       do_test $tn.$subtest [list set {} $h_concat] $h_two
57     }
58     set c_prev $c
59     rename S s_prev
60   }
62   catch { s_prev delete }
65 #-------------------------------------------------------------------------
66 # Test cases session5-1.* - simple tests.
68 do_execsql_test 1.0 {
69   CREATE TABLE t1(a PRIMARY KEY, b);
72 do_concat_test 1.1.1 {
73   INSERT INTO t1 VALUES(1, 'one');
74 } {
75   INSERT INTO t1 VALUES(2, 'two');
78 do_concat_test 1.1.2 {
79   UPDATE t1 SET b = 'five' WHERE a = 1;
80 } {
81   UPDATE t1 SET b = 'six' WHERE a = 2;
84 do_concat_test 1.1.3 {
85   DELETE FROM t1 WHERE a = 1;
86 } {
87   DELETE FROM t1 WHERE a = 2;
91 # 1.2.1:    INSERT + DELETE                     -> (none)
92 # 1.2.2:    INSERT + UPDATE                     -> INSERT
94 # 1.2.3:    DELETE + INSERT (matching data)     -> (none)
95 # 1.2.4:    DELETE + INSERT (non-matching data) -> UPDATE
97 # 1.2.5:    UPDATE + UPDATE (matching data)     -> (none)
98 # 1.2.6:    UPDATE + UPDATE (non-matching data) -> UPDATE
99 # 1.2.7:    UPDATE + DELETE                     -> DELETE
101 do_concat_test 1.2.1 {
102   INSERT INTO t1 VALUES('x', 'y');
103 } {
104   DELETE FROM t1 WHERE a = 'x';
106 do_concat_test 1.2.2 {
107   INSERT INTO t1 VALUES(5.0, 'five');
108 } {
109   UPDATE t1 SET b = 'six' WHERE a = 5.0;
112 do_execsql_test 1.2.3.1 "INSERT INTO t1 VALUES('I', 'one')"
113 do_concat_test 1.2.3.2 {
114   DELETE FROM t1 WHERE a = 'I';
115 } {
116   INSERT INTO t1 VALUES('I', 'one');
118 do_concat_test 1.2.4 {
119   DELETE FROM t1 WHERE a = 'I';
120 } {
121   INSERT INTO t1 VALUES('I', 'two');
123 do_concat_test 1.2.5 {
124   UPDATE t1 SET b = 'five' WHERE a = 'I';
125 } {
126   UPDATE t1 SET b = 'two' WHERE a = 'I';
128 do_concat_test 1.2.6 {
129   UPDATE t1 SET b = 'six' WHERE a = 'I';
130 } {
131   UPDATE t1 SET b = 'seven' WHERE a = 'I';
133 do_concat_test 1.2.7 {
134   UPDATE t1 SET b = 'eight' WHERE a = 'I';
135 } {
136   DELETE FROM t1 WHERE a = 'I';
140 #-------------------------------------------------------------------------
141 # Test cases session5-2.* - more complex tests.
143 db function indirect indirect 
144 proc indirect {{x -1}} {
145   S indirect $x
146   s_prev indirect $x
148 do_concat_test 2.1 {
149   CREATE TABLE abc(a, b, c PRIMARY KEY);
150   INSERT INTO abc VALUES(NULL, NULL, 1);
151   INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
152 } {
153   DELETE FROM abc WHERE c = 1;
154   UPDATE abc SET c = 1 WHERE c = 2;
155 } {
156   INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
157   INSERT INTO abc VALUES(1.0, 2.0, 3);
158 } {
159   UPDATE abc SET a = a-1;
160 } {
161   CREATE TABLE def(d, e, f, PRIMARY KEY(e, f));
162   INSERT INTO def VALUES('x', randomblob(11000), 67);
163   INSERT INTO def SELECT d, e, f+1 FROM def;
164   INSERT INTO def SELECT d, e, f+2 FROM def;
165   INSERT INTO def SELECT d, e, f+4 FROM def;
166 } {
167   DELETE FROM def WHERE rowid>4;
168 } { 
169   INSERT INTO def SELECT d, e, f+4 FROM def; 
170 } {
171   INSERT INTO abc VALUES(22, 44, -1);
172 } { 
173   UPDATE abc SET c=-2 WHERE c=-1;
174   UPDATE abc SET c=-3 WHERE c=-2;
175 } {
176   UPDATE abc SET c=-4 WHERE c=-3;
177 } {
178   UPDATE abc SET a=a+1 WHERE c=-3;
179   UPDATE abc SET a=a+1 WHERE c=-3;
180 } {
181   UPDATE abc SET a=a+1 WHERE c=-3;
182   UPDATE abc SET a=a+1 WHERE c=-3;
183 } {
184   INSERT INTO abc VALUES('one', 'two', 'three');
185 } {
186   SELECT indirect(1);
187   UPDATE abc SET a='one point five' WHERE c = 'three';
188 } {
189   SELECT indirect(0);
190   UPDATE abc SET a='one point six' WHERE c = 'three';
191 } {
192   CREATE TABLE x1(a, b, PRIMARY KEY(a));
193   SELECT indirect(1);
194   INSERT INTO x1 VALUES(1, 2);
195 } {
196   SELECT indirect(1);
197   UPDATE x1 SET b = 3 WHERE a = 1;
200 catch {db close}
201 forcedelete test.db
202 sqlite3 db test.db
203 do_concat_test 2.2 {
204   CREATE TABLE t1(a, b, PRIMARY KEY(b));
205   CREATE TABLE t2(a PRIMARY KEY, b);
206   INSERT INTO t1 VALUES('string', 1);
207   INSERT INTO t1 VALUES(4, 2);
208   INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
209 } {
210   INSERT INTO t2 VALUES('one', 'two');
211   INSERT INTO t2 VALUES(1, NULL);
212   UPDATE t1 SET a = 5 WHERE a = 2;
213 } {
214   DELETE FROM t2 WHERE a = 1;
215   UPDATE t1 SET a = 4 WHERE a = 2;
216   INSERT INTO t2 VALUES('x', 'y');
219 do_test 2.3.0 {
220   catch {db close}
221   forcedelete test.db
222   sqlite3 db test.db
224   set sql1 ""
225   set sql2 ""
226   for {set i 1} {$i < 120} {incr i} {
227     append sql1 "INSERT INTO x1 VALUES($i*4, $i);"
228   }
229   for {set i 1} {$i < 120} {incr i} {
230     append sql2 "DELETE FROM x1 WHERE a = $i*4;"
231   }
232   set {} {}
233 } {}
234 do_concat_test 2.3 {
235   CREATE TABLE x1(a PRIMARY KEY, b)
236 } $sql1 $sql2 $sql1 $sql2
238 do_concat_test 2.4 {
239   CREATE TABLE x2(a PRIMARY KEY, b);
240   CREATE TABLE x3(a PRIMARY KEY, b);
242   INSERT INTO x2 VALUES('a', 'b');
243   INSERT INTO x2 VALUES('x', 'y');
244   INSERT INTO x3 VALUES('a', 'b');
245 } {
246   INSERT INTO x2 VALUES('c', 'd');
247   INSERT INTO x3 VALUES('e', 'f');
248   INSERT INTO x3 VALUES('x', 'y');
251 do_concat_test 2.5 {
252   UPDATE x3 SET b = 'Y' WHERE a = 'x'
253 } {
254   DELETE FROM x3 WHERE a = 'x'
255 } {
256   DELETE FROM x2 WHERE a = 'a'
257 } {
258   INSERT INTO x2 VALUES('a', 'B');
261 for {set k 1} {$k <=10} {incr k} {
262   do_test 2.6.$k.1 {
263     drop_all_tables
264     set sql1 ""
265     set sql2 ""
266     for {set i 1} {$i < 120} {incr i} {
267       append sql1 "INSERT INTO x1 VALUES(randomblob(20+(random()%10)), $i);"
268     }
269     for {set i 1} {$i < 120} {incr i} {
270       append sql2 "DELETE FROM x1 WHERE rowid = $i;"
271     }
272     set {} {}
273   } {}
274   do_concat_test 2.6.$k {
275     CREATE TABLE x1(a PRIMARY KEY, b)
276   } $sql1 $sql2 $sql1 $sql2
279 for {set k 1} {$k <=10} {incr k} {
280   do_test 2.7.$k.1 {
281     drop_all_tables
282     set sql1 ""
283     set sql2 ""
284     for {set i 1} {$i < 120} {incr i} {
285       append sql1 {
286         INSERT INTO x1 VALUES(
287          CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END,
288          CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END
289         );
290       }
291     }
292     for {set i 1} {$i < 120} {incr i} {
293       append sql2 "DELETE FROM x1 WHERE rowid = $i;"
294     }
295     set {} {}
296   } {}
297   do_concat_test 2.7.$k {
298     CREATE TABLE x1(a PRIMARY KEY, b)
299   } $sql1 $sql2 $sql1 $sql2
303 #-------------------------------------------------------------------------
304 # Test that schema incompatibilities are detected correctly.
306 #   session5-3.1: Incompatible number of columns.
307 #   session5-3.2: Incompatible PK definition.
310 do_test 3.1 {
311   db close
312   forcedelete test.db
313   sqlite3 db test.db
315   execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
316   set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
317   execsql { 
318     DROP TABLE t1;
319     CREATE TABLE t1(a PRIMARY KEY, b, c);
320   }
321   set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3, 4) }]
323   list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
324 } {1 SQLITE_SCHEMA}
326 do_test 3.2 {
327   db close
328   forcedelete test.db
329   sqlite3 db test.db
331   execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
332   set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
333   execsql { 
334     DROP TABLE t1;
335     CREATE TABLE t1(a, b PRIMARY KEY);
336   }
337   set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3) }]
339   list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
340 } {1 SQLITE_SCHEMA}
342 #-------------------------------------------------------------------------
343 # Test that concat() handles these properly:
345 #   session5-4.1: INSERT + INSERT
346 #   session5-4.2: UPDATE + INSERT
347 #   session5-4.3: DELETE + UPDATE
348 #   session5-4.4: DELETE + DELETE
351 proc do_concat_test2 {tn sql1 sqlX sql2 expected} {
352   sqlite3session S db main ; S attach *
353   execsql $sql1
354   set ::c1 [S changeset]
355   S delete
357   execsql $sqlX
359   sqlite3session S db main ; S attach *
360   execsql $sql2
361   set ::c2 [S changeset]
362   S delete
364   uplevel do_test $tn [list {
365     changeset_to_list [sqlite3changeset_concat $::c1 $::c2]
366   }] [list [normalize_list $expected]]
369 drop_all_tables db
370 do_concat_test2 4.1 {
371   CREATE TABLE t1(a PRIMARY KEY, b);
372   INSERT INTO t1 VALUES('key', 'value');
373 } {
374   DELETE FROM t1 WHERE a = 'key';
375 } {
376   INSERT INTO t1 VALUES('key', 'xxx');
377 } {
378   {INSERT t1 0 X. {} {t key t value}}
380 do_concat_test2 4.2 {
381   UPDATE t1 SET b = 'yyy';
382 } {
383   DELETE FROM t1 WHERE a = 'key';
384 } {
385   INSERT INTO t1 VALUES('key', 'value');
386 } {
387   {UPDATE t1 0 X. {t key t xxx} {{} {} t yyy}}
389 do_concat_test2 4.3 {
390   DELETE FROM t1 WHERE a = 'key';
391 } {
392   INSERT INTO t1 VALUES('key', 'www');
393 } {
394   UPDATE t1 SET b = 'valueX' WHERE a = 'key';
395 } {
396   {DELETE t1 0 X. {t key t value} {}}
398 do_concat_test2 4.4 {
399   DELETE FROM t1 WHERE a = 'key';
400 } {
401   INSERT INTO t1 VALUES('key', 'ttt');
402 } {
403   DELETE FROM t1 WHERE a = 'key';
404 } {
405   {DELETE t1 0 X. {t key t valueX} {}}
408 finish_test