]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fixes for the matchinfo() function related to FTS4 common token handling.
authordan <dan@noemail.net>
Sat, 23 Oct 2010 19:07:30 +0000 (19:07 +0000)
committerdan <dan@noemail.net>
Sat, 23 Oct 2010 19:07:30 +0000 (19:07 +0000)
FossilOrigin-Name: deb80eac9112d21835dfd3cee08ed8f09d975bf7

ext/fts3/fts3.c
ext/fts3/fts3Int.h
ext/fts3/fts3_expr.c
ext/fts3/fts3_snippet.c
ext/fts3/fts3_write.c
manifest
manifest.uuid
test/fts3defer2.test

index 0f8b887f7ab54dfbe90fcd0f83c3329e52fbde00..89dc26525f6ae7a0dbff7d01534b09b5951cbbe4 100644 (file)
@@ -2108,7 +2108,6 @@ static int fts3DeferExpression(Fts3Cursor *pCsr, Fts3Expr *pExpr){
     if( pExpr->eType==FTSQUERY_PHRASE ){
       int iCol = pExpr->pPhrase->iColumn;
       int i;
-      pExpr->bDeferred = 1;
       for(i=0; rc==SQLITE_OK && i<pExpr->pPhrase->nToken; i++){
         Fts3PhraseToken *pToken = &pExpr->pPhrase->aToken[i];
         if( pToken->pDeferred==0 ){
@@ -2170,22 +2169,28 @@ static int fts3PhraseSelect(
   int iCol = pPhrase->iColumn;
   int isTermPos = (pPhrase->nToken>1 || isReqPos);
   Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
+  int isFirst = 1;
 
   int iPrevTok = 0;
   int nDoc = 0;
 
   /* If this is an xFilter() evaluation, create a segment-reader for each
-  ** phrase token. Or, if this is an xNest() or snippet/offsets/matchinfo
+  ** phrase token. Or, if this is an xNext() or snippet/offsets/matchinfo
   ** evaluation, only create segment-readers if there are no Fts3DeferredToken
   ** objects attached to the phrase-tokens.
   */
   for(ii=0; ii<pPhrase->nToken; ii++){
     Fts3PhraseToken *pTok = &pPhrase->aToken[ii];
-    if( pTok->pArray==0 && (pCsr->doDeferred==0 || pTok->pDeferred==0) ){
-      rc = fts3TermSegReaderArray(
-          pCsr, pTok->z, pTok->n, pTok->isPrefix, &pTok->pArray
-      );
-      if( rc!=SQLITE_OK ) return rc;
+    if( pTok->pArray==0 ){
+      if( (pCsr->eEvalmode==FTS3_EVAL_FILTER)
+       || (pCsr->eEvalmode==FTS3_EVAL_NEXT && pCsr->pDeferred==0) 
+       || (pCsr->eEvalmode==FTS3_EVAL_MATCHINFO && pTok->bFulltext) 
+      ){
+        rc = fts3TermSegReaderArray(
+            pCsr, pTok->z, pTok->n, pTok->isPrefix, &pTok->pArray
+        );
+        if( rc!=SQLITE_OK ) return rc;
+      }
     }
   }
 
@@ -2199,7 +2204,12 @@ static int fts3PhraseSelect(
     ** are processed in order from least to most costly. Otherwise, tokens 
     ** are processed in the order in which they occur in the phrase.
     */
-    if( pCsr->doDeferred || isReqPos ){
+    if( pCsr->eEvalmode==FTS3_EVAL_MATCHINFO ){
+      assert( isReqPos );
+      iTok = ii;
+      pTok = &pPhrase->aToken[iTok];
+      if( pTok->bFulltext==0 ) continue;
+    }else if( pCsr->eEvalmode==FTS3_EVAL_NEXT || isReqPos ){
       iTok = ii;
       pTok = &pPhrase->aToken[iTok];
     }else{
@@ -2227,21 +2237,23 @@ static int fts3PhraseSelect(
       }
     }
 
-    if( pCsr->doDeferred && pTok->pDeferred ){
+    if( pCsr->eEvalmode==FTS3_EVAL_NEXT && pTok->pDeferred ){
       rc = fts3DeferredTermSelect(pTok->pDeferred, isTermPos, &nList, &pList);
     }else{
       assert( pTok->pArray );
       rc = fts3TermSelect(p, pTok, iCol, isTermPos, &nList, &pList);
+      pTok->bFulltext = 1;
     }
-    assert( rc!=SQLITE_OK || pCsr->doDeferred || pTok->pArray==0 );
+    assert( rc!=SQLITE_OK || pCsr->eEvalmode || pTok->pArray==0 );
     if( rc!=SQLITE_OK ) break;
 
-    if( ii==0 ){
+    if( isFirst ){
       pOut = pList;
       nOut = nList;
-      if( pCsr->doDeferred==0 && pPhrase->nToken>1 ){
+      if( pCsr->eEvalmode==FTS3_EVAL_FILTER && pPhrase->nToken>1 ){
         nDoc = fts3DoclistCountDocids(1, pOut, nOut);
       }
+      isFirst = 0;
     }else{
       /* Merge the new term list and the current output. */
       char *aLeft, *aRight;
@@ -2282,8 +2294,8 @@ static int fts3PhraseSelect(
   }
 
   if( rc==SQLITE_OK ){
-    if( ii!=pPhrase->nToken ){
-      assert( pCsr->doDeferred==0 && isReqPos==0 );
+    if( ii!=pPhrase->nToken && pCsr->eEvalmode==FTS3_EVAL_FILTER ){
+      assert( pCsr->eEvalmode==FTS3_EVAL_FILTER && isReqPos==0 );
       fts3DoclistStripPositions(pOut, &nOut);
     }
     *paOut = pOut;
@@ -2398,7 +2410,8 @@ static int fts3ExprAllocateSegReaders(
 ){
   int rc = SQLITE_OK;             /* Return code */
 
-  if( pCsr->doDeferred ) return SQLITE_OK;
+  assert( pCsr->eEvalmode!=FTS3_EVAL_MATCHINFO );
+  if( pCsr->eEvalmode==FTS3_EVAL_NEXT ) return SQLITE_OK;
   if( pnExpr && pExpr->eType!=FTSQUERY_AND ){
     (*pnExpr)++;
     pnExpr = 0;
@@ -2559,7 +2572,7 @@ static int fts3EvalExpr(
           paOut, pnOut
       );
       fts3ExprFreeSegReaders(pExpr);
-    }else if( p->doDeferred==0 && pExpr->eType==FTSQUERY_AND ){
+    }else if( p->eEvalmode==FTS3_EVAL_FILTER && pExpr->eType==FTSQUERY_AND ){
       ExprAndCost *aExpr = 0;     /* Array of AND'd expressions and costs */
       int nExpr = 0;              /* Size of aExpr[] */
       char *aRet = 0;             /* Doclist to return to caller */
@@ -2628,7 +2641,7 @@ static int fts3EvalExpr(
       assert( pExpr->eType==FTSQUERY_NEAR 
            || pExpr->eType==FTSQUERY_OR
            || pExpr->eType==FTSQUERY_NOT
-           || (pExpr->eType==FTSQUERY_AND && p->doDeferred)
+           || (pExpr->eType==FTSQUERY_AND && p->eEvalmode==FTS3_EVAL_NEXT)
       );
 
       if( 0==(rc = fts3EvalExpr(p, pExpr->pRight, &aRight, &nRight, isReqPos))
@@ -2725,9 +2738,7 @@ static int fts3EvalDeferred(
     if( rc==SQLITE_OK ){
       char *a = 0;
       int n = 0;
-      pCsr->doDeferred = 1;
       rc = fts3EvalExpr(pCsr, pCsr->pExpr, &a, &n, 0);
-      pCsr->doDeferred = 0;
       assert( n>=0 );
       *pbRes = (n>0);
       sqlite3_free(a);
@@ -2752,6 +2763,7 @@ static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
   int rc = SQLITE_OK;             /* Return code */
   Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
 
+  pCsr->eEvalmode = FTS3_EVAL_NEXT;
   do {
     if( pCsr->aDoclist==0 ){
       if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){
@@ -3003,9 +3015,24 @@ static int fts3RollbackMethod(sqlite3_vtab *pVtab){
 */
 int sqlite3Fts3ExprLoadDoclist(Fts3Cursor *pCsr, Fts3Expr *pExpr){
   int rc;
-  pCsr->doDeferred = 1;
+  assert( pExpr->eType==FTSQUERY_PHRASE && pExpr->pPhrase );
+  assert( pCsr->eEvalmode==FTS3_EVAL_NEXT );
   rc = fts3EvalExpr(pCsr, pExpr, &pExpr->aDoclist, &pExpr->nDoclist, 1);
-  pCsr->doDeferred = 0;
+  return rc;
+}
+
+int sqlite3Fts3ExprLoadFtDoclist(
+  Fts3Cursor *pCsr, 
+  Fts3Expr *pExpr,
+  char **paDoclist,
+  int *pnDoclist
+){
+  int rc;
+  assert( pCsr->eEvalmode==FTS3_EVAL_NEXT );
+  assert( pExpr->eType==FTSQUERY_PHRASE && pExpr->pPhrase );
+  pCsr->eEvalmode = FTS3_EVAL_MATCHINFO;
+  rc = fts3EvalExpr(pCsr, pExpr, paDoclist, pnDoclist, 1);
+  pCsr->eEvalmode = FTS3_EVAL_NEXT;
   return rc;
 }
 
index 5d73b2c7737f1357d3e36e441fff85b577c9b407..ad43570cb4e3e376354d241b4912058a80b3bc95 100644 (file)
@@ -163,10 +163,14 @@ struct Fts3Cursor {
   int nDoclist;                   /* Size of buffer at aDoclist */
   int isMatchinfoNeeded;          /* True when aMatchinfo[] needs filling in */
   u32 *aMatchinfo;                /* Information about most recent match */
-  int doDeferred;
+  int eEvalmode;                  /* An FTS3_EVAL_XX constant */
   int nRowAvg;                    /* Average size of database rows, in pages */
 };
 
+#define FTS3_EVAL_FILTER    0
+#define FTS3_EVAL_NEXT      1
+#define FTS3_EVAL_MATCHINFO 2
+
 /*
 ** The Fts3Cursor.eSearch member is always set to one of the following.
 ** Actualy, Fts3Cursor.eSearch can be greater than or equal to
@@ -191,16 +195,24 @@ struct Fts3Cursor {
 ** sequence.  A single token is the base case and the most common case.
 ** For a sequence of tokens contained in double-quotes (i.e. "one two three")
 ** nToken will be the number of tokens in the string.
+**
+** The nDocMatch and nMatch variables contain data that may be used by the
+** matchinfo() function. They are populated when the full-text index is 
+** queried for hits on the phrase. If one or more tokens in the phrase
+** are deferred, the nDocMatch and nMatch variables are populated based
+** on the assumption that the 
 */
 struct Fts3PhraseToken {
   char *z;                        /* Text of the token */
   int n;                          /* Number of bytes in buffer z */
   int isPrefix;                   /* True if token ends with a "*" character */
+  int bFulltext;                  /* True if full-text index was used */
   Fts3SegReaderArray *pArray;     /* Segment-reader for this token */
   Fts3DeferredToken *pDeferred;   /* Deferred token object for this token */
 };
 
 struct Fts3Phrase {
+  /* Variables populated by fts3_expr.c when parsing a MATCH expression */
   int nToken;                /* Number of tokens in the phrase */
   int iColumn;               /* Index of column this phrase must match */
   int isNot;                 /* Phrase prefixed by unary not (-) operator */
@@ -228,8 +240,6 @@ struct Fts3Expr {
   Fts3Expr *pRight;          /* Right operand */
   Fts3Phrase *pPhrase;       /* Valid if eType==FTSQUERY_PHRASE */
 
-  int bDeferred;
-
   int isLoaded;              /* True if aDoclist/nDoclist are initialized. */
   char *aDoclist;            /* Buffer containing doclist */
   int nDoclist;              /* Size of aDoclist in bytes */
@@ -307,6 +317,7 @@ void sqlite3Fts3Dequote(char *);
 
 char *sqlite3Fts3FindPositions(Fts3Expr *, sqlite3_int64, int);
 int sqlite3Fts3ExprLoadDoclist(Fts3Cursor *, Fts3Expr *);
+int sqlite3Fts3ExprLoadFtDoclist(Fts3Cursor *, Fts3Expr *, char **, int *);
 int sqlite3Fts3ExprNearTrim(Fts3Expr *, Fts3Expr *, int);
 
 /* fts3_tokenizer.c */
index 0f411f097fce2ecac195a478d38aa12df3829017..662697b24e387f2cb03ad04578fd06ffa4c83b1e 100644 (file)
@@ -106,6 +106,18 @@ static int fts3isspace(char c){
   return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
 }
 
+/*
+** Allocate nByte bytes of memory using sqlite3_malloc(). If successful,
+** zero the memory before returning a pointer to it. If unsuccessful, 
+** return NULL.
+*/
+static void *fts3MallocZero(int nByte){
+  void *pRet = sqlite3_malloc(nByte);
+  if( pRet ) memset(pRet, 0, nByte);
+  return pRet;
+}
+
+
 /*
 ** Extract the next token from buffer z (length n) using the tokenizer
 ** and other information (column names etc.) in pParse. Create an Fts3Expr
@@ -143,11 +155,10 @@ static int getNextToken(
 
     if( rc==SQLITE_OK ){
       nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
-      pRet = (Fts3Expr *)sqlite3_malloc(nByte);
+      pRet = (Fts3Expr *)fts3MallocZero(nByte);
       if( !pRet ){
         rc = SQLITE_NOMEM;
       }else{
-        memset(pRet, 0, nByte);
         pRet->eType = FTSQUERY_PHRASE;
         pRet->pPhrase = (Fts3Phrase *)&pRet[1];
         pRet->pPhrase->nToken = 1;
@@ -233,10 +244,9 @@ static int getNextString(
           p->pPhrase = (Fts3Phrase *)&p[1];
         }
         p->pPhrase = (Fts3Phrase *)&p[1];
+        memset(&p->pPhrase->aToken[ii], 0, sizeof(Fts3PhraseToken));
         p->pPhrase->nToken = ii+1;
         p->pPhrase->aToken[ii].n = nToken;
-        p->pPhrase->aToken[ii].pDeferred = 0;
-        p->pPhrase->aToken[ii].pArray = 0;
         memcpy(&zTemp[nTemp], zToken, nToken);
         nTemp += nToken;
         if( iEnd<nInput && zInput[iEnd]=='*' ){
@@ -374,11 +384,10 @@ static int getNextNode(
       if( fts3isspace(cNext) 
        || cNext=='"' || cNext=='(' || cNext==')' || cNext==0
       ){
-        pRet = (Fts3Expr *)sqlite3_malloc(sizeof(Fts3Expr));
+        pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr));
         if( !pRet ){
           return SQLITE_NOMEM;
         }
-        memset(pRet, 0, sizeof(Fts3Expr));
         pRet->eType = pKey->eType;
         pRet->nNear = nNear;
         *ppExpr = pRet;
@@ -554,13 +563,12 @@ static int fts3ExprParse(
        && p->eType==FTSQUERY_PHRASE && p->pPhrase->isNot 
       ){
         /* Create an implicit NOT operator. */
-        Fts3Expr *pNot = sqlite3_malloc(sizeof(Fts3Expr));
+        Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr));
         if( !pNot ){
           sqlite3Fts3ExprFree(p);
           rc = SQLITE_NOMEM;
           goto exprparse_out;
         }
-        memset(pNot, 0, sizeof(Fts3Expr));
         pNot->eType = FTSQUERY_NOT;
         pNot->pRight = p;
         if( pNotBranch ){
@@ -588,13 +596,12 @@ static int fts3ExprParse(
           /* Insert an implicit AND operator. */
           Fts3Expr *pAnd;
           assert( pRet && pPrev );
-          pAnd = sqlite3_malloc(sizeof(Fts3Expr));
+          pAnd = fts3MallocZero(sizeof(Fts3Expr));
           if( !pAnd ){
             sqlite3Fts3ExprFree(p);
             rc = SQLITE_NOMEM;
             goto exprparse_out;
           }
-          memset(pAnd, 0, sizeof(Fts3Expr));
           pAnd->eType = FTSQUERY_AND;
           insertBinaryOperator(&pRet, pPrev, pAnd);
           pPrev = pAnd;
index 21f858545d485d6ca0b2a3f46b097413a3e9acb5..2873d67f10befdcb5d9e83b40d652215884ca586 100644 (file)
@@ -268,7 +268,6 @@ static int fts3ExprLoadDoclists(
   }
   if( pnPhrase ) *pnPhrase = sCtx.nPhrase;
   if( pnToken ) *pnToken = sCtx.nToken;
-  sqlite3Fts3SegmentsClose((Fts3Table *)pCsr->base.pVtab);
   return rc;
 }
 
@@ -793,20 +792,47 @@ static int fts3ExprGlobalMatchinfoCb(
   void *pCtx                      /* Pointer to MatchInfo structure */
 ){
   MatchInfo *p = (MatchInfo *)pCtx;
-  char *pCsr;
+  Fts3Cursor *pCsr = p->pCursor;
+  char *pIter;
   char *pEnd;
+  char *pFree = 0;
   const int iStart = 2 + (iPhrase * p->nCol * 3) + 1;
 
   assert( pExpr->isLoaded );
+  assert( pExpr->eType==FTSQUERY_PHRASE );
+
+  if( pCsr->pDeferred ){
+    Fts3Phrase *pPhrase = pExpr->pPhrase;
+    int ii;
+    for(ii=0; ii<pPhrase->nToken; ii++){
+      if( pPhrase->aToken[ii].bFulltext ) break;
+    }
+    if( ii<pPhrase->nToken ){
+      int nFree = 0;
+      int rc = sqlite3Fts3ExprLoadFtDoclist(pCsr, pExpr, &pFree, &nFree);
+      if( rc!=SQLITE_OK ) return rc;
+      pIter = pFree;
+      pEnd = &pFree[nFree];
+    }else{
+      int nDoc = p->aMatchinfo[2 + 3*p->nCol*p->aMatchinfo[0]];
+      for(ii=0; ii<p->nCol; ii++){
+        p->aMatchinfo[iStart + ii*3] = nDoc;
+        p->aMatchinfo[iStart + ii*3 + 1] = nDoc;
+      }
+      return SQLITE_OK;
+    }
+  }else{
+    pIter = pExpr->aDoclist;
+    pEnd = &pExpr->aDoclist[pExpr->nDoclist];
+  }
 
   /* Fill in the global hit count matrix row for this phrase. */
-  pCsr = pExpr->aDoclist;
-  pEnd = &pExpr->aDoclist[pExpr->nDoclist];
-  while( pCsr<pEnd ){
-    while( *pCsr++ & 0x80 );      /* Skip past docid. */
-    fts3LoadColumnlistCounts(&pCsr, &p->aMatchinfo[iStart], 1);
+  while( pIter<pEnd ){
+    while( *pIter++ & 0x80 );      /* Skip past docid. */
+    fts3LoadColumnlistCounts(&pIter, &p->aMatchinfo[iStart], 1);
   }
 
+  sqlite3_free(pFree);
   return SQLITE_OK;
 }
 
@@ -875,15 +901,14 @@ static int fts3GetMatchinfo(Fts3Cursor *pCsr){
     }
     memset(sInfo.aMatchinfo, 0, sizeof(u32)*nMatchinfo);
 
-
     /* First element of match-info is the number of phrases in the query */
     sInfo.aMatchinfo[0] = nPhrase;
     sInfo.aMatchinfo[1] = sInfo.nCol;
-    (void)fts3ExprIterate(pCsr->pExpr, fts3ExprGlobalMatchinfoCb,(void*)&sInfo);
     if( pTab->bHasDocsize ){
       int ofst = 2 + 3*sInfo.aMatchinfo[0]*sInfo.aMatchinfo[1];
       rc = sqlite3Fts3MatchinfoDocsizeGlobal(pCsr, &sInfo.aMatchinfo[ofst]);
     }
+    (void)fts3ExprIterate(pCsr->pExpr, fts3ExprGlobalMatchinfoCb,(void*)&sInfo);
     pCsr->aMatchinfo = sInfo.aMatchinfo;
     pCsr->isMatchinfoNeeded = 1;
   }
@@ -993,6 +1018,7 @@ void sqlite3Fts3Snippet(
   }
 
  snippet_out:
+  sqlite3Fts3SegmentsClose(pTab);
   if( rc!=SQLITE_OK ){
     sqlite3_result_error_code(pCtx, rc);
     sqlite3_free(res.z);
@@ -1172,6 +1198,7 @@ void sqlite3Fts3Offsets(
  offsets_out:
   sqlite3_free(sCtx.aTerm);
   assert( rc!=SQLITE_DONE );
+  sqlite3Fts3SegmentsClose(pTab);
   if( rc!=SQLITE_OK ){
     sqlite3_result_error_code(pCtx,  rc);
     sqlite3_free(res.z);
@@ -1191,6 +1218,7 @@ void sqlite3Fts3Matchinfo(sqlite3_context *pContext, Fts3Cursor *pCsr){
     return;
   }
   rc = fts3GetMatchinfo(pCsr);
+  sqlite3Fts3SegmentsClose((Fts3Table *)pCsr->base.pVtab );
   if( rc!=SQLITE_OK ){
     sqlite3_result_error_code(pContext, rc);
   }else{
index 76f11405bf5c22aa11c758616167aa2cd8c59bbd..49bede68cbd7c2d3aa49f19a3122e4f6ed4f524f 100644 (file)
@@ -2644,7 +2644,7 @@ static void fts3DeferredDoclistClear(Fts3Expr *pExpr){
   if( pExpr ){
     fts3DeferredDoclistClear(pExpr->pLeft);
     fts3DeferredDoclistClear(pExpr->pRight);
-    if( pExpr->bDeferred && pExpr->isLoaded ){
+    if( pExpr->isLoaded ){
       sqlite3_free(pExpr->aDoclist);
       pExpr->isLoaded = 0;
       pExpr->aDoclist = 0;
@@ -2665,7 +2665,9 @@ void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){
     sqlite3_free(pDef->pList);
     pDef->pList = 0;
   }
-  fts3DeferredDoclistClear(pCsr->pExpr);
+  if( pCsr->pDeferred ){
+    fts3DeferredDoclistClear(pCsr->pExpr);
+  }
 }
 
 /*
index 5e1278d700c181bbdc64b13772b5af7418ddcc01..aa200eab43cf278fb3e757b8f22c390646113022 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\snew\stest\sfile\sfts3defer2.test.
-D 2010-10-22T19:03:34
+C Fixes\sfor\sthe\smatchinfo()\sfunction\srelated\sto\sFTS4\scommon\stoken\shandling.
+D 2010-10-23T19:07:30
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2c8cefd962eca0147132c7cf9eaa4bb24c656f3f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -61,19 +61,19 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
 F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c e2f031ea6b213371a31cc5bf181c2177fef86aad
+F ext/fts3/fts3.c b7442369abecdda3cb58dc0ed482e7d1e852028f
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h 068d80157cc7a4bf674d2df817f3b427001ad94a
-F ext/fts3/fts3_expr.c a5aee50edde20e5c9116199bd58be869a3a22c9f
+F ext/fts3/fts3Int.h 11fa12ce041bacbc6ac53db127eb0bcc0538af51
+F ext/fts3/fts3_expr.c ee48b9278b8b2432a05a03320fbcacba151dbaa5
 F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c
 F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec
 F ext/fts3/fts3_icu.c ac494aed69835008185299315403044664bda295
 F ext/fts3/fts3_porter.c 8df6f6efcc4e9e31f8bf73a4007c2e9abca1dfba
-F ext/fts3/fts3_snippet.c ca60a2a47de5e7abb22a804ccd1a743f81c2fe3e
+F ext/fts3/fts3_snippet.c 300c12b7f0a2a6ae0491bb2d00e2d5ff9c28f685
 F ext/fts3/fts3_tokenizer.c b4f2d01c24573852755bc92864816785dae39318
 F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
 F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d
-F ext/fts3/fts3_write.c 54ddeed7323f62af6e55162f0d4102822b991684
+F ext/fts3/fts3_write.c 1b9211904f8157ebca8e17034e1150f3653e6c3f
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
@@ -434,7 +434,7 @@ F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
 F test/fts3cov.test 54cf1f98c72abee246447cd688590898c9ecbaf7
 F test/fts3d.test 95fb3c862cbc4297c93fceb9a635543744e9ef52
 F test/fts3defer.test cf66bf69afcc2fb8373d3aed31c55399409e83f2
-F test/fts3defer2.test 98259e5d7fa16b2d275d9b6a6c0c972e285fa18c
+F test/fts3defer2.test acd2fdd4db0a3b7f0ce6b1b3154c9521cb62d27d
 F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
 F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c
 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
@@ -876,7 +876,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 1c9c70fec3c88319f7b2efe5316694a6ce0ab1a5
-R d4195a622cd830429b9e32aeb4872a48
+P 5a4d5bfcaeb78a81713f138b01c0ea45a15c4d6c
+R eb3b2e3c665e63f01c554e4a5a259aeb
 U dan
-Z 7c9af859e7e36df7363e90eaf6cd38eb
+Z f37bf8cb2dd9e3f74310b44a4142ec1c
index 5fc6ae80f4450d36d665099fc06a24a4c669a1a9..185975bf9491e6a83a42c3520242c59ebb16b259 100644 (file)
@@ -1 +1 @@
-5a4d5bfcaeb78a81713f138b01c0ea45a15c4d6c
\ No newline at end of file
+deb80eac9112d21835dfd3cee08ed8f09d975bf7
\ No newline at end of file
index 2ec3d4f10b0927f5cf34f8629513d7a216d008fb..3a4a3507210433ad9b669372be972b771fd9f019 100644 (file)
@@ -57,7 +57,7 @@ do_execsql_test 1.2.2 {
 } [list                              \
    {a b c d [e] [f] [a] x y}         \
    {0 1 8 1 0 0 10 1 0 2 12 1}       \
-   [list 3 1   1 1 1   1 1 1   1 1 1   3 13336 9]
+   [list 3 1   1 1 1   1 3 3   1 3 3   3 13336 9]
 ]
 
 do_execsql_test 1.2.3 {
@@ -66,7 +66,7 @@ do_execsql_test 1.2.3 {
 } [list                                 \
    {[a] b c d [e] [f] [a] x y}          \
    {0 2 0 1 0 1 8 1 0 0 10 1 0 2 12 1}  \
-   [list 3 1   1 1 1   1 1 1   2 2 1   3 13336 9]
+   [list 3 1   1 1 1   1 3 3   2 3 3   3 13336 9]
 ]
 
 do_execsql_test 1.3.1 { DROP TABLE t1 }
@@ -77,9 +77,10 @@ do_execsql_test 1.3.1 { DROP TABLE t1 }
 do_execsql_test 2.1.1 {
   CREATE VIRTUAL TABLE t2 USING fts4;
 }
-do_execsql_test 2.1.2 "INSERT INTO t2 VALUES('[string repeat {a } 20000]')"
-do_execsql_test 2.1.3 "INSERT INTO t2 VALUES('[string repeat {z } 20000]')"
-do_execsql_test 2.1.4 {
+do_execsql_test 2.1.2 "INSERT INTO t2 VALUES('[string repeat {a } 10000]')"
+do_execsql_test 2.1.3 "INSERT INTO t2 VALUES('b [string repeat {z } 10000]')"
+do_execsql_test 2.1.4 [string repeat "INSERT INTO t2 VALUES('x');" 50]
+do_execsql_test 2.1.5 {
   INSERT INTO t2 VALUES('a b c d e f g');
   INSERT INTO t2 VALUES('a b c d e f g');
 }
@@ -91,13 +92,12 @@ foreach {tn sql} {
       WHERE length(block)>10000;
   }
 } {
-if {$tn==3} break
   execsql $sql
   do_execsql_test 2.2.$tn.1 {
     SELECT mit(matchinfo(t2)) FROM t2 WHERE t2 MATCH 'a b';
   } [list                                          \
-    [list 2 1  1 20002 3  1 2 2  4 10004 7]        \
-    [list 2 1  1 20002 3  1 2 2  4 10004 7]        \
+    [list 2 1  1 54 54  1 3 3  54 372 7]        \
+    [list 2 1  1 54 54  1 3 3  54 372 7]        \
   ]
 }