]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Reimplement [ec69e09a] so that each call to the xNext() method does not involve two...
authordan <dan@noemail.net>
Tue, 2 Jun 2015 17:57:01 +0000 (17:57 +0000)
committerdan <dan@noemail.net>
Tue, 2 Jun 2015 17:57:01 +0000 (17:57 +0000)
FossilOrigin-Name: 80fe305b3eefb17310a9d6185d1c8cd73ee38b1e

ext/fts5/fts5_expr.c
ext/fts5/fts5parse.y
ext/fts5/test/fts5auto.test
manifest
manifest.uuid

index ab0874bced4b079da52cf9251ce3264b21634afb..11dfd42502f96f1a15c5fcace45fc4a206d76edc 100644 (file)
@@ -48,10 +48,13 @@ struct Fts5Expr {
 **       FTS5_OR                  (nChild, apChild valid)
 **       FTS5_NOT                 (nChild, apChild valid)
 **       FTS5_STRING              (pNear valid)
+**       FTS5_TERM                (pNear valid)
 */
 struct Fts5ExprNode {
   int eType;                      /* Node type */
   int bEof;                       /* True at EOF */
+  int bNomatch;                   /* True if entry is not a match */
+
   i64 iRowid;                     /* Current rowid */
   Fts5ExprNearset *pNear;         /* For FTS5_STRING - cluster of phrases */
 
@@ -61,6 +64,8 @@ struct Fts5ExprNode {
   Fts5ExprNode *apChild[0];       /* Array of child nodes */
 };
 
+#define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
+
 /*
 ** An instance of the following structure represents a single search term
 ** or term prefix.
@@ -287,7 +292,7 @@ int sqlite3Fts5ExprPhraseExpr(
       pNew->apExprPhrase = apPhrase;
       pNew->apExprPhrase[0] = pCopy;
 
-      pNode->eType = FTS5_STRING;
+      pNode->eType = (pCopy->nTerm==1 ? FTS5_TERM : FTS5_STRING);
       pNode->pNear = pNear;
 
       pNear->nPhrase = 1;
@@ -590,13 +595,14 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){
 */
 static int fts5ExprNearAdvanceFirst(
   Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
-  Fts5ExprNode *pNode,            /* FTS5_STRING node */
+  Fts5ExprNode *pNode,            /* FTS5_STRING or FTS5_TERM node */
   int bFromValid,
   i64 iFrom 
 ){
   Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
   int rc;
 
+  assert( Fts5NodeIsString(pNode) );
   if( bFromValid ){
     rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
   }else{
@@ -642,55 +648,6 @@ static int fts5ExprAdvanceto(
   return 0;
 }
 
-/*
-** All individual term iterators in pNear are guaranteed to be valid when
-** this function is called. This function checks if all term iterators
-** point to the same rowid, and if not, advances them until they do.
-** If an EOF is reached before this happens, *pbEof is set to true before
-** returning.
-**
-** SQLITE_OK is returned if an error occurs, or an SQLite error code 
-** otherwise. It is not considered an error code if an iterator reaches
-** EOF.
-*/
-static int fts5ExprNearNextRowidMatch(
-  Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
-  Fts5ExprNode *pNode
-){
-  Fts5ExprNearset *pNear = pNode->pNear;
-  i64 iLast;                      /* Lastest rowid any iterator points to */
-  int rc = SQLITE_OK;
-
-  /* Initialize iLast, the "lastest" rowid any iterator points to. If the
-  ** iterator skips through rowids in the default ascending order, this means
-  ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
-  ** means the minimum rowid.  */
-  iLast = sqlite3Fts5IterRowid(pNear->apPhrase[0]->aTerm[0].pIter);
-
-  if( pNear->nPhrase>1 || pNear->apPhrase[0]->nTerm>1 ){
-    int i, j;                     /* Phrase and token index, respectively */
-    int bMatch;                   /* True if all terms are at the same rowid */
-    do {
-      bMatch = 1;
-      for(i=0; i<pNear->nPhrase; i++){
-        Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
-        for(j=0; j<pPhrase->nTerm; j++){
-          Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
-          i64 iRowid = sqlite3Fts5IterRowid(pIter);
-          if( iRowid!=iLast ) bMatch = 0;
-          if( fts5ExprAdvanceto(pIter, pExpr->bDesc, &iLast,&rc,&pNode->bEof) ){
-            return rc;
-          }
-        }
-      }
-    }while( bMatch==0 );
-  }
-
-  pNode->iRowid = iLast;
-  return rc;
-}
-
-
 /*
 ** IN/OUT parameter (*pa) points to a position list n bytes in size. If
 ** the position list contains entries for column iCol, then (*pa) is set
@@ -817,45 +774,97 @@ static int fts5ExprNearTest(
   return 0;
 }
 
+static int fts5ExprTokenTest(
+  Fts5Expr *pExpr,                /* Expression that pNear is a part of */
+  Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_TERM) */
+){
+  /* As this "NEAR" object is actually a single phrase that consists 
+  ** of a single term only, grab pointers into the poslist managed by the
+  ** fts5_index.c iterator object. This is much faster than synthesizing 
+  ** a new poslist the way we have to for more complicated phrase or NEAR
+  ** expressions.  */
+  Fts5ExprNearset *pNear = pNode->pNear;
+  Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
+  Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
+  Fts5ExprColset *pColset = pNear->pColset;
+  const u8 *pPos;
+  int nPos;
+  int rc;
+
+  assert( pNode->eType==FTS5_TERM );
+  assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
+
+  rc = sqlite3Fts5IterPoslist(pIter, &pPos, &nPos, &pNode->iRowid);
+
+  /* If the term may match any column, then this must be a match. 
+  ** Return immediately in this case. Otherwise, try to find the
+  ** part of the poslist that corresponds to the required column.
+  ** If it can be found, return. If it cannot, the next iteration
+  ** of the loop will test the next rowid in the database for this
+  ** term.  */
+  if( pColset==0 ){
+    assert( pPhrase->poslist.nSpace==0 );
+    pPhrase->poslist.p = (u8*)pPos;
+    pPhrase->poslist.n = nPos;
+  }else if( pColset->nCol==1 ){
+    assert( pPhrase->poslist.nSpace==0 );
+    pPhrase->poslist.n = fts5ExprExtractCol(&pPos, nPos, pColset->aiCol[0]);
+    pPhrase->poslist.p = (u8*)pPos;
+  }else if( rc==SQLITE_OK ){
+    rc = fts5ExprExtractColset(pColset, pPos, nPos, &pPhrase->poslist);
+  }
+
+  pNode->bNomatch = (pPhrase->poslist.n==0);
+  return rc;
+}
+
 /*
-** Argument pNode points to a NEAR node. All individual term iterators 
-** point to valid entries (not EOF).
-*
-** This function tests if the term iterators currently all point to the
-** same rowid, and if so, if the row matches the phrase and NEAR constraints. 
-** If so, the pPhrase->poslist buffers are populated and the pNode->iRowid
-** variable set before returning. Or, if the current combination of 
-** iterators is not a match, they are advanced until they are. If one of
-** the iterators reaches EOF before a match is found, *pbEof is set to
-** true before returning. The final values of the pPhrase->poslist and 
-** iRowid fields are undefined in this case.
+** All individual term iterators in pNear are guaranteed to be valid when
+** this function is called. This function checks if all term iterators
+** point to the same rowid, and if not, advances them until they do.
+** If an EOF is reached before this happens, *pbEof is set to true before
+** returning.
 **
 ** SQLITE_OK is returned if an error occurs, or an SQLite error code 
 ** otherwise. It is not considered an error code if an iterator reaches
 ** EOF.
 */
 static int fts5ExprNearNextMatch(
-  Fts5Expr *pExpr,                /* Expression that pNear is a part of */
-  Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_STRING) */
+  Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
+  Fts5ExprNode *pNode
 ){
+  Fts5ExprNearset *pNear = pNode->pNear;
+  Fts5ExprPhrase *pLeft = pNear->apPhrase[0];
   int rc = SQLITE_OK;
+  i64 iLast;                      /* Lastest rowid any iterator points to */
+  int i, j;                       /* Phrase and token index, respectively */
+  int bMatch;                     /* True if all terms are at the same rowid */
 
-  assert( pNode->pNear );
-  while( 1 ){
-
-    /* Advance the iterators until they all point to the same rowid */
-    rc = fts5ExprNearNextRowidMatch(pExpr, pNode);
-    if( rc!=SQLITE_OK || pNode->bEof ) break;
+  assert( pNear->nPhrase>1 || pNear->apPhrase[0]->nTerm>1 );
 
-    if( fts5ExprNearTest(&rc, pExpr, pNode) ) break;
+  /* Initialize iLast, the "lastest" rowid any iterator points to. If the
+  ** iterator skips through rowids in the default ascending order, this means
+  ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
+  ** means the minimum rowid.  */
+  iLast = sqlite3Fts5IterRowid(pLeft->aTerm[0].pIter);
 
-    /* If control flows to here, then the current rowid is not a match.
-    ** Advance all term iterators in all phrases to the next rowid. */
-    if( rc==SQLITE_OK ){
-      rc = fts5ExprNearAdvanceFirst(pExpr, pNode, 0, 0);
+  do {
+    bMatch = 1;
+    for(i=0; i<pNear->nPhrase; i++){
+      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+      for(j=0; j<pPhrase->nTerm; j++){
+        Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
+        i64 iRowid = sqlite3Fts5IterRowid(pIter);
+        if( iRowid!=iLast ) bMatch = 0;
+        if( fts5ExprAdvanceto(pIter, pExpr->bDesc, &iLast,&rc,&pNode->bEof) ){
+          return rc;
+        }
+      }
     }
-    if( pNode->bEof || rc!=SQLITE_OK ) break;
-  }
+  }while( bMatch==0 );
+
+  pNode->bNomatch = (0==fts5ExprNearTest(&rc, pExpr, pNode));
+  pNode->iRowid = iLast;
 
   return rc;
 }
@@ -939,6 +948,22 @@ static void fts5ExprSetEof(Fts5ExprNode *pNode){
   }
 }
 
+static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
+  if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
+    Fts5ExprNearset *pNear = pNode->pNear;
+    int i;
+    for(i=0; i<pNear->nPhrase; i++){
+      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
+      pPhrase->poslist.n = 0;
+    }
+  }else{
+    int i;
+    for(i=0; i<pNode->nChild; i++){
+      fts5ExprNodeZeroPoslist(pNode->apChild[i]);
+    }
+  }
+}
+
 
 static int fts5ExprNodeNext(Fts5Expr*, Fts5ExprNode*, int, i64);
 
