Add tests (and associated fixes) to restore coverage of rtree.c.

FossilOrigin-Name: b06f4695bdab244d9c764c082cd434a764dc5c29
This commit is contained in:
dan 2010-08-30 15:43:45 +00:00
parent 75c014c321
commit 7bddb7550b
8 changed files with 116 additions and 58 deletions

View File

@ -1106,14 +1106,14 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
int nBlob; int nBlob;
/* Check that value is actually a blob. */ /* Check that value is actually a blob. */
if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_MISUSE; if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR;
/* Check that the blob is roughly the right size. */ /* Check that the blob is roughly the right size. */
nBlob = sqlite3_value_bytes(pValue); nBlob = sqlite3_value_bytes(pValue);
if( nBlob<sizeof(RtreeGeomBlob) if( nBlob<sizeof(RtreeGeomBlob)
|| ((nBlob-sizeof(RtreeGeomBlob))%sizeof(double))!=0 || ((nBlob-sizeof(RtreeGeomBlob))%sizeof(double))!=0
){ ){
return SQLITE_MISUSE; return SQLITE_ERROR;
} }
pGeom = (RtreeGeometry *)sqlite3_malloc(sizeof(RtreeGeometry) + nBlob); pGeom = (RtreeGeometry *)sqlite3_malloc(sizeof(RtreeGeometry) + nBlob);
@ -1125,8 +1125,8 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
if( p->magic!=RTREE_GEOMETRY_MAGIC if( p->magic!=RTREE_GEOMETRY_MAGIC
|| nBlob!=(sizeof(RtreeGeomBlob) + (p->nParam-1)*sizeof(double)) || nBlob!=(sizeof(RtreeGeomBlob) + (p->nParam-1)*sizeof(double))
){ ){
sqlite3_free(p); sqlite3_free(pGeom);
return SQLITE_MISUSE; return SQLITE_ERROR;
} }
pGeom->pContext = p->pContext; pGeom->pContext = p->pContext;
@ -1295,6 +1295,8 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
} }
if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ if( p->usable && (p->iColumn>0 || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){
int j, opmsk;
static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
u8 op = 0; u8 op = 0;
switch( p->op ){ switch( p->op ){
case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
@ -1302,32 +1304,33 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; default:
assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
op = RTREE_MATCH;
break;
} }
if( op ){ assert( op!=0 );
/* Make sure this particular constraint has not been used before.
** If it has been used before, ignore it. /* Make sure this particular constraint has not been used before.
** ** If it has been used before, ignore it.
** A <= or < can be used if there is a prior >= or >. **
** A >= or > can be used if there is a prior < or <=. ** A <= or < can be used if there is a prior >= or >.
** A <= or < is disqualified if there is a prior <=, <, or ==. ** A >= or > can be used if there is a prior < or <=.
** A >= or > is disqualified if there is a prior >=, >, or ==. ** A <= or < is disqualified if there is a prior <=, <, or ==.
** A == is disqualifed if there is any prior constraint. ** A >= or > is disqualified if there is a prior >=, >, or ==.
*/ ** A == is disqualifed if there is any prior constraint.
int j, opmsk; */
static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 }; assert( compatible[RTREE_EQ & 7]==0 );
assert( compatible[RTREE_EQ & 7]==0 ); assert( compatible[RTREE_LT & 7]==1 );
assert( compatible[RTREE_LT & 7]==1 ); assert( compatible[RTREE_LE & 7]==1 );
assert( compatible[RTREE_LE & 7]==1 ); assert( compatible[RTREE_GT & 7]==2 );
assert( compatible[RTREE_GT & 7]==2 ); assert( compatible[RTREE_GE & 7]==2 );
assert( compatible[RTREE_GE & 7]==2 ); cCol = p->iColumn - 1 + 'a';
cCol = p->iColumn - 1 + 'a'; opmsk = compatible[op & 7];
opmsk = compatible[op & 7]; for(j=0; j<iIdx; j+=2){
for(j=0; j<iIdx; j+=2){ if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){ op = 0;
op = 0; break;
break;
}
} }
} }
if( op ){ if( op ){

View File

@ -206,4 +206,32 @@ do_faultsim_test rtree3-8 -faults oom-* -prep {
sqlite3 db test.db sqlite3 db test.db
} }
do_faultsim_test rtree3-9 -faults oom-* -prep {
sqlite3 db :memory:
} -body {
set rc [register_cube_geom db]
if {$rc != "SQLITE_OK"} { error $rc }
} -test {
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
}
do_test rtree3-10.prep {
faultsim_delete_and_reopen
execsql {
CREATE VIRTUAL TABLE rt USING rtree(ii, x1, x2, y1, y2, z1, z2);
INSERT INTO rt VALUES(1, 10, 10, 10, 11, 11, 11);
INSERT INTO rt VALUES(2, 5, 6, 6, 7, 7, 8);
}
faultsim_save_and_close
} {}
do_faultsim_test rtree3-10 -faults oom-* -prep {
faultsim_restore_and_reopen
register_cube_geom db
execsql { SELECT * FROM rt }
} -body {
execsql { SELECT ii FROM rt WHERE ii MATCH cube(4.5, 5.5, 6.5, 1, 1, 1) }
} -test {
faultsim_test_result {0 2}
}
finish_test finish_test

View File

@ -129,7 +129,7 @@ do_execsql_test rtree8-2.2.3 {
populate_t1 10 populate_t1 10
do_catchsql_test rtree8-3.1 { do_catchsql_test rtree8-3.1 {
SELECT * FROM t1 WHERE x1 MATCH '1234' SELECT * FROM t1 WHERE x1 MATCH '1234'
} {1 {library routine called out of sequence}} } {1 {SQL logic error or missing database}}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# Test a couple of invalid arguments to rtreedepth(). # Test a couple of invalid arguments to rtreedepth().

View File

@ -32,13 +32,13 @@ do_execsql_test rtree9-1.4 {
DELETE FROM rt; DELETE FROM rt;
} {} } {}
for {set i 0} {$i < 1000} {incr i} { for {set i 0} {$i < 1000} {incr i} {
set x [expr $i%10] set x [expr $i%10]
set y [expr ($i/10)%10] set y [expr ($i/10)%10]
set z [expr ($i/100)%10] set z [expr ($i/100)%10]
execsql { INSERT INTO rt VALUES($i, $x, $x+1, $y, $y+1, $z, $z+1) } execsql { INSERT INTO rt VALUES($i, $x, $x+1, $y, $y+1, $z, $z+1) }
} }
do_execsql_test rtree9-2.1 { do_execsql_test rtree9-2.1 {
SELECT id FROM rt WHERE id MATCH cube(2.5, 2.5, 2.5, 1, 1, 1) ORDER BY id; SELECT id FROM rt WHERE id MATCH cube(2.5, 2.5, 2.5, 1, 1, 1) ORDER BY id;
} {222 223 232 233 322 323 332 333} } {222 223 232 233 322 323 332 333}
@ -46,8 +46,37 @@ do_execsql_test rtree9-2.2 {
SELECT id FROM rt WHERE id MATCH cube(5.5, 5.5, 5.5, 1, 1, 1) ORDER BY id; SELECT id FROM rt WHERE id MATCH cube(5.5, 5.5, 5.5, 1, 1, 1) ORDER BY id;
} {555 556 565 566 655 656 665 666} } {555 556 565 566 655 656 665 666}
do_catchsql_test rtree9-3.1 {
SELECT id FROM rt WHERE id MATCH cube(5.5, 5.5, 1, 1, 1) ORDER BY id; do_execsql_test rtree9-3.1 {
CREATE VIRTUAL TABLE rt32 USING rtree_i32(id, x1, x2, y1, y2, z1, z2);
} {}
for {set i 0} {$i < 1000} {incr i} {
set x [expr $i%10]
set y [expr ($i/10)%10]
set z [expr ($i/100)%10]
execsql { INSERT INTO rt32 VALUES($i, $x, $x+1, $y, $y+1, $z, $z+1) }
}
do_execsql_test rtree9-3.2 {
SELECT id FROM rt32 WHERE id MATCH cube(3, 3, 3, 1, 1, 1) ORDER BY id;
} {222 223 224 232 233 234 242 243 244 322 323 324 332 333 334 342 343 344 422 423 424 432 433 434 442 443 444}
do_execsql_test rtree9-3.3 {
SELECT id FROM rt32 WHERE id MATCH cube(5.5, 5.5, 5.5, 1, 1, 1) ORDER BY id;
} {555 556 565 566 655 656 665 666}
do_catchsql_test rtree9-4.1 {
SELECT id FROM rt32 WHERE id MATCH cube(5.5, 5.5, 1, 1, 1) ORDER BY id;
} {1 {SQL logic error or missing database}}
for {set x 2} {$x<200} {incr x 2} {
do_catchsql_test rtree9-4.2.[expr $x/2] {
SELECT id FROM rt WHERE id MATCH randomblob($x)
} {1 {SQL logic error or missing database}}
}
do_catchsql_test rtree9-4.3 {
SELECT id FROM rt WHERE id MATCH CAST(
(cube(5.5, 5.5, 5.5, 1, 1, 1) || X'1234567812345678') AS blob
)
} {1 {SQL logic error or missing database}} } {1 {SQL logic error or missing database}}

