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