Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Unified Diff: third_party/sqlite/src/ext/rtree/rtree.c

Issue 1610963002: Import SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/sqlite/src/ext/rbu/test_rbu.c ('k') | third_party/sqlite/src/ext/rtree/rtree1.test » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/sqlite/src/ext/rtree/rtree.c
diff --git a/third_party/sqlite/src/ext/rtree/rtree.c b/third_party/sqlite/src/ext/rtree/rtree.c
index 8150538d452d1b31ebc91b54b5fcb3e6dad8f3aa..4e473a22c28a45fd0a2ad9df0099b40c99397197 100644
--- a/third_party/sqlite/src/ext/rtree/rtree.c
+++ b/third_party/sqlite/src/ext/rtree/rtree.c
@@ -351,6 +351,7 @@ struct RtreeMatchArg {
u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
RtreeGeomCallback cb; /* Info about the callback functions */
int nParam; /* Number of parameters to the SQL function */
+ sqlite3_value **apSqlParam; /* Original SQL parameter values */
RtreeDValue aParam[1]; /* Values for parameters to the SQL function */
};
@@ -369,13 +370,12 @@ static int readInt16(u8 *p){
return (p[0]<<8) + p[1];
}
static void readCoord(u8 *p, RtreeCoord *pCoord){
- u32 i = (
+ pCoord->u = (
(((u32)p[0]) << 24) +
(((u32)p[1]) << 16) +
(((u32)p[2]) << 8) +
(((u32)p[3]) << 0)
);
- *(u32 *)pCoord = i;
}
static i64 readInt64(u8 *p){
return (
@@ -404,7 +404,7 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){
u32 i;
assert( sizeof(RtreeCoord)==4 );
assert( sizeof(u32)==4 );
- i = *(u32 *)pCoord;
+ i = pCoord->u;
p[0] = (i>>24)&0xFF;
p[1] = (i>>16)&0xFF;
p[2] = (i>> 8)&0xFF;
@@ -735,14 +735,13 @@ static void nodeGetCell(
RtreeCell *pCell /* OUT: Write the cell contents here */
){
u8 *pData;
- u8 *pEnd;
RtreeCoord *pCoord;
+ int ii;
pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
- pEnd = pData + pRtree->nDim*8;
pCoord = pCell->aCoord;
- for(; pData<pEnd; pData+=4, pCoord++){
- readCoord(pData, pCoord);
+ for(ii=0; ii<pRtree->nDim*2; ii++){
+ readCoord(&pData[ii*4], &pCoord[ii]);
}
}
@@ -1182,7 +1181,7 @@ static RtreeSearchPoint *rtreeEnqueue(
pNew = pCur->aPoint + i;
pNew->rScore = rScore;
pNew->iLevel = iLevel;
- assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH );
+ assert( iLevel<=RTREE_MAX_DEPTH );
while( i>0 ){
RtreeSearchPoint *pParent;
j = (i-1)/2;
@@ -1484,9 +1483,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
/* Check that the blob is roughly the right size. */
nBlob = sqlite3_value_bytes(pValue);
- if( nBlob<(int)sizeof(RtreeMatchArg)
- || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
- ){
+ if( nBlob<(int)sizeof(RtreeMatchArg) ){
return SQLITE_ERROR;
}
@@ -1497,6 +1494,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
nExpected = (int)(sizeof(RtreeMatchArg) +
+ pBlob->nParam*sizeof(sqlite3_value*) +
(pBlob->nParam-1)*sizeof(RtreeDValue));
if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
sqlite3_free(pInfo);
@@ -1505,6 +1503,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
pInfo->pContext = pBlob->cb.pContext;
pInfo->nParam = pBlob->nParam;
pInfo->aParam = pBlob->aParam;
+ pInfo->apSqlParam = pBlob->apSqlParam;
if( pBlob->cb.xGeom ){
pCons->u.xGeom = pBlob->cb.xGeom;
@@ -1671,17 +1670,30 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
Rtree *pRtree = (Rtree*)tab;
int rc = SQLITE_OK;
int ii;
+ int bMatch = 0; /* True if there exists a MATCH constraint */
i64 nRow; /* Estimated rows returned by this scan */
int iIdx = 0;
char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
memset(zIdxStr, 0, sizeof(zIdxStr));
+ /* Check if there exists a MATCH constraint - even an unusable one. If there
+ ** is, do not consider the lookup-by-rowid plan as using such a plan would
+ ** require the VDBE to evaluate the MATCH constraint, which is not currently
+ ** possible. */
+ for(ii=0; ii<pIdxInfo->nConstraint; ii++){
+ if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){
+ bMatch = 1;
+ }
+ }
+
assert( pIdxInfo->idxStr==0 );
for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
- if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ if( bMatch==0 && p->usable
+ && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ
+ ){
/* We have an equality constraint on the rowid. Use strategy 1. */
int jj;
for(jj=0; jj<ii; jj++){
@@ -2806,6 +2818,8 @@ static int rtreeUpdate(
rtreeReference(pRtree);
assert(nData>=1);
+ cell.iRowid = 0; /* Used only to suppress a compiler warning */
+
/* Constraint handling. A write operation on an r-tree table may return
** SQLITE_CONSTRAINT for two reasons:
**
@@ -2820,11 +2834,19 @@ static int rtreeUpdate(
if( nData>1 ){
int ii;
- /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
- assert( nData==(pRtree->nDim*2 + 3) );
+ /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
+ **
+ ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
+ ** with "column" that are interpreted as table constraints.
+ ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
+ ** This problem was discovered after years of use, so we silently ignore
+ ** these kinds of misdeclared tables to avoid breaking any legacy.
+ */
+ assert( nData<=(pRtree->nDim*2 + 3) );
+
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ for(ii=0; ii<nData-4; ii+=2){
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
@@ -2835,7 +2857,7 @@ static int rtreeUpdate(
}else
#endif
{
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ for(ii=0; ii<nData-4; ii+=2){
cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
@@ -3365,6 +3387,18 @@ static void rtreeFreeCallback(void *p){
}
/*
+** This routine frees the BLOB that is returned by geomCallback().
+*/
+static void rtreeMatchArgFree(void *pArg){
+ int i;
+ RtreeMatchArg *p = (RtreeMatchArg*)pArg;
+ for(i=0; i<p->nParam; i++){
+ sqlite3_value_free(p->apSqlParam[i]);
+ }
+ sqlite3_free(p);
+}
+
+/*
** Each call to sqlite3_rtree_geometry_callback() or
** sqlite3_rtree_query_callback() creates an ordinary SQLite
** scalar function that is implemented by this routine.
@@ -3382,8 +3416,10 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
RtreeMatchArg *pBlob;
int nBlob;
+ int memErr = 0;
- nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
+ nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
+ + nArg*sizeof(sqlite3_value*);
pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
if( !pBlob ){
sqlite3_result_error_nomem(ctx);
@@ -3391,15 +3427,23 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
int i;
pBlob->magic = RTREE_GEOMETRY_MAGIC;
pBlob->cb = pGeomCtx[0];
+ pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
pBlob->nParam = nArg;
for(i=0; i<nArg; i++){
+ pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
+ if( pBlob->apSqlParam[i]==0 ) memErr = 1;
#ifdef SQLITE_RTREE_INT_ONLY
pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
#else
pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
#endif
}
- sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
+ if( memErr ){
+ sqlite3_result_error_nomem(ctx);
+ rtreeMatchArgFree(pBlob);
+ }else{
+ sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
+ }
}
}
« no previous file with comments | « third_party/sqlite/src/ext/rbu/test_rbu.c ('k') | third_party/sqlite/src/ext/rtree/rtree1.test » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698