1*1e25d20cSdan# 2021 Februar 20 2*1e25d20cSdan# 3*1e25d20cSdan# The author disclaims copyright to this source code. In place of 4*1e25d20cSdan# a legal notice, here is a blessing: 5*1e25d20cSdan# 6*1e25d20cSdan# May you do good and not evil. 7*1e25d20cSdan# May you find forgiveness for yourself and forgive others. 8*1e25d20cSdan# May you share freely, never taking more than you give. 9*1e25d20cSdan# 10*1e25d20cSdan#*********************************************************************** 11*1e25d20cSdan# This file implements regression tests for SQLite library. 12*1e25d20cSdan# 13*1e25d20cSdan 14*1e25d20cSdanif {![info exists testdir]} { 15*1e25d20cSdan set testdir [file join [file dirname [info script]] .. .. test] 16*1e25d20cSdan} 17*1e25d20cSdansource [file join [file dirname [info script]] session_common.tcl] 18*1e25d20cSdansource $testdir/tester.tcl 19*1e25d20cSdanifcapable !session {finish_test; return} 20*1e25d20cSdan 21*1e25d20cSdanset testprefix sessionnoop 22*1e25d20cSdan 23*1e25d20cSdan#------------------------------------------------------------------------- 24*1e25d20cSdan# Test plan: 25*1e25d20cSdan# 26*1e25d20cSdan# 1.*: Test that concatenating changesets cannot produce a noop UPDATE. 27*1e25d20cSdan# 2.*: Test that rebasing changesets cannot produce a noop UPDATE. 28*1e25d20cSdan# 3.*: Test that sqlite3changeset_apply() ignores noop UPDATE changes. 29*1e25d20cSdan# 30*1e25d20cSdan 31*1e25d20cSdando_execsql_test 1.0 { 32*1e25d20cSdan CREATE TABLE t1(a PRIMARY KEY, b, c, d); 33*1e25d20cSdan INSERT INTO t1 VALUES(1, 1, 1, 1); 34*1e25d20cSdan INSERT INTO t1 VALUES(2, 2, 2, 2); 35*1e25d20cSdan INSERT INTO t1 VALUES(3, 3, 3, 3); 36*1e25d20cSdan} 37*1e25d20cSdan 38*1e25d20cSdanproc do_concat_test {tn sql1 sql2 res} { 39*1e25d20cSdan uplevel [list do_test $tn [subst -nocommands { 40*1e25d20cSdan set C1 [changeset_from_sql {$sql1}] 41*1e25d20cSdan set C2 [changeset_from_sql {$sql2}] 42*1e25d20cSdan set C3 [sqlite3changeset_concat [set C1] [set C2]] 43*1e25d20cSdan set got [list] 44*1e25d20cSdan sqlite3session_foreach elem [set C3] { lappend got [set elem] } 45*1e25d20cSdan set got 46*1e25d20cSdan }] [list {*}$res]] 47*1e25d20cSdan} 48*1e25d20cSdan 49*1e25d20cSdando_concat_test 1.1 { 50*1e25d20cSdan UPDATE t1 SET c=c+1; 51*1e25d20cSdan} { 52*1e25d20cSdan UPDATE t1 SET c=c-1; 53*1e25d20cSdan} { 54*1e25d20cSdan} 55*1e25d20cSdan 56*1e25d20cSdan#------------------------------------------------------------------------- 57*1e25d20cSdanreset_db 58*1e25d20cSdando_execsql_test 2.0 { 59*1e25d20cSdan CREATE TABLE t1(a PRIMARY KEY, b, c); 60*1e25d20cSdan INSERT INTO t1 VALUES(1, 1, 1); 61*1e25d20cSdan INSERT INTO t1 VALUES(2, 2, 2); 62*1e25d20cSdan INSERT INTO t1 VALUES(3, 3, 3); 63*1e25d20cSdan} 64*1e25d20cSdan 65*1e25d20cSdanproc do_rebase_test {tn sql_local sql_remote conflict_res expected} { 66*1e25d20cSdan proc xConflict {args} [list return $conflict_res] 67*1e25d20cSdan 68*1e25d20cSdan uplevel [list \ 69*1e25d20cSdan do_test $tn [subst -nocommands { 70*1e25d20cSdan execsql BEGIN 71*1e25d20cSdan set c_remote [changeset_from_sql {$sql_remote}] 72*1e25d20cSdan execsql ROLLBACK 73*1e25d20cSdan 74*1e25d20cSdan execsql BEGIN 75*1e25d20cSdan set c_local [changeset_from_sql {$sql_local}] 76*1e25d20cSdan set base [sqlite3changeset_apply_v2 db [set c_remote] xConflict] 77*1e25d20cSdan execsql ROLLBACK 78*1e25d20cSdan 79*1e25d20cSdan sqlite3rebaser_create R 80*1e25d20cSdan R config [set base] 81*1e25d20cSdan set res [list] 82*1e25d20cSdan sqlite3session_foreach elem [R rebase [set c_local]] { 83*1e25d20cSdan lappend res [set elem] 84*1e25d20cSdan } 85*1e25d20cSdan R delete 86*1e25d20cSdan set res 87*1e25d20cSdan }] [list {*}$expected] 88*1e25d20cSdan ] 89*1e25d20cSdan} 90*1e25d20cSdan 91*1e25d20cSdando_rebase_test 2.1 { 92*1e25d20cSdan UPDATE t1 SET c=2 WHERE a=1; -- local 93*1e25d20cSdan} { 94*1e25d20cSdan UPDATE t1 SET c=3 WHERE a=1; -- remote 95*1e25d20cSdan} OMIT { 96*1e25d20cSdan {UPDATE t1 0 X.. {i 1 {} {} i 3} {{} {} {} {} i 2}} 97*1e25d20cSdan} 98*1e25d20cSdan 99*1e25d20cSdando_rebase_test 2.2 { 100*1e25d20cSdan UPDATE t1 SET c=2 WHERE a=1; -- local 101*1e25d20cSdan} { 102*1e25d20cSdan UPDATE t1 SET c=3 WHERE a=1; -- remote 103*1e25d20cSdan} REPLACE { 104*1e25d20cSdan} 105*1e25d20cSdan 106*1e25d20cSdando_rebase_test 2.3.1 { 107*1e25d20cSdan UPDATE t1 SET c=4 WHERE a=1; -- local 108*1e25d20cSdan} { 109*1e25d20cSdan UPDATE t1 SET c=4 WHERE a=1 -- remote 110*1e25d20cSdan} OMIT { 111*1e25d20cSdan {UPDATE t1 0 X.. {i 1 {} {} i 4} {{} {} {} {} i 4}} 112*1e25d20cSdan} 113*1e25d20cSdan 114*1e25d20cSdando_rebase_test 2.3.2 { 115*1e25d20cSdan UPDATE t1 SET c=5 WHERE a=1; -- local 116*1e25d20cSdan} { 117*1e25d20cSdan UPDATE t1 SET c=5 WHERE a=1 -- remote 118*1e25d20cSdan} REPLACE { 119*1e25d20cSdan} 120*1e25d20cSdan 121*1e25d20cSdan#------------------------------------------------------------------------- 122*1e25d20cSdan# 123*1e25d20cSdanreset_db 124*1e25d20cSdando_execsql_test 3.0 { 125*1e25d20cSdan CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); 126*1e25d20cSdan INSERT INTO t1 VALUES(1, 1, 1); 127*1e25d20cSdan INSERT INTO t1 VALUES(2, 2, 2); 128*1e25d20cSdan INSERT INTO t1 VALUES(3, 3, 3); 129*1e25d20cSdan INSERT INTO t1 VALUES(4, 4, 4); 130*1e25d20cSdan} 131*1e25d20cSdan 132*1e25d20cSdan# Arg $pkstr contains one character for each column in the table. An 133*1e25d20cSdan# "X" for PK column, or a "." for a non-PK. 134*1e25d20cSdan# 135*1e25d20cSdanproc mk_tbl_header {name pkstr} { 136*1e25d20cSdan set ret [binary format H2c 54 [string length $pkstr]] 137*1e25d20cSdan foreach i [split $pkstr {}] { 138*1e25d20cSdan if {$i=="X"} { 139*1e25d20cSdan append ret [binary format H2 01] 140*1e25d20cSdan } else { 141*1e25d20cSdan if {$i!="."} {error "bad pkstr: $pkstr ($i)"} 142*1e25d20cSdan append ret [binary format H2 00] 143*1e25d20cSdan } 144*1e25d20cSdan } 145*1e25d20cSdan append ret $name 146*1e25d20cSdan append ret [binary format H2 00] 147*1e25d20cSdan set ret 148*1e25d20cSdan} 149*1e25d20cSdan 150*1e25d20cSdanproc mk_update_change {args} { 151*1e25d20cSdan set ret [binary format H2H2 17 00] 152*1e25d20cSdan foreach a $args { 153*1e25d20cSdan if {$a==""} { 154*1e25d20cSdan append ret [binary format H2 00] 155*1e25d20cSdan } else { 156*1e25d20cSdan append ret [binary format H2W 01 $a] 157*1e25d20cSdan } 158*1e25d20cSdan } 159*1e25d20cSdan set ret 160*1e25d20cSdan} 161*1e25d20cSdan 162*1e25d20cSdanproc xConflict {args} { return "ABORT" } 163*1e25d20cSdando_test 3.1 { 164*1e25d20cSdan set C [mk_tbl_header t1 X..] 165*1e25d20cSdan append C [mk_update_change 1 {} 1 {} {} 500] 166*1e25d20cSdan append C [mk_update_change 2 {} {} {} {} {}] 167*1e25d20cSdan append C [mk_update_change 3 3 {} {} 600 {}] 168*1e25d20cSdan append C [mk_update_change 4 {} {} {} {} {}] 169*1e25d20cSdan 170*1e25d20cSdan sqlite3changeset_apply_v2 db $C xConflict 171*1e25d20cSdan} {} 172*1e25d20cSdando_execsql_test 3.2 { 173*1e25d20cSdan SELECT * FROM t1 174*1e25d20cSdan} { 175*1e25d20cSdan 1 1 500 176*1e25d20cSdan 2 2 2 177*1e25d20cSdan 3 600 3 178*1e25d20cSdan 4 4 4 179*1e25d20cSdan} 180*1e25d20cSdan 181*1e25d20cSdan 182*1e25d20cSdan 183*1e25d20cSdan 184*1e25d20cSdan 185*1e25d20cSdan 186*1e25d20cSdanfinish_test 187*1e25d20cSdan 188