@@ -956,6 +981,7 @@ static int fts5ExprAndNextRowid(
 
   assert( pAnd->bEof==0 );
   do {
+    pAnd->bNomatch = 0;
     bMatch = 1;
     for(iChild=0; iChild<pAnd->nChild; iChild++){
       Fts5ExprNode *pChild = pAnd->apChild[iChild];
@@ -983,9 +1009,16 @@ static int fts5ExprAndNextRowid(
         bMatch = 0;
         iLast = pChild->iRowid;
       }
+
+      if( pChild->bNomatch ){
+        pAnd->bNomatch = 1;
+      }
     }
   }while( bMatch==0 );
 
+  if( pAnd->bNomatch && pAnd!=pExpr->pRoot ){
+    fts5ExprNodeZeroPoslist(pAnd);
+  }
   pAnd->iRowid = iLast;
   return SQLITE_OK;
 }
@@ -1035,6 +1068,15 @@ static int fts5ExprNodeNext(
         break;
       };
 
+      case FTS5_TERM: {
+        rc = fts5ExprNearAdvanceFirst(pExpr, pNode, bFromValid, iFrom);
+        if( pNode->bEof==0 ){
+          assert( rc==SQLITE_OK );
+          rc = fts5ExprTokenTest(pExpr, pNode);
+        }
+        return rc;
+      };
+
       case FTS5_AND: {
         Fts5ExprNode *pLeft = pNode->apChild[0];
         rc = fts5ExprNodeNext(pExpr, pLeft, bFromValid, iFrom);
@@ -1087,76 +1129,6 @@ static int fts5ExprNodeNext(
   return rc;
 }
 
-static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
-  if( pNode->eType==FTS5_STRING ){
-    Fts5ExprNearset *pNear = pNode->pNear;
-    int i;
-    for(i=0; i<pNear->nPhrase; i++){
-      Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
-      pPhrase->poslist.n = 0;
-    }
-  }else{
-    int i;
-    for(i=0; i<pNode->nChild; i++){
-      fts5ExprNodeZeroPoslist(pNode->apChild[i]);
-    }
-  }
-}
-
-static int fts5ExprNodeTest(
-  int *pRc, 
-  Fts5Expr *pExpr, 
-  i64 iRowid,
-  Fts5ExprNode *pNode
-){
-  int bRes = 0;
-  if( pNode->bEof || pNode->iRowid!=iRowid ){
-    bRes = 0;
-  }else {
-    switch( pNode->eType ){
-      case FTS5_STRING:
-        bRes = fts5ExprNearTest(pRc, pExpr, pNode);
-        if( *pRc ) bRes = 0;
-        break;
-
-      case FTS5_AND: {
-        int i;
-        for(i=0; i<pNode->nChild; i++){
-          if( fts5ExprNodeTest(pRc, pExpr, iRowid, pNode->apChild[i])==0 ){
-            break;
-          }
-        }
-        bRes = (i==pNode->nChild);
-        if( bRes==0 && i>0 ){
-          for(i=0; i<pNode->nChild; i++){
-            fts5ExprNodeZeroPoslist(pNode->apChild[i]);
-          }
-        }
-
-        break;
-      }
-
-      case FTS5_OR: {
-        int i;
-        for(i=0; i<pNode->nChild; i++){
-          if( fts5ExprNodeTest(pRc, pExpr, iRowid, pNode->apChild[i]) ){
-            bRes = 1;
-          }
-        }
-        break;
-      }
-
-      default:
-        assert( pNode->eType==FTS5_NOT );
-        assert( pNode->nChild==2 );
-        bRes = fts5ExprNodeTest(pRc, pExpr, iRowid, pNode->apChild[0]);
-        break;
-    }
-  }
-
-  return bRes;
-}
-
 
 /*
 ** If pNode currently points to a match, this function returns SQLITE_OK
@@ -1172,10 +1144,13 @@ static int fts5ExprNodeNextMatch(
     switch( pNode->eType ){
 
       case FTS5_STRING: {
-#if 0
+        /* Advance the iterators until they all point to the same rowid */
         rc = fts5ExprNearNextMatch(pExpr, pNode);
