diff options
author | dan <dan@noemail.net> | 2011-03-19 15:37:02 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2011-03-19 15:37:02 +0000 |
commit | 7cf7df7d35579c9575ded280577b8337efd9c1c5 (patch) | |
tree | acc01bbb5eb16012bf6ebacf3cb8a2e5fe41d09a | |
parent | 319eeb7b33eb9380924475f799ec66773c7ea953 (diff) | |
download | sqlite-7cf7df7d35579c9575ded280577b8337efd9c1c5.tar.gz sqlite-7cf7df7d35579c9575ded280577b8337efd9c1c5.zip |
Fix some bugs in sqlite3changeset_apply().
FossilOrigin-Name: 7250318dda542c5bbf28852c1f1d0f3c52ae8f96
-rw-r--r-- | ext/session/session2.test | 138 | ||||
-rw-r--r-- | ext/session/sqlite3session.c | 36 | ||||
-rw-r--r-- | manifest | 18 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/test_config.c | 6 | ||||
-rw-r--r-- | test/permutations.test | 9 | ||||
-rw-r--r-- | test/session.test | 18 |
7 files changed, 202 insertions, 25 deletions
diff --git a/ext/session/session2.test b/ext/session/session2.test new file mode 100644 index 000000000..21a457fde --- /dev/null +++ b/ext/session/session2.test @@ -0,0 +1,138 @@ +# 2011 Mar 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl + +set testprefix session2 + +proc test_reset {} { + catch { db close } + catch { db2 close } + forcedelete test.db test.db2 + sqlite3 db test.db + sqlite3 db2 test.db2 +} + +proc do_common_sql {sql} { + execsql $sql db + execsql $sql db2 +} +proc xConflict args { return "OMIT" } + +proc do_then_apply_sql {sql} { + sqlite3session S db main + db eval {SELECT name FROM sqlite_master WHERE type = 'table'} { + S attach $name + } + + db eval $sql + sqlite3changeset_apply db2 [S changeset] xConflict + S delete +} + +proc do_iterator_test {tn tbl_list sql res} { + sqlite3session S db main + foreach t $tbl_list {S attach $t} + execsql $sql + + set r [list] + foreach v $res { lappend r $v } + + set x [list] + sqlite3session_foreach c [S changeset] { lappend x $c } + uplevel do_test $tn [list [list set {} $x]] [list $r] + + S delete +} + +# Compare the contents of all tables in [db1] and [db2]. Throw an error if +# they are not identical, or return an empty string if they are. +# +proc compare_db {db1 db2} { + + set sql {SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name} + set lot1 [$db1 eval $sql] + set lot2 [$db2 eval $sql] + + if {$lot1 != $lot2} { error "databases contain different tables" } + + foreach tbl $lot1 { + set col1 [list] + set col2 [list] + + $db1 eval "PRAGMA table_info = $tbl" { lappend col1 $name } + $db2 eval "PRAGMA table_info = $tbl" { lappend col2 $name } + if {$col1 != $col2} { error "table $tbl schema mismatch" } + + set sql "SELECT * FROM $tbl ORDER BY [join $col1 ,]" + set data1 [$db1 eval $sql] + set data2 [$db2 eval $sql] + if {$data1 != $data2} { error "table $tbl data mismatch" } + } + + return "" +} + +########################################################################## +# End of proc definitions. Start of tests. +########################################################################## + +test_reset +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES('i', 'one'); +} +do_iterator_test 1.1 t1 { + DELETE FROM t1 WHERE a = 'i'; + INSERT INTO t1 VALUES('ii', 'two'); +} { + {DELETE t1 {t i t one} {}} + {INSERT t1 {} {t ii t two}} +} + +test_reset +do_common_sql { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t2(a, b INTEGER PRIMARY KEY); + CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); +} + +foreach {tn sql} { + 1 { INSERT INTO t1 VALUES(1, 2) } + 2 { + INSERT INTO t2 VALUES(1, NULL); + INSERT INTO t2 VALUES(2, NULL); + INSERT INTO t2 VALUES(3, NULL); + DELETE FROM t2 WHERE a = 2; + INSERT INTO t2 VALUES(4, NULL); + UPDATE t2 SET b=0 WHERE b=1; + } + 3 { INSERT INTO t3 SELECT *, NULL FROM t2 } + 4 { + INSERT INTO t3 SELECT a||a, b||b, NULL FROM t3; + DELETE FROM t3 WHERE rowid%2; + } + 5 { UPDATE t3 SET c = a||b } + 6 { UPDATE t1 SET a = 32 } +} { + do_then_apply_sql $sql + do_test $tn { compare_db db db2 } {} +} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 64114718d..411e08237 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -1777,6 +1777,7 @@ static int sessionDeleteRow( const char *zSep = ""; int rc = SQLITE_OK; SessionBuffer buf = {0, 0, 0}; + int nPk = 0; sessionAppendStr(&buf, "DELETE FROM ", &rc); sessionAppendIdent(&buf, zTab, &rc); @@ -1784,29 +1785,32 @@ static int sessionDeleteRow( for(i=0; i<p->nCol; i++){ if( p->abPK[i] ){ + nPk++; sessionAppendStr(&buf, zSep, &rc); sessionAppendIdent(&buf, p->azCol[i], &rc); sessionAppendStr(&buf, " = ?", &rc); sessionAppendInteger(&buf, i+1, &rc); - zSep = "AND "; + zSep = " AND "; } } - sessionAppendStr(&buf, " AND (?", &rc); - sessionAppendInteger(&buf, p->nCol+1, &rc); - sessionAppendStr(&buf, " OR ", &rc); - - zSep = ""; - for(i=0; i<p->nCol; i++){ - if( !p->abPK[i] ){ - sessionAppendStr(&buf, zSep, &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " IS ?", &rc); - sessionAppendInteger(&buf, i+1, &rc); - zSep = "AND "; + if( nPk<p->nCol ){ + sessionAppendStr(&buf, " AND (?", &rc); + sessionAppendInteger(&buf, p->nCol+1, &rc); + sessionAppendStr(&buf, " OR ", &rc); + + zSep = ""; + for(i=0; i<p->nCol; i++){ + if( !p->abPK[i] ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[i], &rc); + sessionAppendStr(&buf, " IS ?", &rc); + sessionAppendInteger(&buf, i+1, &rc); + zSep = "AND "; + } } + sessionAppendStr(&buf, ")", &rc); } - sessionAppendStr(&buf, ")", &rc); if( rc==SQLITE_OK ){ rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0); @@ -2171,7 +2175,9 @@ static int sessionApplyOneOp( rc = sqlite3_bind_value(p->pDelete, i+1, pVal); } } - if( rc==SQLITE_OK ) rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); + if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){ + rc = sqlite3_bind_int(p->pDelete, nCol+1, pbRetry==0); + } if( rc!=SQLITE_OK ) return rc; sqlite3_step(p->pDelete); @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sINTEGER\sPRIMARY\sKEY\scolumns\sand\sthe\spre-update\shook. -D 2011-03-19T08:38:50 +C Fix\ssome\sbugs\sin\ssqlite3changeset_apply(). +D 2011-03-19T15:37:02 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -99,7 +99,8 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F ext/session/sqlite3session.c d4ba709d457a7b184a72ccd3ab07e5a1e9dd9196 +F ext/session/session2.test 72f5926805b46a9a5f240db856dab0e5f59fc693 +F ext/session/sqlite3session.c 6518a335592f4b118d9e6b9ed9dcbe27b0ebcda7 F ext/session/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 @@ -201,7 +202,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 +F src/test_config.c e9a4ce02dec5bcced1c13e0cf8b72edfd5903d74 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -601,7 +602,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16 -F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 +F test/permutations.test 1e35edce72e6d9e2e392420caed18652a97b1a95 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea @@ -644,6 +645,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532 F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25 F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c +F test/session.test c1a17c11ef7d01c24fe2b9f7871190d949a8e718 F test/session1.test c6851e2e1066269cad5370566ce5494c7dbdfa7e F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c @@ -919,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 1b736ac2934f2361dee5062e9033cbf26b41fc3a -R 162f72638a0f38fbe0fc1273d5b87dc2 +P 24d4d5dd007197a141555bcca6f2ac9ab47cde80 +R 985767b788ac43658b5fdac318a5d51e U dan -Z 3b532fd3ba73ffa805a9d5e7143aadc5 +Z e6cf037758a8ddd02cc6b33f9980e9f6 diff --git a/manifest.uuid b/manifest.uuid index e62b7f494..75eb32260 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24d4d5dd007197a141555bcca6f2ac9ab47cde80
\ No newline at end of file +7250318dda542c5bbf28852c1f1d0f3c52ae8f96
\ No newline at end of file diff --git a/src/test_config.c b/src/test_config.c index 6eee524c0..24ddbaa02 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -404,6 +404,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double", Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_SESSION + Tcl_SetVar2(interp, "sqlite_options", "session", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "session", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_STAT2 Tcl_SetVar2(interp, "sqlite_options", "stat2", "1", TCL_GLOBAL_ONLY); #else diff --git a/test/permutations.test b/test/permutations.test index 9c48d9aa2..7e336b16a 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -89,6 +89,9 @@ foreach f [glob $testdir/*.test] { lappend alltests [file tail $f] } foreach f [glob -nocomplain $testdir/../ext/rtree/*.test] { lappend alltests $f } +foreach f [glob -nocomplain $testdir/../ext/session/*.test] { + lappend alltests $f +} if {$::tcl_platform(platform)!="unix"} { set alltests [test_set $alltests -exclude crash.test crash2.test] @@ -96,7 +99,7 @@ if {$::tcl_platform(platform)!="unix"} { set alltests [test_set $alltests -exclude { all.test async.test quick.test veryquick.test memleak.test permutations.test soak.test fts3.test - mallocAll.test rtree.test + mallocAll.test rtree.test session.test }] set allquicktests [test_set $alltests -exclude { @@ -762,6 +765,10 @@ test_suite "rtree" -description { All R-tree related tests. Provides coverage of source file rtree.c. } -files [glob -nocomplain $::testdir/../ext/rtree/*.test] +test_suite "session" -description { + All session module related tests. +} -files [glob -nocomplain $::testdir/../ext/session/*.test] + test_suite "no_optimization" -description { Run test scripts with optimizations disabled using the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface. diff --git a/test/session.test b/test/session.test new file mode 100644 index 000000000..bf159c3b2 --- /dev/null +++ b/test/session.test @@ -0,0 +1,18 @@ +# 2008 June 23 +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file runs all rtree related tests. +# + +set testdir [file dirname $argv0] +source $testdir/permutations.test + +ifcapable session { + run_test_suite session +} + +finish_test |