View File

@ -1,8 +1,5 @@
-----BEGIN PGP SIGNED MESSAGE----- C Add\stests\s(and\sassociated\sfixes)\sto\srestore\scoverage\sof\srtree.c.
Hash: SHA1 D 2010-08-30T15:43:45
C Remove\sthe\ssqlite3BtreeFactor()\swrapper\sroutine.\s\sAll\smodules\snow\scall\nsqlite3BtreeOpen()\sdirectly.
D 2010-08-30T15:02:28
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -81,17 +78,17 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c 850e9a36567bbcce6bd85a4b68243cad8e3c2de2 F ext/icu/icu.c 850e9a36567bbcce6bd85a4b68243cad8e3c2de2
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c d1a00cf3105c9bfd5c83148aaa4d01373a926ea8 F ext/rtree/rtree.c 2d86907e9b80204530a68f73e1c9368ea87cf603
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test dbd4250ac0ad367a262eb9676f7e3080b0368206 F ext/rtree/rtree1.test dbd4250ac0ad367a262eb9676f7e3080b0368206
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
F ext/rtree/rtree3.test deafc076f639b824466e9f82b39f1601b86dca8e F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc
F ext/rtree/rtree4.test 0061e6f464fd3dc6a79f82454c5a1c3dadbe42af F ext/rtree/rtree4.test 0061e6f464fd3dc6a79f82454c5a1c3dadbe42af
F ext/rtree/rtree5.test ce3d7ccae2cfd9d2e1052b462424964c9bdcda12 F ext/rtree/rtree5.test ce3d7ccae2cfd9d2e1052b462424964c9bdcda12
F ext/rtree/rtree6.test 1ebe0d632a7501cc80ba5a225f028fd4f0fdda08 F ext/rtree/rtree6.test 1ebe0d632a7501cc80ba5a225f028fd4f0fdda08
F ext/rtree/rtree7.test bcb647b42920b3b5d025846689147778485cc318 F ext/rtree/rtree7.test bcb647b42920b3b5d025846689147778485cc318
F ext/rtree/rtree8.test 67c5a03476bb729853ce01ad3828a290bf65eade F ext/rtree/rtree8.test 9772e16da71e17e02bdebf0a5188590f289ab37d
F ext/rtree/rtree9.test 16775c219f0e134471c08a9bb0c3902e75ccb4c6 F ext/rtree/rtree9.test c3ab7efd3617bc4d3da1d96265fdb8a28e5a3d55
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/sqlite3rtree.h 24ded963afda4658cb25a6df4a26efada6204931 F ext/rtree/sqlite3rtree.h 24ded963afda4658cb25a6df4a26efada6204931
@ -211,7 +208,7 @@ F src/test_mutex.c ce06b59aca168cd8c520b77159a24352a7469bd3
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c F src/test_osinst.c f408c6a181f2fb04c56273afd5c3e1e82f60392c
F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8 F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8
F src/test_rtree.c b15a04974186c95ce7245c47d255745121a3286c F src/test_rtree.c a65ca2727c4421f88745dbcc1589ed57276cbb29
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6 F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
F src/test_stat.c f682704b5d1ba8e1d4e7e882a6d7922e2dcf066c F src/test_stat.c f682704b5d1ba8e1d4e7e882a6d7922e2dcf066c
@ -522,7 +519,7 @@ F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb
F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6 F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9 F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9
F test/malloc_common.tcl f4a04b7a733eb114a3da16eb39035cde2c851220 F test/malloc_common.tcl 9b032b2e9172952400be0910d28f1852d5ca1ed1
F test/manydb.test b3d3bc4c25657e7f68d157f031eb4db7b3df0d3c F test/manydb.test b3d3bc4c25657e7f68d157f031eb4db7b3df0d3c
F test/memdb.test 0825155b2290e900264daaaf0334b6dfe69ea498 F test/memdb.test 0825155b2290e900264daaaf0334b6dfe69ea498
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
@ -854,14 +851,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 e1d9ffce0f84469eeb926f50030cb772de98a652 P 0900e35348f4b9bf327d6ae2884c4ddbb6345d8d
R 99f4f04eb0dcfec0215716e50e02a75e R 5dbb020f6f5e802e1badc005581d22db
U drh U dan
Z a752751947895d70480e177dc60c591f Z cbfd87679baec03266025e286025f2d7
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFMe8gHoxKgR168RlERAnuLAJ9JSs0qOCrqjvxSkefDBsw2AGGZOgCdH9Un
dPEOapTn9xdx/Z8zc48MPzw=
=5nXZ
-----END PGP SIGNATURE-----