-#endif
-        rc = fts5ExprNearNextRowidMatch(pExpr, pNode);
+        break;
+      }
+
+      case FTS5_TERM: {
+        rc = fts5ExprTokenTest(pExpr, pNode);
         break;
       }
 
@@ -1187,14 +1162,17 @@ static int fts5ExprNodeNextMatch(
       case FTS5_OR: {
         Fts5ExprNode *pNext = pNode->apChild[0];
         int i;
+
         for(i=1; i<pNode->nChild; i++){
           Fts5ExprNode *pChild = pNode->apChild[i];
-          if( fts5NodeCompare(pExpr, pNext, pChild)>0 ){
+          int cmp = fts5NodeCompare(pExpr, pNext, pChild);
+          if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){
             pNext = pChild;
           }
         }
         pNode->iRowid = pNext->iRowid;
         pNode->bEof = pNext->bEof;
+        pNode->bNomatch = pNext->bNomatch;
         break;
       }
 
@@ -1210,7 +1188,7 @@ static int fts5ExprNodeNextMatch(
             cmp = fts5NodeCompare(pExpr, p1, p2);
           }
           assert( rc!=SQLITE_OK || cmp<=0 );
-          if( 0==fts5ExprNodeTest(&rc, pExpr, p1->iRowid, p2) ) break;
+          if( cmp || p2->bNomatch ) break;
           rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
         }
         pNode->bEof = p1->bEof;
