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

Side by Side 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** 2001 September 15 2 ** 2001 September 15
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 /* 344 /*
345 ** An instance of this structure (in the form of a BLOB) is returned by 345 ** An instance of this structure (in the form of a BLOB) is returned by
346 ** the SQL functions that sqlite3_rtree_geometry_callback() and 346 ** the SQL functions that sqlite3_rtree_geometry_callback() and
347 ** sqlite3_rtree_query_callback() create, and is read as the right-hand 347 ** sqlite3_rtree_query_callback() create, and is read as the right-hand
348 ** operand to the MATCH operator of an R-Tree. 348 ** operand to the MATCH operator of an R-Tree.
349 */ 349 */
350 struct RtreeMatchArg { 350 struct RtreeMatchArg {
351 u32 magic; /* Always RTREE_GEOMETRY_MAGIC */ 351 u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
352 RtreeGeomCallback cb; /* Info about the callback functions */ 352 RtreeGeomCallback cb; /* Info about the callback functions */
353 int nParam; /* Number of parameters to the SQL function */ 353 int nParam; /* Number of parameters to the SQL function */
354 sqlite3_value **apSqlParam; /* Original SQL parameter values */
354 RtreeDValue aParam[1]; /* Values for parameters to the SQL function */ 355 RtreeDValue aParam[1]; /* Values for parameters to the SQL function */
355 }; 356 };
356 357
357 #ifndef MAX 358 #ifndef MAX
358 # define MAX(x,y) ((x) < (y) ? (y) : (x)) 359 # define MAX(x,y) ((x) < (y) ? (y) : (x))
359 #endif 360 #endif
360 #ifndef MIN 361 #ifndef MIN
361 # define MIN(x,y) ((x) > (y) ? (y) : (x)) 362 # define MIN(x,y) ((x) > (y) ? (y) : (x))
362 #endif 363 #endif
363 364
364 /* 365 /*
365 ** Functions to deserialize a 16 bit integer, 32 bit real number and 366 ** Functions to deserialize a 16 bit integer, 32 bit real number and
366 ** 64 bit integer. The deserialized value is returned. 367 ** 64 bit integer. The deserialized value is returned.
367 */ 368 */
368 static int readInt16(u8 *p){ 369 static int readInt16(u8 *p){
369 return (p[0]<<8) + p[1]; 370 return (p[0]<<8) + p[1];
370 } 371 }
371 static void readCoord(u8 *p, RtreeCoord *pCoord){ 372 static void readCoord(u8 *p, RtreeCoord *pCoord){
372 u32 i = ( 373 pCoord->u = (
373 (((u32)p[0]) << 24) + 374 (((u32)p[0]) << 24) +
374 (((u32)p[1]) << 16) + 375 (((u32)p[1]) << 16) +
375 (((u32)p[2]) << 8) + 376 (((u32)p[2]) << 8) +
376 (((u32)p[3]) << 0) 377 (((u32)p[3]) << 0)
377 ); 378 );
378 *(u32 *)pCoord = i;
379 } 379 }
380 static i64 readInt64(u8 *p){ 380 static i64 readInt64(u8 *p){
381 return ( 381 return (
382 (((i64)p[0]) << 56) + 382 (((i64)p[0]) << 56) +
383 (((i64)p[1]) << 48) + 383 (((i64)p[1]) << 48) +
384 (((i64)p[2]) << 40) + 384 (((i64)p[2]) << 40) +
385 (((i64)p[3]) << 32) + 385 (((i64)p[3]) << 32) +
386 (((i64)p[4]) << 24) + 386 (((i64)p[4]) << 24) +
387 (((i64)p[5]) << 16) + 387 (((i64)p[5]) << 16) +
388 (((i64)p[6]) << 8) + 388 (((i64)p[6]) << 8) +
389 (((i64)p[7]) << 0) 389 (((i64)p[7]) << 0)
390 ); 390 );
391 } 391 }
392 392
393 /* 393 /*
394 ** Functions to serialize a 16 bit integer, 32 bit real number and 394 ** Functions to serialize a 16 bit integer, 32 bit real number and
395 ** 64 bit integer. The value returned is the number of bytes written 395 ** 64 bit integer. The value returned is the number of bytes written
396 ** to the argument buffer (always 2, 4 and 8 respectively). 396 ** to the argument buffer (always 2, 4 and 8 respectively).
397 */ 397 */
398 static int writeInt16(u8 *p, int i){ 398 static int writeInt16(u8 *p, int i){
399 p[0] = (i>> 8)&0xFF; 399 p[0] = (i>> 8)&0xFF;
400 p[1] = (i>> 0)&0xFF; 400 p[1] = (i>> 0)&0xFF;
401 return 2; 401 return 2;
402 } 402 }
403 static int writeCoord(u8 *p, RtreeCoord *pCoord){ 403 static int writeCoord(u8 *p, RtreeCoord *pCoord){
404 u32 i; 404 u32 i;
405 assert( sizeof(RtreeCoord)==4 ); 405 assert( sizeof(RtreeCoord)==4 );
406 assert( sizeof(u32)==4 ); 406 assert( sizeof(u32)==4 );
407 i = *(u32 *)pCoord; 407 i = pCoord->u;
408 p[0] = (i>>24)&0xFF; 408 p[0] = (i>>24)&0xFF;
409 p[1] = (i>>16)&0xFF; 409 p[1] = (i>>16)&0xFF;
410 p[2] = (i>> 8)&0xFF; 410 p[2] = (i>> 8)&0xFF;
411 p[3] = (i>> 0)&0xFF; 411 p[3] = (i>> 0)&0xFF;
412 return 4; 412 return 4;
413 } 413 }
414 static int writeInt64(u8 *p, i64 i){ 414 static int writeInt64(u8 *p, i64 i){
415 p[0] = (i>>56)&0xFF; 415 p[0] = (i>>56)&0xFF;
416 p[1] = (i>>48)&0xFF; 416 p[1] = (i>>48)&0xFF;
417 p[2] = (i>>40)&0xFF; 417 p[2] = (i>>40)&0xFF;
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 ** Deserialize cell iCell of node pNode. Populate the structure pointed 728 ** Deserialize cell iCell of node pNode. Populate the structure pointed
729 ** to by pCell with the results. 729 ** to by pCell with the results.
730 */ 730 */
731 static void nodeGetCell( 731 static void nodeGetCell(
732 Rtree *pRtree, /* The overall R-Tree */ 732 Rtree *pRtree, /* The overall R-Tree */
733 RtreeNode *pNode, /* The node containing the cell to be read */ 733 RtreeNode *pNode, /* The node containing the cell to be read */
734 int iCell, /* Index of the cell within the node */ 734 int iCell, /* Index of the cell within the node */
735 RtreeCell *pCell /* OUT: Write the cell contents here */ 735 RtreeCell *pCell /* OUT: Write the cell contents here */
736 ){ 736 ){
737 u8 *pData; 737 u8 *pData;
738 u8 *pEnd;
739 RtreeCoord *pCoord; 738 RtreeCoord *pCoord;
739 int ii;
740 pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell); 740 pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
741 pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell); 741 pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
742 pEnd = pData + pRtree->nDim*8;
743 pCoord = pCell->aCoord; 742 pCoord = pCell->aCoord;
744 for(; pData<pEnd; pData+=4, pCoord++){ 743 for(ii=0; ii<pRtree->nDim*2; ii++){
745 readCoord(pData, pCoord); 744 readCoord(&pData[ii*4], &pCoord[ii]);
746 } 745 }
747 } 746 }
748 747
749 748
750 /* Forward declaration for the function that does the work of 749 /* Forward declaration for the function that does the work of
751 ** the virtual table module xCreate() and xConnect() methods. 750 ** the virtual table module xCreate() and xConnect() methods.
752 */ 751 */
753 static int rtreeInit( 752 static int rtreeInit(
754 sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int 753 sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int
755 ); 754 );
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 int nNew = pCur->nPointAlloc*2 + 8; 1174 int nNew = pCur->nPointAlloc*2 + 8;
1176 pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); 1175 pNew = sqlite3_realloc(pCur->aPoint, nNew*sizeof(pCur->aPoint[0]));
1177 if( pNew==0 ) return 0; 1176 if( pNew==0 ) return 0;
1178 pCur->aPoint = pNew; 1177 pCur->aPoint = pNew;
1179 pCur->nPointAlloc = nNew; 1178 pCur->nPointAlloc = nNew;
1180 } 1179 }
1181 i = pCur->nPoint++; 1180 i = pCur->nPoint++;
1182 pNew = pCur->aPoint + i; 1181 pNew = pCur->aPoint + i;
1183 pNew->rScore = rScore; 1182 pNew->rScore = rScore;
1184 pNew->iLevel = iLevel; 1183 pNew->iLevel = iLevel;
1185 assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH ); 1184 assert( iLevel<=RTREE_MAX_DEPTH );
1186 while( i>0 ){ 1185 while( i>0 ){
1187 RtreeSearchPoint *pParent; 1186 RtreeSearchPoint *pParent;
1188 j = (i-1)/2; 1187 j = (i-1)/2;
1189 pParent = pCur->aPoint + j; 1188 pParent = pCur->aPoint + j;
1190 if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break; 1189 if( rtreeSearchPointCompare(pNew, pParent)>=0 ) break;
1191 rtreeSearchPointSwap(pCur, j, i); 1190 rtreeSearchPointSwap(pCur, j, i);
1192 i = j; 1191 i = j;
1193 pNew = pParent; 1192 pNew = pParent;
1194 } 1193 }
1195 return pNew; 1194 return pNew;
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 RtreeMatchArg *pBlob; /* BLOB returned by geometry function */ 1476 RtreeMatchArg *pBlob; /* BLOB returned by geometry function */
1478 sqlite3_rtree_query_info *pInfo; /* Callback information */ 1477 sqlite3_rtree_query_info *pInfo; /* Callback information */
1479 int nBlob; /* Size of the geometry function blob */ 1478 int nBlob; /* Size of the geometry function blob */
1480 int nExpected; /* Expected size of the BLOB */ 1479 int nExpected; /* Expected size of the BLOB */
1481 1480
1482 /* Check that value is actually a blob. */ 1481 /* Check that value is actually a blob. */
1483 if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; 1482 if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
1484 1483
1485 /* Check that the blob is roughly the right size. */ 1484 /* Check that the blob is roughly the right size. */
1486 nBlob = sqlite3_value_bytes(pValue); 1485 nBlob = sqlite3_value_bytes(pValue);
1487 if( nBlob<(int)sizeof(RtreeMatchArg) 1486 if( nBlob<(int)sizeof(RtreeMatchArg) ){
1488 || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
1489 ){
1490 return SQLITE_ERROR; 1487 return SQLITE_ERROR;
1491 } 1488 }
1492 1489
1493 pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob ); 1490 pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
1494 if( !pInfo ) return SQLITE_NOMEM; 1491 if( !pInfo ) return SQLITE_NOMEM;
1495 memset(pInfo, 0, sizeof(*pInfo)); 1492 memset(pInfo, 0, sizeof(*pInfo));
1496 pBlob = (RtreeMatchArg*)&pInfo[1]; 1493 pBlob = (RtreeMatchArg*)&pInfo[1];
1497 1494
1498 memcpy(pBlob, sqlite3_value_blob(pValue), nBlob); 1495 memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
1499 nExpected = (int)(sizeof(RtreeMatchArg) + 1496 nExpected = (int)(sizeof(RtreeMatchArg) +
1497 pBlob->nParam*sizeof(sqlite3_value*) +
1500 (pBlob->nParam-1)*sizeof(RtreeDValue)); 1498 (pBlob->nParam-1)*sizeof(RtreeDValue));
1501 if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){ 1499 if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
1502 sqlite3_free(pInfo); 1500 sqlite3_free(pInfo);
1503 return SQLITE_ERROR; 1501 return SQLITE_ERROR;
1504 } 1502 }
1505 pInfo->pContext = pBlob->cb.pContext; 1503 pInfo->pContext = pBlob->cb.pContext;
1506 pInfo->nParam = pBlob->nParam; 1504 pInfo->nParam = pBlob->nParam;
1507 pInfo->aParam = pBlob->aParam; 1505 pInfo->aParam = pBlob->aParam;
1506 pInfo->apSqlParam = pBlob->apSqlParam;
1508 1507
1509 if( pBlob->cb.xGeom ){ 1508 if( pBlob->cb.xGeom ){
1510 pCons->u.xGeom = pBlob->cb.xGeom; 1509 pCons->u.xGeom = pBlob->cb.xGeom;
1511 }else{ 1510 }else{
1512 pCons->op = RTREE_QUERY; 1511 pCons->op = RTREE_QUERY;
1513 pCons->u.xQueryFunc = pBlob->cb.xQueryFunc; 1512 pCons->u.xQueryFunc = pBlob->cb.xQueryFunc;
1514 } 1513 }
1515 pCons->pInfo = pInfo; 1514 pCons->pInfo = pInfo;
1516 return SQLITE_OK; 1515 return SQLITE_OK;
1517 } 1516 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 ** ---------------------- 1663 ** ----------------------
1665 ** 1664 **
1666 ** The second of each pair of bytes identifies the coordinate column 1665 ** The second of each pair of bytes identifies the coordinate column
1667 ** to which the constraint applies. The leftmost coordinate column 1666 ** to which the constraint applies. The leftmost coordinate column
1668 ** is 'a', the second from the left 'b' etc. 1667 ** is 'a', the second from the left 'b' etc.
1669 */ 1668 */
1670 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ 1669 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
1671 Rtree *pRtree = (Rtree*)tab; 1670 Rtree *pRtree = (Rtree*)tab;
1672 int rc = SQLITE_OK; 1671 int rc = SQLITE_OK;
1673 int ii; 1672 int ii;
1673 int bMatch = 0; /* True if there exists a MATCH constraint */
1674 i64 nRow; /* Estimated rows returned by this scan */ 1674 i64 nRow; /* Estimated rows returned by this scan */
1675 1675
1676 int iIdx = 0; 1676 int iIdx = 0;
1677 char zIdxStr[RTREE_MAX_DIMENSIONS*8+1]; 1677 char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
1678 memset(zIdxStr, 0, sizeof(zIdxStr)); 1678 memset(zIdxStr, 0, sizeof(zIdxStr));
1679 1679
1680 /* Check if there exists a MATCH constraint - even an unusable one. If there
1681 ** is, do not consider the lookup-by-rowid plan as using such a plan would
1682 ** require the VDBE to evaluate the MATCH constraint, which is not currently
1683 ** possible. */
1684 for(ii=0; ii<pIdxInfo->nConstraint; ii++){
1685 if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){
1686 bMatch = 1;
1687 }
1688 }
1689
1680 assert( pIdxInfo->idxStr==0 ); 1690 assert( pIdxInfo->idxStr==0 );
1681 for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ 1691 for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
1682 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; 1692 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
1683 1693
1684 if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ 1694 if( bMatch==0 && p->usable
1695 && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ
1696 ){
1685 /* We have an equality constraint on the rowid. Use strategy 1. */ 1697 /* We have an equality constraint on the rowid. Use strategy 1. */
1686 int jj; 1698 int jj;
1687 for(jj=0; jj<ii; jj++){ 1699 for(jj=0; jj<ii; jj++){
1688 pIdxInfo->aConstraintUsage[jj].argvIndex = 0; 1700 pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
1689 pIdxInfo->aConstraintUsage[jj].omit = 0; 1701 pIdxInfo->aConstraintUsage[jj].omit = 0;
1690 } 1702 }
1691 pIdxInfo->idxNum = 1; 1703 pIdxInfo->idxNum = 1;
1692 pIdxInfo->aConstraintUsage[ii].argvIndex = 1; 1704 pIdxInfo->aConstraintUsage[ii].argvIndex = 1;
1693 pIdxInfo->aConstraintUsage[jj].omit = 1; 1705 pIdxInfo->aConstraintUsage[jj].omit = 1;
1694 1706
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2799 sqlite_int64 *pRowid 2811 sqlite_int64 *pRowid
2800 ){ 2812 ){
2801 Rtree *pRtree = (Rtree *)pVtab; 2813 Rtree *pRtree = (Rtree *)pVtab;
2802 int rc = SQLITE_OK; 2814 int rc = SQLITE_OK;
2803 RtreeCell cell; /* New cell to insert if nData>1 */ 2815 RtreeCell cell; /* New cell to insert if nData>1 */
2804 int bHaveRowid = 0; /* Set to 1 after new rowid is determined */ 2816 int bHaveRowid = 0; /* Set to 1 after new rowid is determined */
2805 2817
2806 rtreeReference(pRtree); 2818 rtreeReference(pRtree);
2807 assert(nData>=1); 2819 assert(nData>=1);
2808 2820
2821 cell.iRowid = 0; /* Used only to suppress a compiler warning */
2822
2809 /* Constraint handling. A write operation on an r-tree table may return 2823 /* Constraint handling. A write operation on an r-tree table may return
2810 ** SQLITE_CONSTRAINT for two reasons: 2824 ** SQLITE_CONSTRAINT for two reasons:
2811 ** 2825 **
2812 ** 1. A duplicate rowid value, or 2826 ** 1. A duplicate rowid value, or
2813 ** 2. The supplied data violates the "x2>=x1" constraint. 2827 ** 2. The supplied data violates the "x2>=x1" constraint.
2814 ** 2828 **
2815 ** In the first case, if the conflict-handling mode is REPLACE, then 2829 ** In the first case, if the conflict-handling mode is REPLACE, then
2816 ** the conflicting row can be removed before proceeding. In the second 2830 ** the conflicting row can be removed before proceeding. In the second
2817 ** case, SQLITE_CONSTRAINT must be returned regardless of the 2831 ** case, SQLITE_CONSTRAINT must be returned regardless of the
2818 ** conflict-handling mode specified by the user. 2832 ** conflict-handling mode specified by the user.
2819 */ 2833 */
2820 if( nData>1 ){ 2834 if( nData>1 ){
2821 int ii; 2835 int ii;
2822 2836
2823 /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */ 2837 /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
2824 assert( nData==(pRtree->nDim*2 + 3) ); 2838 **
2839 ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
2840 ** with "column" that are interpreted as table constraints.
2841 ** Example: CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
2842 ** This problem was discovered after years of use, so we silently ignore
2843 ** these kinds of misdeclared tables to avoid breaking any legacy.
2844 */
2845 assert( nData<=(pRtree->nDim*2 + 3) );
2846
2825 #ifndef SQLITE_RTREE_INT_ONLY 2847 #ifndef SQLITE_RTREE_INT_ONLY
2826 if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ 2848 if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
2827 for(ii=0; ii<(pRtree->nDim*2); ii+=2){ 2849 for(ii=0; ii<nData-4; ii+=2){
2828 cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]); 2850 cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
2829 cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]); 2851 cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
2830 if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ 2852 if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
2831 rc = SQLITE_CONSTRAINT; 2853 rc = SQLITE_CONSTRAINT;
2832 goto constraint; 2854 goto constraint;
2833 } 2855 }
2834 } 2856 }
2835 }else 2857 }else
2836 #endif 2858 #endif
2837 { 2859 {
2838 for(ii=0; ii<(pRtree->nDim*2); ii+=2){ 2860 for(ii=0; ii<nData-4; ii+=2){
2839 cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]); 2861 cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
2840 cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]); 2862 cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
2841 if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ 2863 if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
2842 rc = SQLITE_CONSTRAINT; 2864 rc = SQLITE_CONSTRAINT;
2843 goto constraint; 2865 goto constraint;
2844 } 2866 }
2845 } 2867 }
2846 } 2868 }
2847 2869
2848 /* If a rowid value was supplied, check if it is already present in 2870 /* If a rowid value was supplied, check if it is already present in
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
3358 ** destructor for an RtreeGeomCallback objecct. This routine is called when 3380 ** destructor for an RtreeGeomCallback objecct. This routine is called when
3359 ** the corresponding SQL function is deleted. 3381 ** the corresponding SQL function is deleted.
3360 */ 3382 */
3361 static void rtreeFreeCallback(void *p){ 3383 static void rtreeFreeCallback(void *p){
3362 RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p; 3384 RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p;
3363 if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext); 3385 if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext);
3364 sqlite3_free(p); 3386 sqlite3_free(p);
3365 } 3387 }
3366 3388
3367 /* 3389 /*
3390 ** This routine frees the BLOB that is returned by geomCallback().
3391 */
3392 static void rtreeMatchArgFree(void *pArg){
3393 int i;
3394 RtreeMatchArg *p = (RtreeMatchArg*)pArg;
3395 for(i=0; i<p->nParam; i++){
3396 sqlite3_value_free(p->apSqlParam[i]);
3397 }
3398 sqlite3_free(p);
3399 }
3400
3401 /*
3368 ** Each call to sqlite3_rtree_geometry_callback() or 3402 ** Each call to sqlite3_rtree_geometry_callback() or
3369 ** sqlite3_rtree_query_callback() creates an ordinary SQLite 3403 ** sqlite3_rtree_query_callback() creates an ordinary SQLite
3370 ** scalar function that is implemented by this routine. 3404 ** scalar function that is implemented by this routine.
3371 ** 3405 **
3372 ** All this function does is construct an RtreeMatchArg object that 3406 ** All this function does is construct an RtreeMatchArg object that
3373 ** contains the geometry-checking callback routines and a list of 3407 ** contains the geometry-checking callback routines and a list of
3374 ** parameters to this function, then return that RtreeMatchArg object 3408 ** parameters to this function, then return that RtreeMatchArg object
3375 ** as a BLOB. 3409 ** as a BLOB.
3376 ** 3410 **
3377 ** The R-Tree MATCH operator will read the returned BLOB, deserialize 3411 ** The R-Tree MATCH operator will read the returned BLOB, deserialize
3378 ** the RtreeMatchArg object, and use the RtreeMatchArg object to figure 3412 ** the RtreeMatchArg object, and use the RtreeMatchArg object to figure
3379 ** out which elements of the R-Tree should be returned by the query. 3413 ** out which elements of the R-Tree should be returned by the query.
3380 */ 3414 */
3381 static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ 3415 static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
3382 RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); 3416 RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
3383 RtreeMatchArg *pBlob; 3417 RtreeMatchArg *pBlob;
3384 int nBlob; 3418 int nBlob;
3419 int memErr = 0;
3385 3420
3386 nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue); 3421 nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
3422 + nArg*sizeof(sqlite3_value*);
3387 pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob); 3423 pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
3388 if( !pBlob ){ 3424 if( !pBlob ){
3389 sqlite3_result_error_nomem(ctx); 3425 sqlite3_result_error_nomem(ctx);
3390 }else{ 3426 }else{
3391 int i; 3427 int i;
3392 pBlob->magic = RTREE_GEOMETRY_MAGIC; 3428 pBlob->magic = RTREE_GEOMETRY_MAGIC;
3393 pBlob->cb = pGeomCtx[0]; 3429 pBlob->cb = pGeomCtx[0];
3430 pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
3394 pBlob->nParam = nArg; 3431 pBlob->nParam = nArg;
3395 for(i=0; i<nArg; i++){ 3432 for(i=0; i<nArg; i++){
3433 pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
3434 if( pBlob->apSqlParam[i]==0 ) memErr = 1;
3396 #ifdef SQLITE_RTREE_INT_ONLY 3435 #ifdef SQLITE_RTREE_INT_ONLY
3397 pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); 3436 pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
3398 #else 3437 #else
3399 pBlob->aParam[i] = sqlite3_value_double(aArg[i]); 3438 pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
3400 #endif 3439 #endif
3401 } 3440 }
3402 sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free); 3441 if( memErr ){
3442 sqlite3_result_error_nomem(ctx);
3443 rtreeMatchArgFree(pBlob);
3444 }else{
3445 sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
3446 }
3403 } 3447 }
3404 } 3448 }
3405 3449
3406 /* 3450 /*
3407 ** Register a new geometry function for use with the r-tree MATCH operator. 3451 ** Register a new geometry function for use with the r-tree MATCH operator.
3408 */ 3452 */
3409 int sqlite3_rtree_geometry_callback( 3453 int sqlite3_rtree_geometry_callback(
3410 sqlite3 *db, /* Register SQL function on this connection */ 3454 sqlite3 *db, /* Register SQL function on this connection */
3411 const char *zGeom, /* Name of the new SQL function */ 3455 const char *zGeom, /* Name of the new SQL function */
3412 int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ 3456 int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3459 sqlite3 *db, 3503 sqlite3 *db,
3460 char **pzErrMsg, 3504 char **pzErrMsg,
3461 const sqlite3_api_routines *pApi 3505 const sqlite3_api_routines *pApi
3462 ){ 3506 ){
3463 SQLITE_EXTENSION_INIT2(pApi) 3507 SQLITE_EXTENSION_INIT2(pApi)
3464 return sqlite3RtreeInit(db); 3508 return sqlite3RtreeInit(db);
3465 } 3509 }
3466 #endif 3510 #endif
3467 3511
3468 #endif 3512 #endif
OLDNEW
« 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