]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Use doclist-indexes with "ORDER BY rowid ASC" fts5 queries as well.
authordan <dan@noemail.net>
Tue, 5 Aug 2014 19:00:22 +0000 (19:00 +0000)
committerdan <dan@noemail.net>
Tue, 5 Aug 2014 19:00:22 +0000 (19:00 +0000)
FossilOrigin-Name: d028ba6589f3122b635474c2683c0f93d5bc6c7c

ext/fts5/fts5_index.c
manifest
manifest.uuid
test/fts5aa.test
test/fts5ac.test
test/fts5ah.test

index a1735a1104801ff5864d1592a933af03f201612a..7d98ef72ffadd9be558dda018217882f28551ad2 100644 (file)
@@ -550,18 +550,23 @@ struct Fts5NodeIter {
 ** of a doclist-index record.
 **
 ** pData:
-**   A reference to the dlidx record.
+**   Record containing the doclist-index data.
+**
+** bEof:
+**   Set to true once iterator has reached EOF.
+**
+** iOff:
+**   Set to the current offset within record pData.
 */
 struct Fts5DlidxIter {
   Fts5Data *pData;              /* Data for doclist index, if any */
   int iOff;                     /* Current offset into pDlidx */
-  int bRowidValid;              /* iRowid is valid */
   int bEof;                     /* At EOF already */
+  int iFirstOff;                /* Used by reverse iterators only */
 
   /* Output variables */
   int iLeafPgno;                /* Page number of current leaf page */
-  int bZero;                    /* True if current leaf has no rowids */
-  i64 iRowid;                   /* If bZero==0, first rowid on leaf */
+  i64 iRowid;                   /* First rowid on leaf iLeafPgno */
 };
 
 
@@ -1124,14 +1129,83 @@ static void fts5NodeIterFree(Fts5NodeIter *pIter){
 }
 
 /*
-** Return non-zero if EOF is reached.
+** The iterator passed as the first argument has the following fields set
+** as follows. This function sets up the rest of the iterator so that it
+** points to the first rowid in the doclist-index.
+**
+**   pData: pointer to doclist-index record, 
+**   iLeafPgno: page number that this doclist-index is associated with.
+*/
+static int fts5DlidxIterFirst(Fts5DlidxIter *pIter){
+  Fts5Data *pData = pIter->pData;
+  int i;
+
+  assert( pIter->pData );
+  assert( pIter->iLeafPgno>0 );
+
+  /* Count the number of leading 0x00 bytes. Then set iLeafPgno. */
+  for(i=0; i<pData->n; i++){ 
+    if( pData->p[i] ) break;
+  }
+  pIter->iLeafPgno += (i+1);
+  pIter->iOff = i;
+
+  /* Unless we are already at the end of the doclist-index, load the first
+  ** rowid value.  */
+  if( pIter->iOff<pData->n ){
+    pIter->iOff += getVarint(&pData->p[pIter->iOff], (u64*)&pIter->iRowid);
+  }else{
+    pIter->bEof = 1;
+  }
+  pIter->iFirstOff = pIter->iOff;
+  return pIter->bEof;
+}
+
+/*
+** Advance the iterator passed as the only argument.
 */
-static int fts5DlidxIterNext(Fts5DlidxIter *pIter, int bRev){
-  if( bRev ){
+static int fts5DlidxIterNext(Fts5DlidxIter *pIter){
+  Fts5Data *pData = pIter->pData;
+  int iOff;
+
+  for(iOff=pIter->iOff; iOff<pData->n; iOff++){
+    if( pData->p[iOff] ) break; 
+  }
+
+  if( iOff<pData->n ){
     i64 iVal;
-    int iOff = pIter->iOff;
-    int iLimit;
+    pIter->iLeafPgno += (iOff - pIter->iOff) + 1;
+    iOff += getVarint(&pData->p[iOff], (u64*)&iVal);
+    pIter->iRowid -= iVal;
+    pIter->iOff = iOff;
+  }else{
+    pIter->bEof = 1;
+  }
+
+  return pIter->bEof;
+}
+
+static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){
+  return (p->rc!=SQLITE_OK || pIter->bEof);
+}
+
+static void fts5DlidxIterLast(Fts5DlidxIter *pIter){
+  if( fts5DlidxIterFirst(pIter)==0 ){
+    while( 0==fts5DlidxIterNext(pIter) );
+    pIter->bEof = 0;
+  }
+}
+
+static int fts5DlidxIterPrev(Fts5DlidxIter *pIter){
+  int iOff = pIter->iOff;
+
+  assert( pIter->bEof==0 );
+  if( iOff<=pIter->iFirstOff ){
+    pIter->bEof = 1;
+  }else{
     u8 *a = pIter->pData->p;
+    i64 iVal;
+    int iLimit;
 
     /* Currently iOff points to the first byte of a varint. This block 
     ** decrements iOff until it points to the first byte of the previous 
@@ -1141,53 +1215,19 @@ static int fts5DlidxIterNext(Fts5DlidxIter *pIter, int bRev){
     for(iOff--; iOff>iLimit; iOff--){
       if( (a[iOff-1] & 0x80)==0 ) break;
     }
-    pIter->iOff = iOff;
-
-    if( iOff<=0 ){
-      pIter->bEof = 1;
-      return 1;
-    }
 
     getVarint(&a[iOff], (u64*)&iVal);
-    if( iVal==0 ){
-      pIter->bZero = 1;
-    }else if( iOff==0 ){
-      pIter->iRowid = iVal;
-    }else{
-      pIter->iRowid += iVal;
-    }
+    pIter->iRowid += iVal;
     pIter->iLeafPgno--;
-  }else{
-    i64 iVal;
-    if( pIter->iOff>=pIter->pData->n ){
-      pIter->bEof = 1;
-      return 1;
-    }
-    pIter->iOff += getVarint(&pIter->pData->p[pIter->iOff], (u64*)&iVal);
-    if( iVal==0 ){
-      pIter->bZero = 1;
-    }else{
-      pIter->bZero = 0;
-      if( pIter->bRowidValid ){
-        pIter->iRowid -= iVal;
-      }else{
-        pIter->bRowidValid = 1;
-        pIter->iRowid = iVal;
-      }
+
+    while( a[iOff-1]==0x00 ){
+      iOff--;
+      pIter->iLeafPgno--;
     }
-    pIter->iLeafPgno++;
+    pIter->iOff = iOff;
   }
-  return 0;
-}
-
-static void fts5DlidxIterLast(Fts5DlidxIter *pIter){
-  while( 0==fts5DlidxIterNext(pIter, 0) );
-  assert( pIter->iOff==pIter->pData->n && pIter->bEof==1 );
-  pIter->bEof = 0;
-}
 
-static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){
-  return (p->rc!=SQLITE_OK || pIter->bEof);
+  return pIter->bEof;
 }
 
 static void fts5DlidxIterInit(
@@ -1213,10 +1253,9 @@ static void fts5DlidxIterInit(
   }
 
   pIter->pData = pDlidx;
-
   pIter->iLeafPgno = iLeafPgno;
   if( bRev==0 ){
-    fts5DlidxIterNext(pIter, 0);
+    fts5DlidxIterFirst(pIter);
   }else{
     fts5DlidxIterLast(pIter);
   }
@@ -1438,44 +1477,6 @@ static void fts5SegIterNext(
         pIter->iRowid += iDelta;
       }else{
         fts5SegIterReverseNewPage(p, pIter);
-#if 0
-        fts5DataRelease(pIter->pLeaf);
-        pIter->pLeaf = 0;
-        while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){
-          Fts5Data *pNew;
-          pIter->iLeafPgno--;
-          pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID(
-                pIter->iIdx, pIter->pSeg->iSegid, 0, pIter->iLeafPgno
-          ));
-          if( pNew ){
-            if( pIter->iLeafPgno==pIter->iTermLeafPgno ){
-              if( pIter->iTermLeafOffset<pNew->n ){
-                pIter->pLeaf = pNew;
-                pIter->iLeafOffset = pIter->iTermLeafOffset;
-              }
-            }else{
-              int iRowidOff, dummy;
-              fts5LeafHeader(pNew, &iRowidOff, &dummy);
-              if( iRowidOff ){
-                pIter->pLeaf = pNew;
-                pIter->iLeafOffset = iRowidOff;
-              }
-            }
-
-            if( pIter->pLeaf ){
-              u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
-              pIter->iLeafOffset += getVarint(a, (u64*)&pIter->iRowid);
-              break;
-            }else{
-              fts5DataRelease(pNew);
-            }
-          }
-        }
-
-        if( pIter->pLeaf ){
-          fts5SegIterReverseInitPage(p, pIter);
-        }
-#endif
       }
     }else{
       Fts5Data *pLeaf = pIter->pLeaf;
@@ -1555,43 +1556,49 @@ static void fts5SegIterReverse(Fts5Index *p, int iIdx, Fts5SegIter *pIter){
   /* Move to the page that contains the last rowid in this doclist. */
   pLeaf = pIter->pLeaf;
 
-  while( iOff<pLeaf->n ){
-    int nPos;
-    i64 iDelta;
+  if( pIter->pDlidx ){
+    int iSegid = pIter->pSeg->iSegid;
+    pgnoLast = pIter->pDlidx->iLeafPgno;
+    pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, pgnoLast));
+  }else{
+    while( iOff<pLeaf->n ){
+      int nPos;
+      i64 iDelta;
 
-    /* Position list size in bytes */
-    iOff += getVarint32(&pLeaf->p[iOff], nPos);
-    iOff += nPos;
-    if( iOff>=pLeaf->n ) break;
+      /* Position list size in bytes */
+      iOff += getVarint32(&pLeaf->p[iOff], nPos);
+      iOff += nPos;
+      if( iOff>=pLeaf->n ) break;
 
-    /* Rowid delta. Or, if 0x00, the end of doclist marker. */
-    nPos = getVarint(&pLeaf->p[iOff], (u64*)&iDelta);
-    if( iDelta==0 ) break;
-    iOff += nPos;
-  }
-
-  if( iOff>=pLeaf->n ){
-    Fts5StructureSegment *pSeg = pIter->pSeg;
-    i64 iAbs = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pIter->iLeafPgno);
-    i64 iLast = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pSeg->pgnoLast);
-
-    /* The last rowid in the doclist may not be on the current page. Search
-    ** forward to find the page containing the last rowid.  */
-    for(iAbs++; p->rc==SQLITE_OK && iAbs<=iLast; iAbs++){
-      Fts5Data *pNew = fts5DataRead(p, iAbs);
-      if( pNew ){
-        int iRowid, iTerm;
-        fts5LeafHeader(pNew, &iRowid, &iTerm);
-        if( iRowid ){
-          Fts5Data *pTmp = pLast;
-          pLast = pNew;
-          pNew = pTmp;
-          pgnoLast = iAbs & (((i64)1 << FTS5_DATA_PAGE_B) - 1);
-        }
-        if( iTerm ){
-          iAbs = iLast;
+      /* Rowid delta. Or, if 0x00, the end of doclist marker. */
+      nPos = getVarint(&pLeaf->p[iOff], (u64*)&iDelta);
+      if( iDelta==0 ) break;
+      iOff += nPos;
+    }
+
+    if( iOff>=pLeaf->n ){
+      Fts5StructureSegment *pSeg = pIter->pSeg;
+      i64 iAbs = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pIter->iLeafPgno);
+      i64 iLast = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pSeg->pgnoLast);
+
+      /* The last rowid in the doclist may not be on the current page. Search
+       ** forward to find the page containing the last rowid.  */
+      for(iAbs++; p->rc==SQLITE_OK && iAbs<=iLast; iAbs++){
+        Fts5Data *pNew = fts5DataRead(p, iAbs);
+        if( pNew ){
+          int iRowid, iTerm;
+          fts5LeafHeader(pNew, &iRowid, &iTerm);
+          if( iRowid ){
+            Fts5Data *pTmp = pLast;
+            pLast = pNew;
+            pNew = pTmp;
+            pgnoLast = iAbs & (((i64)1 << FTS5_DATA_PAGE_B) - 1);
+          }
+          if( iTerm ){
+            iAbs = iLast;
+          }
+          fts5DataRelease(pNew);
         }
-        fts5DataRelease(pNew);
       }
     }
   }
@@ -1615,7 +1622,6 @@ static void fts5SegIterReverse(Fts5Index *p, int iIdx, Fts5SegIter *pIter){
   }
 
   fts5SegIterReverseInitPage(p, pIter);
-  pIter->flags |= FTS5_SEGITER_REVERSE;
 }
 
 /*
@@ -1733,6 +1739,9 @@ static void fts5SegIterSeekInit(
   if( bGe==0 ){
     pIter->flags |= FTS5_SEGITER_ONETERM;
     if( pIter->pLeaf ){
+      if( flags & FTS5INDEX_QUERY_ASC ){
+        pIter->flags |= FTS5_SEGITER_REVERSE;
+      }
       if( bDlidx ){
         fts5SegIterLoadDlidx(p, iIdx, pIter);
       }
@@ -1879,37 +1888,44 @@ static void fts5SegIterNextFrom(
   int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
   Fts5DlidxIter *pDlidx = pIter->pDlidx;
   int iLeafPgno = pIter->iLeafPgno;
+  int bMove = 1;
 
   assert( pIter->flags & FTS5_SEGITER_ONETERM );
   assert( pIter->pDlidx );
   assert( pIter->pLeaf );
 
-
   if( bRev==0 ){
     while( fts5DlidxIterEof(p, pDlidx)==0 && iMatch<pDlidx->iRowid ){
-      if( pDlidx->bZero==0 ) iLeafPgno = pDlidx->iLeafPgno;
-      fts5DlidxIterNext(pDlidx, 0);
+      iLeafPgno = pDlidx->iLeafPgno;
+      fts5DlidxIterNext(pDlidx);
     }
     assert( iLeafPgno>=pIter->iLeafPgno || p->rc );
     if( iLeafPgno>pIter->iLeafPgno ){
       fts5SegIterGotoPage(p, pIter, iLeafPgno);
+      bMove = 0;
     }
-  }else if( 0 ){
+  }else{
+    assert( iMatch>pIter->iRowid );
     while( fts5DlidxIterEof(p, pDlidx)==0 && iMatch>pDlidx->iRowid ){
-      fts5DlidxIterNext(pDlidx, 0);
-      if( pDlidx->bZero==0 ) iLeafPgno = pDlidx->iLeafPgno;
+      fts5DlidxIterPrev(pDlidx);
     }
-    assert( iLeafPgno<=pIter->iLeafPgno || p->rc );
+    iLeafPgno = pDlidx->iLeafPgno;
+
+    assert( fts5DlidxIterEof(p, pDlidx) || iLeafPgno<=pIter->iLeafPgno );
+
     if( iLeafPgno<pIter->iLeafPgno ){
-      fts5SegIterGotoPage(p, pIter, iLeafPgno);
+      pIter->iLeafPgno = iLeafPgno+1;
+      fts5SegIterReverseNewPage(p, pIter);
+      bMove = 0;
     }
   }
 
   while( 1 ){
-    fts5SegIterNext(p, pIter);
+    if( bMove ) fts5SegIterNext(p, pIter);
     if( pIter->pLeaf==0 ) break;
     if( bRev==0 && pIter->iRowid<=iMatch ) break;
     if( bRev!=0 && pIter->iRowid>=iMatch ) break;
+    bMove = 1;
   }
 }
 
@@ -3377,7 +3393,50 @@ static void fts5BtreeIterFree(Fts5BtreeIter *pIter){
   fts5BufferFree(&pIter->term);
 }
 
+/*
+** This function is purely an internal test. It does not contribute to 
+** FTS functionality, or even the integrity-check, in any way.
+**
+** Instead, it tests that the same set of pgno/rowid combinations are 
+** visited regardless of whether the doclist-index identified by parameters
+** iIdx/iSegid/iLeaf is iterated in forwards or reverse order.
+*/
+#ifdef SQLITE_DEBUG
+static void fts5DlidxIterTestReverse(
+  Fts5Index *p, 
+  int iIdx,                       /* Index to load doclist-index from */
+  int iSegid,                     /* Segment id to load from */
+  int iLeaf                       /* Load doclist-index for this leaf */
+){
+  Fts5DlidxIter *pDlidx = 0;
+  i64 cksum1 = 13;
+  i64 cksum2 = 13;
 
+  for(fts5DlidxIterInit(p, 0, iIdx, iSegid, iLeaf, &pDlidx);
+      fts5DlidxIterEof(p, pDlidx)==0;
+      fts5DlidxIterNext(pDlidx)
+  ){
+    cksum1 = (cksum1 ^ ( (i64)(pDlidx->iLeafPgno) << 32 ));
+    cksum1 = (cksum1 ^ pDlidx->iRowid);
+  }
+  fts5DlidxIterFree(pDlidx);
+  pDlidx = 0;
+
+  for(fts5DlidxIterInit(p, 1, iIdx, iSegid, iLeaf, &pDlidx);
+      fts5DlidxIterEof(p, pDlidx)==0;
+      fts5DlidxIterPrev(pDlidx)
+  ){
+    cksum2 = (cksum2 ^ ( (i64)(pDlidx->iLeafPgno) << 32 ));
+    cksum2 = (cksum2 ^ pDlidx->iRowid);
+  }
+  fts5DlidxIterFree(pDlidx);
+  pDlidx = 0;
+
+  if( p->rc==SQLITE_OK && cksum1!=cksum2 ) p->rc = FTS5_CORRUPT; 
+}
+#else
+# define fts5DlidxIterTestReverse(w,x,y,z)
+#endif
 
 static void fts5IndexIntegrityCheckSegment(
   Fts5Index *p,                   /* FTS5 backend object */
@@ -3421,7 +3480,6 @@ static void fts5IndexIntegrityCheckSegment(
     fts5DataRelease(pLeaf);
     if( p->rc ) break;
 
-
     /* Now check that the iter.nEmpty leaves following the current leaf
     ** (a) exist and (b) contain no terms. */
     for(i=1; p->rc==SQLITE_OK && i<=iter.nEmpty; i++){
@@ -3435,35 +3493,52 @@ static void fts5IndexIntegrityCheckSegment(
     /* If there is a doclist-index, check that it looks right. */
     if( iter.bDlidx ){
       Fts5DlidxIter *pDlidx = 0;  /* For iterating through doclist index */
-      int nEntry = 0;
+      int iPrevLeaf = iter.iLeaf;
       int iSegid = pSeg->iSegid;
-      int bRev = 0;
+      int iPg;
+      i64 iKey;
 
-      for(fts5DlidxIterInit(p, bRev, iIdx, iSegid, iter.iLeaf, &pDlidx);
+      for(fts5DlidxIterInit(p, 0, iIdx, iSegid, iter.iLeaf, &pDlidx);
           fts5DlidxIterEof(p, pDlidx)==0;
-          fts5DlidxIterNext(pDlidx, bRev)
+          fts5DlidxIterNext(pDlidx)
       ){
-        i64 iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, pDlidx->iLeafPgno);
+
+        /* Check any rowid-less pages that occur before the current leaf. */
+        for(iPg=iPrevLeaf+1; iPg<pDlidx->iLeafPgno; iPg++){
+          iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, iPg);
+          pLeaf = fts5DataRead(p, iKey);
+          if( pLeaf ){
+            if( fts5GetU16(&pLeaf->p[0])!=0 ) p->rc = FTS5_CORRUPT;
+            fts5DataRelease(pLeaf);
+          }
+        }
+        iPrevLeaf = pDlidx->iLeafPgno;
+
+        /* Check that the leaf page indicated by the iterator really does
+        ** contain the rowid suggested by the same. */
+        iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, pDlidx->iLeafPgno);
         pLeaf = fts5DataRead(p, iKey);
         if( pLeaf ){
+          i64 iRowid;
           int iRowidOff = fts5GetU16(&pLeaf->p[0]);
-          if( pDlidx->bZero ){
-            if( iRowidOff!=0 ) p->rc = FTS5_CORRUPT;
-          }else{
-            i64 iRowid;
-            getVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
-            if( iRowid!=pDlidx->iRowid ) p->rc = FTS5_CORRUPT;
-          }
+          getVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
+          if( iRowid!=pDlidx->iRowid ) p->rc = FTS5_CORRUPT;
           fts5DataRelease(pLeaf);
         }
-        nEntry++;
+
       }
 
-      /* Check that the doclist-index was the right length */
-      if( p->rc==SQLITE_OK && nEntry!=iter.nEmpty && nEntry!=iter.nEmpty+1 ){
-        p->rc = FTS5_CORRUPT;
+      for(iPg=iPrevLeaf+1; iPg<=(iter.iLeaf + iter.nEmpty); iPg++){
+        iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, iPg);
+        pLeaf = fts5DataRead(p, iKey);
+        if( pLeaf ){
+          if( fts5GetU16(&pLeaf->p[0])!=0 ) p->rc = FTS5_CORRUPT;
+          fts5DataRelease(pLeaf);
+        }
       }
+
       fts5DlidxIterFree(pDlidx);
+      fts5DlidxIterTestReverse(p, iIdx, iSegid, iter.iLeaf);
     }
   }
 
index bd1784eeb1a1b27c1e3574fcd4d78f9d6fddc797..cca7f70664ad107effbfede7d4d8124b79ffd319 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sfts5_index.c\sto\suse\sdoclist-indexes\swhen\spossible.\sOnly\ssome\scases\swork\sso\sfar.
-D 2014-08-04T20:07:40.532
+C Use\sdoclist-indexes\swith\s"ORDER\sBY\srowid\sASC"\sfts5\squeries\sas\swell.
+D 2014-08-05T19:00:22.438
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in b03432313a3aad96c706f8164fb9f5307eaf19f5
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -110,7 +110,7 @@ F ext/fts5/fts5_aux.c 366057c7186bc3615deb5ecc0ff61de50b6d2dbc
 F ext/fts5/fts5_buffer.c 248c61ac9fec001602efc72a45704f3b8d367c00
 F ext/fts5/fts5_config.c f4ebf143e141b8c77355e3b15aba81b7be51d710
 F ext/fts5/fts5_expr.c 9402474456732ddb5019f83a77907852f108a96a
-F ext/fts5/fts5_index.c 3578823a9a43fcc77ce46c7f6efddfd155544053
+F ext/fts5/fts5_index.c 40d9086948d6f1420a078bd9fb0b5372e54ec791
 F ext/fts5/fts5_storage.c 2866e7e1de9dc851756c3a9c76b6e1d75e0facb7
 F ext/fts5/fts5parse.y 777da8e5819f75c217982c79c29d014c293acac9
 F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
@@ -595,14 +595,14 @@ F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b
 F test/fts4noti.test 524807f0c36d49deea7920cdd4cd687408b58849
 F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36
-F test/fts5aa.test f54245091fee924030722234070fcba95a493549
+F test/fts5aa.test 2d136b61c4523ec018699e59b35c005313569b9e
 F test/fts5ab.test dc04ed48cf93ca957d174406e6c192f2ff4f3397
-F test/fts5ac.test 9be418d037763f4cc5d86f4239db41fc86bb4f85
+F test/fts5ac.test 399533fe52b7383053368ab8ba01ae182391e5d7
 F test/fts5ad.test 2ed38bbc865678cb2905247120d02ebba7f20e07
 F test/fts5ae.test cb37b3135a00d3afd5492ec534ecf654be5ff69e
 F test/fts5af.test 9ebe23aa3875896076952c7bc6e8308813a63c74
 F test/fts5ag.test 0747bf3bade16d5165810cf891f875933b28b420
-F test/fts5ah.test ca1f12b5738992c2edbdeb6c16133d41cfb9c031
+F test/fts5ah.test 009b993a9b7ebc43f84c10e53bd778b1dc8ffbe7
 F test/fts5ea.test ff43b40f8879ba50b82def70f2ab67c195d1a1d4
 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
 F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
@@ -1199,7 +1199,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P b8864da95db2c0e611116304d607e35a86c9247d
-R 2807aba63fb0a8821d708dc4cbc7f577
+P 90b82d3ef613b2915e0e280dc1d2e5a2b617d59c
+R 0266e2e08ce753d75d582fc91e12512e
 U dan
-Z 6114a7973c3151dffa74bd597b78489f
+Z 1a32a19af984c36e1b27a239a8950f8a
index a558eb60084225e66860fd9a96f0364f9066fb72..42fda0330831cfeeb1e36dd063c52187406ed94c 100644 (file)
@@ -1 +1 @@
-90b82d3ef613b2915e0e280dc1d2e5a2b617d59c
\ No newline at end of file
+d028ba6589f3122b635474c2683c0f93d5bc6c7c
\ No newline at end of file
index 3d1fc992899c99dc346fa59f58cb6a6d379e74ed..5bd0912435ccfff8505c0cd54b99177480f41d92 100644 (file)
@@ -148,6 +148,7 @@ do_execsql_test 6.2 {
 #-------------------------------------------------------------------------
 #
 reset_db
+expr srand(0)
 do_execsql_test 7.0 {
   CREATE VIRTUAL TABLE t1 USING fts5(x,y,z);
   INSERT INTO t1(t1) VALUES('pgsz=32');
@@ -173,7 +174,7 @@ proc dump_structure {} {
 
 for {set i 1} {$i <= 10} {incr i} {
   do_test 7.$i {
-    for {set j 0} {$j < 100} {incr j} {
+    for {set j 0} {$j < 10} {incr j} {
       set x [doc]
       set y [doc]
       set z [doc]
index ae6e56e7e7582afeb15a53072a9676ffbfc9855f..b137e3a93804a26b12d100fe05423ed3c08f8b39 100644 (file)
@@ -364,6 +364,10 @@ foreach {tn expr tclexpr} {
 
 #-------------------------------------------------------------------------
 #
+do_execsql_test 6.integrity {
+  INSERT INTO xx(xx) VALUES('integrity-check');
+}
+#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM xx_data} {puts $r}
 foreach {bAsc sql} {
   0 {SELECT rowid FROM xx WHERE xx MATCH $expr}
   1 {SELECT rowid FROM xx WHERE xx MATCH $expr ORDER BY rowid ASC}
index 3f217d9f86491f0a165797f5bb0d82d564f1c873..f5e25848ab33fba6aabf697907e03a78ef533dfc 100644 (file)
@@ -53,6 +53,12 @@ proc reads {} {
   db one {SELECT t1 FROM t1 WHERE t1 MATCH '*reads'}
 }
 
+proc execsql_reads {sql} {
+  set nRead [reads]
+  execsql $sql
+  expr [reads] - $nRead
+}
+
 do_test 1.4 {
   set nRead [reads]
   execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'x' }
@@ -60,6 +66,14 @@ do_test 1.4 {
   expr $nReadX>1000
 } {1}
 
+do_test 1.5 {
+  set fwd [execsql_reads {SELECT rowid FROM t1 WHERE t1 MATCH 'x' }]
+  set bwd [execsql_reads {
+    SELECT rowid FROM t1 WHERE t1 MATCH 'x' ORDER BY 1 ASC 
+  }]
+  expr {$bwd < $fwd + 10}
+} {1}
+
 foreach {tn q res} "
   1 { SELECT rowid FROM t1 WHERE t1 MATCH 'w + x'   }  [list $W]
   2 { SELECT rowid FROM t1 WHERE t1 MATCH 'x + w'   }  [list $W]
@@ -67,22 +81,18 @@ foreach {tn q res} "
   4 { SELECT rowid FROM t1 WHERE t1 MATCH 'y AND x' }  [list $Y]
 " {
 
-  do_test 1.5.$tn.1 {
-    set nRead [reads]
-    execsql $q
-    set n [expr [reads] - $nRead]
+  do_test 1.6.$tn.1 {
+    set n [execsql_reads $q]
     expr {$n < ($nReadX / 10)}
   } {1}
 
-  do_test 1.5.$tn.2 {
-    set nRead [reads]
-    execsql "$q ORDER BY rowid ASC"
-    set n [expr [reads] - $nRead]
+  do_test 1.6.$tn.2 {
+    set n [execsql_reads "$q ORDER BY rowid ASC"]
     expr {$n < ($nReadX / 10)}
   } {1}
 
-  do_execsql_test 1.5.$tn.3 $q [lsort -int -decr $res]
-  do_execsql_test 1.5.$tn.4 "$q ORDER BY rowid ASC" [lsort -int -incr $res]
+  do_execsql_test 1.6.$tn.3 $q [lsort -int -decr $res]
+  do_execsql_test 1.6.$tn.4 "$q ORDER BY rowid ASC" [lsort -int -incr $res]
 }
 
 #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r}