mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
Enhance the RTREE extension so that it give correct query results even if
the query uses non-numeric constraints. Ticket [a55ab6d97d01ecbc] FossilOrigin-Name: f898d04cf272ef0130dcae146cb86d8630b10a6f19aecfc2fa70e97e082bd51c
This commit is contained in:
@ -325,6 +325,12 @@ struct RtreeConstraint {
|
||||
#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */
|
||||
#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */
|
||||
|
||||
/* Special operators available only on cursors. Needs to be consecutive
|
||||
** with the normal values above, but must be less than RTREE_MATCH. These
|
||||
** are used in the cursor for contraints such as x=NULL (RTREE_FALSE) or
|
||||
** x<'xyz' (RTREE_TRUE) */
|
||||
#define RTREE_TRUE 0x3f /* ? */
|
||||
#define RTREE_FALSE 0x40 /* @ */
|
||||
|
||||
/*
|
||||
** An rtree structure node.
|
||||
@ -1244,9 +1250,12 @@ static void rtreeNonleafConstraint(
|
||||
pCellData += 8 + 4*(p->iCoord&0xfe);
|
||||
|
||||
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
|
||||
|| p->op==RTREE_GT || p->op==RTREE_EQ );
|
||||
|| p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
|
||||
|| p->op==RTREE_FALSE );
|
||||
assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
|
||||
switch( p->op ){
|
||||
case RTREE_TRUE: return; /* Always satisfied */
|
||||
case RTREE_FALSE: break; /* Never satisfied */
|
||||
case RTREE_LE:
|
||||
case RTREE_LT:
|
||||
case RTREE_EQ:
|
||||
@ -1284,16 +1293,19 @@ static void rtreeLeafConstraint(
|
||||
RtreeDValue xN; /* Coordinate value converted to a double */
|
||||
|
||||
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
|
||||
|| p->op==RTREE_GT || p->op==RTREE_EQ );
|
||||
|| p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
|
||||
|| p->op==RTREE_FALSE );
|
||||
pCellData += 8 + p->iCoord*4;
|
||||
assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
|
||||
RTREE_DECODE_COORD(eInt, pCellData, xN);
|
||||
switch( p->op ){
|
||||
case RTREE_LE: if( xN <= p->u.rValue ) return; break;
|
||||
case RTREE_LT: if( xN < p->u.rValue ) return; break;
|
||||
case RTREE_GE: if( xN >= p->u.rValue ) return; break;
|
||||
case RTREE_GT: if( xN > p->u.rValue ) return; break;
|
||||
default: if( xN == p->u.rValue ) return; break;
|
||||
case RTREE_TRUE: return; /* Always satisfied */
|
||||
case RTREE_FALSE: break; /* Never satisfied */
|
||||
case RTREE_LE: if( xN <= p->u.rValue ) return; break;
|
||||
case RTREE_LT: if( xN < p->u.rValue ) return; break;
|
||||
case RTREE_GE: if( xN >= p->u.rValue ) return; break;
|
||||
case RTREE_GT: if( xN > p->u.rValue ) return; break;
|
||||
default: if( xN == p->u.rValue ) return; break;
|
||||
}
|
||||
*peWithin = NOT_WITHIN;
|
||||
}
|
||||
@ -1835,6 +1847,7 @@ static int rtreeFilter(
|
||||
|| (idxStr && (int)strlen(idxStr)==argc*2) );
|
||||
for(ii=0; ii<argc; ii++){
|
||||
RtreeConstraint *p = &pCsr->aConstraint[ii];
|
||||
int eType = sqlite3_value_type(argv[ii]);
|
||||
p->op = idxStr[ii*2];
|
||||
p->iCoord = idxStr[ii*2+1]-'0';
|
||||
if( p->op>=RTREE_MATCH ){
|
||||
@ -1849,12 +1862,21 @@ static int rtreeFilter(
|
||||
p->pInfo->nCoord = pRtree->nDim2;
|
||||
p->pInfo->anQueue = pCsr->anQueue;
|
||||
p->pInfo->mxLevel = pRtree->iDepth + 1;
|
||||
}else{
|
||||
}else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
|
||||
#ifdef SQLITE_RTREE_INT_ONLY
|
||||
p->u.rValue = sqlite3_value_int64(argv[ii]);
|
||||
#else
|
||||
p->u.rValue = sqlite3_value_double(argv[ii]);
|
||||
#endif
|
||||
}else{
|
||||
p->u.rValue = RTREE_ZERO;
|
||||
if( eType==SQLITE_NULL ){
|
||||
p->op = RTREE_FALSE;
|
||||
}else if( p->op==RTREE_LT || p->op==RTREE_LE ){
|
||||
p->op = RTREE_TRUE;
|
||||
}else{
|
||||
p->op = RTREE_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,13 +374,36 @@ do_test rtree-8.1.1 {
|
||||
INSERT INTO t6 VALUES(2, 4, 6);
|
||||
}
|
||||
} {}
|
||||
do_test rtree-8.1.2 { execsql { SELECT ii FROM t6 WHERE x1>2 } } {1 2}
|
||||
do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } } {2}
|
||||
do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } } {}
|
||||
do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } } {}
|
||||
do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1<3 } } {}
|
||||
do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1<4 } } {1}
|
||||
do_test rtree-8.1.8 { execsql { SELECT ii FROM t6 WHERE x1<5 } } {1 2}
|
||||
do_test rtree-8.1.2 { execsql { SELECT ii FROM t6 WHERE x1>2 } } {1 2}
|
||||
do_test rtree-8.1.3 { execsql { SELECT ii FROM t6 WHERE x1>3 } } {2}
|
||||
do_test rtree-8.1.4 { execsql { SELECT ii FROM t6 WHERE x1>4 } } {}
|
||||
do_test rtree-8.1.5 { execsql { SELECT ii FROM t6 WHERE x1>5 } } {}
|
||||
do_test rtree-8.1.6 { execsql { SELECT ii FROM t6 WHERE x1>''} } {}
|
||||
do_test rtree-8.1.7 { execsql { SELECT ii FROM t6 WHERE x1>null}} {}
|
||||
do_test rtree-8.2.2 { execsql { SELECT ii FROM t6 WHERE x1>=2 } } {1 2}
|
||||
do_test rtree-8.2.3 { execsql { SELECT ii FROM t6 WHERE x1>=3 } } {1 2}
|
||||
do_test rtree-8.2.4 { execsql { SELECT ii FROM t6 WHERE x1>=4 } } {2}
|
||||
do_test rtree-8.2.5 { execsql { SELECT ii FROM t6 WHERE x1>=5 } } {}
|
||||
do_test rtree-8.2.6 { execsql { SELECT ii FROM t6 WHERE x1>=''} } {}
|
||||
do_test rtree-8.2.7 { execsql { SELECT ii FROM t6 WHERE x1>=null}} {}
|
||||
do_test rtree-8.3.2 { execsql { SELECT ii FROM t6 WHERE x1<2 } } {}
|
||||
do_test rtree-8.3.3 { execsql { SELECT ii FROM t6 WHERE x1<3 } } {}
|
||||
do_test rtree-8.3.4 { execsql { SELECT ii FROM t6 WHERE x1<4 } } {1}
|
||||
do_test rtree-8.3.5 { execsql { SELECT ii FROM t6 WHERE x1<5 } } {1 2}
|
||||
do_test rtree-8.3.6 { execsql { SELECT ii FROM t6 WHERE x1<''} } {1 2}
|
||||
do_test rtree-8.3.7 { execsql { SELECT ii FROM t6 WHERE x1<null}} {}
|
||||
do_test rtree-8.4.2 { execsql { SELECT ii FROM t6 WHERE x1<=2 } } {}
|
||||
do_test rtree-8.4.3 { execsql { SELECT ii FROM t6 WHERE x1<=3 } } {1}
|
||||
do_test rtree-8.4.4 { execsql { SELECT ii FROM t6 WHERE x1<=4 } } {1 2}
|
||||
do_test rtree-8.4.5 { execsql { SELECT ii FROM t6 WHERE x1<=5 } } {1 2}
|
||||
do_test rtree-8.4.6 { execsql { SELECT ii FROM t6 WHERE x1<=''} } {1 2}
|
||||
do_test rtree-8.4.7 { execsql { SELECT ii FROM t6 WHERE x1<=null}} {}
|
||||
do_test rtree-8.5.2 { execsql { SELECT ii FROM t6 WHERE x1=2 } } {}
|
||||
do_test rtree-8.5.3 { execsql { SELECT ii FROM t6 WHERE x1=3 } } {1}
|
||||
do_test rtree-8.5.4 { execsql { SELECT ii FROM t6 WHERE x1=4 } } {2}
|
||||
do_test rtree-8.5.5 { execsql { SELECT ii FROM t6 WHERE x1=5 } } {}
|
||||
do_test rtree-8.5.6 { execsql { SELECT ii FROM t6 WHERE x1=''} } {}
|
||||
do_test rtree-8.5.7 { execsql { SELECT ii FROM t6 WHERE x1=null}} {}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Test cases rtree-9.*
|
||||
|
Reference in New Issue
Block a user