View File

@ -1 +1 @@
0900e35348f4b9bf327d6ae2884c4ddbb6345d8d b06f4695bdab244d9c764c082cd434a764dc5c29

View File

@ -31,6 +31,11 @@ static void cube_context_free(void *p){
sqlite3_free(p); sqlite3_free(p);
} }
/*
** The context pointer registered along with the 'cube' callback is
** always ((void *)&gHere). This is just to facilitate testing, it is not
** actually used for anything.
*/
static int gHere = 42; static int gHere = 42;
/* /*
@ -96,14 +101,17 @@ static int register_cube_geom(
){ ){
#ifdef SQLITE_ENABLE_RTREE #ifdef SQLITE_ENABLE_RTREE
extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
extern const char *sqlite3TestErrorName(int);
sqlite3 *db; sqlite3 *db;
int rc;
if( objc!=2 ){ if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "DB"); Tcl_WrongNumArgs(interp, 1, objv, "DB");
return TCL_ERROR; return TCL_ERROR;
} }
if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
sqlite3_rtree_geometry_callback(db, "cube", cube_geom, (void *)&gHere); rc = sqlite3_rtree_geometry_callback(db, "cube", cube_geom, (void *)&gHere);
Tcl_SetResult(interp, sqlite3TestErrorName(rc), TCL_STATIC);
#endif #endif
return TCL_OK; return TCL_OK;
} }

View File

@ -185,7 +185,7 @@ proc faultsim_delete_and_reopen {{file test.db}} {
# injecting OOM faults into test cases. # injecting OOM faults into test cases.
# #
proc oom_injectstart {nRepeat iFail} { proc oom_injectstart {nRepeat iFail} {
sqlite3_memdebug_fail $iFail -repeat $nRepeat sqlite3_memdebug_fail [expr $iFail-1] -repeat $nRepeat
} }
proc oom_injectstop {} { proc oom_injectstop {} {
sqlite3_memdebug_fail -1 sqlite3_memdebug_fail -1