From: drh Date: Thu, 17 Apr 2014 13:15:33 +0000 (+0000) Subject: Refactor the constraint checking logic in RTree. The new-style constraint X-Git-Tag: version-3.13.0~148^2~145^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=78b486ea1203ce902bb929589024786f681f77a5;p=thirdparty%2Fsqlite.git Refactor the constraint checking logic in RTree. The new-style constraint callbacks created by sqlite3_rtree_query_callback() are now hooked up from end to end, though still untested. FossilOrigin-Name: 32a13870175a1dd1d33af3572dde09ff607a04b6 --- diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 6bf1db11c4..3c9a8daba9 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -274,13 +274,13 @@ struct RtreeConstraint { }; /* Possible values for RtreeConstraint.op */ -#define RTREE_EQ 0x41 -#define RTREE_LE 0x42 -#define RTREE_LT 0x43 -#define RTREE_GE 0x44 -#define RTREE_GT 0x45 -#define RTREE_MATCH 0x46 /* Old-style sqlite3_rtree_geometry_callback() */ -#define RTREE_QUERY 0x47 /* New-style sqlite3_rtree_query_callback() */ +#define RTREE_EQ 0x41 /* A */ +#define RTREE_LE 0x42 /* B */ +#define RTREE_LT 0x43 /* C */ +#define RTREE_GE 0x44 /* D */ +#define RTREE_GT 0x45 /* E */ +#define RTREE_MATCH 0x46 /* F: Old-style sqlite3_rtree_geometry_callback() */ +#define RTREE_QUERY 0x47 /* G: New-style sqlite3_rtree_query_callback() */ /* @@ -900,149 +900,131 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){ } /* -** The r-tree constraint passed as the second argument to this function is -** guaranteed to be a MATCH constraint. +** Convert raw bits from the on-disk RTree record into a coordinate value +** The on-disk record stores integer coordinates if eInt is true and it +** stores 32-bit floating point records if eInt is false. a[] is the four +** bytes of the on-disk record to be decoded. Store the results in "r". */ -static int rtreeTestGeom( - Rtree *pRtree, /* R-Tree object */ - RtreeConstraint *pConstraint, /* MATCH constraint to test */ - RtreeCell *pCell, /* Cell to test */ - int *pbRes /* OUT: Test result */ -){ - int i; - RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2]; - int nCoord = pRtree->nDim*2; - - assert( pConstraint->op==RTREE_MATCH ); - assert( pConstraint->pGeom ); +#define RTREE_DECODE_COORD(eInt, a, r) { \ + u32 x; /* Raw bits of the coordinate value */ \ + RtreeCoord c; /* Coordinate decoded */ \ + x = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ + +((u32)a[2]<<8) + a[3]; \ + c.i = *(int*)&x; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ +} + - for(i=0; iaCoord[i]); +/* +** Check the RTree node or entry given by pCellData and p against the MATCH +** constraint pConstraint. +*/ +static int rtreeCallbackConstraint( + RtreeConstraint *pConstraint, /* The constraint to test */ + int eInt, /* True if RTree holding integer coordinates */ + u8 *pCellData, /* Raw cell content */ + RtreeSearchPoint *pSearch, /* Container of this cell */ + sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ + int *peWithin /* OUT: visibility of the cell */ +){ + int i; /* Loop counter */ + sqlite3_rtree_query_info *pGeom = pConstraint->pGeom; /* Callback info */ + int nCoord = pGeom->nCoord; /* No. of coordinates */ + int rc; /* Callback return code */ + sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ + + assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); + assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); + + pCellData += 8; + for(i=0; iop==RTREE_MATCH ){ + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pGeom, + nCoord, aCoord, &i); + if( i==0 ) *peWithin = NOT_WITHIN; + }else{ + pGeom->aCoord = aCoord; + pGeom->iLevel = pSearch->iLevel; + pGeom->rScore = pGeom->rParentScore = pSearch->rScore; + pGeom->eWithin = pGeom->eParentWithin = pSearch->eWithin; + rc = pConstraint->u.xQueryFunc(pGeom); + if( pGeom->eWithin<*peWithin ) *peWithin = pGeom->eWithin; + if( pGeom->rScore<*prScore ) *prScore = pGeom->rScore; } - return pConstraint->u.xGeom((sqlite3_rtree_geometry*)pConstraint->pGeom, - nCoord, aCoord, pbRes); + return rc; } /* -** Cursor pCursor currently points to a cell in a non-leaf page. -** Set *peWithin to NOT_WITHIN if the constraints in pCursor->aConstraint[] -** are guaranteed to never be satisfied by any subelement under the -** current cell. If some subelement of the cell might satisfy all -** constraints, then set *peWithin to PARTLY_WITHIN. If all subelements -** of the cell are guaranteed to fully satisfy all constraints, then -** set *peWithin to FULLY_WITHIN. -** -** In other words, set *peWithin to NOT_WITHIN, PARTLY_WITHIN, or -** FULLY_WITHIN if the cell is completely outside of the field-of-view, -** overlaps the field of view, or is completely contained within the -** field of view, respectively. -** -** It is not an error to set *peWithin to PARTLY_WITHIN when FULLY_WITHIN -** would be correct. Doing so is suboptimal, but will still give the -** correct answer. -** -** Return SQLITE_OK if successful or an SQLite error code if an error -** occurs. Errors can only possible if there is a geometry callback. -*/ -static int rtreeTestCell( - RtreeCursor *pCursor, /* The cursor to check */ - RtreeCell *pCell, /* The cell to check */ - int *peWithin /* Set true if element is out-of-bounds */ +** Check the internal RTree node given by pCellData against constraint p. +** If this constraint cannot be satisfied by any child within the node, +** set *peWithin to NOT_WITHIN. +*/ +static void rtreeNonleafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ ){ - int ii; - int bOutOfBounds = 0; - int rc = SQLITE_OK; - Rtree *pRtree = RTREE_OF_CURSOR(pCursor); - - for(ii=0; bOutOfBounds==0 && iinConstraint; ii++){ - RtreeConstraint *p = &pCursor->aConstraint[ii]; - RtreeDValue cell_min = DCOORD(pCell->aCoord[(p->iCoord>>1)*2]); - RtreeDValue cell_max = DCOORD(pCell->aCoord[(p->iCoord>>1)*2+1]); - - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH - ); - - switch( p->op ){ - case RTREE_LE: case RTREE_LT: - bOutOfBounds = p->u.rValueu.rValue>cell_max; - break; + /* p->iCoord might point to either a lower or upper bound coordinate + ** in a coordinate pair. But make pCellData point to the lower bound. + */ + pCellData += 8 + 4*(p->iCoord&0xfe); - case RTREE_EQ: - bOutOfBounds = (p->u.rValue>cell_max || p->u.rValueop==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ ); + switch( p->op ){ + case RTREE_LE: + case RTREE_LT: + case RTREE_EQ: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ) return; + if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */ + /* Fall through for the RTREE_EQ case */ - default: { - assert( p->op==RTREE_MATCH ); - rc = rtreeTestGeom(pRtree, p, pCell, &bOutOfBounds); - bOutOfBounds = !bOutOfBounds; - break; - } - } + default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */ + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; } - - *peWithin = bOutOfBounds ? NOT_WITHIN : PARTLY_WITHIN; - return rc; + *peWithin = NOT_WITHIN; } -/* -** pCursor points to a leaf r-tree entry which is a candidate for output. -** This routine sets *peWithin to one of NOT_WITHIN, PARTLY_WITHIN, or -** FULLY_WITHIN depending on whether or not the leaf entry is completely -** outside the region defined by pCursor->aConstraints[], or overlaps the -** region, or is completely within the region, respectively. -** -** This routine is more selective than rtreeTestCell(). rtreeTestCell() -** will return PARTLY_WITHIN or FULLY_WITHIN if the constraints are such -** that a subelement of the cell to be included in the result set. This -** routine is is only called for leaf r-tree entries and does not need -** to concern itself with subelements. Hence it only sets *peWithin to -** PARTLY_WITHIN or FULLY_WITHIN if the cell itself meets the requirements. +/* +** Check the leaf RTree cell given by pCellData against constraint p. +** If this constraint is not satisfied, set *peWithin to NOT_WITHIN. +** If the constraint is satisfied, leave *peWithin unchanged. ** -** Return SQLITE_OK if successful or an SQLite error code if an error -** occurs within a geometry callback. +** The constraint is of the form: xN op $val ** -** This function assumes that the cell is part of a leaf node. -*/ -static int rtreeTestEntry( - RtreeCursor *pCursor, /* Cursor pointing to the leaf element */ - RtreeCell *pCell, /* The cell to check */ - int *peWithin /* OUT: NOT_WITHIN, PARTLY_WITHIN, or FULLY_WITHIN */ +** The op is given by p->op. The xN is p->iCoord-th coordinate in +** pCellData. $val is given by p->u.rValue. +*/ +static void rtreeLeafConstraint( + RtreeConstraint *p, /* The constraint to test */ + int eInt, /* True if RTree holds integer coordinates */ + u8 *pCellData, /* Raw cell content as appears on disk */ + int *peWithin /* Adjust downward, as appropriate */ ){ - Rtree *pRtree = RTREE_OF_CURSOR(pCursor); - int ii; - int res = 1; /* Innocent until proven guilty */ + RtreeDValue xN; /* Coordinate value converted to a double */ - for(ii=0; res && iinConstraint; ii++){ - RtreeConstraint *p = &pCursor->aConstraint[ii]; - RtreeDValue coord = DCOORD(pCell->aCoord[p->iCoord]); - assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE - || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH - ); - switch( p->op ){ - case RTREE_LE: res = (coord<=p->u.rValue); break; - case RTREE_LT: res = (coordu.rValue); break; - case RTREE_GE: res = (coord>=p->u.rValue); break; - case RTREE_GT: res = (coord>p->u.rValue); break; - case RTREE_EQ: res = (coord==p->u.rValue); break; - default: { - int rc; - assert( p->op==RTREE_MATCH ); - rc = rtreeTestGeom(pRtree, p, pCell, &res); - if( rc!=SQLITE_OK ){ - return rc; - } - break; - } - } + assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE + || p->op==RTREE_GT || p->op==RTREE_EQ ); + pCellData += 8 + p->iCoord*4; + 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; } - - *peWithin = res ? FULLY_WITHIN : NOT_WITHIN; - return SQLITE_OK; + *peWithin = NOT_WITHIN; } /* @@ -1295,39 +1277,53 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){ int eWithin; int rc = SQLITE_OK; int nCell; - RtreeCell cell; + int nConstraint = pCur->nConstraint; + int ii; + int eInt; RtreeSearchPoint x; + eInt = pRtree->eCoordType==RTREE_COORD_INT32; while( (p = rtreeSearchPointFirst(pCur))!=0 && p->iLevel>0 ){ pNode = rtreeNodeOfFirstSearchPoint(pCur, &rc); if( rc ) return rc; nCell = NCELL(pNode); assert( nCell<200 ); while( p->iCelliCell, &cell); - if( p->iLevel==1 ){ - rc = rtreeTestEntry(pCur, &cell, &eWithin); - }else{ - rc = rtreeTestCell(pCur, &cell, &eWithin); + sqlite3_rtree_dbl rScore = (sqlite3_rtree_dbl)0; + u8 *pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); + eWithin = FULLY_WITHIN; + for(ii=0; iiaConstraint + ii; + if( pConstraint->op>=RTREE_MATCH ){ + rc = rtreeCallbackConstraint(pConstraint, eInt, pCellData, p, + &rScore, &eWithin); + if( rc ) return rc; + }else if( p->iLevel==1 ){ + rtreeLeafConstraint(pConstraint, eInt, pCellData, &eWithin); + }else{ + rtreeNonleafConstraint(pConstraint, eInt, pCellData, &eWithin); + } + if( eWithin==NOT_WITHIN ) break; } - if( rc ) return rc; - x = *p; p->iCell++; if( eWithin==NOT_WITHIN ) continue; + x.iLevel = p->iLevel - 1; + if( x.iLevel ){ + x.id = readInt64(pCellData); + x.iCell = 0; + }else{ + x.id = p->id; + x.iCell = p->iCell - 1; + } if( p->iCell>=nCell ){ RTREE_QUEUE_TRACE(pCur, "POP-S:"); rtreeSearchPointPop(pCur); } - p = rtreeSearchPointNew(pCur, /*rScore*/0.0, x.iLevel-1); + p = rtreeSearchPointNew(pCur, rScore, x.iLevel); if( p==0 ) return SQLITE_NOMEM; p->eWithin = eWithin; - if( p->iLevel ){ - p->id = cell.iRowid; - p->iCell = 0; - }else{ - p->id = x.id; - p->iCell = x.iCell; - } + p->id = x.id; + p->iCell = x.iCell; RTREE_QUEUE_TRACE(pCur, "PUSH-S:"); break; } @@ -1460,7 +1456,6 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ sqlite3_free(pGeom); return SQLITE_ERROR; } - pGeom->pContext = p->cb.pContext; pGeom->nParam = p->nParam; pGeom->aParam = p->aParam; @@ -1525,7 +1520,7 @@ static int rtreeFilter( for(ii=0; iiaConstraint[ii]; p->op = idxStr[ii*2]; - p->iCoord = idxStr[ii*2+1]-'a'; + p->iCoord = idxStr[ii*2+1]-'0'; if( p->op==RTREE_MATCH ){ /* A MATCH operator. The right-hand-side must be a blob that ** can be cast into an RtreeMatchArg object. One created using @@ -1535,6 +1530,7 @@ static int rtreeFilter( if( rc!=SQLITE_OK ){ break; } + p->pGeom->nCoord = pRtree->nDim*2; }else{ #ifdef SQLITE_RTREE_INT_ONLY p->u.rValue = sqlite3_value_int64(argv[ii]); @@ -1663,7 +1659,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ break; } zIdxStr[iIdx++] = op; - zIdxStr[iIdx++] = p->iColumn - 1 + 'a'; + zIdxStr[iIdx++] = p->iColumn - 1 + '0'; pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); pIdxInfo->aConstraintUsage[ii].omit = 1; } diff --git a/ext/rtree/rtree6.test b/ext/rtree/rtree6.test index bdc9bb4146..c5a78bb3e3 100644 --- a/ext/rtree/rtree6.test +++ b/ext/rtree/rtree6.test @@ -57,31 +57,31 @@ do_test rtree6-1.1 { do_test rtree6-1.2 { rtree_strategy {SELECT * FROM t1 WHERE x1>10} -} {Ea} +} {E0} do_test rtree6-1.3 { rtree_strategy {SELECT * FROM t1 WHERE x1<10} -} {Ca} +} {C0} do_test rtree6-1.4 { rtree_strategy {SELECT * FROM t1,t2 WHERE k=ii AND x1<10} -} {Ca} +} {C0} do_test rtree6-1.5 { rtree_strategy {SELECT * FROM t1,t2 WHERE k=+ii AND x1<10} -} {Ca} +} {C0} do_eqp_test rtree6.2.1 { SELECT * FROM t1,t2 WHERE k=+ii AND x1<10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:Ca} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} 0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} } do_eqp_test rtree6.2.2 { SELECT * FROM t1,t2 WHERE k=ii AND x1<10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:Ca} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0} 0 1 1 {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid=?)} } @@ -95,7 +95,7 @@ do_eqp_test rtree6.2.3 { do_eqp_test rtree6.2.4 { SELECT * FROM t1,t2 WHERE v=10 and x1<10 and x2>10 } { - 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:CaEb} + 0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 2:C0E1} 0 1 1 {SEARCH TABLE t2 USING AUTOMATIC COVERING INDEX (v=?)} } @@ -126,7 +126,7 @@ do_test rtree6.3.2 { x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 } -} {EaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa} +} {E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0} do_test rtree6.3.3 { rtree_strategy { SELECT * FROM t3 WHERE @@ -137,7 +137,7 @@ do_test rtree6.3.3 { x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 AND x1>0.5 } -} {EaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEaEa} +} {E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0E0} do_execsql_test rtree6-3.4 { SELECT * FROM t3 WHERE x1>0.5 AND x1>0.8 AND x1>1.1 diff --git a/ext/rtree/rtreeC.test b/ext/rtree/rtreeC.test index 23dc607841..94db05a4d1 100644 --- a/ext/rtree/rtreeC.test +++ b/ext/rtree/rtreeC.test @@ -29,7 +29,7 @@ do_eqp_test 1.1 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 1 {SCAN TABLE t} - 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 1.2 { @@ -37,7 +37,7 @@ do_eqp_test 1.2 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 1.3 { @@ -45,7 +45,7 @@ do_eqp_test 1.3 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 1.5 { @@ -82,7 +82,7 @@ do_eqp_test 2.1 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 1 {SCAN TABLE t} - 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 0 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 2.2 { @@ -90,7 +90,7 @@ do_eqp_test 2.2 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND t.x<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 2.3 { @@ -98,7 +98,7 @@ do_eqp_test 2.3 { WHERE t.x>=min_x AND t.x<=max_x AND t.y>=min_y AND ?<=max_y } { 0 0 0 {SCAN TABLE t} - 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:DdBcDbBa} + 0 1 1 {SCAN TABLE r_tree VIRTUAL TABLE INDEX 2:D3B2D1B0} } do_eqp_test 2.5 { @@ -271,4 +271,3 @@ ifcapable rtree { finish_test - diff --git a/manifest b/manifest index 336104aca0..d10804afcb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\son\snodeGetCell()\sin\sR-Tree. -D 2014-04-16T21:02:28.844 +C Refactor\sthe\sconstraint\schecking\slogic\sin\sRTree.\s\sThe\snew-style\sconstraint\ncallbacks\screated\sby\ssqlite3_rtree_query_callback()\sare\snow\shooked\sup\sfrom\nend\sto\send,\sthough\sstill\suntested. +D 2014-04-17T13:15:33.281 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e4ee6d36cdf6136aee0158675a3b24dd3bf31a5a F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -120,20 +120,20 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 1a59db351a8dfaa46c59b3105865a1aaa5192a61 +F ext/rtree/rtree.c 117aaebed87a7c1e5d3e03afbad83c3700aa5ab8 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test cf679265ecafff494a768ac9c2f43a70915a6290 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 F ext/rtree/rtree5.test 6a510494f12454bf57ef28f45bc7764ea279431e -F ext/rtree/rtree6.test fe0bd377a21c68ce2826129d14354c884cb1f354 +F ext/rtree/rtree6.test 756585abc51727fec97c77852476445c10c0ee95 F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971 F ext/rtree/rtree8.test db79c812f9e4a11f9b1f3f9934007884610a713a F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34 F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e -F ext/rtree/rtreeC.test 16d7aa86ecb6a876d2a38cf590a1471a41b3a46d +F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06 F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea @@ -1175,7 +1175,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f26936f71a16ab25590540f7feb273514dfb69ff -R b2b62cbe51f5e73202ce646c31659a05 +P 5d20ff9ec837ad35bc44d6c25d13764b350e81dd +R 9ddd572c495f4e9fca0e8e969ae19d88 U drh -Z 74eaec9038e9087250153055260f329f +Z 43698a2882be63e69b530e3c48875378 diff --git a/manifest.uuid b/manifest.uuid index a27b70bb21..5fbbb6cae9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d20ff9ec837ad35bc44d6c25d13764b350e81dd \ No newline at end of file +32a13870175a1dd1d33af3572dde09ff607a04b6 \ No newline at end of file