Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: third_party/sqlite/src/ext/session/sessionB.test

Issue 2751253002: [sql] Import SQLite 3.17.0. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # 2014 August 16
2 #
3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
5 #
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.
9 #
10 #***********************************************************************
11 #
12 # This file implements regression tests for sessions SQLite extension.
13 # Specifically, this file contains tests for "patchset" changes.
14 #
15
16 if {![info exists testdir]} {
17 set testdir [file join [file dirname [info script]] .. .. test]
18 }
19 source [file join [file dirname [info script]] session_common.tcl]
20 source $testdir/tester.tcl
21 ifcapable !session {finish_test; return}
22
23 set testprefix sessionB
24
25 #
26 # 1.*: Test that the blobs returned by the session_patchset() API are
27 # as expected. Also the sqlite3_changeset_iter functions.
28 #
29 # 2.*: Test that patchset blobs are handled by sqlite3changeset_apply().
30 #
31 # 3.*: Test that sqlite3changeset_invert() works with patchset blobs.
32 # Correct behaviour is to return SQLITE_CORRUPT.
33
34 proc do_sql2patchset_test {tn sql res} {
35 sqlite3session S db main
36 S attach *
37 execsql $sql
38 uplevel [list do_patchset_test $tn S $res]
39 S delete
40 }
41
42 #-------------------------------------------------------------------------
43 # Run simple tests of the _patchset() API.
44 #
45 do_execsql_test 1.0 {
46 CREATE TABLE t1(a, b, c, d, PRIMARY KEY(d, a));
47 INSERT INTO t1 VALUES(1, 2, 3, 4);
48 INSERT INTO t1 VALUES(5, 6, 7, 8);
49 INSERT INTO t1 VALUES(9, 10, 11, 12);
50 }
51
52 do_test 1.1 {
53 sqlite3session S db main
54 S attach t1
55 execsql {
56 INSERT INTO t1 VALUES('w', 'x', 'y', 'z');
57 DELETE FROM t1 WHERE d=4;
58 UPDATE t1 SET c = 14 WHERE a=5;
59 }
60 } {}
61
62 do_patchset_test 1.2 S {
63 {UPDATE t1 0 X..X {i 5 {} {} {} {} i 8} {{} {} {} {} i 14 {} {}}}
64 {INSERT t1 0 X..X {} {t w t x t y t z}}
65 {DELETE t1 0 X..X {i 1 {} {} {} {} i 4} {}}
66 }
67
68 do_test 1.3 {
69 S delete
70 } {}
71
72 do_sql2patchset_test 1.4 {
73 DELETE FROM t1;
74 } {
75 {DELETE t1 0 X..X {i 5 {} {} {} {} i 8} {}}
76 {DELETE t1 0 X..X {t w {} {} {} {} t z} {}}
77 {DELETE t1 0 X..X {i 9 {} {} {} {} i 12} {}}
78 }
79
80 do_sql2patchset_test 1.5 {
81 INSERT INTO t1 VALUES(X'61626364', NULL, NULL, 4.2);
82 INSERT INTO t1 VALUES(4.2, NULL, NULL, X'61626364');
83 } {
84 {INSERT t1 0 X..X {} {f 4.2 n {} n {} b abcd}}
85 {INSERT t1 0 X..X {} {b abcd n {} n {} f 4.2}}
86 }
87
88 do_sql2patchset_test 1.6 {
89 UPDATE t1 SET b=45 WHERE typeof(a)=='blob';
90 UPDATE t1 SET c='zzzz' WHERE typeof(a)!='blob';
91 } {
92 {UPDATE t1 0 X..X {f 4.2 {} {} {} {} b abcd} {{} {} {} {} t zzzz {} {}}}
93 {UPDATE t1 0 X..X {b abcd {} {} {} {} f 4.2} {{} {} i 45 {} {} {} {}}}
94 }
95
96 do_sql2patchset_test 1.7 {
97 UPDATE t1 SET b='xyz' WHERE typeof(a)=='blob';
98 UPDATE t1 SET c='xyz' WHERE typeof(a)!='blob';
99 UPDATE t1 SET b=45 WHERE typeof(a)=='blob';
100 UPDATE t1 SET c='zzzz' WHERE typeof(a)!='blob';
101 } {
102 }
103
104 do_sql2patchset_test 1.8 {
105 DELETE FROM t1;
106 } {
107 {DELETE t1 0 X..X {f 4.2 {} {} {} {} b abcd} {}}
108 {DELETE t1 0 X..X {b abcd {} {} {} {} f 4.2} {}}
109 }
110
111 #-------------------------------------------------------------------------
112 # Run simple tests of _apply() with patchset objects.
113 #
114 reset_db
115
116 proc noop {args} { error $args }
117 proc exec_rollback_replay {sql} {
118 sqlite3session S db main
119 S attach *
120 execsql BEGIN
121 execsql $sql
122 set patchset [S patchset]
123 S delete
124 execsql ROLLBACK
125 sqlite3changeset_apply db $patchset noop
126 }
127
128 do_execsql_test 2.0 {
129 CREATE TABLE t2(a, b, c, d, PRIMARY KEY(b,c));
130 CREATE TABLE t3(w, x, y, z, PRIMARY KEY(w));
131 }
132
133 do_test 2.1 {
134 exec_rollback_replay {
135 INSERT INTO t2 VALUES(1, 2, 3, 4);
136 INSERT INTO t2 VALUES('w', 'x', 'y', 'z');
137 }
138 execsql { SELECT * FROM t2 }
139 } {1 2 3 4 w x y z}
140
141 do_test 2.2 {
142 exec_rollback_replay {
143 DELETE FROM t2 WHERE a=1;
144 UPDATE t2 SET d = 'a';
145 }
146 execsql { SELECT * FROM t2 }
147 } {w x y a}
148
149 #-------------------------------------------------------------------------
150 # sqlite3changeset_invert()
151 #
152 reset_db
153
154 do_execsql_test 3.1 { CREATE TABLE t1(x PRIMARY KEY, y) }
155 do_test 3.2 {
156 sqlite3session S db main
157 S attach *
158 execsql { INSERT INTO t1 VALUES(1, 2) }
159 set patchset [S patchset]
160 S delete
161 list [catch { sqlite3changeset_invert $patchset } msg] [set msg]
162 } {1 SQLITE_CORRUPT}
163
164
165 #-------------------------------------------------------------------------
166 # sqlite3changeset_concat()
167 #
168 reset_db
169
170 proc do_patchconcat_test {tn args} {
171 set bRevert 0
172 if {[lindex $args 0] == "-revert"} {
173 set bRevert 1
174 set args [lrange $args 1 end]
175 }
176 set nSql [expr [llength $args]-1]
177 set res [lindex $args $nSql]
178 set patchlist [list]
179
180 execsql BEGIN
181 if {$bRevert} { execsql { SAVEPOINT x } }
182 foreach sql [lrange $args 0 end-1] {
183 sqlite3session S db main
184 S attach *
185 execsql $sql
186 lappend patchlist [S patchset]
187 S delete
188 if {$bRevert} { execsql { ROLLBACK TO x } }
189 }
190 execsql ROLLBACK
191
192 set patch [lindex $patchlist 0]
193 foreach p [lrange $patchlist 1 end] {
194 set patch [sqlite3changeset_concat $patch $p]
195 }
196
197 set x [list]
198 sqlite3session_foreach c $patch { lappend x $c }
199
200 uplevel [list do_test $tn [list set {} $x] [list {*}$res]]
201 }
202
203 do_execsql_test 4.1.1 {
204 CREATE TABLE t1(x PRIMARY KEY, y, z);
205 }
206 do_patchconcat_test 4.1.2 {
207 INSERT INTO t1 VALUES(1, 2, 3);
208 } {
209 INSERT INTO t1 VALUES(4, 5, 6);
210 } {
211 {INSERT t1 0 X.. {} {i 1 i 2 i 3}}
212 {INSERT t1 0 X.. {} {i 4 i 5 i 6}}
213 }
214
215 do_execsql_test 4.2.1 {
216 INSERT INTO t1 VALUES(1, 2, 3);
217 INSERT INTO t1 VALUES(4, 5, 6);
218 }
219
220 do_patchconcat_test 4.2.2 {
221 UPDATE t1 SET z = 'abc' WHERE x=1
222 } {
223 UPDATE t1 SET z = 'def' WHERE x=4
224 } {
225 {UPDATE t1 0 X.. {i 1 {} {} {} {}} {{} {} {} {} t abc}}
226 {UPDATE t1 0 X.. {i 4 {} {} {} {}} {{} {} {} {} t def}}
227 }
228
229 do_patchconcat_test 4.2.3 {
230 DELETE FROM t1 WHERE x=1;
231 } {
232 DELETE FROM t1 WHERE x=4;
233 } {
234 {DELETE t1 0 X.. {i 1 {} {} {} {}} {}}
235 {DELETE t1 0 X.. {i 4 {} {} {} {}} {}}
236 }
237
238
239 do_execsql_test 4.3.1 {
240 CREATE TABLE t2(a, b, c, d, PRIMARY KEY(c, b));
241 INSERT INTO t2 VALUES('.', 1, 1, '.');
242 INSERT INTO t2 VALUES('.', 1, 2, '.');
243 INSERT INTO t2 VALUES('.', 2, 1, '.');
244 INSERT INTO t2 VALUES('.', 2, 2, '.');
245 }
246
247 # INSERT + INSERT
248 do_patchconcat_test 4.3.2 -revert {
249 INSERT INTO t2 VALUES('a', 'a', 'a', 'a');
250 } {
251 INSERT INTO t2 VALUES('b', 'a', 'a', 'b');
252 } {
253 {INSERT t2 0 .XX. {} {t a t a t a t a}}
254 }
255
256 # INSERT + DELETE
257 do_patchconcat_test 4.3.3 {
258 INSERT INTO t2 VALUES('a', 'a', 'a', 'a');
259 } {
260 DELETE FROM t2 WHERE c = 'a';
261 } {
262 }
263
264 # INSERT + UPDATE
265 do_patchconcat_test 4.3.4 {
266 INSERT INTO t2 VALUES('a', 'a', 'a', 'a');
267 } {
268 UPDATE t2 SET d = 'b' WHERE c='a';
269 } {
270 {INSERT t2 0 .XX. {} {t a t a t a t b}}
271 }
272
273 # UPDATE + UPDATE
274 do_patchconcat_test 4.3.5 {
275 UPDATE t2 SET a = 'a' WHERE c=1 AND b=2;
276 } {
277 UPDATE t2 SET d = 'd' WHERE c=1 AND b=2;
278 } {
279 {UPDATE t2 0 .XX. {{} {} i 2 i 1 {} {}} {t a {} {} {} {} t d}}
280 }
281
282 # UPDATE + DELETE
283 do_patchconcat_test 4.3.6 {
284 UPDATE t2 SET a = 'a' WHERE c=1 AND b=2;
285 } {
286 DELETE FROM t2 WHERE c=1 AND b=2;
287 } {
288 {DELETE t2 0 .XX. {{} {} i 2 i 1 {} {}} {}}
289 }
290
291 # DELETE + INSERT
292 do_patchconcat_test 4.3.7 {
293 DELETE FROM t2 WHERE b=1;
294 } {
295 INSERT INTO t2 VALUES('x', 1, 2, '.');
296 } {
297 {DELETE t2 0 .XX. {{} {} i 1 i 1 {} {}} {}}
298 {UPDATE t2 0 .XX. {{} {} i 1 i 2 {} {}} {t x {} {} {} {} t .}}
299 }
300
301 # DELETE + UPDATE
302 do_patchconcat_test 4.3.8 -revert {
303 DELETE FROM t2 WHERE b=1 AND c=2;
304 } {
305 UPDATE t2 SET a=5 WHERE b=1 AND c=2;
306 } {
307 {DELETE t2 0 .XX. {{} {} i 1 i 2 {} {}} {}}
308 }
309
310 # DELETE + UPDATE
311 do_patchconcat_test 4.3.9 -revert {
312 DELETE FROM t2 WHERE b=1 AND c=2;
313 } {
314 DELETE FROM t2 WHERE b=1;
315 } {
316 {DELETE t2 0 .XX. {{} {} i 1 i 1 {} {}} {}}
317 {DELETE t2 0 .XX. {{} {} i 1 i 2 {} {}} {}}
318 }
319
320 #-------------------------------------------------------------------------
321 # More rigorous testing of the _patchset(), _apply and _concat() APIs.
322 #
323 # The inputs to each test are a populate database and a list of DML
324 # statements. This test determines that the final database is the same
325 # if:
326 #
327 # 1) the statements are executed directly on the database.
328 #
329 # 2) a single patchset is collected while executing the statements and
330 # then applied to a copy of the original database file.
331 #
332 # 3) individual patchsets are collected for statement while executing
333 # them and concatenated together before being applied to a copy of
334 # the original database. The concatenation is done in a couple of
335 # different ways - linear, pairwise etc.
336 #
337 # All tests, as it happens, are run with both changesets and patchsets.
338 # But the focus is on patchset capabilities.
339 #
340
341 # Return a checksum of the contents of the database file. Implicit IPK
342 # columns are not included in the checksum - just modifying rowids does
343 # not change the database checksum.
344 #
345 proc databasecksum {db} {
346 set alltab [$db eval {SELECT name FROM sqlite_master WHERE type='table'}]
347 foreach tab $alltab {
348 $db eval "SELECT * FROM $tab LIMIT 1" res { }
349 set slist [list]
350 foreach col [lsort $res(*)] {
351 lappend slist "quote($col)"
352 }
353 set sql "SELECT [join $slist ,] FROM $tab"
354 append txt "[lsort [$db eval $sql]]\n"
355 }
356 return [md5 $txt]
357 }
358
359 proc do_patchset_test {tn tstcmd lSql} {
360 if {$tstcmd != "patchset" && $tstcmd != "changeset"} {
361 error "have $tstcmd: must be patchset or changeset"
362 }
363
364 foreach fname {test.db2 test.db3 test.db4 test.db5} {
365 forcedelete $fname
366 forcecopy test.db $fname
367 }
368
369 # Execute the SQL statements on [db]. Collect a patchset for each
370 # individual statement, as well as a single patchset for the entire
371 # operation.
372 sqlite3session S db main
373 S attach *
374 foreach sql $lSql {
375 sqlite3session T db main
376 T attach *
377 db eval $sql
378 lappend lPatch [T $tstcmd]
379 T delete
380 }
381 set patchset [S $tstcmd]
382 S delete
383
384 # Calculate a checksum for the final database.
385 set cksum [databasecksum db]
386
387 # 1. Apply the single large patchset to test.db2
388 sqlite3 db2 test.db2
389 sqlite3changeset_apply db2 $patchset noop
390 uplevel [list do_test $tn.1 { databasecksum db2 } $cksum ]
391 db2 close
392
393 # 2. Apply each of the single-statement patchsets to test.db3
394 sqlite3 db2 test.db3
395 foreach p $lPatch {
396 sqlite3changeset_apply db2 $p noop
397 }
398 uplevel [list do_test $tn.2 { databasecksum db2 } $cksum ]
399 db2 close
400
401 # 3. Concatenate all single-statement patchsets into a single large
402 # patchset, then apply it to test.db4.
403 #
404 sqlite3 db2 test.db4
405 set big ""
406 foreach p $lPatch {
407 set big [sqlite3changeset_concat $big $p]
408 }
409 sqlite3changeset_apply db2 $big noop
410 uplevel [list do_test $tn.3 { databasecksum db2 } $cksum ]
411 db2 close
412
413 # 4. Concatenate all single-statement patchsets pairwise into a single
414 # large patchset, then apply it to test.db5. Pairwise concatenation:
415 #
416 # a b c d e f g h i j k
417 # -> {a b} {c d} {e f} {g h} {i j} k
418 # -> {a b c d} {e f g h} {i j k}
419 # -> {a b c d e f g h} {i j k}
420 # -> {a b c d e f g h i j k}
421 # -> APPLY!
422 #
423 sqlite3 db2 test.db5
424 set L $lPatch
425 while {[llength $L] > 1} {
426 set O [list]
427 for {set i 0} {$i < [llength $L]} {incr i 2} {
428 if {$i==[llength $L]-1} {
429 lappend O [lindex $L $i]
430 } else {
431 set i1 [expr $i+1]
432 lappend O [sqlite3changeset_concat [lindex $L $i] [lindex $L $i1]]
433 }
434 }
435 set L $O
436 }
437 sqlite3changeset_apply db2 [lindex $L 0] noop
438 uplevel [list do_test $tn.4 { databasecksum db2 } $cksum ]
439 db2 close
440 }
441
442 proc do_patchset_changeset_test {tn initsql args} {
443 foreach tstcmd {patchset changeset} {
444 reset_db
445 execsql $initsql
446 set x 0
447 foreach sql $args {
448 incr x
449 set lSql [split $sql ";"]
450 uplevel [list do_patchset_test $tn.$tstcmd.$x $tstcmd $lSql]
451 }
452 }
453 }
454
455 do_patchset_changeset_test 5.1 {
456 CREATE TABLE t1(a PRIMARY KEY, b, c);
457 INSERT INTO t1 VALUES(1, 2, 3);
458 } {
459 INSERT INTO t1 VALUES(4, 5, 6);
460 DELETE FROM t1 WHERE a=1;
461 } {
462 INSERT INTO t1 VALUES(7, 8, 9);
463 UPDATE t1 SET c = 5;
464 INSERT INTO t1 VALUES(10, 11, 12);
465 UPDATE t1 SET c = 6;
466 INSERT INTO t1 VALUES(13, 14, 15);
467 } {
468 UPDATE t1 SET c=c+1;
469 DELETE FROM t1 WHERE (a%2);
470 }
471
472 do_patchset_changeset_test 5.2 {
473 CREATE TABLE t1(a PRIMARY KEY, b, c);
474 CREATE TABLE t2(a, b, c, d, PRIMARY KEY(c, b));
475 } {
476 INSERT INTO t1 VALUES(x'00', 0, 'zero');
477 INSERT INTO t1 VALUES(x'01', 1, 'one');
478 INSERT INTO t1 VALUES(x'02', 4, 'four');
479 INSERT INTO t1 VALUES(x'03', 9, 'nine');
480 INSERT INTO t1 VALUES(x'04', 16, 'sixteen');
481 INSERT INTO t1 VALUES(x'05', 25, 'twenty-five');
482 } {
483 UPDATE t1 SET a = b WHERE b<=4;
484 INSERT INTO t2 SELECT NULL, * FROM t1;
485 DELETE FROM t1 WHERE b=25;
486 } {
487 DELETE FROM t2;
488 INSERT INTO t2 SELECT NULL, * FROM t1;
489 DELETE FROM t1;
490 INSERT INTO t1 SELECT b, c, d FROM t2;
491 UPDATE t1 SET b = b+1;
492 UPDATE t1 SET b = b+1;
493 UPDATE t1 SET b = b+1;
494 }
495
496 set initsql { CREATE TABLE t1(a, b, c, PRIMARY KEY(c, b)); }
497 for {set i 0} {$i < 1000} {incr i} {
498 append insert "INSERT INTO t1 VALUES($i, $i, $i);"
499 append delete "DELETE FROM t1 WHERE b=$i;"
500 }
501 do_patchset_changeset_test 5.3 \
502 $initsql $insert $delete \
503 $insert $delete \
504 "$insert $delete" \
505 $delete
506
507
508 finish_test
OLDNEW
« no previous file with comments | « third_party/sqlite/src/ext/session/sessionA.test ('k') | third_party/sqlite/src/ext/session/sessionC.test » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698