1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

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;
/* 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. */
nBlob = sqlite3_value_bytes(pValue);
if( nBlob<sizeof(RtreeGeomBlob)
|| ((nBlob-sizeof(RtreeGeomBlob))%sizeof(double))!=0
){
return SQLITE_MISUSE;
return SQLITE_ERROR;
}
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
|| nBlob!=(sizeof(RtreeGeomBlob) + (p->nParam-1)*sizeof(double))
){
sqlite3_free(p);
return SQLITE_MISUSE;
sqlite3_free(pGeom);
return SQLITE_ERROR;
}
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) ){
int j, opmsk;
static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
u8 op = 0;
switch( p->op ){
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_LT: op = RTREE_LT; 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 ){
/* 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 < 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.
*/
int j, opmsk;
static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
assert( compatible[RTREE_EQ & 7]==0 );
assert( compatible[RTREE_LT & 7]==1 );
assert( compatible[RTREE_LE & 7]==1 );
assert( compatible[RTREE_GT & 7]==2 );
assert( compatible[RTREE_GE & 7]==2 );
cCol = p->iColumn - 1 + 'a';
opmsk = compatible[op & 7];
for(j=0; j<iIdx; j+=2){
if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
op = 0;
break;
}
assert( op!=0 );
/* 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 < 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.
*/
assert( compatible[RTREE_EQ & 7]==0 );
assert( compatible[RTREE_LT & 7]==1 );
assert( compatible[RTREE_LE & 7]==1 );
assert( compatible[RTREE_GT & 7]==2 );
assert( compatible[RTREE_GE & 7]==2 );
cCol = p->iColumn - 1 + 'a';
opmsk = compatible[op & 7];
for(j=0; j<iIdx; j+=2){
if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
op = 0;
break;
}
}
if( op ){

View File

@ -206,4 +206,32 @@ do_faultsim_test rtree3-8 -faults oom-* -prep {
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

View File

@ -129,7 +129,7 @@ do_execsql_test rtree8-2.2.3 {
populate_t1 10
do_catchsql_test rtree8-3.1 {
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().

View File

@ -32,13 +32,13 @@ do_execsql_test rtree9-1.4 {
DELETE FROM rt;
} {}
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 rt VALUES($i, $x, $x+1, $y, $y+1, $z, $z+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;
} {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;
} {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}}