xref: /sqlite-3.40.0/ext/session/session5.test (revision f1a08ad8)
15d607a6eSdan# 2011 April 13
25d607a6eSdan#
35d607a6eSdan# The author disclaims copyright to this source code.  In place of
45d607a6eSdan# a legal notice, here is a blessing:
55d607a6eSdan#
65d607a6eSdan#    May you do good and not evil.
75d607a6eSdan#    May you find forgiveness for yourself and forgive others.
85d607a6eSdan#    May you share freely, never taking more than you give.
95d607a6eSdan#
105d607a6eSdan#***********************************************************************
115d607a6eSdan# This file implements regression tests for the session module.
125d607a6eSdan# Specifically, for the sqlite3changeset_concat() command.
135d607a6eSdan#
145d607a6eSdan
155d607a6eSdanif {![info exists testdir]} {
165d607a6eSdan  set testdir [file join [file dirname [info script]] .. .. test]
175d607a6eSdan}
185d607a6eSdansource [file join [file dirname [info script]] session_common.tcl]
195d607a6eSdansource $testdir/tester.tcl
205d607a6eSdanifcapable !session {finish_test; return}
215d607a6eSdan
225d607a6eSdanset testprefix session5
235d607a6eSdan
246cda207fSdan# Organization of tests:
256cda207fSdan#
266cda207fSdan#   session5-1.*: Simple tests to check the concat() function produces
276cda207fSdan#                 correct results.
286cda207fSdan#
296cda207fSdan#   session5-2.*: More complicated tests.
306cda207fSdan#
316cda207fSdan#   session5-3.*: Schema mismatch errors.
326cda207fSdan#
33*6734007dSdan#   session5-4.*: Test the concat cases that indicate that the database
34*6734007dSdan#                 was modified in between recording of the two changesets
35*6734007dSdan#                 being concatenated (i.e. two changesets that INSERT rows
36*6734007dSdan#                 with the same PK values).
37*6734007dSdan#
385d607a6eSdan
396cda207fSdanproc do_concat_test {tn args} {
405d607a6eSdan
416cda207fSdan  set subtest 0
426cda207fSdan  foreach sql $args {
436cda207fSdan    incr subtest
446cda207fSdan    sqlite3session S db main ; S attach *
456cda207fSdan    execsql $sql
465d607a6eSdan
476cda207fSdan    set c [S changeset]
486cda207fSdan    if {[info commands s_prev] != ""} {
496cda207fSdan      set c_concat [sqlite3changeset_concat $c_prev $c]
506cda207fSdan      set c_two [s_prev changeset]
516cda207fSdan      s_prev delete
525d607a6eSdan
536cda207fSdan      set h_concat [changeset_to_list $c_concat]
546cda207fSdan      set h_two [changeset_to_list $c_two]
555d607a6eSdan
566cda207fSdan      do_test $tn.$subtest [list set {} $h_concat] $h_two
576cda207fSdan    }
586cda207fSdan    set c_prev $c
596cda207fSdan    rename S s_prev
606cda207fSdan  }
615d607a6eSdan
626cda207fSdan  catch { s_prev delete }
635d607a6eSdan}
645d607a6eSdan
65f29123b5Sdan#-------------------------------------------------------------------------
66f29123b5Sdan# Test cases session5-1.* - simple tests.
67f29123b5Sdan#
685d607a6eSdando_execsql_test 1.0 {
695d607a6eSdan  CREATE TABLE t1(a PRIMARY KEY, b);
705d607a6eSdan}
715d607a6eSdan
725d607a6eSdando_concat_test 1.1.1 {
735d607a6eSdan  INSERT INTO t1 VALUES(1, 'one');
745d607a6eSdan} {
755d607a6eSdan  INSERT INTO t1 VALUES(2, 'two');
765d607a6eSdan}
775d607a6eSdan
785d607a6eSdando_concat_test 1.1.2 {
795d607a6eSdan  UPDATE t1 SET b = 'five' WHERE a = 1;
805d607a6eSdan} {
815d607a6eSdan  UPDATE t1 SET b = 'six' WHERE a = 2;
825d607a6eSdan}
835d607a6eSdan
845d607a6eSdando_concat_test 1.1.3 {
855d607a6eSdan  DELETE FROM t1 WHERE a = 1;
865d607a6eSdan} {
875d607a6eSdan  DELETE FROM t1 WHERE a = 2;
885d607a6eSdan}
895d607a6eSdan
905d607a6eSdan
915d607a6eSdan# 1.2.1:    INSERT + DELETE                     -> (none)
925d607a6eSdan# 1.2.2:    INSERT + UPDATE                     -> INSERT
935d607a6eSdan#
945d607a6eSdan# 1.2.3:    DELETE + INSERT (matching data)     -> (none)
955d607a6eSdan# 1.2.4:    DELETE + INSERT (non-matching data) -> UPDATE
965d607a6eSdan#
975d607a6eSdan# 1.2.5:    UPDATE + UPDATE (matching data)     -> (none)
985d607a6eSdan# 1.2.6:    UPDATE + UPDATE (non-matching data) -> UPDATE
995d607a6eSdan# 1.2.7:    UPDATE + DELETE                     -> DELETE
1005d607a6eSdan#
1015d607a6eSdando_concat_test 1.2.1 {
1025d607a6eSdan  INSERT INTO t1 VALUES('x', 'y');
1035d607a6eSdan} {
1045d607a6eSdan  DELETE FROM t1 WHERE a = 'x';
1055d607a6eSdan}
1065d607a6eSdando_concat_test 1.2.2 {
1075d607a6eSdan  INSERT INTO t1 VALUES(5.0, 'five');
1085d607a6eSdan} {
1095d607a6eSdan  UPDATE t1 SET b = 'six' WHERE a = 5.0;
1105d607a6eSdan}
1115d607a6eSdan
1125d607a6eSdando_execsql_test 1.2.3.1 "INSERT INTO t1 VALUES('I', 'one')"
1135d607a6eSdando_concat_test 1.2.3.2 {
1145d607a6eSdan  DELETE FROM t1 WHERE a = 'I';
1155d607a6eSdan} {
1165d607a6eSdan  INSERT INTO t1 VALUES('I', 'one');
1175d607a6eSdan}
1185d607a6eSdando_concat_test 1.2.4 {
1195d607a6eSdan  DELETE FROM t1 WHERE a = 'I';
1205d607a6eSdan} {
1215d607a6eSdan  INSERT INTO t1 VALUES('I', 'two');
1225d607a6eSdan}
1235d607a6eSdando_concat_test 1.2.5 {
1245d607a6eSdan  UPDATE t1 SET b = 'five' WHERE a = 'I';
1255d607a6eSdan} {
1265d607a6eSdan  UPDATE t1 SET b = 'two' WHERE a = 'I';
1275d607a6eSdan}
1285d607a6eSdando_concat_test 1.2.6 {
1295d607a6eSdan  UPDATE t1 SET b = 'six' WHERE a = 'I';
1305d607a6eSdan} {
1315d607a6eSdan  UPDATE t1 SET b = 'seven' WHERE a = 'I';
1325d607a6eSdan}
1335d607a6eSdando_concat_test 1.2.7 {
1345d607a6eSdan  UPDATE t1 SET b = 'eight' WHERE a = 'I';
1355d607a6eSdan} {
1365d607a6eSdan  DELETE FROM t1 WHERE a = 'I';
1375d607a6eSdan}
1385d607a6eSdan
139f29123b5Sdan
140f29123b5Sdan#-------------------------------------------------------------------------
141f29123b5Sdan# Test cases session5-2.* - more complex tests.
142f29123b5Sdan#
1436cda207fSdandb function indirect indirect
1446cda207fSdanproc indirect {{x -1}} {
1456cda207fSdan  S indirect $x
1466cda207fSdan  s_prev indirect $x
1476cda207fSdan}
1486cda207fSdando_concat_test 2.1 {
1496cda207fSdan  CREATE TABLE abc(a, b, c PRIMARY KEY);
1506cda207fSdan  INSERT INTO abc VALUES(NULL, NULL, 1);
1516cda207fSdan  INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
1526cda207fSdan} {
1536cda207fSdan  DELETE FROM abc WHERE c = 1;
1546cda207fSdan  UPDATE abc SET c = 1 WHERE c = 2;
1556cda207fSdan} {
1566cda207fSdan  INSERT INTO abc VALUES('abcdefghijkl', NULL, 2);
1576cda207fSdan  INSERT INTO abc VALUES(1.0, 2.0, 3);
1586cda207fSdan} {
1596cda207fSdan  UPDATE abc SET a = a-1;
1606cda207fSdan} {
1616cda207fSdan  CREATE TABLE def(d, e, f, PRIMARY KEY(e, f));
1626cda207fSdan  INSERT INTO def VALUES('x', randomblob(11000), 67);
1636cda207fSdan  INSERT INTO def SELECT d, e, f+1 FROM def;
1646cda207fSdan  INSERT INTO def SELECT d, e, f+2 FROM def;
1656cda207fSdan  INSERT INTO def SELECT d, e, f+4 FROM def;
1666cda207fSdan} {
1676cda207fSdan  DELETE FROM def WHERE rowid>4;
1686cda207fSdan} {
1696cda207fSdan  INSERT INTO def SELECT d, e, f+4 FROM def;
1706cda207fSdan} {
1716cda207fSdan  INSERT INTO abc VALUES(22, 44, -1);
1726cda207fSdan} {
1736cda207fSdan  UPDATE abc SET c=-2 WHERE c=-1;
1746cda207fSdan  UPDATE abc SET c=-3 WHERE c=-2;
1756cda207fSdan} {
1766cda207fSdan  UPDATE abc SET c=-4 WHERE c=-3;
1776cda207fSdan} {
1786cda207fSdan  UPDATE abc SET a=a+1 WHERE c=-3;
1796cda207fSdan  UPDATE abc SET a=a+1 WHERE c=-3;
1806cda207fSdan} {
1816cda207fSdan  UPDATE abc SET a=a+1 WHERE c=-3;
1826cda207fSdan  UPDATE abc SET a=a+1 WHERE c=-3;
1836cda207fSdan} {
1846cda207fSdan  INSERT INTO abc VALUES('one', 'two', 'three');
1856cda207fSdan} {
1866cda207fSdan  SELECT indirect(1);
1876cda207fSdan  UPDATE abc SET a='one point five' WHERE c = 'three';
1886cda207fSdan} {
1896cda207fSdan  SELECT indirect(0);
1906cda207fSdan  UPDATE abc SET a='one point six' WHERE c = 'three';
191b08a1efaSdan} {
192b08a1efaSdan  CREATE TABLE x1(a, b, PRIMARY KEY(a));
193b08a1efaSdan  SELECT indirect(1);
194b08a1efaSdan  INSERT INTO x1 VALUES(1, 2);
195b08a1efaSdan} {
196b08a1efaSdan  SELECT indirect(1);
197b08a1efaSdan  UPDATE x1 SET b = 3 WHERE a = 1;
1986cda207fSdan}
1996cda207fSdan
2001756ae10Sdancatch {db close}
2011756ae10Sdanforcedelete test.db
2021756ae10Sdansqlite3 db test.db
2031756ae10Sdando_concat_test 2.2 {
2041756ae10Sdan  CREATE TABLE t1(a, b, PRIMARY KEY(b));
2051756ae10Sdan  CREATE TABLE t2(a PRIMARY KEY, b);
2061756ae10Sdan  INSERT INTO t1 VALUES('string', 1);
2071756ae10Sdan  INSERT INTO t1 VALUES(4, 2);
2081756ae10Sdan  INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
2091756ae10Sdan} {
2101756ae10Sdan  INSERT INTO t2 VALUES('one', 'two');
2111756ae10Sdan  INSERT INTO t2 VALUES(1, NULL);
2121756ae10Sdan  UPDATE t1 SET a = 5 WHERE a = 2;
2131756ae10Sdan} {
2141756ae10Sdan  DELETE FROM t2 WHERE a = 1;
2151756ae10Sdan  UPDATE t1 SET a = 4 WHERE a = 2;
2161756ae10Sdan  INSERT INTO t2 VALUES('x', 'y');
2171756ae10Sdan}
2181756ae10Sdan
219b08a1efaSdando_test 2.3.0 {
220b08a1efaSdan  catch {db close}
221b08a1efaSdan  forcedelete test.db
222b08a1efaSdan  sqlite3 db test.db
223b08a1efaSdan
224b08a1efaSdan  set sql1 ""
225b08a1efaSdan  set sql2 ""
226b08a1efaSdan  for {set i 1} {$i < 120} {incr i} {
227b08a1efaSdan    append sql1 "INSERT INTO x1 VALUES($i*4, $i);"
228b08a1efaSdan  }
229b08a1efaSdan  for {set i 1} {$i < 120} {incr i} {
230b08a1efaSdan    append sql2 "DELETE FROM x1 WHERE a = $i*4;"
231b08a1efaSdan  }
232b08a1efaSdan  set {} {}
233b08a1efaSdan} {}
234b08a1efaSdando_concat_test 2.3 {
235b08a1efaSdan  CREATE TABLE x1(a PRIMARY KEY, b)
236b08a1efaSdan} $sql1 $sql2 $sql1 $sql2
237b08a1efaSdan
238b08a1efaSdando_concat_test 2.4 {
239b08a1efaSdan  CREATE TABLE x2(a PRIMARY KEY, b);
240b08a1efaSdan  CREATE TABLE x3(a PRIMARY KEY, b);
241b08a1efaSdan
242b08a1efaSdan  INSERT INTO x2 VALUES('a', 'b');
243b08a1efaSdan  INSERT INTO x2 VALUES('x', 'y');
244b08a1efaSdan  INSERT INTO x3 VALUES('a', 'b');
245b08a1efaSdan} {
246b08a1efaSdan  INSERT INTO x2 VALUES('c', 'd');
247b08a1efaSdan  INSERT INTO x3 VALUES('e', 'f');
248b08a1efaSdan  INSERT INTO x3 VALUES('x', 'y');
249b08a1efaSdan}
250b08a1efaSdan
251b08a1efaSdando_concat_test 2.5 {
252b08a1efaSdan  UPDATE x3 SET b = 'Y' WHERE a = 'x'
253b08a1efaSdan} {
254b08a1efaSdan  DELETE FROM x3 WHERE a = 'x'
255b08a1efaSdan} {
256b08a1efaSdan  DELETE FROM x2 WHERE a = 'a'
257b08a1efaSdan} {
258b08a1efaSdan  INSERT INTO x2 VALUES('a', 'B');
259b08a1efaSdan}
260b08a1efaSdan
261*6734007dSdanfor {set k 1} {$k <=10} {incr k} {
262*6734007dSdan  do_test 2.6.$k.1 {
263*6734007dSdan    drop_all_tables
264*6734007dSdan    set sql1 ""
265*6734007dSdan    set sql2 ""
266*6734007dSdan    for {set i 1} {$i < 120} {incr i} {
267*6734007dSdan      append sql1 "INSERT INTO x1 VALUES(randomblob(20+(random()%10)), $i);"
268*6734007dSdan    }
269*6734007dSdan    for {set i 1} {$i < 120} {incr i} {
270*6734007dSdan      append sql2 "DELETE FROM x1 WHERE rowid = $i;"
271*6734007dSdan    }
272*6734007dSdan    set {} {}
273*6734007dSdan  } {}
274*6734007dSdan  do_concat_test 2.6.$k {
275*6734007dSdan    CREATE TABLE x1(a PRIMARY KEY, b)
276*6734007dSdan  } $sql1 $sql2 $sql1 $sql2
277*6734007dSdan}
278*6734007dSdan
279*6734007dSdanfor {set k 1} {$k <=10} {incr k} {
280*6734007dSdan  do_test 2.7.$k.1 {
281*6734007dSdan    drop_all_tables
282*6734007dSdan    set sql1 ""
283*6734007dSdan    set sql2 ""
284*6734007dSdan    for {set i 1} {$i < 120} {incr i} {
285*6734007dSdan      append sql1 {
286*6734007dSdan        INSERT INTO x1 VALUES(
287*6734007dSdan         CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END,
288*6734007dSdan         CASE WHEN random()%2 THEN random() ELSE randomblob(20+random()%10) END
289*6734007dSdan        );
290*6734007dSdan      }
291*6734007dSdan    }
292*6734007dSdan    for {set i 1} {$i < 120} {incr i} {
293*6734007dSdan      append sql2 "DELETE FROM x1 WHERE rowid = $i;"
294*6734007dSdan    }
295*6734007dSdan    set {} {}
296*6734007dSdan  } {}
297*6734007dSdan  do_concat_test 2.7.$k {
298*6734007dSdan    CREATE TABLE x1(a PRIMARY KEY, b)
299*6734007dSdan  } $sql1 $sql2 $sql1 $sql2
300*6734007dSdan}
301*6734007dSdan
302b08a1efaSdan
303f29123b5Sdan#-------------------------------------------------------------------------
304f29123b5Sdan# Test that schema incompatibilities are detected correctly.
305f29123b5Sdan#
306f29123b5Sdan#   session5-3.1: Incompatible number of columns.
307f29123b5Sdan#   session5-3.2: Incompatible PK definition.
308f29123b5Sdan#
309f29123b5Sdan
310f29123b5Sdando_test 3.1 {
311f29123b5Sdan  db close
312f29123b5Sdan  forcedelete test.db
313f29123b5Sdan  sqlite3 db test.db
314f29123b5Sdan
315f29123b5Sdan  execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
3161756ae10Sdan  set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
317f29123b5Sdan  execsql {
318f29123b5Sdan    DROP TABLE t1;
319f29123b5Sdan    CREATE TABLE t1(a PRIMARY KEY, b, c);
320f29123b5Sdan  }
3211756ae10Sdan  set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3, 4) }]
322f29123b5Sdan
323f29123b5Sdan  list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
324f29123b5Sdan} {1 SQLITE_SCHEMA}
325f29123b5Sdan
326f29123b5Sdando_test 3.2 {
327f29123b5Sdan  db close
328f29123b5Sdan  forcedelete test.db
329f29123b5Sdan  sqlite3 db test.db
330f29123b5Sdan
331f29123b5Sdan  execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
3321756ae10Sdan  set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
333f29123b5Sdan  execsql {
334f29123b5Sdan    DROP TABLE t1;
335f29123b5Sdan    CREATE TABLE t1(a, b PRIMARY KEY);
336f29123b5Sdan  }
3371756ae10Sdan  set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3) }]
338f29123b5Sdan
339f29123b5Sdan  list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
340f29123b5Sdan} {1 SQLITE_SCHEMA}
341f29123b5Sdan
342*6734007dSdan#-------------------------------------------------------------------------
343*6734007dSdan# Test that concat() handles these properly:
344*6734007dSdan#
345*6734007dSdan#   session5-4.1: INSERT + INSERT
346*6734007dSdan#   session5-4.2: UPDATE + INSERT
347*6734007dSdan#   session5-4.3: DELETE + UPDATE
348*6734007dSdan#   session5-4.4: DELETE + DELETE
349*6734007dSdan#
350*6734007dSdan
351*6734007dSdanproc do_concat_test2 {tn sql1 sqlX sql2 expected} {
352*6734007dSdan  sqlite3session S db main ; S attach *
353*6734007dSdan  execsql $sql1
354*6734007dSdan  set ::c1 [S changeset]
355*6734007dSdan  S delete
356*6734007dSdan
357*6734007dSdan  execsql $sqlX
358*6734007dSdan
359*6734007dSdan  sqlite3session S db main ; S attach *
360*6734007dSdan  execsql $sql2
361*6734007dSdan  set ::c2 [S changeset]
362*6734007dSdan  S delete
363*6734007dSdan
364*6734007dSdan  uplevel do_test $tn [list {
365*6734007dSdan    changeset_to_list [sqlite3changeset_concat $::c1 $::c2]
366*6734007dSdan  }] [list [normalize_list $expected]]
367*6734007dSdan}
368*6734007dSdan
369*6734007dSdandrop_all_tables db
370*6734007dSdando_concat_test2 4.1 {
371*6734007dSdan  CREATE TABLE t1(a PRIMARY KEY, b);
372*6734007dSdan  INSERT INTO t1 VALUES('key', 'value');
373*6734007dSdan} {
374*6734007dSdan  DELETE FROM t1 WHERE a = 'key';
375*6734007dSdan} {
376*6734007dSdan  INSERT INTO t1 VALUES('key', 'xxx');
377*6734007dSdan} {
378*6734007dSdan  {INSERT t1 0 X. {} {t key t value}}
379*6734007dSdan}
380*6734007dSdando_concat_test2 4.2 {
381*6734007dSdan  UPDATE t1 SET b = 'yyy';
382*6734007dSdan} {
383*6734007dSdan  DELETE FROM t1 WHERE a = 'key';
384*6734007dSdan} {
385*6734007dSdan  INSERT INTO t1 VALUES('key', 'value');
386*6734007dSdan} {
387*6734007dSdan  {UPDATE t1 0 X. {t key t xxx} {{} {} t yyy}}
388*6734007dSdan}
389*6734007dSdando_concat_test2 4.3 {
390*6734007dSdan  DELETE FROM t1 WHERE a = 'key';
391*6734007dSdan} {
392*6734007dSdan  INSERT INTO t1 VALUES('key', 'www');
393*6734007dSdan} {
394*6734007dSdan  UPDATE t1 SET b = 'valueX' WHERE a = 'key';
395*6734007dSdan} {
396*6734007dSdan  {DELETE t1 0 X. {t key t value} {}}
397*6734007dSdan}
398*6734007dSdando_concat_test2 4.4 {
399*6734007dSdan  DELETE FROM t1 WHERE a = 'key';
400*6734007dSdan} {
401*6734007dSdan  INSERT INTO t1 VALUES('key', 'ttt');
402*6734007dSdan} {
403*6734007dSdan  DELETE FROM t1 WHERE a = 'key';
404*6734007dSdan} {
405*6734007dSdan  {DELETE t1 0 X. {t key t valueX} {}}
406*6734007dSdan}
407f29123b5Sdan
4085d607a6eSdanfinish_test
409