mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Add tests and fixes for OOM handling in sqlite3changeset_concat().
FossilOrigin-Name: df0b2d21dcd81679e55b24866f97568019932983
This commit is contained in:
@ -31,12 +31,6 @@ set testprefix session5
|
|||||||
# session5-3.*: Schema mismatch errors.
|
# session5-3.*: Schema mismatch errors.
|
||||||
#
|
#
|
||||||
|
|
||||||
proc changeset_to_list {c} {
|
|
||||||
set list [list]
|
|
||||||
sqlite3session_foreach elem $c { lappend list $elem }
|
|
||||||
lsort $list
|
|
||||||
}
|
|
||||||
|
|
||||||
proc do_concat_test {tn args} {
|
proc do_concat_test {tn args} {
|
||||||
|
|
||||||
set subtest 0
|
set subtest 0
|
||||||
@ -191,20 +185,31 @@ do_concat_test 2.1 {
|
|||||||
UPDATE abc SET a='one point six' WHERE c = 'three';
|
UPDATE abc SET a='one point six' WHERE c = 'three';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
catch {db close}
|
||||||
|
forcedelete test.db
|
||||||
|
sqlite3 db test.db
|
||||||
|
do_concat_test 2.2 {
|
||||||
|
CREATE TABLE t1(a, b, PRIMARY KEY(b));
|
||||||
|
CREATE TABLE t2(a PRIMARY KEY, b);
|
||||||
|
INSERT INTO t1 VALUES('string', 1);
|
||||||
|
INSERT INTO t1 VALUES(4, 2);
|
||||||
|
INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
|
||||||
|
} {
|
||||||
|
INSERT INTO t2 VALUES('one', 'two');
|
||||||
|
INSERT INTO t2 VALUES(1, NULL);
|
||||||
|
UPDATE t1 SET a = 5 WHERE a = 2;
|
||||||
|
} {
|
||||||
|
DELETE FROM t2 WHERE a = 1;
|
||||||
|
UPDATE t1 SET a = 4 WHERE a = 2;
|
||||||
|
INSERT INTO t2 VALUES('x', 'y');
|
||||||
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
# Test that schema incompatibilities are detected correctly.
|
# Test that schema incompatibilities are detected correctly.
|
||||||
#
|
#
|
||||||
# session5-3.1: Incompatible number of columns.
|
# session5-3.1: Incompatible number of columns.
|
||||||
# session5-3.2: Incompatible PK definition.
|
# session5-3.2: Incompatible PK definition.
|
||||||
#
|
#
|
||||||
proc sql_to_changeset {sql} {
|
|
||||||
sqlite3session S db main
|
|
||||||
S attach *
|
|
||||||
execsql $sql
|
|
||||||
set c [S changeset]
|
|
||||||
S delete
|
|
||||||
return $c
|
|
||||||
}
|
|
||||||
|
|
||||||
do_test 3.1 {
|
do_test 3.1 {
|
||||||
db close
|
db close
|
||||||
@ -212,12 +217,12 @@ do_test 3.1 {
|
|||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
|
|
||||||
execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
|
execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
|
||||||
set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }]
|
set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
|
||||||
execsql {
|
execsql {
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1(a PRIMARY KEY, b, c);
|
CREATE TABLE t1(a PRIMARY KEY, b, c);
|
||||||
}
|
}
|
||||||
set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3, 4) }]
|
set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3, 4) }]
|
||||||
|
|
||||||
list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
|
list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
|
||||||
} {1 SQLITE_SCHEMA}
|
} {1 SQLITE_SCHEMA}
|
||||||
@ -228,12 +233,12 @@ do_test 3.2 {
|
|||||||
sqlite3 db test.db
|
sqlite3 db test.db
|
||||||
|
|
||||||
execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
|
execsql { CREATE TABLE t1(a PRIMARY KEY, b) }
|
||||||
set c1 [sql_to_changeset { INSERT INTO t1 VALUES(1, 2) }]
|
set c1 [changeset_from_sql { INSERT INTO t1 VALUES(1, 2) }]
|
||||||
execsql {
|
execsql {
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1(a, b PRIMARY KEY);
|
CREATE TABLE t1(a, b PRIMARY KEY);
|
||||||
}
|
}
|
||||||
set c2 [sql_to_changeset { INSERT INTO t1 VALUES(2, 3) }]
|
set c2 [changeset_from_sql { INSERT INTO t1 VALUES(2, 3) }]
|
||||||
|
|
||||||
list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
|
list [catch { sqlite3changeset_concat $c1 $c2 } msg] $msg
|
||||||
} {1 SQLITE_SCHEMA}
|
} {1 SQLITE_SCHEMA}
|
||||||
|
@ -128,5 +128,9 @@ proc compare_db {db1 db2} {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc changeset_to_list {c} {
|
||||||
|
set list [list]
|
||||||
|
sqlite3session_foreach elem $c { lappend list $elem }
|
||||||
|
lsort $list
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -251,4 +251,47 @@ do_faultsim_test 5 -faults oom* -body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Test that OOM errors in sqlite3changeset_concat() are handled correctly.
|
||||||
|
#
|
||||||
|
catch {db close}
|
||||||
|
forcedelete test.db
|
||||||
|
sqlite3 db test.db
|
||||||
|
do_execsql_test 5.prep1 {
|
||||||
|
CREATE TABLE t1(a, b, PRIMARY KEY(b));
|
||||||
|
CREATE TABLE t2(a PRIMARY KEY, b);
|
||||||
|
INSERT INTO t1 VALUES('string', 1);
|
||||||
|
INSERT INTO t1 VALUES(4, 2);
|
||||||
|
INSERT INTO t1 VALUES(X'FFAAFFAAFFAA', 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_test 5.prep2 {
|
||||||
|
sqlite3session M db main
|
||||||
|
M attach *
|
||||||
|
set ::c2 [changeset_from_sql {
|
||||||
|
INSERT INTO t2 VALUES(randomblob(1000), randomblob(1000));
|
||||||
|
INSERT INTO t2 VALUES('one', 'two');
|
||||||
|
INSERT INTO t2 VALUES(1, NULL);
|
||||||
|
UPDATE t1 SET a = 5 WHERE a = 2;
|
||||||
|
}]
|
||||||
|
set ::c1 [changeset_from_sql {
|
||||||
|
DELETE FROM t2 WHERE a = 1;
|
||||||
|
UPDATE t1 SET a = 4 WHERE a = 2;
|
||||||
|
INSERT INTO t2 VALUES('x', 'y');
|
||||||
|
}]
|
||||||
|
set ::total [changeset_to_list [M changeset]]
|
||||||
|
M delete
|
||||||
|
} {}
|
||||||
|
|
||||||
|
do_faultsim_test 6 -faults oom-* -body {
|
||||||
|
set ::result [sqlite3changeset_concat $::c1 $::c2]
|
||||||
|
set {} {}
|
||||||
|
} -test {
|
||||||
|
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||||
|
if {$testrc==0} {
|
||||||
|
set v [changeset_to_list $::result]
|
||||||
|
if {$v != $::total} { error "result no good" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -2786,6 +2786,7 @@ static int sessionChangeMerge(
|
|||||||
nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
|
nByte = sizeof(SessionChange) + pExist->nRecord + nRec;
|
||||||
pNew = (SessionChange *)sqlite3_malloc(nByte);
|
pNew = (SessionChange *)sqlite3_malloc(nByte);
|
||||||
if( !pNew ){
|
if( !pNew ){
|
||||||
|
sqlite3_free(pExist);
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
memset(pNew, 0, sizeof(SessionChange));
|
memset(pNew, 0, sizeof(SessionChange));
|
||||||
@ -2886,7 +2887,10 @@ int sessionConcatChangeset(
|
|||||||
pTab->zName = (char *)zNew;
|
pTab->zName = (char *)zNew;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sessionGrowHash(pTab) ) break;
|
if( sessionGrowHash(pTab) ){
|
||||||
|
rc = SQLITE_NOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
iHash = sessionChangeHash(pTab, aRec, pTab->nChange);
|
iHash = sessionChangeHash(pTab, aRec, pTab->nChange);
|
||||||
|
|
||||||
/* Search for existing entry. If found, remove it from the hash table.
|
/* Search for existing entry. If found, remove it from the hash table.
|
||||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
|||||||
C Have\ssqlite3changeset_concat()\sreturn\sSQLITE_SCHEMA\sif\san\sattempt\sis\smade\sto\sconcatenate\schangesets\sbased\son\sincompatible\sdatabase\sschemas.
|
C Add\stests\sand\sfixes\sfor\sOOM\shandling\sin\ssqlite3changeset_concat().
|
||||||
D 2011-04-15T15:04:31.042
|
D 2011-04-15T16:03:32.057
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
|
F Makefile.in 7a4d9524721d40ef9ee26f93f9bd6a51dba106f2
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -103,10 +103,10 @@ F ext/session/session1.test 7a92a2a6f531aef1e9764ffb7f983fb8b315376d
|
|||||||
F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb
|
F ext/session/session2.test c3e5f78d5eb988e35cc2ba9ce3678f706283cfdb
|
||||||
F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3
|
F ext/session/session3.test bfa2376db7cbb2ac69496f84d93a8d81b13110d3
|
||||||
F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84
|
F ext/session/session4.test a6ed685da7a5293c5d6f99855bcf41dbc352ca84
|
||||||
F ext/session/session5.test cbb011a1b2f487d2fe4b014fb6ae3a67e5f7f767
|
F ext/session/session5.test 940d77c748808769cac50fb62bb674aa84e472f2
|
||||||
F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28
|
F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5
|
||||||
F ext/session/sessionfault.test 2544a2e2ecad56e3c07a32c09799871d243c114c
|
F ext/session/sessionfault.test 2766cd620f1793f0e54f1e3859a184bcea55bad4
|
||||||
F ext/session/sqlite3session.c b5293510224e42c50d69a509e6bfaca45defec76
|
F ext/session/sqlite3session.c 08573805932a9db4158f36663e01747d0ff69342
|
||||||
F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf
|
F ext/session/sqlite3session.h 665f5591562e3c71eb3d0da26f1a1efae26f7bcf
|
||||||
F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7
|
F ext/session/test_session.c f4d1dca94db71ec2177ee61eab51e718e58476d7
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
@ -938,7 +938,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
|||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P ada9efa53a6ea55f89d237cfd530f1d180343e19
|
P 343b64517d244b75097e38342dc273eb5a52915b
|
||||||
R bdb9eba45cd97b77f78325d72d96c5f4
|
R c818789c65113df118a04c3a29f3e5ba
|
||||||
U dan
|
U dan
|
||||||
Z 570068f4f013ca36918b632f2a36093d
|
Z 7081c2709375635b8446c7ef8a86300e
|
||||||
|
@ -1 +1 @@
|
|||||||
343b64517d244b75097e38342dc273eb5a52915b
|
df0b2d21dcd81679e55b24866f97568019932983
|
Reference in New Issue
Block a user