1a38e6c57Sdan# 2018 March 14 2a38e6c57Sdan# 3a38e6c57Sdan# The author disclaims copyright to this source code. In place of 4a38e6c57Sdan# a legal notice, here is a blessing: 5a38e6c57Sdan# 6a38e6c57Sdan# May you do good and not evil. 7a38e6c57Sdan# May you find forgiveness for yourself and forgive others. 8a38e6c57Sdan# May you share freely, never taking more than you give. 9a38e6c57Sdan# 10a38e6c57Sdan#*********************************************************************** 11a38e6c57Sdan# This file implements regression tests for SQLite library. 12a38e6c57Sdan# 13a38e6c57Sdan 14a38e6c57Sdanif {![info exists testdir]} { 15a38e6c57Sdan set testdir [file join [file dirname [info script]] .. .. test] 16a38e6c57Sdan} 17a38e6c57Sdansource [file join [file dirname [info script]] session_common.tcl] 18a38e6c57Sdansource $testdir/tester.tcl 19a38e6c57Sdanifcapable !session {finish_test; return} 20a38e6c57Sdan 21a38e6c57Sdanset testprefix sessionrebase 22a38e6c57Sdan 23a38e6c57Sdanset ::lConflict [list] 24a38e6c57Sdanproc xConflict {args} { 25a38e6c57Sdan set res [lindex $::lConflict 0] 26a38e6c57Sdan set ::lConflict [lrange $::lConflict 1 end] 27a38e6c57Sdan return $res 28a38e6c57Sdan} 29a38e6c57Sdan 30a38e6c57Sdan#------------------------------------------------------------------------- 31a38e6c57Sdan# The following test cases - 1.* - test that the rebase blobs output by 32a38e6c57Sdan# sqlite3_changeset_apply_v2 look correct in some simple cases. The blob 33a38e6c57Sdan# is itself a changeset, containing records determined as follows: 34a38e6c57Sdan# 35a38e6c57Sdan# * For each conflict resolved with REPLACE, the rebase blob contains 36a38e6c57Sdan# a DELETE record. All fields other than the PK fields are undefined. 37a38e6c57Sdan# 38a38e6c57Sdan# * For each conflict resolved with OMIT, the rebase blob contains an 39a38e6c57Sdan# INSERT record. For an INSERT or UPDATE operation, the indirect flag 40a38e6c57Sdan# is clear and all updated fields are defined. For a DELETE operation, 41a38e6c57Sdan# the indirect flag is set and all non-PK fields left undefined. 42a38e6c57Sdan# 43a38e6c57Sdanproc do_apply_v2_test {tn sql modsql conflict_handler res} { 44a38e6c57Sdan 45a38e6c57Sdan execsql BEGIN 46a38e6c57Sdan sqlite3session S db main 47a38e6c57Sdan S attach * 48a38e6c57Sdan execsql $sql 49a38e6c57Sdan set changeset [S changeset] 50a38e6c57Sdan S delete 51a38e6c57Sdan execsql ROLLBACK 52a38e6c57Sdan 53a38e6c57Sdan execsql BEGIN 54a38e6c57Sdan execsql $modsql 55a38e6c57Sdan set ::lConflict $conflict_handler 56a38e6c57Sdan set blob [sqlite3changeset_apply_v2 db $changeset xConflict] 57a38e6c57Sdan execsql ROLLBACK 58a38e6c57Sdan 59a38e6c57Sdan uplevel [list do_test $tn [list changeset_to_list $blob] [list {*}$res]] 60a38e6c57Sdan} 61a38e6c57Sdan 62bd45374cSdan 63bd45374cSdanset ::lConflict [list] 64bd45374cSdanproc xConflict {args} { 65bd45374cSdan set res [lindex $::lConflict 0] 66bd45374cSdan set ::lConflict [lrange $::lConflict 1 end] 67bd45374cSdan return $res 68bd45374cSdan} 69bd45374cSdan 70bd45374cSdan# Take a copy of database test.db in file test.db2. Execute $sql1 71bd45374cSdan# against test.db and $sql2 against test.db2. Capture a changeset 72bd45374cSdan# for each. Then send the test.db2 changeset to test.db and apply 73bd45374cSdan# it with the conflict handlers in $conflict_handler. Patch the 74bd45374cSdan# test.db changeset and then execute it against test.db2. Test that 75bd45374cSdan# the two databases come out the same. 76bd45374cSdan# 77bd45374cSdanproc do_rebase_test {tn sql1 sql2 conflict_handler {testsql ""} {testres ""}} { 78bd45374cSdan 79bd45374cSdan for {set i 1} {$i <= 2} {incr i} { 80bd45374cSdan forcedelete test.db2 test.db2-journal test.db2-wal 81bd45374cSdan forcecopy test.db test.db2 82bd45374cSdan sqlite3 db2 test.db2 83bd45374cSdan 84bd45374cSdan db eval BEGIN 85bd45374cSdan 86bd45374cSdan sqlite3session S1 db main 87bd45374cSdan S1 attach * 88bd45374cSdan execsql $sql1 db 89bd45374cSdan set c1 [S1 changeset] 90bd45374cSdan S1 delete 91bd45374cSdan 92bd45374cSdan if {$i==1} { 93bd45374cSdan sqlite3session S2 db2 main 94bd45374cSdan S2 attach * 95bd45374cSdan execsql $sql2 db2 96bd45374cSdan set c2 [S2 changeset] 97bd45374cSdan S2 delete 98bd45374cSdan } else { 99bd45374cSdan set c2 [list] 100bd45374cSdan foreach sql [split $sql2 ";"] { 101bd45374cSdan if {[string is space $sql]} continue 102bd45374cSdan sqlite3session S2 db2 main 103bd45374cSdan S2 attach * 104bd45374cSdan execsql $sql db2 105bd45374cSdan lappend c2 [S2 changeset] 106bd45374cSdan S2 delete 107bd45374cSdan } 108bd45374cSdan } 109bd45374cSdan 110bd45374cSdan set ::lConflict $conflict_handler 111bd45374cSdan set rebase [list] 112bd45374cSdan if {$i==1} { 113bd45374cSdan lappend rebase [sqlite3changeset_apply_v2 db $c2 xConflict] 114bd45374cSdan } else { 115bd45374cSdan foreach c $c2 { 116*f231e18cSdan#puts "apply_v2: [changeset_to_list $c]" 117bd45374cSdan lappend rebase [sqlite3changeset_apply_v2 db $c xConflict] 118bd45374cSdan } 119*f231e18cSdan #puts "llength: [llength $rebase]" 120bd45374cSdan } 121bd45374cSdan #if {$tn=="2.1.4"} { puts [changeset_to_list $rebase] ; breakpoint } 122bd45374cSdan #puts [changeset_to_list [lindex $rebase 0]] ; breakpoint 123bd45374cSdan #puts [llength $rebase] 124bd45374cSdan 125bd45374cSdan sqlite3rebaser_create R 126bd45374cSdan foreach r $rebase { 127*f231e18cSdan#puts [changeset_to_list $r] 128bd45374cSdan R configure $r 129bd45374cSdan } 130bd45374cSdan set c1r [R rebase $c1] 131bd45374cSdan R delete 132bd45374cSdan #if {$tn=="2.1.4"} { puts [changeset_to_list $c1r] } 133bd45374cSdan 134bd45374cSdan sqlite3changeset_apply_v2 db2 $c1r xConflictAbort 135bd45374cSdan 136*f231e18cSdan if {[string range $tn end end]!="*"} { 137bd45374cSdan uplevel [list do_test $tn.$i.1 [list compare_db db db2] {}] 138*f231e18cSdan } 139bd45374cSdan db2 close 140bd45374cSdan 141bd45374cSdan if {$testsql!=""} { 142bd45374cSdan uplevel [list do_execsql_test $tn.$i.2 $testsql $testres] 143bd45374cSdan } 144bd45374cSdan 145bd45374cSdan db eval ROLLBACK 146bd45374cSdan } 147bd45374cSdan} 148bd45374cSdan 149a38e6c57Sdando_execsql_test 1.0 { 150a38e6c57Sdan CREATE TABLE t1(a INTEGER PRIMARY KEY, b); 151a38e6c57Sdan INSERT INTO t1 VALUES(1, 'value A'); 152a38e6c57Sdan} 153a38e6c57Sdan 154a38e6c57Sdando_apply_v2_test 1.1.1 { 155a38e6c57Sdan UPDATE t1 SET b = 'value B' WHERE a=1; 156a38e6c57Sdan} { 157a38e6c57Sdan UPDATE t1 SET b = 'value C' WHERE a=1; 158a38e6c57Sdan} { 159a38e6c57Sdan OMIT 160a38e6c57Sdan} { 161a38e6c57Sdan {INSERT t1 0 X. {} {i 1 t {value B}}} 162a38e6c57Sdan} 163f01d3a7eSdan 164a38e6c57Sdando_apply_v2_test 1.1.2 { 165a38e6c57Sdan UPDATE t1 SET b = 'value B' WHERE a=1; 166a38e6c57Sdan} { 167a38e6c57Sdan UPDATE t1 SET b = 'value C' WHERE a=1; 168a38e6c57Sdan} { 169a38e6c57Sdan REPLACE 170a38e6c57Sdan} { 171f01d3a7eSdan {INSERT t1 1 X. {} {i 1 t {value B}}} 172a38e6c57Sdan} 173a38e6c57Sdan 174a38e6c57Sdando_apply_v2_test 1.2.1 { 175a38e6c57Sdan INSERT INTO t1 VALUES(2, 'first'); 176a38e6c57Sdan} { 177a38e6c57Sdan INSERT INTO t1 VALUES(2, 'second'); 178a38e6c57Sdan} { 179a38e6c57Sdan OMIT 180a38e6c57Sdan} { 181a38e6c57Sdan {INSERT t1 0 X. {} {i 2 t first}} 182a38e6c57Sdan} 183a38e6c57Sdando_apply_v2_test 1.2.2 { 184a38e6c57Sdan INSERT INTO t1 VALUES(2, 'first'); 185a38e6c57Sdan} { 186a38e6c57Sdan INSERT INTO t1 VALUES(2, 'second'); 187a38e6c57Sdan} { 188a38e6c57Sdan REPLACE 189a38e6c57Sdan} { 190f01d3a7eSdan {INSERT t1 1 X. {} {i 2 t first}} 191a38e6c57Sdan} 192a38e6c57Sdan 193a38e6c57Sdando_apply_v2_test 1.3.1 { 194a38e6c57Sdan DELETE FROM t1 WHERE a=1; 195a38e6c57Sdan} { 196a38e6c57Sdan UPDATE t1 SET b='value D' WHERE a=1; 197a38e6c57Sdan} { 198a38e6c57Sdan OMIT 199a38e6c57Sdan} { 200f01d3a7eSdan {DELETE t1 0 X. {i 1 t {value A}} {}} 201a38e6c57Sdan} 202a38e6c57Sdando_apply_v2_test 1.3.2 { 203a38e6c57Sdan DELETE FROM t1 WHERE a=1; 204a38e6c57Sdan} { 205a38e6c57Sdan UPDATE t1 SET b='value D' WHERE a=1; 206a38e6c57Sdan} { 207a38e6c57Sdan REPLACE 208a38e6c57Sdan} { 209f01d3a7eSdan {DELETE t1 1 X. {i 1 t {value A}} {}} 210a38e6c57Sdan} 211a38e6c57Sdan 212f1b40e83Sdan#------------------------------------------------------------------------- 213f1b40e83Sdan# Test cases 2.* - simple tests of rebasing actual changesets. 214f1b40e83Sdan# 215f1b40e83Sdan# 2.1.1 - 1u2u1r 216f1b40e83Sdan# 2.1.2 - 1u2u2r 217f1b40e83Sdan# 2.1.3 - 1d2d 218f1b40e83Sdan# 2.1.4 - 1d2u1r 219f1b40e83Sdan# 2.1.5 - 1d2u2r !! 220f1b40e83Sdan# 2.1.6 - 1u2d1r 221f01d3a7eSdan# 2.1.7 - 1u2d2r 222f01d3a7eSdan# 223f01d3a7eSdan# 2.1.8 - 1i2i2r 224f01d3a7eSdan# 2.1.9 - 1i2i1r 225f01d3a7eSdan# 226f1b40e83Sdan 227f1b40e83Sdanproc xConflictAbort {args} { 228f1b40e83Sdan return "ABORT" 229f1b40e83Sdan} 230f1b40e83Sdan 231f1b40e83Sdanreset_db 232f1b40e83Sdando_execsql_test 2.1.0 { 233f1b40e83Sdan CREATE TABLE t1 (a INTEGER PRIMARY KEY, b TEXT); 234f1b40e83Sdan INSERT INTO t1 VALUES(1, 'one'); 235f1b40e83Sdan INSERT INTO t1 VALUES(2, 'two'); 236f1b40e83Sdan INSERT INTO t1 VALUES(3, 'three'); 237f1b40e83Sdan} 238f1b40e83Sdando_rebase_test 2.1.1 { 239bd45374cSdan UPDATE t1 SET b = 'two.1' WHERE a=2 240f1b40e83Sdan} { 241f1b40e83Sdan UPDATE t1 SET b = 'two.2' WHERE a=2; 242f1b40e83Sdan} { 243f1b40e83Sdan OMIT 244f1b40e83Sdan} { SELECT * FROM t1 } {1 one 2 two.1 3 three} 245f1b40e83Sdan 246f1b40e83Sdando_rebase_test 2.1.2 { 247bd45374cSdan UPDATE t1 SET b = 'two.1' WHERE a=2 248f1b40e83Sdan} { 249f1b40e83Sdan UPDATE t1 SET b = 'two.2' WHERE a=2; 250f1b40e83Sdan} { 251f1b40e83Sdan REPLACE 252f1b40e83Sdan} { SELECT * FROM t1 } {1 one 2 two.2 3 three} 253f1b40e83Sdan 254f1b40e83Sdando_rebase_test 2.1.3 { 255bd45374cSdan DELETE FROM t1 WHERE a=3 256f1b40e83Sdan} { 257f1b40e83Sdan DELETE FROM t1 WHERE a=3; 258f1b40e83Sdan} { 259f1b40e83Sdan OMIT 260f1b40e83Sdan} { SELECT * FROM t1 } {1 one 2 two} 261f1b40e83Sdan 262f1b40e83Sdando_rebase_test 2.1.4 { 263bd45374cSdan DELETE FROM t1 WHERE a=1 264f1b40e83Sdan} { 265f1b40e83Sdan UPDATE t1 SET b='one.2' WHERE a=1 266f1b40e83Sdan} { 267f1b40e83Sdan OMIT 268f1b40e83Sdan} { SELECT * FROM t1 } {2 two 3 three} 269f1b40e83Sdan 270f1b40e83Sdan#do_rebase_test 2.1.5 { 271f1b40e83Sdan# DELETE FROM t1 WHERE a=1; 272f1b40e83Sdan#} { 273f1b40e83Sdan# UPDATE t1 SET b='one.2' WHERE a=1 274f1b40e83Sdan#} { 275f1b40e83Sdan# REPLACE 276f1b40e83Sdan#} { SELECT * FROM t1 } {2 two 3 three} 277f1b40e83Sdan 278f1b40e83Sdando_rebase_test 2.1.6 { 279bd45374cSdan UPDATE t1 SET b='three.1' WHERE a=3 280f1b40e83Sdan} { 281f1b40e83Sdan DELETE FROM t1 WHERE a=3; 282f1b40e83Sdan} { 283f1b40e83Sdan OMIT 284f1b40e83Sdan} { SELECT * FROM t1 } {1 one 2 two 3 three.1} 285f1b40e83Sdan 286f1b40e83Sdando_rebase_test 2.1.7 { 287bd45374cSdan UPDATE t1 SET b='three.1' WHERE a=3 288f1b40e83Sdan} { 289f1b40e83Sdan DELETE FROM t1 WHERE a=3; 290f1b40e83Sdan} { 291f1b40e83Sdan REPLACE 292f1b40e83Sdan} { SELECT * FROM t1 } {1 one 2 two} 293a38e6c57Sdan 294f01d3a7eSdando_rebase_test 2.1.8 { 295bd45374cSdan INSERT INTO t1 VALUES(4, 'four.1') 296f01d3a7eSdan} { 297f01d3a7eSdan INSERT INTO t1 VALUES(4, 'four.2'); 298f01d3a7eSdan} { 299f01d3a7eSdan REPLACE 300f01d3a7eSdan} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.2} 301f01d3a7eSdan 302f01d3a7eSdando_rebase_test 2.1.9 { 303bd45374cSdan INSERT INTO t1 VALUES(4, 'four.1') 304f01d3a7eSdan} { 305f01d3a7eSdan INSERT INTO t1 VALUES(4, 'four.2'); 306f01d3a7eSdan} { 307f01d3a7eSdan OMIT 308f01d3a7eSdan} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.1} 309f01d3a7eSdan 310f01d3a7eSdando_execsql_test 2.2.0 { 311f01d3a7eSdan CREATE TABLE t2(x, y, z PRIMARY KEY); 312f01d3a7eSdan INSERT INTO t2 VALUES('i', 'a', 'A'); 313f01d3a7eSdan INSERT INTO t2 VALUES('ii', 'b', 'B'); 314f01d3a7eSdan INSERT INTO t2 VALUES('iii', 'c', 'C'); 315f01d3a7eSdan 316f01d3a7eSdan CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c); 317f01d3a7eSdan INSERT INTO t3 VALUES(-1, 'z', 'Z'); 318f01d3a7eSdan INSERT INTO t3 VALUES(-2, 'y', 'Y'); 319f01d3a7eSdan} 320f01d3a7eSdan 321f01d3a7eSdando_rebase_test 2.2.1 { 322bd45374cSdan UPDATE t2 SET x=1 WHERE z='A' 323f01d3a7eSdan} { 324f01d3a7eSdan UPDATE t2 SET y='one' WHERE z='A'; 325f01d3a7eSdan} { 326f01d3a7eSdan} { SELECT * FROM t2 WHERE z='A' } { 1 one A } 327f01d3a7eSdan 328f01d3a7eSdando_rebase_test 2.2.2 { 329bd45374cSdan UPDATE t2 SET x=1, y='one' WHERE z='B' 330f01d3a7eSdan} { 331f01d3a7eSdan UPDATE t2 SET y='two' WHERE z='B'; 332f01d3a7eSdan} { 333f01d3a7eSdan REPLACE 334f01d3a7eSdan} { SELECT * FROM t2 WHERE z='B' } { 1 two B } 335f01d3a7eSdan 336f01d3a7eSdando_rebase_test 2.2.3 { 337bd45374cSdan UPDATE t2 SET x=1, y='one' WHERE z='B' 338f01d3a7eSdan} { 339f01d3a7eSdan UPDATE t2 SET y='two' WHERE z='B'; 340f01d3a7eSdan} { 341f01d3a7eSdan OMIT 342f01d3a7eSdan} { SELECT * FROM t2 WHERE z='B' } { 1 one B } 343f01d3a7eSdan 344bd45374cSdan#------------------------------------------------------------------------- 345bd45374cSdanreset_db 346bd45374cSdando_execsql_test 3.0 { 347bd45374cSdan CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c)); 348bd45374cSdan CREATE TABLE abcdefghijkl(x PRIMARY KEY, y, z); 349bd45374cSdan 350bd45374cSdan INSERT INTO t3 VALUES(1, 2, 3); 351bd45374cSdan INSERT INTO t3 VALUES(4, 2, 5); 352bd45374cSdan INSERT INTO t3 VALUES(7, 2, 9); 353bd45374cSdan 354bd45374cSdan INSERT INTO abcdefghijkl VALUES('a', 'b', 'c'); 355bd45374cSdan INSERT INTO abcdefghijkl VALUES('d', 'e', 'f'); 356bd45374cSdan INSERT INTO abcdefghijkl VALUES('g', 'h', 'i'); 357bd45374cSdan} 358bd45374cSdan 359*f231e18cSdanbreakpoint 360*f231e18cSdan# do_rebase_test 3.6.tn { 361*f231e18cSdan# UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; 362*f231e18cSdan# } { 363*f231e18cSdan# UPDATE abcdefghijkl SET y=1 WHERE x='d'; 364*f231e18cSdan# UPDATE abcdefghijkl SET z=1 WHERE x='d'; 365*f231e18cSdan# } [list REPLACE REPLACE REPLACE] 366*f231e18cSdan 367bd45374cSdanforeach {tn p} { 368bd45374cSdan 1 OMIT 2 REPLACE 369bd45374cSdan} { 370bd45374cSdan do_rebase_test 3.1.$tn { 371bd45374cSdan INSERT INTO t3 VALUES(1, 1, 1); 372bd45374cSdan UPDATE abcdefghijkl SET y=2; 373bd45374cSdan } { 374bd45374cSdan INSERT INTO t3 VALUES(4, 1, 1); 375bd45374cSdan DELETE FROM abcdefghijkl; 376bd45374cSdan } [list $p $p $p $p $p $p $p $p] 377bd45374cSdan 378bd45374cSdan do_rebase_test 3.2.$tn { 379bd45374cSdan INSERT INTO abcdefghijkl SELECT * FROM t3; 380bd45374cSdan UPDATE t3 SET b=b+1; 381bd45374cSdan } { 382bd45374cSdan INSERT INTO t3 VALUES(3, 3, 3); 383bd45374cSdan INSERT INTO abcdefghijkl SELECT * FROM t3; 384bd45374cSdan } [list $p $p $p $p $p $p $p $p] 385bd45374cSdan 386bd45374cSdan do_rebase_test 3.3.$tn { 387bd45374cSdan INSERT INTO abcdefghijkl VALUES(22, 23, 24); 388bd45374cSdan } { 389bd45374cSdan INSERT INTO abcdefghijkl VALUES(22, 25, 26); 390bd45374cSdan UPDATE abcdefghijkl SET y=400 WHERE x=22; 391bd45374cSdan } [list $p $p $p $p $p $p $p $p] 39295ccb6dcSdan 39395ccb6dcSdan do_rebase_test 3.4.$tn { 39495ccb6dcSdan INSERT INTO abcdefghijkl VALUES(22, 23, 24); 39595ccb6dcSdan } { 39695ccb6dcSdan INSERT INTO abcdefghijkl VALUES(22, 25, 26); 39795ccb6dcSdan UPDATE abcdefghijkl SET y=400 WHERE x=22; 39895ccb6dcSdan } [list REPLACE $p] 399*f231e18cSdan 400*f231e18cSdan do_rebase_test 3.5.$tn* { 401*f231e18cSdan UPDATE abcdefghijkl SET y='X' WHERE x='d'; 402*f231e18cSdan } { 403*f231e18cSdan DELETE FROM abcdefghijkl WHERE x='d'; 404*f231e18cSdan INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); 405*f231e18cSdan } [list $p $p $p] 406*f231e18cSdan do_rebase_test 3.5.$tn { 407*f231e18cSdan UPDATE abcdefghijkl SET y='X' WHERE x='d'; 408*f231e18cSdan } { 409*f231e18cSdan DELETE FROM abcdefghijkl WHERE x='d'; 410*f231e18cSdan INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); 411*f231e18cSdan } [list REPLACE $p $p] 412*f231e18cSdan 413*f231e18cSdan do_rebase_test 3.6.$tn { 414*f231e18cSdan UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; 415*f231e18cSdan } { 416*f231e18cSdan UPDATE abcdefghijkl SET y=1 WHERE x='d'; 417*f231e18cSdan UPDATE abcdefghijkl SET z=1 WHERE x='d'; 418*f231e18cSdan } [list REPLACE $p $p] 419bd45374cSdan} 420bd45374cSdan 4213fa5463cSdan#------------------------------------------------------------------------- 4223fa5463cSdan# Check that apply_v2() does not create a rebase buffer for a patchset. 4233fa5463cSdan# And that it is not possible to rebase a patchset. 4243fa5463cSdan# 4253fa5463cSdando_execsql_test 4.0 { 4263fa5463cSdan CREATE TABLE t5(o PRIMARY KEY, p, q); 4273fa5463cSdan INSERT INTO t5 VALUES(1, 2, 3); 4283fa5463cSdan INSERT INTO t5 VALUES(4, 5, 6); 4293fa5463cSdan} 4303fa5463cSdanforeach {tn cmd rebasable} { 4313fa5463cSdan 1 patchset 0 4323fa5463cSdan 2 changeset 1 4333fa5463cSdan} { 4343fa5463cSdan proc xConflict {args} { return "OMIT" } 4353fa5463cSdan do_test 4.1.$tn { 4363fa5463cSdan execsql { 4373fa5463cSdan BEGIN; 4383fa5463cSdan DELETE FROM t5 WHERE o=4; 4393fa5463cSdan } 4403fa5463cSdan 4413fa5463cSdan sqlite3session S db main 4423fa5463cSdan S attach * 4433fa5463cSdan execsql { 4443fa5463cSdan INSERT INTO t5 VALUES(4, 'five', 'six'); 4453fa5463cSdan } 4463fa5463cSdan set P [S $cmd] 4473fa5463cSdan S delete 4483fa5463cSdan 4493fa5463cSdan execsql ROLLBACK; 4503fa5463cSdan 4513fa5463cSdan set ::rebase [sqlite3changeset_apply_v2 db $P xConflict] 4523fa5463cSdan expr [llength $::rebase]>0 4533fa5463cSdan } $rebasable 4543fa5463cSdan} 4553fa5463cSdan 4563fa5463cSdanforeach {tn cmd rebasable} { 4573fa5463cSdan 1 patchset 0 4583fa5463cSdan 2 changeset 1 4593fa5463cSdan} { 4603fa5463cSdan do_test 4.2.$tn { 4613fa5463cSdan sqlite3session S db main 4623fa5463cSdan S attach * 4633fa5463cSdan execsql { 4643fa5463cSdan INSERT INTO t5 VALUES(5+$tn, 'five', 'six'); 4653fa5463cSdan } 4663fa5463cSdan set P [S $cmd] 4673fa5463cSdan S delete 4683fa5463cSdan 4693fa5463cSdan sqlite3rebaser_create R 4703fa5463cSdan R configure $::rebase 4713fa5463cSdan expr [catch {R rebase $P}]==0 4723fa5463cSdan } $rebasable 4733fa5463cSdan 4743fa5463cSdan catch { R delete } 4753fa5463cSdan} 476a38e6c57Sdanfinish_test 477