@@ -1234,29 +1212,19 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
   int rc = SQLITE_OK;
   pNode->bEof = 0;
 
-  if( pNode->eType==FTS5_STRING ){
-
+  if( Fts5NodeIsString(pNode) ){
     /* Initialize all term iterators in the NEAR object. */
     rc = fts5ExprNearInitAll(pExpr, pNode);
-
-    /* Attempt to advance to the first match */
-    if( rc==SQLITE_OK && pNode->bEof==0 ){
-#if 0
-      rc = fts5ExprNearNextMatch(pExpr, pNode);
-#endif
-      rc = fts5ExprNearNextRowidMatch(pExpr, pNode);
-    }
-
   }else{
     int i;
     for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
       rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
     }
-
     pNode->iRowid = pNode->apChild[0]->iRowid;
-    if( rc==SQLITE_OK ){
-      rc = fts5ExprNodeNextMatch(pExpr, pNode);
-    }
+  }
+
+  if( rc==SQLITE_OK ){
+    rc = fts5ExprNodeNextMatch(pExpr, pNode);
   }
   return rc;
 }
@@ -1278,11 +1246,9 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, int bDesc){
     p->pIndex = pIdx;
     p->bDesc = bDesc;
     rc = fts5ExprNodeFirst(p, pRoot);
-    if( pRoot->bEof==0 
-     && 0==fts5ExprNodeTest(&rc, p, pRoot->iRowid, pRoot) 
-     && rc==SQLITE_OK 
-    ){
-      rc = sqlite3Fts5ExprNext(p);
+
+    while( pRoot->bNomatch && rc==SQLITE_OK && pRoot->bEof==0 ){
+      rc = fts5ExprNodeNext(p, pRoot, 0, 0);
     }
   }
   return rc;
@@ -1299,10 +1265,7 @@ int sqlite3Fts5ExprNext(Fts5Expr *p){
   Fts5ExprNode *pRoot = p->pRoot;
   do {
     rc = fts5ExprNodeNext(p, pRoot, 0, 0);
-  }while( pRoot->bEof==0 
-      && fts5ExprNodeTest(&rc, p, pRoot->iRowid, p->pRoot)==0 
-      && rc==SQLITE_OK 
-  );
+  }while( pRoot->bNomatch && pRoot->bEof==0 && rc==SQLITE_OK );
   return rc;
 }
 
