]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The SQLITE_RTREE_INT_ONLY compile-time option causes the RTree extension
authordrh <drh@noemail.net>
Mon, 2 Apr 2012 21:35:42 +0000 (21:35 +0000)
committerdrh <drh@noemail.net>
Mon, 2 Apr 2012 21:35:42 +0000 (21:35 +0000)
to use only integer math and store only integer coordinates.

FossilOrigin-Name: 02b7640f5118e0a635b68f65765191bb3171b7bd

13 files changed:
ext/rtree/rtree.c
ext/rtree/rtree1.test
ext/rtree/rtree4.test
ext/rtree/rtree5.test
ext/rtree/rtree6.test
ext/rtree/rtree7.test
ext/rtree/rtree9.test
ext/rtree/rtreeB.test
ext/rtree/sqlite3rtree.h
manifest
manifest.uuid
src/test_config.c
src/test_rtree.c

index ce76e61f08ddf3dc263701b78de81ac6788551f7..d6cdde9fc453bca729846214d70263c7015e06fd 100644 (file)
@@ -182,6 +182,19 @@ struct Rtree {
 #define RTREE_COORD_REAL32 0
 #define RTREE_COORD_INT32  1
 
+/*
+** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will
+** only deal with integer coordinates.  No floating point operations
+** will be done.
+*/
+#ifdef SQLITE_RTREE_INT_ONLY
+  typedef sqlite3_int64 RtreeDValue;       /* High accuracy coordinate */
+  typedef int RtreeValue;                  /* Low accuracy coordinate */
+#else
+  typedef double RtreeDValue;              /* High accuracy coordinate */
+  typedef float RtreeValue;                /* Low accuracy coordinate */
+#endif
+
 /*
 ** The minimum number of cells allowed for a node is a third of the 
 ** maximum. In Gutman's notation:
@@ -217,20 +230,25 @@ struct RtreeCursor {
 };
 
 union RtreeCoord {
-  float f;
+  RtreeValue f;
   int i;
 };
 
 /*
 ** The argument is an RtreeCoord. Return the value stored within the RtreeCoord
-** formatted as a double. This macro assumes that local variable pRtree points
-** to the Rtree structure associated with the RtreeCoord.
+** formatted as a RtreeDValue (double or int64). This macro assumes that local
+** variable pRtree points to the Rtree structure associated with the
+** RtreeCoord.
 */
-#define DCOORD(coord) (                           \
-  (pRtree->eCoordType==RTREE_COORD_REAL32) ?      \
-    ((double)coord.f) :                           \
-    ((double)coord.i)                             \
-)
+#ifdef SQLITE_RTREE_INT_ONLY
+# define DCOORD(coord) ((RtreeDValue)coord.i)
+#else
+# define DCOORD(coord) (                           \
+    (pRtree->eCoordType==RTREE_COORD_REAL32) ?      \
+      ((double)coord.f) :                           \
+      ((double)coord.i)                             \
+  )
+#endif
 
 /*
 ** A search constraint.
@@ -238,8 +256,8 @@ union RtreeCoord {
 struct RtreeConstraint {
   int iCoord;                     /* Index of constrained coordinate */
   int op;                         /* Constraining operation */
-  double rValue;                  /* Constraint value. */
-  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
+  RtreeDValue rValue;             /* Constraint value. */
+  int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
   sqlite3_rtree_geometry *pGeom;  /* Constraint callback argument for a MATCH */
 };
 
@@ -287,10 +305,10 @@ struct RtreeCell {
 */
 struct RtreeMatchArg {
   u32 magic;                      /* Always RTREE_GEOMETRY_MAGIC */
-  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
+  int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *);
   void *pContext;
   int nParam;
-  double aParam[1];
+  RtreeDValue aParam[1];
 };
 
 /*
@@ -302,7 +320,7 @@ struct RtreeMatchArg {
 ** the geometry callback function).
 */
 struct RtreeGeomCallback {
-  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *);
+  int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
   void *pContext;
 };
 
@@ -868,7 +886,7 @@ static int testRtreeGeom(
   int *pbRes                      /* OUT: Test result */
 ){
   int i;
-  double aCoord[RTREE_MAX_DIMENSIONS*2];
+  RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2];
   int nCoord = pRtree->nDim*2;
 
   assert( pConstraint->op==RTREE_MATCH );
@@ -898,8 +916,8 @@ static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){
   nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
   for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
     RtreeConstraint *p = &pCursor->aConstraint[ii];
-    double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
-    double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
+    RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
+    RtreeDValue cell_max = DCOORD(cell.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
@@ -951,7 +969,7 @@ static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor, int *pbEof){
   nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
   for(ii=0; ii<pCursor->nConstraint; ii++){
     RtreeConstraint *p = &pCursor->aConstraint[ii];
-    double coord = DCOORD(cell.aCoord[p->iCoord]);
+    RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]);
     int res;
     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
@@ -1149,9 +1167,12 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
   }else{
     RtreeCoord c;
     nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
+#ifndef SQLITE_RTREE_INT_ONLY
     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
       sqlite3_result_double(ctx, c.f);
-    }else{
+    }else
+#endif
+    {
       assert( pRtree->eCoordType==RTREE_COORD_INT32 );
       sqlite3_result_int(ctx, c.i);
     }
@@ -1198,7 +1219,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(double))!=0
+   || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
   ){
     return SQLITE_ERROR;
   }
