1# 2011 March 07 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# This file implements regression tests for SQLite library. 12# 13 14if {![info exists testdir]} { 15 set testdir [file join [file dirname [info script]] .. .. test] 16} 17source [file join [file dirname [info script]] session_common.tcl] 18source $testdir/tester.tcl 19ifcapable !session {finish_test; return} 20 21set testprefix session1 22 23# Run all tests in this file twice. Once with "WITHOUT ROWID", and once 24# with regular rowid tables. 25# 26foreach {tn trailing} { 27 1 "" 28 2 " WITHOUT ROWID " 29} { 30eval [string map [list %WR% $trailing] { 31 32db close 33forcedelete test.db test.db2 34reset_db 35 36do_execsql_test $tn.1.0 { 37 CREATE TABLE t1(x PRIMARY KEY, y) %WR%; 38 INSERT INTO t1 VALUES('abc', 'def'); 39} 40 41#------------------------------------------------------------------------- 42# Test creating, attaching tables to and deleting session objects. 43# 44do_test $tn.1.1 { sqlite3session S db main } {S} 45do_test $tn.1.2 { S delete } {} 46do_test $tn.1.3 { sqlite3session S db main } {S} 47do_test $tn.1.4 { S attach t1 } {} 48do_test $tn.1.5 { S delete } {} 49do_test $tn.1.6 { sqlite3session S db main } {S} 50do_test $tn.1.7 { S attach t1 ; S attach t2 ; S attach t3 } {} 51do_test $tn.1.8 { S attach t1 ; S attach t2 ; S attach t3 } {} 52do_test $tn.1.9 { S delete } {} 53do_test $tn.1.10 { 54 sqlite3session S db main 55 S attach t1 56 execsql { INSERT INTO t1 VALUES('ghi', 'jkl') } 57} {} 58do_test $tn.1.11 { S delete } {} 59if {$tn==1} { 60 do_test $tn.1.12 { 61 sqlite3session S db main 62 S attach t1 63 execsql { INSERT INTO t1 VALUES('mno', 'pqr') } 64 execsql { UPDATE t1 SET x = 111 WHERE rowid = 1 } 65 execsql { DELETE FROM t1 WHERE rowid = 2 } 66 } {} 67 do_test $tn.1.13 { 68 S changeset 69 S delete 70 } {} 71} 72 73#------------------------------------------------------------------------- 74# Simple changeset tests. Also test the sqlite3changeset_invert() 75# function. 76# 77do_test $tn.2.1.1 { 78 execsql { DELETE FROM t1 } 79 sqlite3session S db main 80 S attach t1 81 execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } 82 execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } 83 execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } 84} {} 85do_changeset_test $tn.2.1.2 S { 86 {INSERT t1 0 X. {} {i 1 t Sukhothai}} 87 {INSERT t1 0 X. {} {i 2 t Ayutthaya}} 88 {INSERT t1 0 X. {} {i 3 t Thonburi}} 89} 90do_changeset_invert_test $tn.2.1.3 S { 91 {DELETE t1 0 X. {i 1 t Sukhothai} {}} 92 {DELETE t1 0 X. {i 2 t Ayutthaya} {}} 93 {DELETE t1 0 X. {i 3 t Thonburi} {}} 94} 95do_test $tn.2.1.4 { S delete } {} 96 97do_test $tn.2.2.1 { 98 sqlite3session S db main 99 S attach t1 100 execsql { DELETE FROM t1 WHERE 1 } 101} {} 102do_changeset_test $tn.2.2.2 S { 103 {DELETE t1 0 X. {i 1 t Sukhothai} {}} 104 {DELETE t1 0 X. {i 2 t Ayutthaya} {}} 105 {DELETE t1 0 X. {i 3 t Thonburi} {}} 106} 107do_changeset_invert_test $tn.2.2.3 S { 108 {INSERT t1 0 X. {} {i 1 t Sukhothai}} 109 {INSERT t1 0 X. {} {i 2 t Ayutthaya}} 110 {INSERT t1 0 X. {} {i 3 t Thonburi}} 111} 112do_test $tn.2.2.4 { S delete } {} 113 114do_test $tn.2.3.1 { 115 execsql { DELETE FROM t1 } 116 sqlite3session S db main 117 execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') } 118 execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') } 119 execsql { INSERT INTO t1 VALUES(3, 'Thonburi') } 120 S attach t1 121 execsql { 122 UPDATE t1 SET x = 10 WHERE x = 1; 123 UPDATE t1 SET y = 'Surin' WHERE x = 2; 124 UPDATE t1 SET x = 20, y = 'Thapae' WHERE x = 3; 125 } 126} {} 127 128do_changeset_test $tn.2.3.2 S { 129 {INSERT t1 0 X. {} {i 10 t Sukhothai}} 130 {DELETE t1 0 X. {i 1 t Sukhothai} {}} 131 {UPDATE t1 0 X. {i 2 t Ayutthaya} {{} {} t Surin}} 132 {DELETE t1 0 X. {i 3 t Thonburi} {}} 133 {INSERT t1 0 X. {} {i 20 t Thapae}} 134} 135 136do_changeset_invert_test $tn.2.3.3 S { 137 {DELETE t1 0 X. {i 10 t Sukhothai} {}} 138 {INSERT t1 0 X. {} {i 1 t Sukhothai}} 139 {UPDATE t1 0 X. {i 2 t Surin} {{} {} t Ayutthaya}} 140 {INSERT t1 0 X. {} {i 3 t Thonburi}} 141 {DELETE t1 0 X. {i 20 t Thapae} {}} 142} 143do_test $tn.2.3.4 { S delete } {} 144 145do_test $tn.2.4.1 { 146 sqlite3session S db main 147 S attach t1 148 execsql { INSERT INTO t1 VALUES(100, 'Bangkok') } 149 execsql { DELETE FROM t1 WHERE x = 100 } 150} {} 151do_changeset_test $tn.2.4.2 S {} 152do_changeset_invert_test $tn.2.4.3 S {} 153do_test $tn.2.4.4 { S delete } {} 154 155do_execsql_test $tn.2.5.0 { 156 SELECT * FROM t1 ORDER BY x 157} { 158 2 Surin 159 10 Sukhothai 160 20 Thapae 161} 162 163do_test $tn.2.5.1 { 164 sqlite3session S db main 165 S attach t1 166 execsql { DELETE FROM t1 } 167} {} 168do_changeset_test $tn.2.5.2 S { 169 {DELETE t1 0 X. {i 10 t Sukhothai} {}} 170 {DELETE t1 0 X. {i 2 t Surin} {}} 171 {DELETE t1 0 X. {i 20 t Thapae} {}} 172} 173do_test $tn.2.5.3 { S delete } {} 174 175#------------------------------------------------------------------------- 176# Test the application of simple changesets. These tests also test that 177# the conflict callback is invoked correctly. For these tests, the 178# conflict callback always returns OMIT. 179# 180db close 181forcedelete test.db test.db2 182sqlite3 db test.db 183sqlite3 db2 test.db2 184 185proc xConflict {args} { 186 lappend ::xConflict $args 187 return "" 188} 189 190proc bgerror {args} { set ::background_error $args } 191 192proc do_conflict_test {tn args} { 193 set O(-tables) [list] 194 set O(-sql) [list] 195 set O(-conflicts) [list] 196 197 array set V $args 198 foreach key [array names V] { 199 if {![info exists O($key)]} {error "no such option: $key"} 200 } 201 array set O $args 202 203 sqlite3session S db main 204 foreach t $O(-tables) { S attach $t } 205 execsql $O(-sql) 206 set ::xConflict [list] 207 sqlite3changeset_apply db2 [S changeset] xConflict 208 209 set conflicts [list] 210 foreach c $O(-conflicts) { 211 lappend conflicts $c 212 } 213 214 after 1 {set go 1} 215 vwait go 216 217 uplevel do_test $tn [list { set ::xConflict }] [list $conflicts] 218 S delete 219} 220 221proc do_db2_test {testname sql {result {}}} { 222 uplevel do_test $testname [list "execsql {$sql} db2"] [list [list {*}$result]] 223} 224 225# Test INSERT changesets. 226# 227do_test $tn.3.1.0 { 228 execsql { CREATE TABLE t1(a PRIMARY KEY, b NOT NULL) %WR% } db2 229 execsql { 230 CREATE TABLE t1(a PRIMARY KEY, b) %WR%; 231 INSERT INTO t1 VALUES(1, 'one'); 232 INSERT INTO t1 VALUES(2, 'two'); 233 } db 234} {} 235do_db2_test $tn.3.1.1 "INSERT INTO t1 VALUES(6, 'VI')" 236do_conflict_test $tn.3.1.2 -tables t1 -sql { 237 INSERT INTO t1 VALUES(3, 'three'); 238 INSERT INTO t1 VALUES(4, 'four'); 239 INSERT INTO t1 VALUES(5, 'five'); 240 INSERT INTO t1 VALUES(6, 'six'); 241 INSERT INTO t1 VALUES(7, 'seven'); 242 INSERT INTO t1 VALUES(8, NULL); 243} -conflicts { 244 {INSERT t1 CONFLICT {i 6 t six} {i 6 t VI}} 245 {INSERT t1 CONSTRAINT {i 8 n {}}} 246} 247 248do_db2_test $tn.3.1.3 "SELECT * FROM t1 ORDER BY a" { 249 3 three 4 four 5 five 6 VI 7 seven 250} 251do_execsql_test $tn.3.1.4 "SELECT * FROM t1" { 252 1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 {} 253} 254 255# Test DELETE changesets. 256# 257do_execsql_test $tn.3.2.1 { 258 PRAGMA foreign_keys = on; 259 CREATE TABLE t2(a PRIMARY KEY, b)%WR%; 260 CREATE TABLE t3(c, d REFERENCES t2); 261 INSERT INTO t2 VALUES(1, 'one'); 262 INSERT INTO t2 VALUES(2, 'two'); 263 INSERT INTO t2 VALUES(3, 'three'); 264 INSERT INTO t2 VALUES(4, 'four'); 265} 266do_db2_test $tn.3.2.2 { 267 PRAGMA foreign_keys = on; 268 CREATE TABLE t2(a PRIMARY KEY, b)%WR%; 269 CREATE TABLE t3(c, d REFERENCES t2); 270 INSERT INTO t2 VALUES(1, 'one'); 271 INSERT INTO t2 VALUES(2, 'two'); 272 INSERT INTO t2 VALUES(4, 'five'); 273 INSERT INTO t3 VALUES('i', 1); 274} 275do_conflict_test $tn.3.2.3 -tables t2 -sql { 276 DELETE FROM t2 WHERE a = 1; 277 DELETE FROM t2 WHERE a = 2; 278 DELETE FROM t2 WHERE a = 3; 279 DELETE FROM t2 WHERE a = 4; 280} -conflicts { 281 {DELETE t2 NOTFOUND {i 3 t three}} 282 {DELETE t2 DATA {i 4 t four} {i 4 t five}} 283 {FOREIGN_KEY 1} 284} 285do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {} 286do_db2_test $tn.3.2.5 "SELECT * FROM t2" {4 five} 287 288# Test UPDATE changesets. 289# 290do_execsql_test $tn.3.3.1 { 291 CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c))%WR%; 292 INSERT INTO t4 VALUES(1, 2, 3); 293 INSERT INTO t4 VALUES(4, 5, 6); 294 INSERT INTO t4 VALUES(7, 8, 9); 295 INSERT INTO t4 VALUES(10, 11, 12); 296} 297do_db2_test $tn.3.3.2 { 298 CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c))%WR%; 299 INSERT INTO t4 VALUES(0, 2, 3); 300 INSERT INTO t4 VALUES(4, 5, 7); 301 INSERT INTO t4 VALUES(7, 8, 9); 302 INSERT INTO t4 VALUES(10, 11, 12); 303} 304do_conflict_test $tn.3.3.3 -tables t4 -sql { 305 UPDATE t4 SET a = -1 WHERE b = 2; 306 UPDATE t4 SET a = -1 WHERE b = 5; 307 UPDATE t4 SET a = NULL WHERE c = 9; 308 UPDATE t4 SET a = 'x' WHERE b = 11; 309} -conflicts { 310 {UPDATE t4 DATA {i 1 i 2 i 3} {i -1 {} {} {} {}} {i 0 i 2 i 3}} 311 {UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}} 312 {UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}} 313} 314do_db2_test $tn.3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12} 315do_execsql_test $tn.3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12} 316 317#------------------------------------------------------------------------- 318# This next block of tests verifies that values returned by the conflict 319# handler are intepreted correctly. 320# 321 322proc test_reset {} { 323 db close 324 db2 close 325 forcedelete test.db test.db2 326 sqlite3 db test.db 327 sqlite3 db2 test.db2 328} 329 330proc xConflict {args} { 331 lappend ::xConflict $args 332 return $::conflict_return 333} 334 335foreach {tn2 conflict_return after} { 336 1 OMIT {1 2 value1 4 5 7 10 x x} 337 2 REPLACE {1 2 value1 4 5 value2 10 8 9} 338} { 339 test_reset 340 341 do_test $tn.4.$tn2.1 { 342 foreach db {db db2} { 343 execsql { 344 CREATE TABLE t1(a, b, c, PRIMARY KEY(a))%WR%; 345 INSERT INTO t1 VALUES(1, 2, 3); 346 INSERT INTO t1 VALUES(4, 5, 6); 347 INSERT INTO t1 VALUES(7, 8, 9); 348 } $db 349 } 350 execsql { 351 REPLACE INTO t1 VALUES(4, 5, 7); 352 REPLACE INTO t1 VALUES(10, 'x', 'x'); 353 } db2 354 } {} 355 356 do_conflict_test $tn.4.$tn2.2 -tables t1 -sql { 357 UPDATE t1 SET c = 'value1' WHERE a = 1; -- no conflict 358 UPDATE t1 SET c = 'value2' WHERE a = 4; -- DATA conflict 359 UPDATE t1 SET a = 10 WHERE a = 7; -- CONFLICT conflict 360 } -conflicts { 361 {INSERT t1 CONFLICT {i 10 i 8 i 9} {i 10 t x t x}} 362 {UPDATE t1 DATA {i 4 {} {} i 6} {{} {} {} {} t value2} {i 4 i 5 i 7}} 363 } 364 365 do_db2_test $tn.4.$tn2.3 "SELECT * FROM t1 ORDER BY a" $after 366} 367 368foreach {tn2 conflict_return} { 369 1 OMIT 370 2 REPLACE 371} { 372 test_reset 373 374 do_test $tn.5.$tn2.1 { 375 # Create an identical schema in both databases. 376 set schema { 377 CREATE TABLE "'foolish name'"(x, y, z, PRIMARY KEY(x, y))%WR%; 378 } 379 execsql $schema db 380 execsql $schema db2 381 382 # Add some rows to [db2]. These rows will cause conflicts later 383 # on when the changeset from [db] is applied to it. 384 execsql { 385 INSERT INTO "'foolish name'" VALUES('one', 'one', 'ii'); 386 INSERT INTO "'foolish name'" VALUES('one', 'two', 'i'); 387 INSERT INTO "'foolish name'" VALUES('two', 'two', 'ii'); 388 } db2 389 390 } {} 391 392 do_conflict_test $tn.5.$tn2.2 -tables {{'foolish name'}} -sql { 393 INSERT INTO "'foolish name'" VALUES('one', 'two', 2); 394 } -conflicts { 395 {INSERT {'foolish name'} CONFLICT {t one t two i 2} {t one t two t i}} 396 } 397 398 set res(REPLACE) {one one ii one two 2 two two ii} 399 set res(OMIT) {one one ii one two i two two ii} 400 do_db2_test $tn.5.$tn2.3 { 401 SELECT * FROM "'foolish name'" ORDER BY x, y 402 } $res($conflict_return) 403 404 405 do_test $tn.5.$tn2.1 { 406 set schema { 407 CREATE TABLE d1("z""z" PRIMARY KEY, y)%WR%; 408 INSERT INTO d1 VALUES(1, 'one'); 409 INSERT INTO d1 VALUES(2, 'two'); 410 } 411 execsql $schema db 412 execsql $schema db2 413 414 execsql { 415 UPDATE d1 SET y = 'TWO' WHERE "z""z" = 2; 416 } db2 417 418 } {} 419 420 do_conflict_test $tn.5.$tn2.2 -tables d1 -sql { 421 DELETE FROM d1 WHERE "z""z" = 2; 422 } -conflicts { 423 {DELETE d1 DATA {i 2 t two} {i 2 t TWO}} 424 } 425 426 set res(REPLACE) {1 one} 427 set res(OMIT) {1 one 2 TWO} 428 do_db2_test $tn.5.$tn2.3 "SELECT * FROM d1" $res($conflict_return) 429} 430 431#------------------------------------------------------------------------- 432# Test that two tables can be monitored by a single session object. 433# 434test_reset 435set schema { 436 CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b)%WR%; 437 CREATE TABLE t2(a, b PRIMARY KEY)%WR%; 438} 439do_test $tn.6.0 { 440 execsql $schema db 441 execsql $schema db2 442 execsql { 443 INSERT INTO t1 VALUES('a', 'b'); 444 INSERT INTO t2 VALUES('a', 'b'); 445 } db2 446} {} 447 448set conflict_return "" 449do_conflict_test $tn.6.1 -tables {t1 t2} -sql { 450 INSERT INTO t1 VALUES('1', '2'); 451 INSERT INTO t1 VALUES('A', 'B'); 452 INSERT INTO t2 VALUES('A', 'B'); 453} -conflicts { 454 {INSERT t1 CONFLICT {t A t B} {t a t b}} 455} 456 457do_db2_test $tn.6.2 "SELECT * FROM t1 ORDER BY a" {1 2 a b} 458do_db2_test $tn.6.3 "SELECT * FROM t2 ORDER BY a" {A B a b} 459 460#------------------------------------------------------------------------- 461# Test that session objects are not confused by changes to table in 462# other databases. 463# 464catch { db2 close } 465drop_all_tables 466forcedelete test.db2 467do_iterator_test $tn.7.1 * { 468 ATTACH 'test.db2' AS aux; 469 CREATE TABLE main.t1(x PRIMARY KEY, y)%WR%; 470 CREATE TABLE aux.t1(x PRIMARY KEY, y)%WR%; 471 472 INSERT INTO main.t1 VALUES('one', 1); 473 INSERT INTO main.t1 VALUES('two', 2); 474 INSERT INTO aux.t1 VALUES('three', 3); 475 INSERT INTO aux.t1 VALUES('four', 4); 476} { 477 {INSERT t1 0 X. {} {t two i 2}} 478 {INSERT t1 0 X. {} {t one i 1}} 479} 480 481#------------------------------------------------------------------------- 482# Test the sqlite3session_isempty() function. 483# 484do_test $tn.8.1 { 485 execsql { 486 CREATE TABLE t5(x PRIMARY KEY, y)%WR%; 487 CREATE TABLE t6(x PRIMARY KEY, y)%WR%; 488 INSERT INTO t5 VALUES('a', 'b'); 489 INSERT INTO t6 VALUES('a', 'b'); 490 } 491 sqlite3session S db main 492 S attach * 493 494 S isempty 495} {1} 496do_test $tn.8.2 { 497 execsql { DELETE FROM t5 } 498 S isempty 499} {0} 500do_test $tn.8.3 { 501 S delete 502 sqlite3session S db main 503 S attach t5 504 execsql { DELETE FROM t5 } 505 S isempty 506} {1} 507do_test $tn.8.4 { S delete } {} 508 509do_test $tn.8.5 { 510 sqlite3session S db main 511 S attach t5 512 S attach t6 513 execsql { INSERT INTO t5 VALUES(1, 2) } 514 S isempty 515} {0} 516 517do_test $tn.8.6 { 518 S delete 519 sqlite3session S db main 520 S attach t5 521 S attach t6 522 execsql { INSERT INTO t6 VALUES(1, 2) } 523 S isempty 524} {0} 525do_test $tn.8.7 { S delete } {} 526 527#------------------------------------------------------------------------- 528# 529do_execsql_test $tn.9.1 { 530 CREATE TABLE t7(a, b, c, d, e PRIMARY KEY, f, g)%WR%; 531 INSERT INTO t7 VALUES(1, 1, 1, 1, 1, 1, 1); 532} 533do_test $tn.9.2 { 534 sqlite3session S db main 535 S attach * 536 execsql { UPDATE t7 SET b=2, d=2 } 537} {} 538do_changeset_test $tn.9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}} 539S delete 540catch { db2 close } 541 542#------------------------------------------------------------------------- 543# Test a really long table name. 544# 545reset_db 546set tblname [string repeat tblname123 100] 547do_test $tn.10.1.1 { 548 execsql " 549 CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%; 550 INSERT INTO $tblname VALUES('xyz', 'def'); 551 " 552 sqlite3session S db main 553 S attach $tblname 554 execsql " 555 INSERT INTO $tblname VALUES('uvw', 'abc'); 556 DELETE FROM $tblname WHERE a = 'xyz'; 557 " 558} {} 559do_changeset_test $tn.10.1.2 S " 560 {INSERT $tblname 0 X. {} {t uvw t abc}} 561 {DELETE $tblname 0 X. {t xyz t def} {}} 562" 563do_test $tn.10.1.4 { S delete } {} 564 565#--------------------------------------------------------------- 566reset_db 567do_execsql_test $tn.11.1 { 568 CREATE TABLE t1(a, b); 569} 570do_test $tn.11.2 { 571 sqlite3session S db main 572 S attach t1 573 execsql { 574 INSERT INTO t1 VALUES(1, 2); 575 } 576 S changeset 577} {} 578 579S delete 580 581 582#------------------------------------------------------------------------- 583# Test a really long table name. 584# 585reset_db 586set tblname [string repeat tblname123 100] 587do_test $tn.10.1.1 { 588 execsql " 589 CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%; 590 INSERT INTO $tblname VALUES('xyz', 'def'); 591 " 592 sqlite3session S db main 593 S attach $tblname 594 execsql " 595 INSERT INTO $tblname VALUES('uvw', 'abc'); 596 DELETE FROM $tblname WHERE a = 'xyz'; 597 " 598} {} 599do_changeset_test $tn.10.1.2 S " 600 {INSERT $tblname 0 X. {} {t uvw t abc}} 601 {DELETE $tblname 0 X. {t xyz t def} {}} 602" 603do_test $tn.10.1.4 { S delete } {} 604 605#------------------------------------------------------------------------- 606# Test the effect of updating a column from 0.0 to 0.0. 607# 608reset_db 609do_execsql_test $tn.11.1 { 610 CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL)%WR%; 611 INSERT INTO t1 VALUES(1, 0.0); 612} 613do_iterator_test $tn.11.2 * { 614 UPDATE t1 SET b = 0.0; 615} { 616} 617 618reset_db 619do_execsql_test $tn.12.1 { 620 CREATE TABLE t1(r INTEGER PRIMARY KEY, a, b)%WR%; 621 CREATE INDEX i1 ON t1(a); 622 INSERT INTO t1 VALUES(1, 1, 1); 623 INSERT INTO t1 VALUES(2, 1, 2); 624 INSERT INTO t1 VALUES(3, 1, 3); 625} 626 627do_iterator_test $tn.12.2 * { 628 UPDATE t1 SET b='one' WHERE a=1; 629} { 630 {UPDATE t1 0 X.. {i 1 {} {} i 1} {{} {} {} {} t one}} 631 {UPDATE t1 0 X.. {i 2 {} {} i 2} {{} {} {} {} t one}} 632 {UPDATE t1 0 X.. {i 3 {} {} i 3} {{} {} {} {} t one}} 633} 634 635#------------------------------------------------------------------------- 636# Test that no savepoint is used if -nosavepoint is specified. 637# 638do_execsql_test $tn.13.1 { 639 CREATE TABLE x1(a INTEGER PRIMARY KEY, b)%WR%; 640} 641do_test $tn.13.2 { 642 execsql BEGIN 643 set C [changeset_from_sql { 644 INSERT INTO x1 VALUES(1, 'one'); 645 INSERT INTO x1 VALUES(2, 'two'); 646 INSERT INTO x1 VALUES(3, 'three'); 647 }] 648 execsql ROLLBACK 649 execsql { 650 INSERT INTO x1 VALUES(1, 'i'); 651 INSERT INTO x1 VALUES(2, 'ii'); 652 INSERT INTO x1 VALUES(3, 'iii'); 653 } 654} {} 655 656proc xConflict {args} { 657 set ret [lindex $::CONFLICT_HANDLERS 0] 658 set ::CONFLICT_HANDLERS [lrange $::CONFLICT_HANDLERS 1 end] 659 set ret 660} 661do_test $tn.13.3 { 662 set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] 663 execsql BEGIN 664 catch { sqlite3changeset_apply_v2 db $C xConflict } msg 665 execsql { 666 SELECT * FROM x1 667 } 668} {1 i 2 ii 3 iii} 669do_test $tn.13.3 { 670 set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] 671 execsql ROLLBACK 672 execsql BEGIN 673 catch { sqlite3changeset_apply_v2 -nosavepoint db $C xConflict } msg 674 execsql { SELECT * FROM x1 } 675} {1 one 2 two 3 iii} 676execsql ROLLBACK 677 678do_test $tn.14.1 { sqlite3session_config strm_size -1 } 64 679do_test $tn.14.2 { sqlite3session_config strm_size 65536 } 65536 680do_test $tn.14.3 { sqlite3session_config strm_size 64 } 64 681do_test $tn.14.4 { 682 list [catch {sqlite3session_config invalid 123} msg] $msg 683} {1 SQLITE_MISUSE} 684 685}] 686} 687 688 689finish_test 690