@@ -1699,6 +1662,9 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
         for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
           pNear->apPhrase[iPhrase]->pNode = pRet;
         }
+        if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 ){
+          pRet->eType = FTS5_TERM;
+        }
       }else{
         fts5ExprAddChildren(pRet, pLeft);
         fts5ExprAddChildren(pRet, pRight);
@@ -1762,7 +1728,7 @@ static char *fts5ExprPrintTcl(
   Fts5ExprNode *pExpr
 ){
   char *zRet = 0;
-  if( pExpr->eType==FTS5_STRING ){
+  if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
     Fts5ExprNearset *pNear = pExpr->pNear;
     int i; 
     int iTerm;
@@ -1836,7 +1802,7 @@ static char *fts5ExprPrintTcl(
 
 static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
   char *zRet = 0;
-  if( pExpr->eType==FTS5_STRING ){
+  if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){
     Fts5ExprNearset *pNear = pExpr->pNear;
     int i; 
     int iTerm;
@@ -1895,7 +1861,8 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){
         sqlite3_free(zRet);
         zRet = 0;
       }else{
-        int b = (pExpr->apChild[i]->eType!=FTS5_STRING);
+        int e = pExpr->apChild[i]->eType;
+        int b = (e!=FTS5_STRING && e!=FTS5_TERM);
         zRet = fts5PrintfAppend(zRet, "%s%s%z%s", 
             (i==0 ? "" : zOp),
             (b?"(":""), z, (b?")":"")
index 43ed42e5a93152280292b72c090156851ec1e7a9..e9c6c3d6c44786a09255b08836a2b3a4962b6bb6 100644 (file)
@@ -63,6 +63,7 @@
 %left OR.
 %left AND.
 %left NOT.
+%left TERM.
 %left COLON.
 
 input ::= expr(X). { sqlite3Fts5ParseFinished(pParse, X); }
index 30333de2212a088e70bbf2869094fd42d1dd8e49..11d09ce8237f6c1e5c3bc5d1055949d9549922b2 100644 (file)
@@ -290,34 +290,36 @@ for {set fold 0} {$fold < 3} {incr fold} {
     DELETE FROM tt;
   }
   foreach {rowid a b c d e f} [string map $map $data] {
+  if {$rowid==-4703774} {
     execsql {
       INSERT INTO tt(rowid, a, b, c, d, e, f) 
       VALUES($rowid, $a, $b, $c, $d, $e, $f)
     }
+    }
   }
   execsql COMMIT
 
 
   foreach {tn expr} {
-    3.1 { [a] : x }
-    3.2 { [a b] : x }
-    3.3 { [a b f] : x }
-    3.4 { [f a b] : x }
-    3.5 { [f a b] : x y }
-    3.6 { [f a b] : x + y }
-    3.7 { [c a b] : x + c }
-    3.8 { [c d] : "l m" }
-    3.9 { [c e] : "l m" }
+    A.1 { [a] : x }
+    A.2 { [a b] : x }
+    A.3 { [a b f] : x }
+    A.4 { [f a b] : x }
+    A.5 { [f a b] : x y }
+    A.6 { [f a b] : x + y }
+    A.7 { [c a b] : x + c }
+    A.8 { [c d] : "l m" }
+    A.9 { [c e] : "l m" }
 
-    4.1 { a NOT b }
-    4.2 { a NOT a:b }
-    4.3 { a OR (b AND c) }
-    4.4 { a OR (b AND [a b c]:c) }
-    4.5 { a OR "b c" }
-    4.6 { a OR b OR c }
+    B.1 { a NOT b }
+    B.2 { a NOT a:b }
+    B.3 { a OR (b AND c) }
+    B.4 { a OR (b AND [a b c]:c) }
+    B.5 { a OR "b c" }
+    B.6 { a OR b OR c }
 
-    5.1 { a OR (b AND "b c") }
-    5.2 { a OR (b AND "z c") }
+    C.1 { a OR (b AND "b c") }
+    C.2 { a OR (b AND "z c") }
   } {
     do_auto_test 3.$fold.$tn $expr
   }
index cba1461913f0d39cf49f90358245dffe083c8523..fb06a6d43dbb1a51e2eda69ab2ffec9940189401 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improve\sperformance\sof\sthe\sfts5\sAND\soperator.
-D 2015-06-01T19:17:06.810
+C Reimplement\s[ec69e09a]\sso\sthat\seach\scall\sto\sthe\sxNext()\smethod\sdoes\snot\sinvolve\stwo\siterations\sof\sthe\smatch\sexpression\stree\s(only\sone).
+D 2015-06-02T17:57:01.304
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2c28e557780395095c307a6e5cb539419027eb5e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -111,7 +111,7 @@ F ext/fts5/fts5Int.h 4c677f3b797acde90ba1b7730eca6a32e7def742
 F ext/fts5/fts5_aux.c d53f00f31ad615ca4f139dd8751f9041afa00971
 F ext/fts5/fts5_buffer.c 9ec57c75c81e81dca118568876b1caead0aadadf
 F ext/fts5/fts5_config.c 11f969ed711a0a8b611d47431d74c372ad78c713
-F ext/fts5/fts5_expr.c e68f969e9276d312554195a158240f9705c374c1
+F ext/fts5/fts5_expr.c ae3cff45a4f36d0bc7561675fbd081d6a1df78b3
 F ext/fts5/fts5_hash.c c1cfdb2cae0fad00b06fae38a40eaf9261563ccc
 F ext/fts5/fts5_index.c 7cea402924cd3d8cd5943a7f9514c9153696571b
 F ext/fts5/fts5_storage.c 04e6717656b78eb230a1c730cac3b935eb94889b
@@ -120,7 +120,7 @@ F ext/fts5/fts5_tokenize.c 97251d68d7a6a9415bde1203f9382864dfc1f989
 F ext/fts5/fts5_unicode2.c da3cf712f05cd8347c8c5bc00964cc0361c88da9
 F ext/fts5/fts5_varint.c 366452037bf9a000c351374b489badc1b3541796
 F ext/fts5/fts5_vocab.c 1f8543b2c1ae4427f127a911bc8e60873fcd7bf9
-F ext/fts5/fts5parse.y 4ee667932d561a150d96483cf563281b95a9e523
+F ext/fts5/fts5parse.y 7f256d4de575f60f06c7c42c1514537168f0c035
 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
 F ext/fts5/test/fts5_common.tcl 0b465b1127adcd1c8131f3454ab4264a6964674c
 F ext/fts5/test/fts5aa.test 5f73afe6a1394fdba9bc18302876ded81021bee6
@@ -135,7 +135,7 @@ F ext/fts5/test/fts5ai.test f20e53bbf0c55bc596f1fd47f2740dae028b8f37
 F ext/fts5/test/fts5aj.test 05b569f5c16ea3098fb1984eec5cf50dbdaae5d8
 F ext/fts5/test/fts5ak.test 7b8c5df96df599293f920b7e5521ebc79f647592
 F ext/fts5/test/fts5al.test fc60ebeac9d8e366e71309d4c31fa72199d711d7
-F ext/fts5/test/fts5auto.test 3810c1c4928be0161b87dfc479ecf1b873f37c6c
+F ext/fts5/test/fts5auto.test 04286120430fea482ee4b3756ce1941acd3d3962
 F ext/fts5/test/fts5aux.test e5631607bbc05ac1c38cf7d691000509aca71ef3
 F ext/fts5/test/fts5auxdata.test c69b86092bf1a157172de5f9169731af3403179b
 F ext/fts5/test/fts5bigpl.test b1cfd00561350ab04994ba7dd9d48468e5e0ec3b
@@ -1333,7 +1333,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 ec69e09a55b4daf1c40aeaaf9ee95091fe86f5c0
-R acaa89910e5f0d02d970b6387ace6327
+P b43e9a5b7a0483ccb102316a4dbc5e32b5bc69ec
+R bd2db0e568f1313170e13c32f86585fb
 U dan
-Z 115cb3cf0377892edfa5b36bfcc4447b
+Z 85ab84df13bd96f34cdaff4b243d8a96
index d1c605efb93493448d9bb3e33a629d94c302c719..b809703e824068f3177f4af0cb1c8286a19d17a5 100644 (file)
@@ -1 +1 @@
-b43e9a5b7a0483ccb102316a4dbc5e32b5bc69ec
\ No newline at end of file
+80fe305b3eefb17310a9d6185d1c8cd73ee38b1e
\ No newline at end of file