mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Fix some bugs in sqlite3changeset_apply().
FossilOrigin-Name: 7250318dda542c5bbf28852c1f1d0f3c52ae8f96
This commit is contained in:
138
ext/session/session2.test
Normal file
138
ext/session/session2.test
Normal file
@ -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
|
||||||
|
|
@ -1777,6 +1777,7 @@ static int sessionDeleteRow(
|
|||||||
const char *zSep = "";
|
const char *zSep = "";
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
SessionBuffer buf = {0, 0, 0};
|
SessionBuffer buf = {0, 0, 0};
|
||||||
|
int nPk = 0;
|
||||||
|
|
||||||
sessionAppendStr(&buf, "DELETE FROM ", &rc);
|
sessionAppendStr(&buf, "DELETE FROM ", &rc);
|
||||||
sessionAppendIdent(&buf, zTab, &rc);
|
sessionAppendIdent(&buf, zTab, &rc);
|
||||||
@ -1784,6 +1785,7 @@ static int sessionDeleteRow(
|
|||||||
|
|
||||||
for(i=0; i<p->nCol; i++){
|
for(i=0; i<p->nCol; i++){
|
||||||
if( p->abPK[i] ){
|
if( p->abPK[i] ){
|
||||||
|
nPk++;
|
||||||
sessionAppendStr(&buf, zSep, &rc);
|
sessionAppendStr(&buf, zSep, &rc);
|
||||||
sessionAppendIdent(&buf, p->azCol[i], &rc);
|
sessionAppendIdent(&buf, p->azCol[i], &rc);
|
||||||
sessionAppendStr(&buf, " = ?", &rc);
|
sessionAppendStr(&buf, " = ?", &rc);
|
||||||
@ -1792,6 +1794,7 @@ static int sessionDeleteRow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( nPk<p->nCol ){
|
||||||
sessionAppendStr(&buf, " AND (?", &rc);
|
sessionAppendStr(&buf, " AND (?", &rc);
|
||||||
sessionAppendInteger(&buf, p->nCol+1, &rc);
|
sessionAppendInteger(&buf, p->nCol+1, &rc);
|
||||||
sessionAppendStr(&buf, " OR ", &rc);
|
sessionAppendStr(&buf, " OR ", &rc);
|
||||||
@ -1807,6 +1810,7 @@ static int sessionDeleteRow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
sessionAppendStr(&buf, ")", &rc);
|
sessionAppendStr(&buf, ")", &rc);
|
||||||
|
}
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0);
|
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);
|
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;
|
if( rc!=SQLITE_OK ) return rc;
|
||||||
|
|
||||||
sqlite3_step(p->pDelete);
|
sqlite3_step(p->pDelete);
|
||||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\sa\sproblem\swith\sINTEGER\sPRIMARY\sKEY\scolumns\sand\sthe\spre-update\shook.
|
C Fix\ssome\sbugs\sin\ssqlite3changeset_apply().
|
||||||
D 2011-03-19T08:38:50
|
D 2011-03-19T15:37:02
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
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/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
|
||||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
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/sqlite3session.h 9551c002efd5fde07c52994c6b592308e0df2d6a
|
||||||
F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
|
F ext/session/test_session.c 2559ef68e421c7fb83e2c19ef08a17343b70d535
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||||
@ -201,7 +202,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
|
|||||||
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
|
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
|
||||||
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
|
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
|
||||||
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
|
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_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5
|
||||||
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
|
||||||
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
|
F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5
|
||||||
@ -601,7 +602,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
|
|||||||
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
|
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
|
||||||
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
|
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
|
||||||
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
|
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
|
||||||
F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6
|
F test/permutations.test 1e35edce72e6d9e2e392420caed18652a97b1a95
|
||||||
F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
|
F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
|
||||||
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
|
||||||
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
|
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
|
||||||
@ -644,6 +645,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532
|
|||||||
F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b
|
F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b
|
||||||
F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25
|
F test/selectC.test f9bf1bc4581b5b8158caa6e4e4f682acb379fb25
|
||||||
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
|
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
|
||||||
|
F test/session.test c1a17c11ef7d01c24fe2b9f7871190d949a8e718
|
||||||
F test/session1.test c6851e2e1066269cad5370566ce5494c7dbdfa7e
|
F test/session1.test c6851e2e1066269cad5370566ce5494c7dbdfa7e
|
||||||
F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e
|
F test/shared.test b9114eaea7e748a3a4c8ff7b9ca806c8f95cef3e
|
||||||
F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c
|
F test/shared2.test 7f6ad2d857d0f4e5d6a0b9a897b5e56a6b6ea18c
|
||||||
@ -919,7 +921,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 1b736ac2934f2361dee5062e9033cbf26b41fc3a
|
P 24d4d5dd007197a141555bcca6f2ac9ab47cde80
|
||||||
R 162f72638a0f38fbe0fc1273d5b87dc2
|
R 985767b788ac43658b5fdac318a5d51e
|
||||||
U dan
|
U dan
|
||||||
Z 3b532fd3ba73ffa805a9d5e7143aadc5
|
Z e6cf037758a8ddd02cc6b33f9980e9f6
|
||||||
|
@ -1 +1 @@
|
|||||||
24d4d5dd007197a141555bcca6f2ac9ab47cde80
|
7250318dda542c5bbf28852c1f1d0f3c52ae8f96
|
@ -404,6 +404,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
|||||||
Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
|
||||||
#endif
|
#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
|
#ifdef SQLITE_ENABLE_STAT2
|
||||||
Tcl_SetVar2(interp, "sqlite_options", "stat2", "1", TCL_GLOBAL_ONLY);
|
Tcl_SetVar2(interp, "sqlite_options", "stat2", "1", TCL_GLOBAL_ONLY);
|
||||||
#else
|
#else
|
||||||
|
@ -89,6 +89,9 @@ foreach f [glob $testdir/*.test] { lappend alltests [file tail $f] }
|
|||||||
foreach f [glob -nocomplain $testdir/../ext/rtree/*.test] {
|
foreach f [glob -nocomplain $testdir/../ext/rtree/*.test] {
|
||||||
lappend alltests $f
|
lappend alltests $f
|
||||||
}
|
}
|
||||||
|
foreach f [glob -nocomplain $testdir/../ext/session/*.test] {
|
||||||
|
lappend alltests $f
|
||||||
|
}
|
||||||
|
|
||||||
if {$::tcl_platform(platform)!="unix"} {
|
if {$::tcl_platform(platform)!="unix"} {
|
||||||
set alltests [test_set $alltests -exclude crash.test crash2.test]
|
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 {
|
set alltests [test_set $alltests -exclude {
|
||||||
all.test async.test quick.test veryquick.test
|
all.test async.test quick.test veryquick.test
|
||||||
memleak.test permutations.test soak.test fts3.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 {
|
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.
|
All R-tree related tests. Provides coverage of source file rtree.c.
|
||||||
} -files [glob -nocomplain $::testdir/../ext/rtree/*.test]
|
} -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 {
|
test_suite "no_optimization" -description {
|
||||||
Run test scripts with optimizations disabled using the
|
Run test scripts with optimizations disabled using the
|
||||||
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface.
|
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface.
|
||||||
|
18
test/session.test
Normal file
18
test/session.test
Normal file
@ -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
|
Reference in New Issue
Block a user