@@ -1212,7 +1233,7 @@ static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
 
   memcpy(p, sqlite3_value_blob(pValue), nBlob);
   if( p->magic!=RTREE_GEOMETRY_MAGIC 
-   || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(double))
+   || nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue))
   ){
     sqlite3_free(pGeom);
     return SQLITE_ERROR;
@@ -1284,7 +1305,11 @@ static int rtreeFilter(
               break;
             }
           }else{
+#ifdef SQLITE_RTREE_INT_ONLY
+            p->rValue = sqlite3_value_int64(argv[ii]);
+#else
             p->rValue = sqlite3_value_double(argv[ii]);
+#endif
           }
         }
       }
@@ -1418,11 +1443,11 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
 /*
 ** Return the N-dimensional volumn of the cell stored in *p.
 */
-static float cellArea(Rtree *pRtree, RtreeCell *p){
-  float area = 1.0;
+static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
+  RtreeDValue area = (RtreeDValue)1;
   int ii;
   for(ii=0; ii<(pRtree->nDim*2); ii+=2){
-    area = (float)(area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
+    area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
   }
   return area;
 }
@@ -1431,11 +1456,11 @@ static float cellArea(Rtree *pRtree, RtreeCell *p){
 ** Return the margin length of cell p. The margin length is the sum
 ** of the objects size in each dimension.
 */
-static float cellMargin(Rtree *pRtree, RtreeCell *p){
-  float margin = 0.0;
+static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
+  RtreeDValue margin = (RtreeDValue)0;
   int ii;
   for(ii=0; ii<(pRtree->nDim*2); ii+=2){
-    margin += (float)(DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
+    margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
   }
   return margin;
 }
@@ -1480,8 +1505,8 @@ static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
 /*
 ** Return the amount cell p would grow by if it were unioned with pCell.
 */
-static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
-  float area;
+static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
+  RtreeDValue area;
   RtreeCell cell;
   memcpy(&cell, p, sizeof(RtreeCell));
   area = cellArea(pRtree, &cell);
@@ -1490,7 +1515,7 @@ static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
 }
 
 #if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT
-static float cellOverlap(
+static RtreeDValue cellOverlap(
   Rtree *pRtree, 
   RtreeCell *p, 
   RtreeCell *aCell, 
@@ -1498,7 +1523,7 @@ static float cellOverlap(
   int iExclude
 ){
   int ii;
-  float overlap = 0.0;
+  RtreeDValue overlap = 0.0;
   for(ii=0; ii<nCell; ii++){
 #if VARIANT_RSTARTREE_CHOOSESUBTREE
     if( ii!=iExclude )
@@ -1508,10 +1533,9 @@ static float cellOverlap(
 #endif
     {
       int jj;
-      float o = 1.0;
+      RtreeDValue o = (RtreeDValue)1;
       for(jj=0; jj<(pRtree->nDim*2); jj+=2){
-        double x1;
-        double x2;
+        RtreeDValue x1, x2;
 
         x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
         x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
@@ -1520,7 +1544,7 @@ static float cellOverlap(
           o = 0.0;
           break;
         }else{
-          o = o * (float)(x2-x1);
+          o = o * (x2-x1);
         }
       }
       overlap += o;
@@ -1531,7 +1555,7 @@ static float cellOverlap(
 #endif
 
 #if VARIANT_RSTARTREE_CHOOSESUBTREE
-static float cellOverlapEnlargement(
+static RtreeDValue cellOverlapEnlargement(
   Rtree *pRtree, 
   RtreeCell *p, 
   RtreeCell *pInsert, 
@@ -1539,12 +1563,11 @@ static float cellOverlapEnlargement(
   int nCell, 
   int iExclude
 ){
-  double before;
-  double after;
+  RtreeDValue before, after;
   before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
   cellUnion(pRtree, p, pInsert);
   after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
-  return (float)(after-before);
+  return (after-before);
 }
 #endif
 
@@ -1568,11 +1591,11 @@ static int ChooseLeaf(
     int iCell;
     sqlite3_int64 iBest = 0;
 
-    float fMinGrowth = 0.0;
-    float fMinArea = 0.0;
+    RtreeDValue fMinGrowth = 0.0;
+    RtreeDValue fMinArea = 0.0;
 #if VARIANT_RSTARTREE_CHOOSESUBTREE
-    float fMinOverlap = 0.0;
-    float overlap;
+    RtreeDValue fMinOverlap = 0.0;
+    RtreeDValue overlap;
 #endif
 
     int nCell = NCELL(pNode);
@@ -1603,8 +1626,8 @@ static int ChooseLeaf(
     */
     for(iCell=0; iCell<nCell; iCell++){
       int bBest = 0;
-      float growth;
-      float area;
+      RtreeDValue growth;
+      RtreeDValue area;
       nodeGetCell(pRtree, pNode, iCell, &cell);
       growth = cellGrowth(pRtree, &cell, pCell);
       area = cellArea(pRtree, &cell);
@@ -1731,7 +1754,7 @@ static void LinearPickSeeds(
   int i;
   int iLeftSeed = 0;
   int iRightSeed = 1;
-  float maxNormalInnerWidth = 0.0;
+  RtreeDValue maxNormalInnerWidth = (RtreeDValue)0;
 
   /* Pick two "seed" cells from the array of cells. The algorithm used
   ** here is the LinearPickSeeds algorithm from Gutman[1984]. The 
@@ -1739,18 +1762,18 @@ static void LinearPickSeeds(
   ** variables iLeftSeek and iRightSeed.
   */
   for(i=0; i<pRtree->nDim; i++){
-    float x1 = DCOORD(aCell[0].aCoord[i*2]);
-    float x2 = DCOORD(aCell[0].aCoord[i*2+1]);
-    float x3 = x1;
-    float x4 = x2;
+    RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]);
+    RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]);
+    RtreeDValue x3 = x1;
+    RtreeDValue x4 = x2;
     int jj;
 
     int iCellLeft = 0;
     int iCellRight = 0;
 
     for(jj=1; jj<nCell; jj++){
-      float left = DCOORD(aCell[jj].aCoord[i*2]);
-      float right = DCOORD(aCell[jj].aCoord[i*2+1]);
+      RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]);
+      RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]);
 
       if( left<x1 ) x1 = left;
       if( right>x4 ) x4 = right;
@@ -1765,7 +1788,7 @@ static void LinearPickSeeds(
     }
 
     if( x4!=x1 ){
-      float normalwidth = (x3 - x2) / (x4 - x1);
+      RtreeDValue normalwidth = (x3 - x2) / (x4 - x1);
       if( normalwidth>maxNormalInnerWidth ){
         iLeftSeed = iCellLeft;
         iRightSeed = iCellRight;
@@ -1794,13 +1817,13 @@ static RtreeCell *QuadraticPickNext(
   #define FABS(a) ((a)<0.0?-1.0*(a):(a))
 
   int iSelect = -1;
-  float fDiff;
+  RtreeDValue fDiff;
   int ii;
   for(ii=0; ii<nCell; ii++){
     if( aiUsed[ii]==0 ){
-      float left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
-      float right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
-      float diff = FABS(right-left);
+      RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
+      RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
+      RtreeDValue diff = FABS(right-left);
       if( iSelect<0 || diff>fDiff ){
         fDiff = diff;
         iSelect = ii;
@@ -1827,13 +1850,13 @@ static void QuadraticPickSeeds(
 
   int iLeftSeed = 0;
   int iRightSeed = 1;
-  float fWaste = 0.0;
+  RtreeDValue fWaste = 0.0;
 
   for(ii=0; ii<nCell; ii++){
     for(jj=ii+1; jj<nCell; jj++){
-      float right = cellArea(pRtree, &aCell[jj]);
-      float growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
-      float waste = growth - right;
+      RtreeDValue right = cellArea(pRtree, &aCell[jj]);
+      RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
+      RtreeDValue waste = growth - right;
 
       if( waste>fWaste ){
         iLeftSeed = ii;
@@ -1868,7 +1891,7 @@ static void QuadraticPickSeeds(
 static void SortByDistance(
   int *aIdx, 
   int nIdx, 
-  float *aDistance, 
+  RtreeDValue *aDistance, 
   int *aSpare
 ){
   if( nIdx>1 ){
@@ -1894,8 +1917,8 @@ static void SortByDistance(
         aIdx[iLeft+iRight] = aLeft[iLeft];
         iLeft++;
       }else{
-        float fLeft = aDistance[aLeft[iLeft]];
-        float fRight = aDistance[aRight[iRight]];
+        RtreeDValue fLeft = aDistance[aLeft[iLeft]];
+        RtreeDValue fRight = aDistance[aRight[iRight]];
         if( fLeft<fRight ){
           aIdx[iLeft+iRight] = aLeft[iLeft];
           iLeft++;
@@ -1911,8 +1934,8 @@ static void SortByDistance(
     {
       int jj;
       for(jj=1; jj<nIdx; jj++){
-        float left = aDistance[aIdx[jj-1]];
-        float right = aDistance[aIdx[jj]];
+        RtreeDValue left = aDistance[aIdx[jj-1]];
+        RtreeDValue right = aDistance[aIdx[jj]];
         assert( left<=right );
       }
     }
@@ -1955,10 +1978,10 @@ static void SortByDimension(
     memcpy(aSpare, aLeft, sizeof(int)*nLeft);
     aLeft = aSpare;
     while( iLeft<nLeft || iRight<nRight ){
-      double xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
-      double xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
-      double xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
-      double xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
+      RtreeDValue xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
+      RtreeDValue xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
+      RtreeDValue xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
+      RtreeDValue xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
       if( (iLeft!=nLeft) && ((iRight==nRight)
        || (xleft1<xright1)
        || (xleft1==xright1 && xleft2<xright2)
@@ -1976,10 +1999,10 @@ static void SortByDimension(
     {
       int jj;
       for(jj=1; jj<nIdx; jj++){
-        float xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
-        float xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
-        float xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
-        float xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
+        RtreeDValue xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
+        RtreeDValue xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
+        RtreeDValue xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
+        RtreeDValue xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
         assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) );
       }
     }
@@ -2006,7 +2029,7 @@ static int splitNodeStartree(
 
   int iBestDim = 0;
   int iBestSplit = 0;
-  float fBestMargin = 0.0;
+  RtreeDValue fBestMargin = 0.0;
 
   int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
 
@@ -2027,9 +2050,9 @@ static int splitNodeStartree(
   }
 
   for(ii=0; ii<pRtree->nDim; ii++){
-    float margin = 0.0;
-    float fBestOverlap = 0.0;
-    float fBestArea = 0.0;
+    RtreeDValue margin = 0.0;
+    RtreeDValue fBestOverlap = 0.0;
+    RtreeDValue fBestArea = 0.0;
     int iBestLeft = 0;
     int nLeft;
 
@@ -2041,8 +2064,8 @@ static int splitNodeStartree(
       RtreeCell left;
       RtreeCell right;
       int kk;
-      float overlap;
-      float area;
+      RtreeDValue overlap;
+      RtreeDValue area;
 
       memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell));
       memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell));
@@ -2125,7 +2148,7 @@ static int splitNodeGuttman(
   for(i=nCell-2; i>0; i--){
     RtreeCell *pNext;
     pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
-    float diff =  
+    RtreeDValue diff =  
       cellGrowth(pRtree, pBboxLeft, pNext) - 
       cellGrowth(pRtree, pBboxRight, pNext)
     ;
@@ -2458,32 +2481,34 @@ static int Reinsert(
   int *aOrder;
   int *aSpare;
   RtreeCell *aCell;
-  float *aDistance;
+  RtreeDValue *aDistance;
   int nCell;
-  float aCenterCoord[RTREE_MAX_DIMENSIONS];
+  RtreeDValue aCenterCoord[RTREE_MAX_DIMENSIONS];
   int iDim;
   int ii;
   int rc = SQLITE_OK;
+  int n;
 
-  memset(aCenterCoord, 0, sizeof(float)*RTREE_MAX_DIMENSIONS);
+  memset(aCenterCoord, 0, sizeof(RtreeDValue)*RTREE_MAX_DIMENSIONS);
 
   nCell = NCELL(pNode)+1;
+  n = (nCell+1)&(~1);
 
   /* Allocate the buffers used by this operation. The allocation is
   ** relinquished before this function returns.
   */
-  aCell = (RtreeCell *)sqlite3_malloc(nCell * (
-    sizeof(RtreeCell) +         /* aCell array */
-    sizeof(int)       +         /* aOrder array */
-    sizeof(int)       +         /* aSpare array */
-    sizeof(float)               /* aDistance array */
+  aCell = (RtreeCell *)sqlite3_malloc(n * (
+    sizeof(RtreeCell)     +         /* aCell array */
+    sizeof(int)           +         /* aOrder array */
+    sizeof(int)           +         /* aSpare array */
+    sizeof(RtreeDValue)             /* aDistance array */
   ));
   if( !aCell ){
     return SQLITE_NOMEM;
   }
-  aOrder    = (int *)&aCell[nCell];
-  aSpare    = (int *)&aOrder[nCell];
-  aDistance = (float *)&aSpare[nCell];
+  aOrder    = (int *)&aCell[n];
+  aSpare    = (int *)&aOrder[n];
+  aDistance = (RtreeDValue *)&aSpare[n];
 
   for(ii=0; ii<nCell; ii++){
     if( ii==(nCell-1) ){
@@ -2493,19 +2518,19 @@ static int Reinsert(
     }
     aOrder[ii] = ii;
     for(iDim=0; iDim<pRtree->nDim; iDim++){
-      aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2]);
-      aCenterCoord[iDim] += (float)DCOORD(aCell[ii].aCoord[iDim*2+1]);
+      aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]);
+      aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]);
     }
   }
   for(iDim=0; iDim<pRtree->nDim; iDim++){
-    aCenterCoord[iDim] = (float)(aCenterCoord[iDim]/((float)nCell*2.0));
+    aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2));
   }
 
   for(ii=0; ii<nCell; ii++){
     aDistance[ii] = 0.0;
     for(iDim=0; iDim<pRtree->nDim; iDim++){
-      float coord = (float)(DCOORD(aCell[ii].aCoord[iDim*2+1]) - 
-          DCOORD(aCell[ii].aCoord[iDim*2]));
+      RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - 
+                               DCOORD(aCell[ii].aCoord[iDim*2]));
       aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]);
     }
   }
@@ -2747,16 +2772,19 @@ static int rtreeUpdate(
 
     /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
     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){
-        cell.aCoord[ii].f = (float)sqlite3_value_double(azData[ii+3]);
-        cell.aCoord[ii+1].f = (float)sqlite3_value_double(azData[ii+4]);
+        cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]);
+        cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]);
         if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
           rc = SQLITE_CONSTRAINT;
           goto constraint;
         }
       }
-    }else{
+    }else
+#endif
+    {
       for(ii=0; ii<(pRtree->nDim*2); ii+=2){
         cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
         cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
@@ -3154,7 +3182,13 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
     sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
     nCell = (int)strlen(zCell);
     for(jj=0; jj<tree.nDim*2; jj++){
-      sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f);
+#ifndef SQLITE_RTREE_INT_ONLY
+      sqlite3_snprintf(512-nCell,&zCell[nCell], " %f",
+                       (double)cell.aCoord[jj].f);
+#else
+      sqlite3_snprintf(512-nCell,&zCell[nCell], " %d",
+                       cell.aCoord[jj].i);
+#endif
       nCell = (int)strlen(zCell);
     }
 
@@ -3196,7 +3230,11 @@ int sqlite3RtreeInit(sqlite3 *db){
     rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
   }
   if( rc==SQLITE_OK ){
+#ifdef SQLITE_RTREE_INT_ONLY
+    void *c = (void *)RTREE_COORD_INT32;
+#else
     void *c = (void *)RTREE_COORD_REAL32;
+#endif
     rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
   }
   if( rc==SQLITE_OK ){
@@ -3230,7 +3268,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
   RtreeMatchArg *pBlob;
   int nBlob;
 
-  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(double);
+  nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
   pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
   if( !pBlob ){
     sqlite3_result_error_nomem(ctx);
@@ -3241,7 +3279,11 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
     pBlob->pContext = pGeomCtx->pContext;
     pBlob->nParam = nArg;
     for(i=0; i<nArg; i++){
+#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, doSqlite3Free);
   }
@@ -3253,7 +3295,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
 int sqlite3_rtree_geometry_callback(
   sqlite3 *db,
   const char *zGeom,
-  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *),
+  int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *),
   void *pContext
 ){
   RtreeGeomCallback *pGeomCtx;      /* Context object for new user-function */
index 583b028507638f1c7b7c77b8093ff9ff6f5414cb..e3c7d68e82d5d804437e10bce932d292702135c6 100644 (file)
@@ -104,6 +104,18 @@ for {set nCol 1} {$nCol<[llength $cols]} {incr nCol} {
   catchsql { DROP TABLE t1 }
 }
 
+# Like execsql except display output as integer where that can be
+# done without loss of information.
+#
+proc execsql_intout {sql} {
+  set out {}
+  foreach term [execsql $sql] {
+    regsub {\.0$} $term {} term
+    lappend out $term
+  }
+  return $out
+}
+
 # Test that it is possible to open an existing database that contains
 # r-tree tables.
 #
@@ -117,8 +129,8 @@ do_test rtree-1.4.1 {
 do_test rtree-1.4.2 {
   db close
   sqlite3 db test.db
-  execsql { SELECT * FROM t1 ORDER BY ii }
-} {1 5.0 10.0 2 15.0 20.0}
+  execsql_intout { SELECT * FROM t1 ORDER BY ii }
+} {1 5 10 2 15 20}
 do_test rtree-1.4.3 {
   execsql { DROP TABLE t1 }
 } {}
@@ -127,12 +139,12 @@ do_test rtree-1.4.3 {
 # column names.
 #
 do_test rtree-1.5.1 {
-  execsql {
+  execsql_intout {
     CREATE VIRTUAL TABLE t1 USING rtree("the key", "x dim.", "x2'dim");
     INSERT INTO t1 VALUES(1, 2, 3);
     SELECT "the key", "x dim.", "x2'dim" FROM t1;
   }
-} {1 2.0 3.0}
+} {1 2 3}
 do_test rtree-1.5.1 {
   execsql { DROP TABLE t1 }
 } {}
@@ -161,8 +173,8 @@ do_test rtree-2.1.1 {
 
 do_test rtree-2.1.2 {
   execsql { INSERT INTO t1 VALUES(NULL, 1, 3, 2, 4) }
-  execsql { SELECT * FROM t1 }
-} {1 1.0 3.0 2.0 4.0}
+  execsql_intout { SELECT * FROM t1 }
+} {1 1 3 2 4}
 do_test rtree-2.1.3 {
   execsql { INSERT INTO t1 VALUES(NULL, 1, 3, 2, 4) }
   execsql { SELECT rowid FROM t1 ORDER BY rowid }
@@ -201,17 +213,17 @@ do_test rtree-3.1.1 {
   }
 } {}
 do_test rtree-3.1.2 {
-  execsql { 
+  execsql_intout { 
     INSERT INTO t1 VALUES(5, 1, 3, 2, 4);
     SELECT * FROM t1;
   }
-} {5 1.0 3.0 2.0 4.0}
+} {5 1 3 2 4}
 do_test rtree-3.1.3 {
-  execsql {
+  execsql_intout {
     INSERT INTO t1 VALUES(6, 2, 6, 4, 8);
     SELECT * FROM t1;
   }
-} {5 1.0 3.0 2.0 4.0 6 2.0 6.0 4.0 8.0}
+} {5 1 3 2 4 6 2 6 4 8}
 
 # Test the constraint on the coordinates (c[i]<=c[i+1] where (i%2==0)):
 do_test rtree-3.2.1 {
@@ -228,25 +240,25 @@ do_test rtree-5.1.1 {
   execsql { CREATE VIRTUAL TABLE t2 USING rtree(ii, x1, x2) }
 } {}
 do_test rtree-5.1.2 {
-  execsql { 
+  execsql_intout { 
     INSERT INTO t2 VALUES(1, 10, 20);
     INSERT INTO t2 VALUES(2, 30, 40);
     INSERT INTO t2 VALUES(3, 50, 60);
     SELECT * FROM t2 ORDER BY ii;
   }
-} {1 10.0 20.0 2 30.0 40.0 3 50.0 60.0}
+} {1 10 20 2 30 40 3 50 60}
 do_test rtree-5.1.3 {
-  execsql { 
+  execsql_intout { 
     DELETE FROM t2 WHERE ii=2;
     SELECT * FROM t2 ORDER BY ii;
   }
-} {1 10.0 20.0 3 50.0 60.0}
+} {1 10 20 3 50 60}
 do_test rtree-5.1.4 {
-  execsql { 
+  execsql_intout { 
     DELETE FROM t2 WHERE ii=1;
     SELECT * FROM t2 ORDER BY ii;
   }
-} {3 50.0 60.0}
+} {3 50 60}
 do_test rtree-5.1.5 {
   execsql { 
     DELETE FROM t2 WHERE ii=3;
@@ -264,16 +276,16 @@ do_test rtree-6.1.1 {
   execsql { CREATE VIRTUAL TABLE t3 USING rtree(ii, x1, x2, y1, y2) }
 } {}
 do_test rtree-6.1.2 {
-  execsql {
+  execsql_intout {
     INSERT INTO t3 VALUES(1, 2, 3, 4, 5);
     UPDATE t3 SET x2=5;
     SELECT * FROM t3;
   }
-} {1 2.0 5.0 4.0 5.0}
+} {1 2 5 4 5}
 do_test rtree-6.1.3 {
   execsql { UPDATE t3 SET ii = 2 }
-  execsql { SELECT * FROM t3 }
-} {2 2.0 5.0 4.0 5.0}
+  execsql_intout { SELECT * FROM t3 }
+} {2 2 5 4 5}
 
 #----------------------------------------------------------------------------
 # Test cases rtree-7.* test rename operations.
@@ -286,29 +298,29 @@ do_test rtree-7.1.1 {
 } {}
 do_test rtree-7.1.2 {
   execsql { ALTER TABLE t4 RENAME TO t5 }
-  execsql { SELECT * FROM t5 }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM t5 }
+} {1 2 3 4 5 6 7}
 do_test rtree-7.1.3 {
   db close
   sqlite3 db test.db
-  execsql { SELECT * FROM t5 }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM t5 }
+} {1 2 3 4 5 6 7}
 do_test rtree-7.1.4 {
   execsql { ALTER TABLE t5 RENAME TO 'raisara "one"'''}
-  execsql { SELECT * FROM "raisara ""one""'" }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM "raisara ""one""'" }
+} {1 2 3 4 5 6 7}
 do_test rtree-7.1.5 {
-  execsql { SELECT * FROM 'raisara "one"''' }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM 'raisara "one"''' }
+} {1 2 3 4 5 6 7}
 do_test rtree-7.1.6 {
   execsql { ALTER TABLE "raisara ""one""'" RENAME TO "abc 123" }
-  execsql { SELECT * FROM "abc 123" }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM "abc 123" }
+} {1 2 3 4 5 6 7}
 do_test rtree-7.1.7 {
   db close
   sqlite3 db test.db
-  execsql { SELECT * FROM "abc 123" }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM "abc 123" }
+} {1 2 3 4 5 6 7}
 
 # An error midway through a rename operation.
 do_test rtree-7.2.1 {
@@ -318,8 +330,8 @@ do_test rtree-7.2.1 {
   catchsql { ALTER TABLE "abc 123" RENAME TO t4 }
 } {1 {SQL logic error or missing database}}
 do_test rtree-7.2.2 {
-  execsql { SELECT * FROM "abc 123" }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM "abc 123" }
+} {1 2 3 4 5 6 7}
 do_test rtree-7.2.3 {
   execsql { 
     DROP TABLE t4_node;
@@ -330,13 +342,13 @@ do_test rtree-7.2.3 {
 do_test rtree-7.2.4 {
   db close
   sqlite3 db test.db
-  execsql { SELECT * FROM "abc 123" }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM "abc 123" }
+} {1 2 3 4 5 6 7}
 do_test rtree-7.2.5 {
   execsql { DROP TABLE t4_rowid }
   execsql { ALTER TABLE "abc 123" RENAME TO t4 }
-  execsql { SELECT * FROM t4 }
-} {1 2.0 3.0 4.0 5.0 6.0 7.0}
+  execsql_intout { SELECT * FROM t4 }
+} {1 2 3 4 5 6 7}
 
 
 #----------------------------------------------------------------------------
index 708d335b067cab91b07dca389be834b2fd4d035b..a3872b073569426bf368bc9fd2ee70dddc8945cc 100644 (file)
@@ -27,21 +27,38 @@ if {[info exists G(isquick)] && $G(isquick)} {
   set ::NROW 250
 }
 
-# Return a floating point number between -X and X.
-# 
-proc rand {X} {
-  return [expr {int((rand()-0.5)*1024.0*$X)/512.0}]
-}
-
-# Return a positive floating point number less than or equal to X
-#
-proc randincr {X} {
-  while 1 {
-    set r [expr {int(rand()*$X*32.0)/32.0}]
-    if {$r>0.0} {return $r}
+ifcapable !rtree_int_only {
+  # Return a floating point number between -X and X.
+  # 
+  proc rand {X} {
+    return [expr {int((rand()-0.5)*1024.0*$X)/512.0}]
+  }
+  
+  # Return a positive floating point number less than or equal to X
+  #
+  proc randincr {X} {
+    while 1 {
+      set r [expr {int(rand()*$X*32.0)/32.0}]
+      if {$r>0.0} {return $r}
+    }
+  }
+} else {
+  # For rtree_int_only, return an number between -X and X.
+  # 
+  proc rand {X} {
+    return [expr {int((rand()-0.5)*2*$X)}]
+  }
+  
+  # Return a positive integer less than or equal to X
+  #
+  proc randincr {X} {
+    while 1 {
+      set r [expr {int(rand()*$X)+1}]
+      if {$r>0} {return $r}
+    }
   }
 }
-
+  
 # Scramble the $inlist into a random order.
 #
 proc scramble {inlist} {
index ea2946f918f2817b8ac3082078f15b4feae4aec5..8990772356a7059b055aaf41239ff3b5a8815559 100644 (file)
@@ -49,9 +49,11 @@ do_test rtree5-1.6 {
 do_test rtree5-1.7 { 
   execsql { SELECT count(*) FROM t1 WHERE x1==5 }
 } {1}
-do_test rtree5-1.8 { 
-  execsql { SELECT count(*) FROM t1 WHERE x1==5.2 }
-} {0}
+ifcapable !rtree_int_only {
+  do_test rtree5-1.8 { 
+    execsql { SELECT count(*) FROM t1 WHERE x1==5.2 }
+  } {0}
+}
 do_test rtree5-1.9 { 
   execsql { SELECT count(*) FROM t1 WHERE x1==5.0 }
 } {1}
index ba0e53c99480d5ce4047e8ad6dd67f8019c10258..9d57016231673a512f2e75eb8f8a0326134375e6 100644 (file)
@@ -16,7 +16,7 @@ if {![info exists testdir]} {
 } 
 source $testdir/tester.tcl
 
-ifcapable !rtree {
+ifcapable !rtree || rtree_int_only {
   finish_test
   return
 }
index 31dae0cd8a28f7a2aed9a5fd886a7ade9fd89360..4eee4c219a61ce1ffde288fbb2a3f188411f128b 100644 (file)
@@ -24,6 +24,18 @@ ifcapable !rtree||!vacuum {
   return
 }
 
+# Like execsql except display output as integer where that can be
+# done without loss of information.
+#
+proc execsql_intout {sql} {
+  set out {}
+  foreach term [execsql $sql] {
+    regsub {\.0$} $term {} term
+    lappend out $term
+  }
+  return $out
+}
+
 do_test rtree7-1.1 {
   execsql {
     PRAGMA page_size = 1024;
@@ -32,27 +44,27 @@ do_test rtree7-1.1 {
   }
 } {}
 do_test rtree7-1.2 {
-  execsql { SELECT * FROM rt }
-} {1 1.0 2.0 3.0 4.0}
+  execsql_intout { SELECT * FROM rt }
+} {1 1 2 3 4}
 do_test rtree7-1.3 {
-  execsql { 
+  execsql_intout { 
     PRAGMA page_size = 2048;
     VACUUM;
     SELECT * FROM rt;
   }
-} {1 1.0 2.0 3.0 4.0}
+} {1 1 2 3 4}
 do_test rtree7-1.4 {
   for {set i 2} {$i <= 51} {incr i} {
     execsql { INSERT INTO rt VALUES($i, 1, 2, 3, 4) }
   }
-  execsql { SELECT sum(x1), sum(x2), sum(y1), sum(y2) FROM rt }
-} {51.0 102.0 153.0 204.0}
+  execsql_intout { SELECT sum(x1), sum(x2), sum(y1), sum(y2) FROM rt }
+} {51 102 153 204}
 do_test rtree7-1.5 {
-  execsql { 
+  execsql_intout { 
     PRAGMA page_size = 512;
     VACUUM;
     SELECT sum(x1), sum(x2), sum(y1), sum(y2) FROM rt
   }
-} {51.0 102.0 153.0 204.0}
+} {51 102 153 204}
 
 finish_test
index ddee277ef526a4badb726ad4956587843de791b6..6479516bed6d04d3b62ca219ec4cde23753b3164 100644 (file)
@@ -17,6 +17,7 @@ if {![info exists testdir]} {
 } 
 source $testdir/tester.tcl
 ifcapable !rtree { finish_test ; return }
+ifcapable rtree_int_only { finish_test; return }
 
 register_cube_geom db
 
index 2756fceedb94bfa47d6227b1afe2c9b07e2b3634..7cb445cc4fa97a0368ecde17badca67416eb1c49 100644 (file)
@@ -18,17 +18,30 @@ if {![info exists testdir]} {
 source $testdir/tester.tcl
 ifcapable !rtree { finish_test ; return }
 
-do_test rtreeB-1.1 {
-  db eval {
-    CREATE VIRTUAL TABLE t1 USING rtree(ii, x0, y0, x1, y1);
-    INSERT INTO t1 VALUES(1073741824, 0.0, 0.0, 100.0, 100.0);
-    INSERT INTO t1 VALUES(2147483646, 0.0, 0.0, 200.0, 200.0);
-    INSERT INTO t1 VALUES(4294967296, 0.0, 0.0, 300.0, 300.0);
-    INSERT INTO t1 VALUES(8589934592, 20.0, 20.0, 150.0, 150.0);
-    INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400);
-    SELECT rtreenode(2, data) FROM t1_node;
-  }
-} {{{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}}}
-
+ifcapable rtree_int_only {
+  do_test rtreeB-1.1-intonly {
+    db eval {
+      CREATE VIRTUAL TABLE t1 USING rtree(ii, x0, y0, x1, y1);
+      INSERT INTO t1 VALUES(1073741824, 0.0, 0.0, 100.0, 100.0);
+      INSERT INTO t1 VALUES(2147483646, 0.0, 0.0, 200.0, 200.0);
+      INSERT INTO t1 VALUES(4294967296, 0.0, 0.0, 300.0, 300.0);
+      INSERT INTO t1 VALUES(8589934592, 20.0, 20.0, 150.0, 150.0);
+      INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400);
+      SELECT rtreenode(2, data) FROM t1_node;
+    }
+  } {{{1073741824 0 0 100 100} {2147483646 0 0 200 200} {4294967296 0 0 300 300} {8589934592 20 20 150 150} {9223372036854775807 150 150 400 400}}}
+} else {  
+  do_test rtreeB-1.1 {
+    db eval {
+      CREATE VIRTUAL TABLE t1 USING rtree(ii, x0, y0, x1, y1);
+      INSERT INTO t1 VALUES(1073741824, 0.0, 0.0, 100.0, 100.0);
+      INSERT INTO t1 VALUES(2147483646, 0.0, 0.0, 200.0, 200.0);
+      INSERT INTO t1 VALUES(4294967296, 0.0, 0.0, 300.0, 300.0);
+      INSERT INTO t1 VALUES(8589934592, 20.0, 20.0, 150.0, 150.0);
+      INSERT INTO t1 VALUES(9223372036854775807, 150, 150, 400, 400);
+      SELECT rtreenode(2, data) FROM t1_node;
+    }
+  } {{{1073741824 0.000000 0.000000 100.000000 100.000000} {2147483646 0.000000 0.000000 200.000000 200.000000} {4294967296 0.000000 0.000000 300.000000 300.000000} {8589934592 20.000000 20.000000 150.000000 150.000000} {9223372036854775807 150.000000 150.000000 400.000000 400.000000}}}
+}
 
 finish_test
index cffb300092ef1d8bf89065067f9584b22633281f..c849091f29a895fb0a462dd4521f93f6b8417b81 100644 (file)
@@ -31,7 +31,11 @@ typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry;
 int sqlite3_rtree_geometry_callback(
   sqlite3 *db,
   const char *zGeom,
-  int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
+#ifdef SQLITE_RTREE_INT_ONLY
+  int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes),
+#else
+  int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes),
+#endif
   void *pContext
 );
 
index d8e545b9dc2b1cbca88417ed1c946d63f18f0949..bebaba541e1a4681a2fc696a117b2fa1c1ab6705 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\s#ifdefs\sto\sallow\sa\stest\sbuild\sto\ssucceed\seven\sif\sSQLITE_ENABLE_FTS3\sis\nnot\sdefined.
-D 2012-04-02T17:18:23.248
+C The\sSQLITE_RTREE_INT_ONLY\scompile-time\soption\scauses\sthe\sRTree\sextension\s\nto\suse\sonly\sinteger\smath\sand\sstore\sonly\sinteger\scoordinates.
+D 2012-04-02T21:35:42.939
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -86,22 +86,22 @@ F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
 F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
-F ext/rtree/rtree.c 4c1878818fc50efe5c2c7b8809d5cd0d88c7d396
+F ext/rtree/rtree.c 73502e5336162fdc8f5d1c4bdd4ec6b1299c2f2a
 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
-F ext/rtree/rtree1.test 28e1b8da4da98093ce3210187434dd760a8d89d8
+F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
 F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc
-F ext/rtree/rtree4.test 0061e6f464fd3dc6a79f82454c5a1c3dadbe42af
-F ext/rtree/rtree5.test ce3d7ccae2cfd9d2e1052b462424964c9bdcda12
-F ext/rtree/rtree6.test 0b380bd9af93f3bc496eef42502a336f58949c1b
-F ext/rtree/rtree7.test bcb647b42920b3b5d025846689147778485cc318
+F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0
+F ext/rtree/rtree5.test 9a229678a00f40e6aedb40cb3a07ec5444af892c
+F ext/rtree/rtree6.test f67ed7d362ab9a0d13dc2b3d34939e69e0829542
+F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971
 F ext/rtree/rtree8.test 9772e16da71e17e02bdebf0a5188590f289ab37d
-F ext/rtree/rtree9.test df9843d1a9195249c8d3b4ea6aedda2d5c73e9c2
+F ext/rtree/rtree9.test d86ebf08ff6328895613ed577dd8a2a37c472c34
 F ext/rtree/rtreeA.test ace05e729a36e342d40cf94e9efc7b4723d9dcdf
-F ext/rtree/rtreeB.test b1916a9cecb86b02529c4cc5a546e8d6e7ff10da
+F ext/rtree/rtreeB.test 983e567b49b5dca165940f66b87e161aa30e82b2
 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
-F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
+F ext/rtree/sqlite3rtree.h c34c1e41d1ab80bb8ad09aae402c9c956871a765
 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
@@ -203,7 +203,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
 F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
 F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
 F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
-F src/test_config.c a036a69b550ebc477ab9ca2b37269201f888436e
+F src/test_config.c 0de329e736eb4aa5845069bed630e5c72f012264
 F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
 F src/test_func.c 6232d722a4ddb193035aa13a03796bf57d6c12fd
@@ -223,7 +223,7 @@ F src/test_osinst.c 7f790ac89c5a585d51b341274d9691c3391e0923
 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
 F src/test_quota.c a545115f837da4ef32f6b5578f147b44cfb13fd7
 F src/test_quota.h 9ffa1d3ad6d0a6a24e8670ea64b909c717ec3358
-F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1
+F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
 F src/test_stat.c d7035cfcc0ff1f93c000b621f36524318e004e11
@@ -1000,7 +1000,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P af602d87736b52802a4e760ffeeaa28112b99d9a
-R 1de8fb5482810a4710e15863a31ff0ee
+P fb121980e48af368353431fd04924e414b65c852
+R 5f487522a2da2d1baf5cda41d792b333
 U drh
-Z 057914300e7aa29e2f4f5068087794b4
+Z f6050a33b89113e7c2cd85615563f7a3
index a74c90f45f457332b42bf44517575ce684692334..211e12f14c7b4184e5122ce35541fdda7473487a 100644 (file)
@@ -1 +1 @@
-fb121980e48af368353431fd04924e414b65c852
\ No newline at end of file
+02b7640f5118e0a635b68f65765191bb3171b7bd
\ No newline at end of file
index 18442a49e0654af18c36dd509c64bdcbc78fdc8e..f096ebf2362fca55c1c015042249a898872c182d 100644 (file)
@@ -420,6 +420,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
   Tcl_SetVar2(interp, "sqlite_options", "rtree", "0", TCL_GLOBAL_ONLY);
 #endif
 
+#ifdef SQLITE_RTREE_INT_ONLY
+  Tcl_SetVar2(interp, "sqlite_options", "rtree_int_only", "1", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "rtree_int_only", "0", TCL_GLOBAL_ONLY);
+#endif
+
 #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
   Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY);
 #else
index 9745b00541779d17dfb3022e561ac8692f170c9a..d3c9e0cb3de92614045d4f0bd534ad23c2d6b7bb 100644 (file)
@@ -49,7 +49,11 @@ static void circle_del(void *p){
 static int circle_geom(
   sqlite3_rtree_geometry *p,
   int nCoord, 
+#ifdef SQLITE_RTREE_INT_ONLY
+  sqlite3_int64 *aCoord,
+#else
   double *aCoord, 
+#endif
   int *pRes
 ){
   int i;                          /* Iterator variable */
@@ -188,8 +192,12 @@ static int gHere = 42;
 */
 static int cube_geom(
   sqlite3_rtree_geometry *p,
-  int nCoord, 
+  int nCoord,
+#ifdef SQLITE_RTREE_INT_ONLY
+  sqlite3_int64 *aCoord, 
+#else
   double *aCoord, 
+#endif
   int *piRes
 ){
   Cube *pCube = (Cube *)p->pUser;