]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Refactor the constraint checking logic in RTree. The new-style constraint
authordrh <drh@noemail.net>
Thu, 17 Apr 2014 13:15:33 +0000 (13:15 +0000)
committerdrh <drh@noemail.net>
Thu, 17 Apr 2014 13:15:33 +0000 (13:15 +0000)
callbacks created by sqlite3_rtree_query_callback() are now hooked up from
end to end, though still untested.

FossilOrigin-Name: 32a13870175a1dd1d33af3572dde09ff607a04b6

ext/rtree/rtree.c
ext/rtree/rtree6.test
ext/rtree/rtreeC.test
manifest
manifest.uuid

index 6bf1db11c4f71ffe2454808a4e91a435ca12647a..3c9a8daba938fd1ef2b096c28f8697c0ee347372 100644 (file)
@@ -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; i<nCoord; i++){
-    aCoord[i] = DCOORD(pCell->aCoord[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; i<nCoord; i++, pCellData += 4){
+    RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]);
+  }
+  if( pConstraint->op==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 && ii<pCursor->nConstraint; 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.rValue<cell_min; 
-        break;
+  sqlite3_rtree_dbl val;     /* Coordinate value convert to a double */
 
-      case RTREE_GE: case RTREE_GT: 
-        bOutOfBounds = p->u.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.rValue<cell_min);
-        break;
+  assert(p->op==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 && ii<pCursor->nConstraint; 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 = (coord<p->u.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->iCell<nCell ){
-      nodeGetCell(pRtree, pNode, p->iCell, &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; ii<nConstraint; ii++){
+        RtreeConstraint *pConstraint = pCur->aConstraint + 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; ii<argc; ii++){
           RtreeConstraint *p = &pCsr->aConstraint[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;
     }
index bdc9bb414613c660a2d464b3d74360a432d41612..c5a78bb3e333383dfd3ab0ca127b5065b8be7463 100644 (file)
@@ -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
index 23dc60784191e535884d65222723f9eb3fd01887..94db05a4d1b77bda2bdfe427e34c49e051a99dcf 100644 (file)
@@ -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
-
index 336104aca0ff43b444688f31eac4be1bbad7ee28..d10804afcba12e49bbf9cd6d5e68c1540804deb7 100644 (file)
--- 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
index a27b70bb2156dda55bcb3fbcf52e57d761bcb12a..5fbbb6cae9bb877239359a4e953dc5e813ba492d 100644 (file)
@@ -1 +1 @@
-5d20ff9ec837ad35bc44d6c25d13764b350e81dd
\ No newline at end of file
+32a13870175a1dd1d33af3572dde09ff607a04b6
\ No newline at end of file