/ Check-in [a4c7e282]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:FTS changes: Remove unreachable code. Fix bugs. When processing a large doclist incrementally, read from disk incrementally too.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fts3-prefix-search
Files: files | file ages | folders
SHA1: a4c7e2820824e82580730c36f85aede2efa66754
User & Date: dan 2011-06-03 18:00:19
Context
2011-06-04
20:04
Allow the "order=DESC" and "order=ASC" parameters in FTS4 "CREATE VIRTUAL TABLE" statements. Tables created with "order=DESC" store all doclists in descending order, which allows optimizations normally applied to "ORDER BY docid ASC" queries to be used with "ORDER BY docid DESC" queries instead. check-in: f6a0193f user: dan tags: fts3-prefix-search
2011-06-03
18:00
FTS changes: Remove unreachable code. Fix bugs. When processing a large doclist incrementally, read from disk incrementally too. check-in: a4c7e282 user: dan tags: fts3-prefix-search
2011-06-02
19:57
Changes to improve performance and support LIMIT clauses on fts3 tables. This branch is unstable for now. check-in: 28149a78 user: dan tags: fts3-prefix-search
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

   309    309   
   310    310   #include "fts3.h"
   311    311   #ifndef SQLITE_CORE 
   312    312   # include "sqlite3ext.h"
   313    313     SQLITE_EXTENSION_INIT1
   314    314   #endif
   315    315   
   316         -static char *fts3EvalPhrasePoslist(Fts3Phrase *, int *);
   317         -static sqlite3_int64 fts3EvalPhraseDocid(Fts3Phrase *);
   318         -
   319    316   /* 
   320    317   ** Write a 64-bit variable-length integer to memory starting at p[0].
   321    318   ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
   322    319   ** The number of bytes written is returned.
   323    320   */
   324    321   int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
   325    322     unsigned char *q = (unsigned char *) p;
................................................................................
  1206   1203     } 
  1207   1204   
  1208   1205     /* Regardless of the strategy selected, FTS can deliver rows in rowid (or
  1209   1206     ** docid) order. Both ascending and descending are possible. 
  1210   1207     */
  1211   1208     if( pInfo->nOrderBy==1 ){
  1212   1209       struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0];
  1213         -    if( pOrder->desc==0 
  1214         -     && (pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1) 
  1215         -    ){
         1210  +    if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){
  1216   1211         if( pOrder->desc ){
  1217   1212           pInfo->idxStr = "DESC";
  1218   1213         }else{
  1219   1214           pInfo->idxStr = "ASC";
  1220   1215         }
  1221   1216         pInfo->orderByConsumed = 1;
  1222   1217       }
................................................................................
  1257   1252     sqlite3Fts3FreeDeferredTokens(pCsr);
  1258   1253     sqlite3_free(pCsr->aDoclist);
  1259   1254     sqlite3_free(pCsr->aMatchinfo);
  1260   1255     sqlite3_free(pCsr);
  1261   1256     return SQLITE_OK;
  1262   1257   }
  1263   1258   
  1264         -static int fts3RowidMethod(sqlite3_vtab_cursor *, sqlite3_int64*);
  1265         -
  1266   1259   /*
  1267   1260   ** Position the pCsr->pStmt statement so that it is on the row
  1268   1261   ** of the %_content table that contains the last match.  Return
  1269   1262   ** SQLITE_OK on success.  
  1270   1263   */
  1271   1264   static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
  1272   1265     if( pCsr->isRequireSeek ){
................................................................................
  1448   1441     assert( !piLeaf2 || !piLeaf || rc!=SQLITE_OK || (*piLeaf<=*piLeaf2) );
  1449   1442   
  1450   1443     if( rc==SQLITE_OK && iHeight>1 ){
  1451   1444       char *zBlob = 0;              /* Blob read from %_segments table */
  1452   1445       int nBlob;                    /* Size of zBlob in bytes */
  1453   1446   
  1454   1447       if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
  1455         -      rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob);
         1448  +      rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0);
  1456   1449         if( rc==SQLITE_OK ){
  1457   1450           rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0);
  1458   1451         }
  1459   1452         sqlite3_free(zBlob);
  1460   1453         piLeaf = 0;
  1461   1454         zBlob = 0;
  1462   1455       }
  1463   1456   
  1464   1457       if( rc==SQLITE_OK ){
  1465         -      rc = sqlite3Fts3ReadBlock(p, piLeaf ? *piLeaf : *piLeaf2, &zBlob, &nBlob);
         1458  +      rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0);
  1466   1459       }
  1467   1460       if( rc==SQLITE_OK ){
  1468   1461         rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2);
  1469   1462       }
  1470   1463       sqlite3_free(zBlob);
  1471   1464     }
  1472   1465   
................................................................................
  2190   2183           pTS->anOutput[iOut] = nMerge;
  2191   2184         }
  2192   2185       }
  2193   2186     }
  2194   2187     return SQLITE_OK;
  2195   2188   }
  2196   2189   
  2197         -static int fts3DeferredTermSelect(
  2198         -  Fts3DeferredToken *pToken,      /* Phrase token */
  2199         -  int isTermPos,                  /* True to include positions */
  2200         -  int *pnOut,                     /* OUT: Size of list */
  2201         -  char **ppOut                    /* OUT: Body of list */
  2202         -){
  2203         -  char *aSource;
  2204         -  int nSource;
  2205         -
  2206         -  aSource = sqlite3Fts3DeferredDoclist(pToken, &nSource);
  2207         -  if( !aSource ){
  2208         -    *pnOut = 0;
  2209         -    *ppOut = 0;
  2210         -  }else if( isTermPos ){
  2211         -    *ppOut = sqlite3_malloc(nSource);
  2212         -    if( !*ppOut ) return SQLITE_NOMEM;
  2213         -    memcpy(*ppOut, aSource, nSource);
  2214         -    *pnOut = nSource;
  2215         -  }else{
  2216         -    sqlite3_int64 docid;
  2217         -    *pnOut = sqlite3Fts3GetVarint(aSource, &docid);
  2218         -    *ppOut = sqlite3_malloc(*pnOut);
  2219         -    if( !*ppOut ) return SQLITE_NOMEM;
  2220         -    sqlite3Fts3PutVarint(*ppOut, docid);
  2221         -  }
  2222         -
  2223         -  return SQLITE_OK;
  2224         -}
  2225         -
  2226   2190   /*
  2227   2191   ** Append SegReader object pNew to the end of the pCsr->apSegment[] array.
  2228   2192   */
  2229   2193   static int fts3SegReaderCursorAppend(
  2230   2194     Fts3MultiSegReader *pCsr, 
  2231   2195     Fts3SegReader *pNew
  2232   2196   ){
................................................................................
  2508   2472         }
  2509   2473       }
  2510   2474     }
  2511   2475   
  2512   2476     return nDoc;
  2513   2477   }
  2514   2478   
  2515         -/*
  2516         -** Call sqlite3Fts3DeferToken() for each token in the expression pExpr.
  2517         -*/
  2518         -static int fts3DeferExpression(Fts3Cursor *pCsr, Fts3Expr *pExpr){
  2519         -  int rc = SQLITE_OK;
  2520         -  if( pExpr ){
  2521         -    rc = fts3DeferExpression(pCsr, pExpr->pLeft);
  2522         -    if( rc==SQLITE_OK ){
  2523         -      rc = fts3DeferExpression(pCsr, pExpr->pRight);
  2524         -    }
  2525         -    if( pExpr->eType==FTSQUERY_PHRASE ){
  2526         -      int iCol = pExpr->pPhrase->iColumn;
  2527         -      int i;
  2528         -      for(i=0; rc==SQLITE_OK && i<pExpr->pPhrase->nToken; i++){
  2529         -        Fts3PhraseToken *pToken = &pExpr->pPhrase->aToken[i];
  2530         -        if( pToken->pDeferred==0 ){
  2531         -          rc = sqlite3Fts3DeferToken(pCsr, pToken, iCol);
  2532         -        }
  2533         -      }
  2534         -    }
  2535         -  }
  2536         -  return rc;
  2537         -}
  2538         -
  2539         -/*
  2540         -** This function removes the position information from a doclist. When
  2541         -** called, buffer aList (size *pnList bytes) contains a doclist that includes
  2542         -** position information. This function removes the position information so
  2543         -** that aList contains only docids, and adjusts *pnList to reflect the new
  2544         -** (possibly reduced) size of the doclist.
  2545         -*/
  2546         -static void fts3DoclistStripPositions(
  2547         -  char *aList,                    /* IN/OUT: Buffer containing doclist */
  2548         -  int *pnList                     /* IN/OUT: Size of doclist in bytes */
  2549         -){
  2550         -  if( aList ){
  2551         -    char *aEnd = &aList[*pnList]; /* Pointer to one byte after EOF */
  2552         -    char *p = aList;              /* Input cursor */
  2553         -    char *pOut = aList;           /* Output cursor */
  2554         -  
  2555         -    while( p<aEnd ){
  2556         -      sqlite3_int64 delta;
  2557         -      p += sqlite3Fts3GetVarint(p, &delta);
  2558         -      fts3PoslistCopy(0, &p);
  2559         -      pOut += sqlite3Fts3PutVarint(pOut, delta);
  2560         -    }
  2561         -
  2562         -    *pnList = (int)(pOut - aList);
  2563         -  }
  2564         -}
  2565         -
  2566         -/*
  2567         -** Return a DocList corresponding to the phrase *pPhrase.
  2568         -**
  2569         -** If this function returns SQLITE_OK, but *pnOut is set to a negative value,
  2570         -** then no tokens in the phrase were looked up in the full-text index. This
  2571         -** is only possible when this function is called from within xFilter(). The
  2572         -** caller should assume that all documents match the phrase. The actual
  2573         -** filtering will take place in xNext().
  2574         -*/
  2575         -static int fts3PhraseSelect(
  2576         -  Fts3Cursor *pCsr,               /* Virtual table cursor handle */
  2577         -  Fts3Phrase *pPhrase,            /* Phrase to return a doclist for */
  2578         -  int isReqPos,                   /* True if output should contain positions */
  2579         -  char **paOut,                   /* OUT: Pointer to malloc'd result buffer */
  2580         -  int *pnOut                      /* OUT: Size of buffer at *paOut */
  2581         -){
  2582         -  char *pOut = 0;
  2583         -  int nOut = 0;
  2584         -  int rc = SQLITE_OK;
  2585         -  int ii;
  2586         -  int iCol = pPhrase->iColumn;
  2587         -  int isTermPos = (pPhrase->nToken>1 || isReqPos);
  2588         -  Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
  2589         -  int isFirst = 1;
  2590         -
  2591         -  int iPrevTok = 0;
  2592         -  int nDoc = 0;
  2593         -
  2594         -  for(ii=0; ii<pPhrase->nToken; ii++){
  2595         -    Fts3PhraseToken *pTok;        /* Token to find doclist for */
  2596         -    int iTok = 0;                 /* The token being queried this iteration */
  2597         -    char *pList = 0;              /* Pointer to token doclist */
  2598         -    int nList = 0;                /* Size of buffer at pList */
  2599         -
  2600         -    /* Select a token to process. If this is an xFilter() call, then tokens 
  2601         -    ** are processed in order from least to most costly. Otherwise, tokens 
  2602         -    ** are processed in the order in which they occur in the phrase.
  2603         -    */
  2604         -    if( pCsr->eEvalmode==FTS3_EVAL_MATCHINFO ){
  2605         -      assert( isReqPos );
  2606         -      iTok = ii;
  2607         -      pTok = &pPhrase->aToken[iTok];
  2608         -      if( pTok->bFulltext==0 ) continue;
  2609         -    }else if( pCsr->eEvalmode==FTS3_EVAL_NEXT || isReqPos ){
  2610         -      iTok = ii;
  2611         -      pTok = &pPhrase->aToken[iTok];
  2612         -    }else{
  2613         -      int nMinCost = 0x7FFFFFFF;
  2614         -      int jj;
  2615         -
  2616         -      /* Find the remaining token with the lowest cost. */
  2617         -      for(jj=0; jj<pPhrase->nToken; jj++){
  2618         -        Fts3MultiSegReader *pSegcsr = pPhrase->aToken[jj].pSegcsr;
  2619         -        if( pSegcsr && pSegcsr->nCost<nMinCost ){
  2620         -          iTok = jj;
  2621         -          nMinCost = pSegcsr->nCost;
  2622         -        }
  2623         -      }
  2624         -      pTok = &pPhrase->aToken[iTok];
  2625         -
  2626         -      /* This branch is taken if it is determined that loading the doclist
  2627         -      ** for the next token would require more IO than loading all documents
  2628         -      ** currently identified by doclist pOut/nOut. No further doclists will
  2629         -      ** be loaded from the full-text index for this phrase.
  2630         -      */
  2631         -      if( nMinCost>nDoc && ii>0 ){
  2632         -        rc = fts3DeferExpression(pCsr, pCsr->pExpr);
  2633         -        break;
  2634         -      }
  2635         -    }
  2636         -
  2637         -    if( pCsr->eEvalmode==FTS3_EVAL_NEXT && pTok->pDeferred ){
  2638         -      rc = fts3DeferredTermSelect(pTok->pDeferred, isTermPos, &nList, &pList);
  2639         -    }else{
  2640         -      if( pTok->pSegcsr ){
  2641         -        rc = fts3TermSelect(p, pTok, iCol, isTermPos, &nList, &pList);
  2642         -      }
  2643         -      pTok->bFulltext = 1;
  2644         -    }
  2645         -    assert( rc!=SQLITE_OK || pCsr->eEvalmode || pTok->pSegcsr==0 );
  2646         -    if( rc!=SQLITE_OK ) break;
  2647         -
  2648         -    if( isFirst ){
  2649         -      pOut = pList;
  2650         -      nOut = nList;
  2651         -      if( pCsr->eEvalmode==FTS3_EVAL_FILTER && pPhrase->nToken>1 ){
  2652         -        nDoc = fts3DoclistCountDocids(1, pOut, nOut);
  2653         -      }
  2654         -      isFirst = 0;
  2655         -      iPrevTok = iTok;
  2656         -    }else{
  2657         -      /* Merge the new term list and the current output. */
  2658         -      char *aLeft, *aRight;
  2659         -      int nLeft, nRight;
  2660         -      int nDist;
  2661         -      int mt;
  2662         -
  2663         -      /* If this is the final token of the phrase, and positions were not
  2664         -      ** requested by the caller, use MERGE_PHRASE instead of POS_PHRASE.
  2665         -      ** This drops the position information from the output list.
  2666         -      */
  2667         -      mt = MERGE_POS_PHRASE;
  2668         -      if( ii==pPhrase->nToken-1 && !isReqPos ) mt = MERGE_PHRASE;
  2669         -
  2670         -      assert( iPrevTok!=iTok );
  2671         -      if( iPrevTok<iTok ){
  2672         -        aLeft = pOut;
  2673         -        nLeft = nOut;
  2674         -        aRight = pList;
  2675         -        nRight = nList;
  2676         -        nDist = iTok-iPrevTok;
  2677         -        iPrevTok = iTok;
  2678         -      }else{
  2679         -        aRight = pOut;
  2680         -        nRight = nOut;
  2681         -        aLeft = pList;
  2682         -        nLeft = nList;
  2683         -        nDist = iPrevTok-iTok;
  2684         -      }
  2685         -      pOut = aRight;
  2686         -      fts3DoclistMerge(
  2687         -          mt, nDist, 0, pOut, &nOut, aLeft, nLeft, aRight, nRight, &nDoc
  2688         -      );
  2689         -      sqlite3_free(aLeft);
  2690         -    }
  2691         -    assert( nOut==0 || pOut!=0 );
  2692         -  }
  2693         -
  2694         -  if( rc==SQLITE_OK ){
  2695         -    if( ii!=pPhrase->nToken ){
  2696         -      assert( pCsr->eEvalmode==FTS3_EVAL_FILTER && isReqPos==0 );
  2697         -      fts3DoclistStripPositions(pOut, &nOut);
  2698         -    }
  2699         -    *paOut = pOut;
  2700         -    *pnOut = nOut;
  2701         -  }else{
  2702         -    sqlite3_free(pOut);
  2703         -  }
  2704         -  return rc;
  2705         -}
  2706         -
  2707   2479   /*
  2708   2480   ** This function merges two doclists according to the requirements of a
  2709   2481   ** NEAR operator.
  2710   2482   **
  2711   2483   ** Both input doclists must include position information. The output doclist 
  2712   2484   ** includes position information if the first argument to this function
  2713   2485   ** is MERGE_POS_NEAR, or does not if it is MERGE_NEAR.
................................................................................
  2742   2514       }
  2743   2515     }
  2744   2516   
  2745   2517     *paOut = aOut;
  2746   2518     return rc;
  2747   2519   }
  2748   2520   
  2749         -/*
  2750         -** This function is used as part of the processing for the snippet() and
  2751         -** offsets() functions.
  2752         -**
  2753         -** Both pLeft and pRight are expression nodes of type FTSQUERY_PHRASE. Both
  2754         -** have their respective doclists (including position information) loaded
  2755         -** in Fts3Expr.aDoclist/nDoclist. This function removes all entries from
  2756         -** each doclist that are not within nNear tokens of a corresponding entry
  2757         -** in the other doclist.
  2758         -*/
  2759         -int sqlite3Fts3ExprNearTrim(Fts3Expr *pELeft, Fts3Expr *pERight, int nNear){
  2760         -  int rc;                         /* Return code */
  2761         -  Fts3Phrase *pLeft = pELeft->pPhrase;
  2762         -  Fts3Phrase *pRight = pERight->pPhrase;
  2763         -
  2764         -  assert( pELeft->eType==FTSQUERY_PHRASE && pLeft );
  2765         -  assert( pERight->eType==FTSQUERY_PHRASE && pRight );
  2766         -  assert( pLeft->isLoaded && pRight->isLoaded );
  2767         -
  2768         -  if( pLeft->aDoclist==0 || pRight->aDoclist==0 ){
  2769         -    sqlite3_free(pLeft->aDoclist);
  2770         -    sqlite3_free(pRight->aDoclist);
  2771         -    pRight->aDoclist = 0;
  2772         -    pLeft->aDoclist = 0;
  2773         -    rc = SQLITE_OK;
  2774         -  }else{
  2775         -    char *aOut;                   /* Buffer in which to assemble new doclist */
  2776         -    int nOut;                     /* Size of buffer aOut in bytes */
  2777         -
  2778         -    rc = fts3NearMerge(MERGE_POS_NEAR, nNear, 
  2779         -        pLeft->nToken, pLeft->aDoclist, pLeft->nDoclist,
  2780         -        pRight->nToken, pRight->aDoclist, pRight->nDoclist,
  2781         -        &aOut, &nOut
  2782         -    );
  2783         -    if( rc!=SQLITE_OK ) return rc;
  2784         -    sqlite3_free(pRight->aDoclist);
  2785         -    pRight->aDoclist = aOut;
  2786         -    pRight->nDoclist = nOut;
  2787         -
  2788         -    rc = fts3NearMerge(MERGE_POS_NEAR, nNear, 
  2789         -        pRight->nToken, pRight->aDoclist, pRight->nDoclist,
  2790         -        pLeft->nToken, pLeft->aDoclist, pLeft->nDoclist,
  2791         -        &aOut, &nOut
  2792         -    );
  2793         -    sqlite3_free(pLeft->aDoclist);
  2794         -    pLeft->aDoclist = aOut;
  2795         -    pLeft->nDoclist = nOut;
  2796         -  }
  2797         -  return rc;
  2798         -}
  2799         -
  2800         -
  2801         -/*
  2802         -** Allocate an Fts3SegReaderArray for each token in the expression pExpr. 
  2803         -** The allocated objects are stored in the Fts3PhraseToken.pArray member
  2804         -** variables of each token structure.
  2805         -*/
  2806         -static int fts3ExprAllocateSegReaders(
  2807         -  Fts3Cursor *pCsr,               /* FTS3 table */
  2808         -  Fts3Expr *pExpr,                /* Expression to create seg-readers for */
  2809         -  int *pnExpr                     /* OUT: Number of AND'd expressions */
  2810         -){
  2811         -  int rc = SQLITE_OK;             /* Return code */
  2812         -
  2813         -  assert( pCsr->eEvalmode==FTS3_EVAL_FILTER );
  2814         -  if( pnExpr && pExpr->eType!=FTSQUERY_AND ){
  2815         -    (*pnExpr)++;
  2816         -    pnExpr = 0;
  2817         -  }
  2818         -
  2819         -  if( pExpr->eType==FTSQUERY_PHRASE ){
  2820         -    int ii;                       /* Used to iterate through phrase tokens */
  2821         -    Fts3Phrase *pPhrase = pExpr->pPhrase;
  2822         -
  2823         -    for(ii=0; rc==SQLITE_OK && ii<pPhrase->nToken; ii++){
  2824         -      Fts3PhraseToken *pTok = &pPhrase->aToken[ii];
  2825         -      if( pTok->pSegcsr==0 ){
  2826         -        rc = sqlite3Fts3TermSegReaderCursor(
  2827         -            pCsr, pTok->z, pTok->n, pTok->isPrefix, &pTok->pSegcsr
  2828         -        );
  2829         -      }
  2830         -    }
  2831         -  }else{ 
  2832         -    rc = fts3ExprAllocateSegReaders(pCsr, pExpr->pLeft, pnExpr);
  2833         -    if( rc==SQLITE_OK ){
  2834         -      rc = fts3ExprAllocateSegReaders(pCsr, pExpr->pRight, pnExpr);
  2835         -    }
  2836         -  }
  2837         -  return rc;
  2838         -}
  2839         -
  2840         -/*
  2841         -** Free the Fts3SegReaderArray objects associated with each token in the
  2842         -** expression pExpr. In other words, this function frees the resources
  2843         -** allocated by fts3ExprAllocateSegReaders().
  2844         -*/
  2845         -static void fts3ExprFreeSegReaders(Fts3Expr *pExpr){
  2846         -  if( pExpr ){
  2847         -    Fts3Phrase *pPhrase = pExpr->pPhrase;
  2848         -    if( pPhrase ){
  2849         -      int kk;
  2850         -      for(kk=0; kk<pPhrase->nToken; kk++){
  2851         -        fts3SegReaderCursorFree(pPhrase->aToken[kk].pSegcsr);
  2852         -        pPhrase->aToken[kk].pSegcsr = 0;
  2853         -      }
  2854         -    }
  2855         -    fts3ExprFreeSegReaders(pExpr->pLeft);
  2856         -    fts3ExprFreeSegReaders(pExpr->pRight);
  2857         -  }
  2858         -}
  2859         -
  2860         -/*
  2861         -** Return the sum of the costs of all tokens in the expression pExpr. This
  2862         -** function must be called after Fts3SegReaderArrays have been allocated
  2863         -** for all tokens using fts3ExprAllocateSegReaders().
  2864         -*/
  2865         -static int fts3ExprCost(Fts3Expr *pExpr){
  2866         -  int nCost;                      /* Return value */
  2867         -  if( pExpr->eType==FTSQUERY_PHRASE ){
  2868         -    Fts3Phrase *pPhrase = pExpr->pPhrase;
  2869         -    int ii;
  2870         -    nCost = 0;
  2871         -    for(ii=0; ii<pPhrase->nToken; ii++){
  2872         -      Fts3MultiSegReader *pSegcsr = pPhrase->aToken[ii].pSegcsr;
  2873         -      if( pSegcsr ) nCost += pSegcsr->nCost;
  2874         -    }
  2875         -  }else{
  2876         -    nCost = fts3ExprCost(pExpr->pLeft) + fts3ExprCost(pExpr->pRight);
  2877         -  }
  2878         -  return nCost;
  2879         -}
  2880         -
  2881         -/*
  2882         -** The following is a helper function (and type) for fts3EvalExpr(). It
  2883         -** must be called after Fts3SegReaders have been allocated for every token
  2884         -** in the expression. See the context it is called from in fts3EvalExpr()
  2885         -** for further explanation.
  2886         -*/
  2887         -typedef struct ExprAndCost ExprAndCost;
  2888         -struct ExprAndCost {
  2889         -  Fts3Expr *pExpr;
  2890         -  int nCost;
  2891         -};
  2892         -static void fts3ExprAssignCosts(
  2893         -  Fts3Expr *pExpr,                /* Expression to create seg-readers for */
  2894         -  ExprAndCost **ppExprCost        /* OUT: Write to *ppExprCost */
  2895         -){
  2896         -  if( pExpr->eType==FTSQUERY_AND ){
  2897         -    fts3ExprAssignCosts(pExpr->pLeft, ppExprCost);
  2898         -    fts3ExprAssignCosts(pExpr->pRight, ppExprCost);
  2899         -  }else{
  2900         -    (*ppExprCost)->pExpr = pExpr;
  2901         -    (*ppExprCost)->nCost = fts3ExprCost(pExpr);
  2902         -    (*ppExprCost)++;
  2903         -  }
  2904         -}
  2905         -
  2906         -/*
  2907         -** Evaluate the full-text expression pExpr against FTS3 table pTab. Store
  2908         -** the resulting doclist in *paOut and *pnOut. This routine mallocs for
  2909         -** the space needed to store the output. The caller is responsible for
  2910         -** freeing the space when it has finished.
  2911         -**
  2912         -** This function is called in two distinct contexts:
  2913         -**
  2914         -**   * From within the virtual table xFilter() method. In this case, the
  2915         -**     output doclist contains entries for all rows in the table, based on
  2916         -**     data read from the full-text index.
  2917         -**
  2918         -**     In this case, if the query expression contains one or more tokens that 
  2919         -**     are very common, then the returned doclist may contain a superset of 
  2920         -**     the documents that actually match the expression.
  2921         -**
  2922         -**   * From within the virtual table xNext() method. This call is only made
  2923         -**     if the call from within xFilter() found that there were very common 
  2924         -**     tokens in the query expression and did return a superset of the 
  2925         -**     matching documents. In this case the returned doclist contains only
  2926         -**     entries that correspond to the current row of the table. Instead of
  2927         -**     reading the data for each token from the full-text index, the data is
  2928         -**     already available in-memory in the Fts3PhraseToken.pDeferred structures.
  2929         -**     See fts3EvalDeferred() for how it gets there.
  2930         -**
  2931         -** In the first case above, Fts3Cursor.doDeferred==0. In the second (if it is
  2932         -** required) Fts3Cursor.doDeferred==1.
  2933         -**
  2934         -** If the SQLite invokes the snippet(), offsets() or matchinfo() function
  2935         -** as part of a SELECT on an FTS3 table, this function is called on each
  2936         -** individual phrase expression in the query. If there were very common tokens
  2937         -** found in the xFilter() call, then this function is called once for phrase
  2938         -** for each row visited, and the returned doclist contains entries for the
  2939         -** current row only. Otherwise, if there were no very common tokens, then this
  2940         -** function is called once only for each phrase in the query and the returned
  2941         -** doclist contains entries for all rows of the table.
  2942         -**
  2943         -** Fts3Cursor.doDeferred==1 when this function is called on phrases as a
  2944         -** result of a snippet(), offsets() or matchinfo() invocation.
  2945         -*/
  2946         -static int fts3EvalExpr(
  2947         -  Fts3Cursor *p,                  /* Virtual table cursor handle */
  2948         -  Fts3Expr *pExpr,                /* Parsed fts3 expression */
  2949         -  char **paOut,                   /* OUT: Pointer to malloc'd result buffer */
  2950         -  int *pnOut,                     /* OUT: Size of buffer at *paOut */
  2951         -  int isReqPos                    /* Require positions in output buffer */
  2952         -){
  2953         -  int rc = SQLITE_OK;             /* Return code */
  2954         -
  2955         -  /* Zero the output parameters. */
  2956         -  *paOut = 0;
  2957         -  *pnOut = 0;
  2958         -
  2959         -  if( pExpr ){
  2960         -    assert( pExpr->eType==FTSQUERY_NEAR   || pExpr->eType==FTSQUERY_OR     
  2961         -         || pExpr->eType==FTSQUERY_AND    || pExpr->eType==FTSQUERY_NOT
  2962         -         || pExpr->eType==FTSQUERY_PHRASE
  2963         -    );
  2964         -    assert( pExpr->eType==FTSQUERY_PHRASE || isReqPos==0 );
  2965         -
  2966         -    if( pExpr->eType==FTSQUERY_PHRASE ){
  2967         -      rc = fts3PhraseSelect(p, pExpr->pPhrase,
  2968         -          isReqPos || (pExpr->pParent && pExpr->pParent->eType==FTSQUERY_NEAR),
  2969         -          paOut, pnOut
  2970         -      );
  2971         -      fts3ExprFreeSegReaders(pExpr);
  2972         -    }else if( p->eEvalmode==FTS3_EVAL_FILTER && pExpr->eType==FTSQUERY_AND ){
  2973         -      ExprAndCost *aExpr = 0;     /* Array of AND'd expressions and costs */
  2974         -      int nExpr = 0;              /* Size of aExpr[] */
  2975         -      char *aRet = 0;             /* Doclist to return to caller */
  2976         -      int nRet = 0;               /* Length of aRet[] in bytes */
  2977         -      int nDoc = 0x7FFFFFFF;
  2978         -
  2979         -      assert( !isReqPos );
  2980         -
  2981         -      rc = fts3ExprAllocateSegReaders(p, pExpr, &nExpr);
  2982         -      if( rc==SQLITE_OK ){
  2983         -        assert( nExpr>1 );
  2984         -        aExpr = sqlite3_malloc(sizeof(ExprAndCost) * nExpr);
  2985         -        if( !aExpr ) rc = SQLITE_NOMEM;
  2986         -      }
  2987         -      if( rc==SQLITE_OK ){
  2988         -        int ii;                   /* Used to iterate through expressions */
  2989         -
  2990         -        fts3ExprAssignCosts(pExpr, &aExpr);
  2991         -        aExpr -= nExpr;
  2992         -        for(ii=0; ii<nExpr; ii++){
  2993         -          char *aNew;
  2994         -          int nNew;
  2995         -          int jj;
  2996         -          ExprAndCost *pBest = 0;
  2997         -  
  2998         -          for(jj=0; jj<nExpr; jj++){
  2999         -            ExprAndCost *pCand = &aExpr[jj];
  3000         -            if( pCand->pExpr && (pBest==0 || pCand->nCost<pBest->nCost) ){
  3001         -              pBest = pCand;
  3002         -            }
  3003         -          }
  3004         -  
  3005         -          if( pBest->nCost>nDoc ){
  3006         -            rc = fts3DeferExpression(p, p->pExpr);
  3007         -            break;
  3008         -          }else{
  3009         -            rc = fts3EvalExpr(p, pBest->pExpr, &aNew, &nNew, 0);
  3010         -            if( rc!=SQLITE_OK ) break;
  3011         -            pBest->pExpr = 0;
  3012         -            if( ii==0 ){
  3013         -              aRet = aNew;
  3014         -              nRet = nNew;
  3015         -              nDoc = fts3DoclistCountDocids(0, aRet, nRet);
  3016         -            }else{
  3017         -              fts3DoclistMerge(
  3018         -                  MERGE_AND, 0, 0, aRet, &nRet, aRet, nRet, aNew, nNew, &nDoc
  3019         -              );
  3020         -              sqlite3_free(aNew);
  3021         -            }
  3022         -          }
  3023         -        }
  3024         -      }
  3025         -
  3026         -      if( rc==SQLITE_OK ){
  3027         -        *paOut = aRet;
  3028         -        *pnOut = nRet;
  3029         -      }else{
  3030         -        assert( *paOut==0 );
  3031         -        sqlite3_free(aRet);
  3032         -      }
  3033         -      sqlite3_free(aExpr);
  3034         -      fts3ExprFreeSegReaders(pExpr);
  3035         -
  3036         -    }else{
  3037         -      char *aLeft;
  3038         -      char *aRight;
  3039         -      int nLeft;
  3040         -      int nRight;
  3041         -
  3042         -      assert( pExpr->eType==FTSQUERY_NEAR 
  3043         -           || pExpr->eType==FTSQUERY_OR
  3044         -           || pExpr->eType==FTSQUERY_NOT
  3045         -           || (pExpr->eType==FTSQUERY_AND && p->eEvalmode==FTS3_EVAL_NEXT)
  3046         -      );
  3047         -
  3048         -      if( 0==(rc = fts3EvalExpr(p, pExpr->pRight, &aRight, &nRight, isReqPos))
  3049         -       && 0==(rc = fts3EvalExpr(p, pExpr->pLeft, &aLeft, &nLeft, isReqPos))
  3050         -      ){
  3051         -        switch( pExpr->eType ){
  3052         -          case FTSQUERY_NEAR: {
  3053         -            Fts3Expr *pLeft;
  3054         -            Fts3Expr *pRight;
  3055         -            int mergetype = MERGE_NEAR;
  3056         -            if( pExpr->pParent && pExpr->pParent->eType==FTSQUERY_NEAR ){
  3057         -              mergetype = MERGE_POS_NEAR;
  3058         -            }
  3059         -            pLeft = pExpr->pLeft;
  3060         -            while( pLeft->eType==FTSQUERY_NEAR ){ 
  3061         -              pLeft=pLeft->pRight;
  3062         -            }
  3063         -            pRight = pExpr->pRight;
  3064         -            assert( pRight->eType==FTSQUERY_PHRASE );
  3065         -            assert( pLeft->eType==FTSQUERY_PHRASE );
  3066         -
  3067         -            rc = fts3NearMerge(mergetype, pExpr->nNear, 
  3068         -                pLeft->pPhrase->nToken, aLeft, nLeft,
  3069         -                pRight->pPhrase->nToken, aRight, nRight,
  3070         -                paOut, pnOut
  3071         -            );
  3072         -            sqlite3_free(aLeft);
  3073         -            break;
  3074         -          }
  3075         -
  3076         -          case FTSQUERY_OR: {
  3077         -            /* Allocate a buffer for the output. The maximum size is the
  3078         -            ** sum of the sizes of the two input buffers. The +1 term is
  3079         -            ** so that a buffer of zero bytes is never allocated - this can
  3080         -            ** cause fts3DoclistMerge() to incorrectly return SQLITE_NOMEM.
  3081         -            */
  3082         -            char *aBuffer = sqlite3_malloc(nRight+nLeft+1);
  3083         -            rc = fts3DoclistMerge(MERGE_OR, 0, 0, aBuffer, pnOut,
  3084         -                aLeft, nLeft, aRight, nRight, 0
  3085         -            );
  3086         -            *paOut = aBuffer;
  3087         -            sqlite3_free(aLeft);
  3088         -            break;
  3089         -          }
  3090         -
  3091         -          default: {
  3092         -            assert( FTSQUERY_NOT==MERGE_NOT && FTSQUERY_AND==MERGE_AND );
  3093         -            fts3DoclistMerge(pExpr->eType, 0, 0, aLeft, pnOut,
  3094         -                aLeft, nLeft, aRight, nRight, 0
  3095         -            );
  3096         -            *paOut = aLeft;
  3097         -            break;
  3098         -          }
  3099         -        }
  3100         -      }
  3101         -      sqlite3_free(aRight);
  3102         -    }
  3103         -  }
  3104         -
  3105         -  assert( rc==SQLITE_OK || *paOut==0 );
  3106         -  return rc;
  3107         -}
  3108         -
  3109         -/*
  3110         -** This function is called from within xNext() for each row visited by
  3111         -** an FTS3 query. If evaluating the FTS3 query expression within xFilter()
  3112         -** was able to determine the exact set of matching rows, this function sets
  3113         -** *pbRes to true and returns SQLITE_IO immediately.
  3114         -**
  3115         -** Otherwise, if evaluating the query expression within xFilter() returned a
  3116         -** superset of the matching documents instead of an exact set (this happens
  3117         -** when the query includes very common tokens and it is deemed too expensive to
  3118         -** load their doclists from disk), this function tests if the current row
  3119         -** really does match the FTS3 query.
  3120         -**
  3121         -** If an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK
  3122         -** is returned and *pbRes is set to true if the current row matches the
  3123         -** FTS3 query (and should be included in the results returned to SQLite), or
  3124         -** false otherwise.
  3125         -*/
  3126         -static int fts3EvalDeferred(
  3127         -  Fts3Cursor *pCsr,               /* FTS3 cursor pointing at row to test */
  3128         -  int *pbRes                      /* OUT: Set to true if row is a match */
  3129         -){
  3130         -  int rc = SQLITE_OK;
  3131         -  if( pCsr->pDeferred==0 ){
  3132         -    *pbRes = 1;
  3133         -  }else{
  3134         -    rc = fts3CursorSeek(0, pCsr);
  3135         -    if( rc==SQLITE_OK ){
  3136         -      sqlite3Fts3FreeDeferredDoclists(pCsr);
  3137         -      rc = sqlite3Fts3CacheDeferredDoclists(pCsr);
  3138         -    }
  3139         -    if( rc==SQLITE_OK ){
  3140         -      char *a = 0;
  3141         -      int n = 0;
  3142         -      rc = fts3EvalExpr(pCsr, pCsr->pExpr, &a, &n, 0);
  3143         -      assert( n>=0 );
  3144         -      *pbRes = (n>0);
  3145         -      sqlite3_free(a);
  3146         -    }
  3147         -  }
  3148         -  return rc;
  3149         -}
  3150         -
  3151   2521   /*
  3152   2522   ** Advance the cursor to the next row in the %_content table that
  3153   2523   ** matches the search criteria.  For a MATCH search, this will be
  3154   2524   ** the next row that matches. For a full-table scan, this will be
  3155   2525   ** simply the next row in the %_content table.  For a docid lookup,
  3156   2526   ** this routine simply sets the EOF flag.
  3157   2527   **
  3158   2528   ** Return SQLITE_OK if nothing goes wrong.  SQLITE_OK is returned
  3159   2529   ** even if we reach end-of-file.  The fts3EofMethod() will be called
  3160   2530   ** subsequently to determine whether or not an EOF was hit.
  3161   2531   */
  3162   2532   static int fts3NextMethod(sqlite3_vtab_cursor *pCursor){
  3163         -  int res;
  3164         -  int rc = SQLITE_OK;             /* Return code */
         2533  +  int rc;
  3165   2534     Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
  3166         -
  3167         -  if( pCsr->bIncremental ){
  3168         -    rc = sqlite3Fts3EvalNext(pCsr, pCsr->pExpr);
         2535  +  if( pCsr->eSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){
         2536  +    if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){
         2537  +      pCsr->isEof = 1;
         2538  +      rc = sqlite3_reset(pCsr->pStmt);
         2539  +    }else{
         2540  +      pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0);
         2541  +      rc = SQLITE_OK;
         2542  +    }
  3169   2543     }else{
  3170         -    pCsr->eEvalmode = FTS3_EVAL_NEXT;
  3171         -    do {
  3172         -      if( pCsr->aDoclist==0 ){
  3173         -        if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){
  3174         -          pCsr->isEof = 1;
  3175         -          rc = sqlite3_reset(pCsr->pStmt);
  3176         -          break;
  3177         -        }
  3178         -        pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0);
  3179         -      }else{
  3180         -        if( pCsr->desc==0 ){
  3181         -          if( pCsr->pNextId>=&pCsr->aDoclist[pCsr->nDoclist] ){
  3182         -            pCsr->isEof = 1;
  3183         -            break;
  3184         -          }
  3185         -          fts3GetDeltaVarint(&pCsr->pNextId, &pCsr->iPrevId);
  3186         -        }else{
  3187         -          fts3GetReverseDeltaVarint(&pCsr->pNextId,pCsr->aDoclist,&pCsr->iPrevId);
  3188         -          if( pCsr->pNextId<=pCsr->aDoclist ){
  3189         -            pCsr->isEof = 1;
  3190         -            break;
  3191         -          }
  3192         -        }
  3193         -        sqlite3_reset(pCsr->pStmt);
  3194         -        pCsr->isRequireSeek = 1;
  3195         -        pCsr->isMatchinfoNeeded = 1;
  3196         -      }
  3197         -    }while( SQLITE_OK==(rc = fts3EvalDeferred(pCsr, &res)) && res==0 );
         2544  +    rc = sqlite3Fts3EvalNext((Fts3Cursor *)pCursor);
  3198   2545     }
  3199         -
  3200   2546     return rc;
  3201   2547   }
  3202   2548   
  3203   2549   /*
  3204   2550   ** This is the xFilter interface for the virtual table.  See
  3205   2551   ** the virtual table xFilter method documentation for additional
  3206   2552   ** information.
................................................................................
  3237   2583     assert( p->pSegments==0 );
  3238   2584   
  3239   2585     /* In case the cursor has been used before, clear it now. */
  3240   2586     sqlite3_finalize(pCsr->pStmt);
  3241   2587     sqlite3_free(pCsr->aDoclist);
  3242   2588     sqlite3Fts3ExprFree(pCsr->pExpr);
  3243   2589     memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
         2590  +
         2591  +  pCsr->bDesc = (idxStr && idxStr[0]=='D');
         2592  +  pCsr->eSearch = (i16)idxNum;
  3244   2593   
  3245   2594     if( idxNum!=FTS3_DOCID_SEARCH && idxNum!=FTS3_FULLSCAN_SEARCH ){
  3246   2595       int iCol = idxNum-FTS3_FULLTEXT_SEARCH;
  3247   2596       const char *zQuery = (const char *)sqlite3_value_text(apVal[0]);
  3248   2597   
  3249   2598       if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
  3250   2599         return SQLITE_NOMEM;
................................................................................
  3260   2609         }
  3261   2610         return rc;
  3262   2611       }
  3263   2612   
  3264   2613       rc = sqlite3Fts3ReadLock(p);
  3265   2614       if( rc!=SQLITE_OK ) return rc;
  3266   2615   
  3267         -    pCsr->bIncremental = 1;
  3268   2616       rc = sqlite3Fts3EvalStart(pCsr, pCsr->pExpr, 1);
  3269   2617   
  3270   2618       sqlite3Fts3SegmentsClose(p);
  3271   2619       if( rc!=SQLITE_OK ) return rc;
  3272   2620       pCsr->pNextId = pCsr->aDoclist;
  3273   2621       pCsr->iPrevId = 0;
  3274   2622     }
................................................................................
  3292   2640     if( rc!=SQLITE_OK ) return rc;
  3293   2641   
  3294   2642     if( idxNum==FTS3_DOCID_SEARCH ){
  3295   2643       rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
  3296   2644       if( rc!=SQLITE_OK ) return rc;
  3297   2645     }
  3298   2646   
  3299         -  assert( pCsr->desc==0 );
  3300         -  pCsr->eSearch = (i16)idxNum;
  3301         -  if( rc==SQLITE_OK && pCsr->nDoclist>0 && idxStr && idxStr[0]=='D' ){
  3302         -    sqlite3_int64 iDocid = 0;
  3303         -    char *csr = pCsr->aDoclist;
  3304         -    while( csr<&pCsr->aDoclist[pCsr->nDoclist] ){
  3305         -      fts3GetDeltaVarint(&csr, &iDocid);
  3306         -    }
  3307         -    pCsr->pNextId = csr;
  3308         -    pCsr->iPrevId = iDocid;
  3309         -    pCsr->desc = 1;
  3310         -    pCsr->isRequireSeek = 1;
  3311         -    pCsr->isMatchinfoNeeded = 1;
  3312         -    pCsr->eEvalmode = FTS3_EVAL_NEXT;
  3313         -    return SQLITE_OK;
  3314         -  }
  3315   2647     return fts3NextMethod(pCursor);
  3316   2648   }
  3317   2649   
  3318   2650   /* 
  3319   2651   ** This is the xEof method of the virtual table. SQLite calls this 
  3320   2652   ** routine to find out if it has reached the end of a result set.
  3321   2653   */
................................................................................
  3327   2659   ** This is the xRowid method. The SQLite core calls this routine to
  3328   2660   ** retrieve the rowid for the current row of the result set. fts3
  3329   2661   ** exposes %_content.docid as the rowid for the virtual table. The
  3330   2662   ** rowid should be written to *pRowid.
  3331   2663   */
  3332   2664   static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
  3333   2665     Fts3Cursor *pCsr = (Fts3Cursor *) pCursor;
  3334         -  if( pCsr->bIncremental ){
  3335         -    *pRowid = sqlite3Fts3EvalDocid(pCsr, pCsr->pExpr);
  3336         -  }else if( pCsr->aDoclist ){
  3337         -    *pRowid = pCsr->iPrevId;
  3338         -  }else{
  3339         -    /* This branch runs if the query is implemented using a full-table scan
  3340         -    ** (not using the full-text index). In this case grab the rowid from the
  3341         -    ** SELECT statement.
  3342         -    */
  3343         -    assert( pCsr->isRequireSeek==0 );
  3344         -    *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
  3345         -  }
         2666  +  *pRowid = pCsr->iPrevId;
  3346   2667     return SQLITE_OK;
  3347   2668   }
  3348   2669   
  3349   2670   /* 
  3350   2671   ** This is the xColumn method, called by SQLite to request a value from
  3351   2672   ** the row that the supplied cursor currently points to.
  3352   2673   */
................................................................................
  3444   2765     Fts3Table *p = (Fts3Table*)pVtab;
  3445   2766     sqlite3Fts3PendingTermsClear(p);
  3446   2767     assert( p->inTransaction!=0 );
  3447   2768     TESTONLY( p->inTransaction = 0 );
  3448   2769     TESTONLY( p->mxSavepoint = -1; );
  3449   2770     return SQLITE_OK;
  3450   2771   }
  3451         -
  3452         -/*
  3453         -** Load the doclist associated with expression pExpr to pExpr->aDoclist.
  3454         -** The loaded doclist contains positions as well as the document ids.
  3455         -** This is used by the matchinfo(), snippet() and offsets() auxillary
  3456         -** functions.
  3457         -*/
  3458         -int sqlite3Fts3ExprLoadDoclist(Fts3Cursor *pCsr, Fts3Expr *pExpr){
  3459         -  int rc = SQLITE_OK;
  3460         -  if( pCsr->bIncremental==0 ){
  3461         -    Fts3Phrase *pPhrase = pExpr->pPhrase;
  3462         -    assert( pExpr->eType==FTSQUERY_PHRASE && pPhrase );
  3463         -    assert( pCsr->eEvalmode==FTS3_EVAL_NEXT );
  3464         -    rc = fts3EvalExpr(pCsr, pExpr, &pPhrase->aDoclist, &pPhrase->nDoclist, 1);
  3465         -  }
  3466         -  return rc;
  3467         -}
  3468         -
  3469         -/*
  3470         -** TODO: This is something to do with matchinfo(). Similar to
  3471         -** sqlite3ExprLoadDoclists() but slightly different.
  3472         -**
  3473         -** UPDATE: Only used when there are deferred tokens.
  3474         -*/
  3475         -int sqlite3Fts3ExprLoadFtDoclist(
  3476         -  Fts3Cursor *pCsr, 
  3477         -  Fts3Expr *pExpr,
  3478         -  char **paDoclist,
  3479         -  int *pnDoclist
  3480         -){
  3481         -  int rc = SQLITE_OK;
  3482         -  assert( pExpr->eType==FTSQUERY_PHRASE && pExpr->pPhrase );
  3483         -  assert( pCsr->eEvalmode==FTS3_EVAL_NEXT );
  3484         -  assert( pCsr->bIncremental==0 );
  3485         -  pCsr->eEvalmode = FTS3_EVAL_MATCHINFO;
  3486         -  rc = fts3EvalExpr(pCsr, pExpr, paDoclist, pnDoclist, 1);
  3487         -  pCsr->eEvalmode = FTS3_EVAL_NEXT;
  3488         -  return rc;
  3489         -}
  3490         -
  3491   2772   
  3492   2773   /*
  3493   2774   ** When called, *ppPoslist must point to the byte immediately following the
  3494   2775   ** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function
  3495   2776   ** moves *ppPoslist so that it instead points to the first byte of the
  3496   2777   ** same position list.
  3497   2778   */
................................................................................
  3905   3186     const sqlite3_api_routines *pApi
  3906   3187   ){
  3907   3188     SQLITE_EXTENSION_INIT2(pApi)
  3908   3189     return sqlite3Fts3Init(db);
  3909   3190   }
  3910   3191   #endif
  3911   3192   
  3912         -/*************************************************************************
  3913         -**************************************************************************
  3914         -**************************************************************************
  3915         -**************************************************************************
  3916         -*************************************************************************/
  3917         -
  3918   3193   
  3919   3194   /*
  3920   3195   ** Allocate an Fts3MultiSegReader for each token in the expression headed
  3921   3196   ** by pExpr. 
  3922   3197   **
  3923   3198   ** An Fts3SegReader object is a cursor that can seek or scan a range of
  3924   3199   ** entries within a single segment b-tree. An Fts3MultiSegReader uses multiple
................................................................................
  4016   3291     int iToken;
  4017   3292     int rc = SQLITE_OK;
  4018   3293   
  4019   3294     int nMaxUndeferred = -1;
  4020   3295     char *aPoslist = 0;
  4021   3296     int nPoslist = 0;
  4022   3297     int iPrev = -1;
         3298  +
         3299  +  assert( pPhrase->doclist.bFreeList==0 );
  4023   3300   
  4024   3301     for(iToken=0; rc==SQLITE_OK && iToken<pPhrase->nToken; iToken++){
  4025   3302       Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
  4026   3303       Fts3DeferredToken *pDeferred = pToken->pDeferred;
  4027   3304   
  4028   3305       if( pDeferred ){
  4029   3306         char *pList;
................................................................................
  4066   3343     }
  4067   3344   
  4068   3345     if( iPrev>=0 ){
  4069   3346       if( nMaxUndeferred<0 ){
  4070   3347         pPhrase->doclist.pList = aPoslist;
  4071   3348         pPhrase->doclist.nList = nPoslist;
  4072   3349         pPhrase->doclist.iDocid = pCsr->iPrevId;
         3350  +      pPhrase->doclist.bFreeList = 1;
  4073   3351       }else{
  4074   3352         int nDistance;
  4075   3353         char *p1;
  4076   3354         char *p2;
  4077   3355         char *aOut;
  4078   3356   
  4079   3357         if( nMaxUndeferred>iPrev ){
................................................................................
  4090   3368         if( !aOut ){
  4091   3369           sqlite3_free(aPoslist);
  4092   3370           return SQLITE_NOMEM;
  4093   3371         }
  4094   3372         
  4095   3373         pPhrase->doclist.pList = aOut;
  4096   3374         if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){
         3375  +        pPhrase->doclist.bFreeList = 1;
  4097   3376           pPhrase->doclist.nList = (aOut - pPhrase->doclist.pList);
  4098         -        sqlite3_free(aPoslist);
  4099   3377         }else{
  4100   3378           sqlite3_free(aOut);
  4101   3379           pPhrase->doclist.pList = 0;
  4102   3380           pPhrase->doclist.nList = 0;
  4103   3381         }
         3382  +      sqlite3_free(aPoslist);
  4104   3383       }
  4105   3384     }
  4106   3385   
  4107   3386     return SQLITE_OK;
  4108   3387   }
  4109   3388   
  4110   3389   
  4111   3390   /*
  4112   3391   ** The following three functions:
  4113   3392   **
  4114   3393   **     fts3EvalPhraseStart()
  4115   3394   **     fts3EvalPhraseNext()
  4116         -**     fts3EvalPhraseReset()
  4117   3395   **
  4118   3396   ** May be used with a phrase object after fts3EvalAllocateReaders() has been
  4119   3397   ** called to iterate through the set of docids that match the phrase.
  4120   3398   **
  4121   3399   ** After a successful call to fts3EvalPhraseNext(), the following two 
  4122   3400   ** functions may be called to access the current docid and position-list.
  4123         -**
  4124         -**     fts3EvalPhraseDocid()
  4125         -**     fts3EvalPhrasePoslist()
         3401  +*/
         3402  +
         3403  +
         3404  +/*
         3405  +** This function is called for each Fts3Phrase in a full-text query 
         3406  +** expression to initialize the mechanism for returning rows. Once this
         3407  +** function has been called successfully on an Fts3Phrase, it may be
         3408  +** used with fts3EvalPhraseNext() to iterate through the matching docids.
  4126   3409   */
  4127   3410   static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){
  4128   3411     int rc;
  4129   3412     Fts3Doclist *pList = &p->doclist;
  4130   3413     Fts3PhraseToken *pFirst = &p->aToken[0];
  4131   3414   
  4132   3415     assert( pList->aAll==0 );
  4133   3416   
  4134         -  if( p->nToken==1 && bOptOk==1 
         3417  +  if( pCsr->bDesc==0 && bOptOk==1 && p->nToken==1 
  4135   3418      && pFirst->pSegcsr && pFirst->pSegcsr->bLookup 
  4136   3419     ){
  4137   3420       /* Use the incremental approach. */
  4138   3421       Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
  4139   3422       int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
  4140   3423       rc = sqlite3Fts3MsrIncrStart(
  4141   3424           pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
  4142   3425       p->bIncr = 1;
  4143   3426   
  4144   3427     }else{
  4145         -
  4146   3428       /* Load the full doclist for the phrase into memory. */
  4147   3429       rc = fts3EvalPhraseLoad(pCsr, p);
  4148   3430       p->bIncr = 0;
  4149   3431     }
  4150   3432   
  4151   3433     assert( rc!=SQLITE_OK || p->nToken<1 || p->aToken[0].pSegcsr==0 || p->bIncr );
  4152   3434     return rc;
................................................................................
  4157   3439   ** If an error occurs, return an SQLite error code. Otherwise, return 
  4158   3440   ** SQLITE_OK.
  4159   3441   **
  4160   3442   ** If there is no "next" entry and no error occurs, then *pbEof is set to
  4161   3443   ** 1 before returning. Otherwise, if no error occurs and the iterator is
  4162   3444   ** successfully advanced, *pbEof is set to 0.
  4163   3445   */
  4164         -static int fts3EvalPhraseNext(Fts3Cursor *pCsr, Fts3Phrase *p, u8 *pbEof){
         3446  +static int fts3EvalPhraseNext(
         3447  +  Fts3Cursor *pCsr, 
         3448  +  Fts3Phrase *p, 
         3449  +  u8 *pbEof
         3450  +){
  4165   3451     int rc = SQLITE_OK;
         3452  +  Fts3Doclist *pDL = &p->doclist;
  4166   3453   
  4167   3454     if( p->bIncr ){
  4168   3455       Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
  4169   3456       assert( p->nToken==1 );
  4170   3457       rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, 
  4171         -        &p->doclist.iDocid, &p->doclist.pList, &p->doclist.nList
         3458  +        &pDL->iDocid, &pDL->pList, &pDL->nList
  4172   3459       );
  4173         -    if( rc==SQLITE_OK && !p->doclist.pList ){
         3460  +    if( rc==SQLITE_OK && !pDL->pList ){
  4174   3461         *pbEof = 1;
  4175   3462       }
         3463  +  }else if( pCsr->bDesc && pDL->aAll ){
         3464  +
         3465  +    if( pDL->pNextDocid==0 ){
         3466  +      sqlite3_int64 iDocid = 0;
         3467  +      char *pNext;
         3468  +      char *pDocid = pDL->aAll;
         3469  +      char *pEnd = &pDocid[pDL->nAll];
         3470  +
         3471  +      while( pDocid<pEnd ){
         3472  +        fts3GetDeltaVarint(&pDocid, &iDocid);
         3473  +        pDL->pNextDocid = pDocid;
         3474  +        pDL->pList = pDocid;
         3475  +        fts3PoslistCopy(0, &pDocid);
         3476  +      }
         3477  +      pDL->nList = (pEnd - pDL->pList);
         3478  +      pDL->iDocid = iDocid;
         3479  +    }else{
         3480  +
         3481  +      assert( *pbEof==0 );
         3482  +      assert( pDL->pNextDocid>pDL->aAll );
         3483  +
         3484  +      fts3GetReverseDeltaVarint(
         3485  +          &pDL->pNextDocid, pDL->aAll, &pDL->iDocid
         3486  +      );
         3487  +      if( pDL->pNextDocid==pDL->aAll ){
         3488  +        *pbEof = 1;
         3489  +      }else{
         3490  +        char *pSave = pDL->pNextDocid;
         3491  +        fts3ReversePoslist(pDL->aAll, &pDL->pNextDocid);
         3492  +        pDL->pList = pDL->pNextDocid;
         3493  +        pDL->nList = pSave - pDL->pNextDocid;
         3494  +      }
         3495  +    }
         3496  +
  4176   3497     }else{
         3498  +
  4177   3499       char *pIter;
  4178         -    Fts3Doclist *pDL = &p->doclist;
  4179         -
  4180   3500       if( pDL->pNextDocid ){
  4181   3501         pIter = pDL->pNextDocid;
  4182   3502       }else{
  4183   3503         pIter = pDL->aAll;
  4184   3504       }
  4185   3505   
  4186   3506       if( pIter>=&pDL->aAll[pDL->nAll] ){
................................................................................
  4195   3515         *pbEof = 0;
  4196   3516       }
  4197   3517     }
  4198   3518   
  4199   3519     return rc;
  4200   3520   }
  4201   3521   
  4202         -static int fts3EvalPhraseReset(Fts3Cursor *pCsr, Fts3Phrase *p){
  4203         -  return SQLITE_OK;
  4204         -}
  4205         -
  4206         -static sqlite3_int64 fts3EvalPhraseDocid(Fts3Phrase *p){
  4207         -  return p->doclist.iDocid;
  4208         -}
  4209         -
  4210         -static char *fts3EvalPhrasePoslist(Fts3Phrase *p, int *pnList){
  4211         -  if( pnList ){
  4212         -    *pnList = p->doclist.nList;
  4213         -  }
  4214         -  return p->doclist.pList;
  4215         -}
  4216         -
  4217   3522   static void fts3EvalStartReaders(
  4218   3523     Fts3Cursor *pCsr, 
  4219   3524     Fts3Expr *pExpr, 
  4220   3525     int bOptOk,
  4221   3526     int *pRc
  4222   3527   ){
  4223   3528     if( pExpr && SQLITE_OK==*pRc ){
................................................................................
  4491   3796   
  4492   3797     /* Fix the results of NEAR expressions. */
  4493   3798     fts3EvalNearTrim(pCsr, pExpr, &rc);
  4494   3799   
  4495   3800     return rc;
  4496   3801   }
  4497   3802   
         3803  +static void fts3EvalFreeDeferredDoclist(Fts3Phrase *pPhrase){
         3804  +  if( pPhrase->doclist.bFreeList ){
         3805  +    sqlite3_free(pPhrase->doclist.pList);
         3806  +    pPhrase->doclist.pList = 0;
         3807  +    pPhrase->doclist.nList = 0;
         3808  +    pPhrase->doclist.bFreeList = 0;
         3809  +  }
         3810  +}
         3811  +
         3812  +/*
         3813  +** This macro is used by the fts3EvalNext() function. The two arguments are
         3814  +** 64-bit docid values. If the current query is "ORDER BY docid ASC", then
         3815  +** the macro returns (i1 - i2). Or if it is "ORDER BY docid DESC", then
         3816  +** it returns (i2 - i1). This allows the same code to be used for merging
         3817  +** doclists in ascending or descending order.
         3818  +*/
         3819  +#define DOCID_CMP(i1, i2) ((pCsr->bDesc?-1:1) * (i1-i2))
         3820  +
  4498   3821   static void fts3EvalNext(
  4499   3822     Fts3Cursor *pCsr, 
  4500   3823     Fts3Expr *pExpr, 
  4501   3824     int *pRc
  4502   3825   ){
  4503   3826     if( *pRc==SQLITE_OK ){
  4504         -
  4505   3827       pExpr->bStart = 1;
         3828  +
  4506   3829       switch( pExpr->eType ){
  4507         -
  4508   3830         case FTSQUERY_NEAR:
  4509   3831         case FTSQUERY_AND: {
  4510   3832           Fts3Expr *pLeft = pExpr->pLeft;
  4511   3833           Fts3Expr *pRight = pExpr->pRight;
  4512   3834   
  4513   3835           assert( !pLeft->bDeferred || !pRight->bDeferred );
  4514   3836           if( pLeft->bDeferred ){
................................................................................
  4520   3842             pExpr->iDocid = pLeft->iDocid;
  4521   3843             pExpr->bEof = pLeft->bEof;
  4522   3844           }else{
  4523   3845             fts3EvalNext(pCsr, pLeft, pRc);
  4524   3846             fts3EvalNext(pCsr, pRight, pRc);
  4525   3847   
  4526   3848             while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){
  4527         -            int iDiff = pLeft->iDocid - pRight->iDocid;
         3849  +            int iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
  4528   3850               if( iDiff==0 ) break;
  4529   3851               if( iDiff<0 ){
  4530   3852                 fts3EvalNext(pCsr, pLeft, pRc);
  4531   3853               }else{
  4532   3854                 fts3EvalNext(pCsr, pRight, pRc);
  4533   3855               }
  4534   3856             }
................................................................................
  4538   3860           }
  4539   3861           break;
  4540   3862         }
  4541   3863     
  4542   3864         case FTSQUERY_OR: {
  4543   3865           Fts3Expr *pLeft = pExpr->pLeft;
  4544   3866           Fts3Expr *pRight = pExpr->pRight;
         3867  +        int iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
  4545   3868   
  4546   3869           assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
  4547   3870           assert( pRight->bStart || pLeft->iDocid==pRight->iDocid );
  4548   3871   
  4549         -        if( pLeft->iDocid==pRight->iDocid ){
         3872  +        if( iCmp==0 ){
  4550   3873             fts3EvalNext(pCsr, pLeft, pRc);
  4551   3874             fts3EvalNext(pCsr, pRight, pRc);
  4552         -        }else if( 
  4553         -          pRight->bEof || (pLeft->bEof==0 && pLeft->iDocid<pRight->iDocid) 
  4554         -        ){
         3875  +        }else if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
  4555   3876             fts3EvalNext(pCsr, pLeft, pRc);
  4556   3877           }else{
  4557   3878             fts3EvalNext(pCsr, pRight, pRc);
  4558   3879           }
  4559   3880     
  4560   3881           pExpr->bEof = (pLeft->bEof && pRight->bEof);
  4561         -        if( pRight->bEof || (pLeft->bEof==0 &&  pLeft->iDocid<pRight->iDocid) ){
         3882  +        iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
         3883  +        if( pRight->bEof || (pLeft->bEof==0 &&  iCmp<0) ){
  4562   3884             pExpr->iDocid = pLeft->iDocid;
  4563   3885           }else{
  4564   3886             pExpr->iDocid = pRight->iDocid;
  4565   3887           }
  4566   3888   
  4567   3889           break;
  4568   3890         }
................................................................................
  4574   3896           if( pRight->bStart==0 ){
  4575   3897             fts3EvalNext(pCsr, pRight, pRc);
  4576   3898             assert( *pRc!=SQLITE_OK || pRight->bStart );
  4577   3899           }
  4578   3900           do {
  4579   3901             fts3EvalNext(pCsr, pLeft, pRc);
  4580   3902             if( pLeft->bEof ) break;
  4581         -          while( !*pRc && !pRight->bEof && pRight->iDocid<pLeft->iDocid ){
         3903  +          while( !*pRc 
         3904  +              && !pRight->bEof 
         3905  +              && DOCID_CMP(pLeft->iDocid, pRight->iDocid)>0 
         3906  +          ){
  4582   3907               fts3EvalNext(pCsr, pRight, pRc);
  4583   3908             }
  4584   3909           }while( !pRight->bEof && pRight->iDocid==pLeft->iDocid && !*pRc );
  4585   3910           pExpr->iDocid = pLeft->iDocid;
  4586   3911           pExpr->bEof = pLeft->bEof;
  4587   3912           break;
  4588   3913         }
  4589   3914   
  4590         -      default:
  4591         -        assert( pExpr->eType==FTSQUERY_PHRASE );
  4592         -        *pRc = fts3EvalPhraseNext(pCsr, pExpr->pPhrase, &pExpr->bEof);
  4593         -        pExpr->iDocid = fts3EvalPhraseDocid(pExpr->pPhrase);
         3915  +      default: {
         3916  +        Fts3Phrase *pPhrase = pExpr->pPhrase;
         3917  +        fts3EvalFreeDeferredDoclist(pPhrase);
         3918  +        *pRc = fts3EvalPhraseNext(pCsr, pPhrase, &pExpr->bEof);
         3919  +        pExpr->iDocid = pPhrase->doclist.iDocid;
  4594   3920           break;
         3921  +      }
  4595   3922       }
  4596   3923     }
  4597   3924   }
  4598   3925   
  4599   3926   static int fts3EvalDeferredTest(Fts3Cursor *pCsr, Fts3Expr *pExpr, int *pRc){
  4600   3927     int bHit = 0;
  4601   3928     if( *pRc==SQLITE_OK ){
................................................................................
  4618   3945         case FTSQUERY_NOT:
  4619   3946           bHit = (
  4620   3947               fts3EvalDeferredTest(pCsr, pExpr->pLeft, pRc)
  4621   3948            && !fts3EvalDeferredTest(pCsr, pExpr->pRight, pRc)
  4622   3949           );
  4623   3950           break;
  4624   3951   
  4625         -      default:
  4626         -        assert( pExpr->eType==FTSQUERY_PHRASE );
  4627         -        *pRc = fts3EvalDeferredPhrase(pCsr, pExpr->pPhrase);
  4628         -        bHit = (pExpr->pPhrase->doclist.pList!=0);
         3952  +      default: {
         3953  +        Fts3Phrase *pPhrase = pExpr->pPhrase;
         3954  +        fts3EvalFreeDeferredDoclist(pPhrase);
         3955  +        *pRc = fts3EvalDeferredPhrase(pCsr, pPhrase);
         3956  +        bHit = (pPhrase->doclist.pList!=0);
  4629   3957           pExpr->iDocid = pCsr->iPrevId;
  4630   3958           break;
         3959  +      }
  4631   3960       }
  4632   3961     }
  4633   3962     return bHit;
  4634   3963   }
  4635   3964   
  4636   3965   /*
  4637   3966   ** Return 1 if both of the following are true:
  4638   3967   **
  4639   3968   **   1. *pRc is SQLITE_OK when this function returns, and
  4640   3969   **
  4641   3970   **   2. After scanning the current FTS table row for the deferred tokens,
  4642   3971   **      it is determined that the row does not match the query.
         3972  +**
         3973  +** Or, if no error occurs and it seems the current row does match the FTS
         3974  +** query, return 0.
  4643   3975   */
  4644   3976   static int fts3EvalLoadDeferred(Fts3Cursor *pCsr, int *pRc){
  4645   3977     int rc = *pRc;
  4646   3978     int bMiss = 0;
  4647   3979     if( rc==SQLITE_OK && pCsr->pDeferred ){
  4648   3980       rc = fts3CursorSeek(0, pCsr);
  4649   3981       if( rc==SQLITE_OK ){
................................................................................
  4654   3986       sqlite3Fts3FreeDeferredDoclists(pCsr);
  4655   3987       *pRc = rc;
  4656   3988     }
  4657   3989     return (rc==SQLITE_OK && bMiss);
  4658   3990   }
  4659   3991   
  4660   3992   /*
  4661         -** Advance to the next document that matches the expression passed as an
  4662         -** argument.
         3993  +** Advance to the next document that matches the FTS expression in
         3994  +** Fts3Cursor.pExpr.
  4663   3995   */
  4664         -int sqlite3Fts3EvalNext(Fts3Cursor *pCsr, Fts3Expr *pExpr){
         3996  +int sqlite3Fts3EvalNext(Fts3Cursor *pCsr){
  4665   3997     int rc = SQLITE_OK;             /* Return Code */
         3998  +  Fts3Expr *pExpr = pCsr->pExpr;
  4666   3999     assert( pCsr->isEof==0 );
  4667         -  assert( pCsr->bIncremental );
  4668   4000     if( pExpr==0 ){
  4669   4001       pCsr->isEof = 1;
  4670   4002     }else{
  4671   4003       do {
  4672         -      sqlite3_reset(pCsr->pStmt);
         4004  +      if( pCsr->isRequireSeek==0 ){
         4005  +        sqlite3_reset(pCsr->pStmt);
         4006  +      }
         4007  +      assert( sqlite3_data_count(pCsr->pStmt)==0 );
  4673   4008         fts3EvalNext(pCsr, pExpr, &rc);
  4674   4009         pCsr->isEof = pExpr->bEof;
  4675   4010         pCsr->isRequireSeek = 1;
  4676   4011         pCsr->isMatchinfoNeeded = 1;
  4677   4012         pCsr->iPrevId = pExpr->iDocid;
  4678   4013       }while( pCsr->isEof==0 && fts3EvalLoadDeferred(pCsr, &rc) );
  4679   4014     }
  4680   4015     return rc;
  4681   4016   }
  4682   4017   
  4683         -int sqlite3Fts3EvalFinish(Fts3Cursor *pCsr, Fts3Expr *pExpr){
  4684         -  return SQLITE_OK;
  4685         -}
  4686         -
  4687         -sqlite3_int64 sqlite3Fts3EvalDocid(Fts3Cursor *pCsr, Fts3Expr *pExpr){
  4688         -  return pExpr->iDocid;
  4689         -}
  4690         -
  4691   4018   /*
  4692   4019   ** Return a pointer to the entire doclist, including positions, associated 
  4693         -** with the phrase passed as the second argument.
         4020  +** with the phrase passed as the second argument. It is illegal to call
         4021  +** this function if the phrase consists entirely of deferred tokens.
         4022  +**
         4023  +** TODO: This function is only used by the code for the matchinfo('x')
         4024  +** auxiliary function - to obtain the following two values:
         4025  +**
         4026  +**   1. The total number of times the phrase appears in each column in all 
         4027  +**      rows in the FTS table.
         4028  +**
         4029  +**   2. For each column, the total number of rows in the FTS table for which
         4030  +**      the phrase appears at least once in the column.
         4031  +**
         4032  +** It would be better if there was an sqlite3Fts3EvalXXX() function 
         4033  +** specifically to retrieve these values. If that were done, the concept
         4034  +** of which tokens are deferred or incremental would be entirely encapsulated
         4035  +** within the sqlite3Fts3EvalXXX()/fts3EvalXXX() functions in this file.
  4694   4036   */
  4695   4037   int sqlite3Fts3EvalPhraseDoclist(
  4696   4038     Fts3Cursor *pCsr,               /* FTS3 cursor object */
  4697   4039     Fts3Expr *pExpr,                /* Phrase to return doclist for */
  4698   4040     const char **ppList,            /* OUT: Buffer containing doclist */
  4699   4041     int *pnList                     /* OUT: Size of returned buffer, in bytes */
  4700   4042   ){
  4701   4043     int rc = SQLITE_OK;
  4702   4044     Fts3Phrase *pPhrase = pExpr->pPhrase;
         4045  +
         4046  +  /* It is illegal to call this function if the phrase is entirely deferred
         4047  +  ** (it may contain some deferred tokens, but must also contain at least
         4048  +  ** one token for which the doclist may be read from the full-text index). 
         4049  +  */
         4050  +  assert( !pExpr->bDeferred );
  4703   4051   
  4704   4052     if( pPhrase->bIncr ){
  4705   4053       /* This phrase was being loaded from disk incrementally. But the 
  4706   4054       ** matchinfo() function requires that the entire doclist be loaded into
  4707   4055       ** memory. This block loads the doclist into memory and modifies the
  4708   4056       ** Fts3Phrase structure so that it does not use the incremental strategy.
  4709   4057       */
................................................................................
  4727   4075     }
  4728   4076   
  4729   4077     *pnList = pPhrase->doclist.nAll;
  4730   4078     *ppList = pPhrase->doclist.aAll;
  4731   4079     return rc;
  4732   4080   }
  4733   4081   
         4082  +/*
         4083  +** The expression pExpr passed as the second argument to this function
         4084  +** must be of type FTSQUERY_PHRASE. 
         4085  +**
         4086  +** The returned value is either NULL or a pointer to a buffer containing
         4087  +** a position-list indicating the occurrences of the phrase in column iCol
         4088  +** of the current row. 
         4089  +**
         4090  +** More specifically, the returned buffer contains 1 varint for each 
         4091  +** occurence of the phrase in the column, stored using the normal (delta+2) 
         4092  +** compression and is terminated by either an 0x01 or 0x00 byte. For example,
         4093  +** if the requested column contains "a b X c d X X" and the position-list
         4094  +** for 'X' is requested, the buffer returned may contain:
         4095  +**
         4096  +**     0x04 0x05 0x03 0x01   or   0x04 0x05 0x03 0x00
         4097  +**
         4098  +** This function works regardless of whether or not the phrase is deferred,
         4099  +** incremental, or neither.
         4100  +*/
  4734   4101   char *sqlite3Fts3EvalPhrasePoslist(
  4735   4102     Fts3Cursor *pCsr,               /* FTS3 cursor object */
  4736   4103     Fts3Expr *pExpr,                /* Phrase to return doclist for */
  4737         -  sqlite3_int64 iDocid,           /* Docid to return position list for */
  4738   4104     int iCol                        /* Column to return position list for */
  4739   4105   ){
  4740   4106     Fts3Phrase *pPhrase = pExpr->pPhrase;
  4741   4107     Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
  4742   4108     char *pIter = pPhrase->doclist.pList;
  4743   4109     int iThis;
  4744   4110   
  4745   4111     assert( iCol>=0 && iCol<pTab->nColumn );
  4746   4112     if( !pIter 
  4747   4113      || pExpr->bEof 
  4748         -   || pExpr->iDocid!=iDocid
         4114  +   || pExpr->iDocid!=pCsr->iPrevId
  4749   4115      || (pPhrase->iColumn<pTab->nColumn && pPhrase->iColumn!=iCol) 
  4750   4116     ){
  4751   4117       return 0;
  4752   4118     }
  4753   4119   
  4754   4120     assert( pPhrase->doclist.nList>0 );
  4755   4121     if( *pIter==0x01 ){
................................................................................
  4764   4130       pIter++;
  4765   4131       pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
  4766   4132     }
  4767   4133   
  4768   4134     return ((iCol==iThis)?pIter:0);
  4769   4135   }
  4770   4136   
         4137  +/*
         4138  +** Free all components of the Fts3Phrase structure that were allocated by
         4139  +** the eval module.
         4140  +*/
  4771   4141   void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){
  4772         -  int i;
  4773         -  sqlite3_free(pPhrase->doclist.aAll);
  4774         -  memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist));
  4775         -  for(i=0; i<pPhrase->nToken; i++){
  4776         -    fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr);
  4777         -    pPhrase->aToken[i].pSegcsr = 0;
         4142  +  if( pPhrase ){
         4143  +    int i;
         4144  +    sqlite3_free(pPhrase->doclist.aAll);
         4145  +    fts3EvalFreeDeferredDoclist(pPhrase);
         4146  +    memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist));
         4147  +    for(i=0; i<pPhrase->nToken; i++){
         4148  +      fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr);
         4149  +      pPhrase->aToken[i].pSegcsr = 0;
         4150  +    }
  4778   4151     }
  4779   4152   }
  4780   4153   
  4781   4154   #endif

Changes to ext/fts3/fts3Int.h.

   226    226   struct Fts3Cursor {
   227    227     sqlite3_vtab_cursor base;       /* Base class used by SQLite core */
   228    228     i16 eSearch;                    /* Search strategy (see below) */
   229    229     u8 isEof;                       /* True if at End Of Results */
   230    230     u8 isRequireSeek;               /* True if must seek pStmt to %_content row */
   231    231     sqlite3_stmt *pStmt;            /* Prepared statement in use by the cursor */
   232    232     Fts3Expr *pExpr;                /* Parsed MATCH query string */
   233         -  int bIncremental;               /* True to use incremental querying */
   234    233     int nPhrase;                    /* Number of matchable phrases in query */
   235    234     Fts3DeferredToken *pDeferred;   /* Deferred search tokens, if any */
   236    235     sqlite3_int64 iPrevId;          /* Previous id read from aDoclist */
   237    236     char *pNextId;                  /* Pointer into the body of aDoclist */
   238    237     char *aDoclist;                 /* List of docids for full-text queries */
   239    238     int nDoclist;                   /* Size of buffer at aDoclist */
   240         -  int desc;                       /* True to sort in descending order */
          239  +  int bDesc;                      /* True to sort in descending order */
   241    240     int eEvalmode;                  /* An FTS3_EVAL_XX constant */
   242    241     int nRowAvg;                    /* Average size of database rows, in pages */
   243    242   
   244    243     int isMatchinfoNeeded;          /* True when aMatchinfo[] needs filling in */
   245    244     u32 *aMatchinfo;                /* Information about most recent match */
   246    245     int nMatchinfo;                 /* Number of elements in aMatchinfo[] */
   247    246     char *zMatchinfo;               /* Matchinfo specification */
................................................................................
   270    269   #define FTS3_DOCID_SEARCH    1    /* Lookup by rowid on %_content table */
   271    270   #define FTS3_FULLTEXT_SEARCH 2    /* Full-text index search */
   272    271   
   273    272   
   274    273   struct Fts3Doclist {
   275    274     char *aAll;                    /* Array containing doclist (or NULL) */
   276    275     int nAll;                      /* Size of a[] in bytes */
   277         -
   278         -  sqlite3_int64 iDocid;          /* Current docid (if p!=0) */
   279    276     char *pNextDocid;              /* Pointer to next docid */
          277  +
          278  +  sqlite3_int64 iDocid;          /* Current docid (if pList!=0) */
          279  +  int bFreeList;                 /* True if pList should be sqlite3_free()d */
   280    280     char *pList;                   /* Pointer to position list following iDocid */
   281    281     int nList;                     /* Length of position list */
   282    282   } doclist;
   283    283   
   284    284   /*
   285    285   ** A "phrase" is a sequence of one or more tokens that must match in
   286    286   ** sequence.  A single token is the base case and the most common case.
................................................................................
   301    301   };
   302    302   
   303    303   struct Fts3Phrase {
   304    304     /* Cache of doclist for this phrase. */
   305    305     Fts3Doclist doclist;
   306    306     int bIncr;                 /* True if doclist is loaded incrementally */
   307    307   
   308         -#if 1
   309         -  int isLoaded;              /* True if aDoclist/nDoclist are initialized. */
   310         -  char *aDoclist;            /* Buffer containing doclist */
   311         -  int nDoclist;              /* Size of aDoclist in bytes */
   312         -  sqlite3_int64 iCurrent;
   313         -  char *pCurrent;
   314         -#endif
   315         -
   316    308     /* Variables below this point are populated by fts3_expr.c when parsing 
   317    309     ** a MATCH expression. Everything above is part of the evaluation phase. 
   318    310     */
   319    311     int nToken;                /* Number of tokens in the phrase */
   320    312     int iColumn;               /* Index of column this phrase must match */
   321    313     Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */
   322    314   };
................................................................................
   376    368     sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**);
   377    369   int sqlite3Fts3SegReaderPending(
   378    370     Fts3Table*,int,const char*,int,int,Fts3SegReader**);
   379    371   void sqlite3Fts3SegReaderFree(Fts3SegReader *);
   380    372   int sqlite3Fts3SegReaderCost(Fts3Cursor *, Fts3SegReader *, int *);
   381    373   int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, sqlite3_stmt **);
   382    374   int sqlite3Fts3ReadLock(Fts3Table *);
   383         -int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*);
          375  +int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*);
   384    376   
   385    377   int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
   386    378   int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **);
   387    379   
   388    380   void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *);
   389    381   int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int);
   390    382   int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *);
................................................................................
   444    436   int sqlite3Fts3PutVarint(char *, sqlite3_int64);
   445    437   int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
   446    438   int sqlite3Fts3GetVarint32(const char *, int *);
   447    439   int sqlite3Fts3VarintLen(sqlite3_uint64);
   448    440   void sqlite3Fts3Dequote(char *);
   449    441   
   450    442   int sqlite3Fts3ExprLoadDoclist(Fts3Cursor *, Fts3Expr *);
   451         -int sqlite3Fts3ExprLoadFtDoclist(Fts3Cursor *, Fts3Expr *, char **, int *);
   452    443   int sqlite3Fts3ExprNearTrim(Fts3Expr *, Fts3Expr *, int);
   453    444   
   454    445   /* fts3_tokenizer.c */
   455    446   const char *sqlite3Fts3NextToken(const char *, int *);
   456    447   int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
   457    448   int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, 
   458    449       sqlite3_tokenizer **, char **
................................................................................
   489    480   
   490    481   int sqlite3Fts3EvalPhraseCache(Fts3Cursor *, Fts3Phrase *);
   491    482   sqlite3_int64 sqlite3Fts3EvalDocid(Fts3Cursor *, Fts3Expr *);
   492    483   int sqlite3Fts3EvalPhraseDoclist(Fts3Cursor*, Fts3Expr*, const char**,int*);
   493    484   void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *);
   494    485   
   495    486   int sqlite3Fts3EvalStart(Fts3Cursor *, Fts3Expr *, int);
   496         -int sqlite3Fts3EvalNext(Fts3Cursor *pCsr, Fts3Expr *pExpr);
          487  +int sqlite3Fts3EvalNext(Fts3Cursor *pCsr);
          488  +
   497    489   int sqlite3Fts3MsrIncrStart(
   498    490       Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
   499    491   int sqlite3Fts3MsrIncrNext(
   500    492       Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
   501         -char *sqlite3Fts3EvalPhrasePoslist(
   502         -  Fts3Cursor *, Fts3Expr *, sqlite3_int64, int iCol); 
          493  +char *sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol); 
   503    494   int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
   504    495   
   505    496   int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
   506    497   
   507    498   #endif /* _FTSINT_H */

Changes to ext/fts3/fts3_expr.c.

   764    764   ** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse().
   765    765   */
   766    766   void sqlite3Fts3ExprFree(Fts3Expr *p){
   767    767     if( p ){
   768    768       assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 );
   769    769       sqlite3Fts3ExprFree(p->pLeft);
   770    770       sqlite3Fts3ExprFree(p->pRight);
   771         -    if( p->pPhrase ){
   772         -      sqlite3Fts3EvalPhraseCleanup(p->pPhrase);
   773         -      sqlite3_free(p->pPhrase->aDoclist);
   774         -    }
          771  +    sqlite3Fts3EvalPhraseCleanup(p->pPhrase);
   775    772       sqlite3_free(p);
   776    773     }
   777    774   }
   778    775   
   779    776   /****************************************************************************
   780    777   *****************************************************************************
   781    778   ** Everything after this point is just test code.

Changes to ext/fts3/fts3_snippet.c.

   172    172     int (*x)(Fts3Expr*,int,void*),  /* Callback function to invoke for phrases */
   173    173     void *pCtx                      /* Second argument to pass to callback */
   174    174   ){
   175    175     int iPhrase = 0;                /* Variable used as the phrase counter */
   176    176     return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
   177    177   }
   178    178   
   179         -/*
   180         -** The argument to this function is always a phrase node. Its doclist 
   181         -** (Fts3Expr.aDoclist[]) and the doclists associated with all phrase nodes
   182         -** to the left of this one in the query tree have already been loaded.
   183         -**
   184         -** If this phrase node is part of a series of phrase nodes joined by 
   185         -** NEAR operators (and is not the left-most of said series), then elements are
   186         -** removed from the phrases doclist consistent with the NEAR restriction. If
   187         -** required, elements may be removed from the doclists of phrases to the
   188         -** left of this one that are part of the same series of NEAR operator 
   189         -** connected phrases.
   190         -**
   191         -** If an OOM error occurs, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK.
   192         -*/
   193         -static int fts3ExprNearTrim(Fts3Expr *pExpr){
   194         -  int rc = SQLITE_OK;
   195         -  Fts3Expr *pParent = pExpr->pParent;
   196         -
   197         -  assert( pExpr->eType==FTSQUERY_PHRASE );
   198         -  while( rc==SQLITE_OK
   199         -   && pParent 
   200         -   && pParent->eType==FTSQUERY_NEAR 
   201         -   && pParent->pRight==pExpr 
   202         -  ){
   203         -    /* This expression (pExpr) is the right-hand-side of a NEAR operator. 
   204         -    ** Find the expression to the left of the same operator.
   205         -    */
   206         -    int nNear = pParent->nNear;
   207         -    Fts3Expr *pLeft = pParent->pLeft;
   208         -
   209         -    if( pLeft->eType!=FTSQUERY_PHRASE ){
   210         -      assert( pLeft->eType==FTSQUERY_NEAR );
   211         -      assert( pLeft->pRight->eType==FTSQUERY_PHRASE );
   212         -      pLeft = pLeft->pRight;
   213         -    }
   214         -
   215         -    rc = sqlite3Fts3ExprNearTrim(pLeft, pExpr, nNear);
   216         -
   217         -    pExpr = pLeft;
   218         -    pParent = pExpr->pParent;
   219         -  }
   220         -
   221         -  return rc;
   222         -}
   223         -
   224    179   /*
   225    180   ** This is an fts3ExprIterate() callback used while loading the doclists
   226    181   ** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
   227    182   ** fts3ExprLoadDoclists().
   228    183   */
   229    184   static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
   230    185     int rc = SQLITE_OK;
................................................................................
   232    187     LoadDoclistCtx *p = (LoadDoclistCtx *)ctx;
   233    188   
   234    189     UNUSED_PARAMETER(iPhrase);
   235    190   
   236    191     p->nPhrase++;
   237    192     p->nToken += pPhrase->nToken;
   238    193   
   239         -  if( pPhrase->isLoaded==0 ){
   240         -    rc = sqlite3Fts3ExprLoadDoclist(p->pCsr, pExpr);
   241         -    pPhrase->isLoaded = 1;
   242         -    if( rc==SQLITE_OK ){
   243         -      rc = fts3ExprNearTrim(pExpr);
   244         -    }
   245         -  }
   246         -
   247    194     return rc;
   248    195   }
   249    196   
   250    197   /*
   251    198   ** Load the doclists for each phrase in the query associated with FTS3 cursor
   252    199   ** pCsr. 
   253    200   **
................................................................................
   412    359   static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
   413    360     SnippetIter *p = (SnippetIter *)ctx;
   414    361     SnippetPhrase *pPhrase = &p->aPhrase[iPhrase];
   415    362     char *pCsr;
   416    363   
   417    364     pPhrase->nToken = pExpr->pPhrase->nToken;
   418    365   
   419         -  pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->pCsr->iPrevId,p->iCol);
          366  +  pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol);
   420    367     if( pCsr ){
   421    368       int iFirst = 0;
   422    369       pPhrase->pList = pCsr;
   423    370       fts3GetDeltaPosition(&pCsr, &iFirst);
   424    371       pPhrase->pHead = pCsr;
   425    372       pPhrase->pTail = pCsr;
   426    373       pPhrase->iHead = iFirst;
................................................................................
   863    810     Fts3Expr *pExpr,                /* Phrase expression node */
   864    811     int iPhrase,                    /* Phrase number */
   865    812     void *pCtx                      /* Pointer to MatchInfo structure */
   866    813   ){
   867    814     MatchInfo *p = (MatchInfo *)pCtx;
   868    815     int iStart = iPhrase * p->nCol * 3;
   869    816     int i;
   870         -  sqlite3_int64 iDocid = p->pCursor->iPrevId;
   871    817   
   872    818     for(i=0; i<p->nCol; i++){
   873    819       char *pCsr;
   874         -    pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, iDocid, i);
          820  +    pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i);
   875    821       if( pCsr ){
   876    822         p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr);
   877    823       }else{
   878    824         p->aMatchinfo[iStart+i*3] = 0;
   879    825       }
   880    826     }
   881    827   
................................................................................
  1016    962   ** undefined.
  1017    963   */
  1018    964   static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
  1019    965     LcsIterator *aIter;
  1020    966     int i;
  1021    967     int iCol;
  1022    968     int nToken = 0;
  1023         -  sqlite3_int64 iDocid = pCsr->iPrevId;
  1024    969   
  1025    970     /* Allocate and populate the array of LcsIterator objects. The array
  1026    971     ** contains one element for each matchable phrase in the query.
  1027    972     **/
  1028    973     aIter = sqlite3_malloc(sizeof(LcsIterator) * pCsr->nPhrase);
  1029    974     if( !aIter ) return SQLITE_NOMEM;
  1030    975     memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
................................................................................
  1038    983   
  1039    984     for(iCol=0; iCol<pInfo->nCol; iCol++){
  1040    985       int nLcs = 0;                 /* LCS value for this column */
  1041    986       int nLive = 0;                /* Number of iterators in aIter not at EOF */
  1042    987   
  1043    988       for(i=0; i<pInfo->nPhrase; i++){
  1044    989         LcsIterator *pIt = &aIter[i];
  1045         -      pIt->pRead = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iDocid, iCol);
          990  +      pIt->pRead = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol);
  1046    991         if( pIt->pRead ){
  1047    992           pIt->iPos = pIt->iPosOffset;
  1048    993           fts3LcsIteratorAdvance(&aIter[i]);
  1049    994           nLive++;
  1050    995         }
  1051    996       }
  1052    997   
................................................................................
  1392   1337     TermOffsetCtx *p = (TermOffsetCtx *)ctx;
  1393   1338     int nTerm;                      /* Number of tokens in phrase */
  1394   1339     int iTerm;                      /* For looping through nTerm phrase terms */
  1395   1340     char *pList;                    /* Pointer to position list for phrase */
  1396   1341     int iPos = 0;                   /* First position in position-list */
  1397   1342   
  1398   1343     UNUSED_PARAMETER(iPhrase);
  1399         -  pList = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iDocid, p->iCol);
         1344  +  pList = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol);
  1400   1345     nTerm = pExpr->pPhrase->nToken;
  1401   1346     if( pList ){
  1402   1347       fts3GetDeltaPosition(&pList, &iPos);
  1403   1348       assert( iPos>=0 );
  1404   1349     }
  1405   1350   
  1406   1351     for(iTerm=0; iTerm<nTerm; iTerm++){

Changes to ext/fts3/fts3_write.c.

    32     32   **
    33     33   ** This means that if we have a pointer into a buffer containing node data,
    34     34   ** it is always safe to read up to two varints from it without risking an
    35     35   ** overread, even if the node data is corrupted.
    36     36   */
    37     37   #define FTS3_NODE_PADDING (FTS3_VARINT_MAX*2)
    38     38   
           39  +/*
           40  +** Under certain circumstances, b-tree nodes (doclists) can be loaded into
           41  +** memory incrementally instead of all at once. This can be a big performance
           42  +** win (reduced IO and CPU) if SQLite stops calling the virtual table xNext()
           43  +** method before retrieving all query results (as may happen, for example,
           44  +** if a query has a LIMIT clause).
           45  +**
           46  +** Incremental loading is used for b-tree nodes FTS3_NODE_CHUNK_THRESHOLD 
           47  +** bytes and larger. Nodes are loaded in chunks of FTS3_NODE_CHUNKSIZE bytes.
           48  +** The code is written so that the hard lower-limit for each of these values 
           49  +** is 1. Clearly such small values would be inefficient, but can be useful 
           50  +** for testing purposes.
           51  +**
           52  +** TODO: Add a test interface to modify these "constants" from a script for
           53  +** this purpose.
           54  +*/
           55  +#define FTS3_NODE_CHUNKSIZE (4*1024) 
           56  +#define FTS3_NODE_CHUNK_THRESHOLD (FTS3_NODE_CHUNKSIZE*4)
           57  +/* #define FTS3_NODE_CHUNKSIZE 1 */
           58  +/* #define FTS3_NODE_CHUNK_THRESHOLD 1 */
           59  +
    39     60   typedef struct PendingList PendingList;
    40     61   typedef struct SegmentNode SegmentNode;
    41     62   typedef struct SegmentWriter SegmentWriter;
    42     63   
    43     64   /*
    44     65   ** Data structure used while accumulating terms in the pending-terms hash
    45     66   ** table. The hash table entry maps from term (a string) to a malloc'd
................................................................................
    89    110     sqlite3_int64 iStartBlock;      /* Rowid of first leaf block to traverse */
    90    111     sqlite3_int64 iLeafEndBlock;    /* Rowid of final leaf block to traverse */
    91    112     sqlite3_int64 iEndBlock;        /* Rowid of final block in segment (or 0) */
    92    113     sqlite3_int64 iCurrentBlock;    /* Current leaf block (or 0) */
    93    114   
    94    115     char *aNode;                    /* Pointer to node data (or NULL) */
    95    116     int nNode;                      /* Size of buffer at aNode (or 0) */
          117  +  int nPopulate;                  /* If >0, bytes of buffer aNode[] loaded */
          118  +  sqlite3_blob *pBlob;            /* If not NULL, blob handle to read node */
          119  +
    96    120     Fts3HashElem **ppNextElem;
    97    121   
    98    122     /* Variables set by fts3SegReaderNext(). These may be read directly
    99    123     ** by the caller. They are valid from the time SegmentReaderNew() returns
   100    124     ** until SegmentReaderNext() returns something other than SQLITE_OK
   101    125     ** (i.e. SQLITE_DONE).
   102    126     */
................................................................................
   929    953   ** method (xFilter etc.) that may directly or indirectly call this function
   930    954   ** must call sqlite3Fts3SegmentsClose() before returning.
   931    955   */
   932    956   int sqlite3Fts3ReadBlock(
   933    957     Fts3Table *p,                   /* FTS3 table handle */
   934    958     sqlite3_int64 iBlockid,         /* Access the row with blockid=$iBlockid */
   935    959     char **paBlob,                  /* OUT: Blob data in malloc'd buffer */
   936         -  int *pnBlob                     /* OUT: Size of blob data */
          960  +  int *pnBlob,                    /* OUT: Size of blob data */
          961  +  int *pnLoad                     /* OUT: Bytes actually loaded */
   937    962   ){
   938    963     int rc;                         /* Return code */
   939    964   
   940    965     /* pnBlob must be non-NULL. paBlob may be NULL or non-NULL. */
   941    966     assert( pnBlob);
   942    967   
   943    968     if( p->pSegments ){
................................................................................
   950    975       rc = sqlite3_blob_open(
   951    976          p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments
   952    977       );
   953    978     }
   954    979   
   955    980     if( rc==SQLITE_OK ){
   956    981       int nByte = sqlite3_blob_bytes(p->pSegments);
          982  +    *pnBlob = nByte;
   957    983       if( paBlob ){
   958    984         char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING);
   959    985         if( !aByte ){
   960    986           rc = SQLITE_NOMEM;
   961    987         }else{
          988  +        if( pnLoad && nByte>(FTS3_NODE_CHUNK_THRESHOLD) ){
          989  +          nByte = FTS3_NODE_CHUNKSIZE;
          990  +          *pnLoad = nByte;
          991  +        }
   962    992           rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0);
   963    993           memset(&aByte[nByte], 0, FTS3_NODE_PADDING);
   964    994           if( rc!=SQLITE_OK ){
   965    995             sqlite3_free(aByte);
   966    996             aByte = 0;
   967    997           }
   968    998         }
   969    999         *paBlob = aByte;
   970   1000       }
   971         -    *pnBlob = nByte;
   972   1001     }
   973   1002   
   974   1003     return rc;
   975   1004   }
   976   1005   
   977   1006   /*
   978   1007   ** Close the blob handle at p->pSegments, if it is open. See comments above
   979   1008   ** the sqlite3Fts3ReadBlock() function for details.
   980   1009   */
   981   1010   void sqlite3Fts3SegmentsClose(Fts3Table *p){
   982   1011     sqlite3_blob_close(p->pSegments);
   983   1012     p->pSegments = 0;
   984   1013   }
         1014  +    
         1015  +static int fts3SegReaderIncrRead(Fts3SegReader *pReader){
         1016  +  int nRead;                      /* Number of bytes to read */
         1017  +  int rc;                         /* Return code */
         1018  +
         1019  +  nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE);
         1020  +  rc = sqlite3_blob_read(
         1021  +      pReader->pBlob, 
         1022  +      &pReader->aNode[pReader->nPopulate],
         1023  +      nRead,
         1024  +      pReader->nPopulate
         1025  +  );
         1026  +
         1027  +  if( rc==SQLITE_OK ){
         1028  +    pReader->nPopulate += nRead;
         1029  +    memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING);
         1030  +    if( pReader->nPopulate==pReader->nNode ){
         1031  +      sqlite3_blob_close(pReader->pBlob);
         1032  +      pReader->pBlob = 0;
         1033  +      pReader->nPopulate = 0;
         1034  +    }
         1035  +  }
         1036  +  return rc;
         1037  +}
         1038  +
         1039  +static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){
         1040  +  int rc = SQLITE_OK;
         1041  +  assert( !pReader->pBlob 
         1042  +       || (pFrom>=pReader->aNode && pFrom<&pReader->aNode[pReader->nNode])
         1043  +  );
         1044  +  while( pReader->pBlob && rc==SQLITE_OK 
         1045  +     &&  (pFrom - pReader->aNode + nByte)>pReader->nPopulate
         1046  +  ){
         1047  +    rc = fts3SegReaderIncrRead(pReader);
         1048  +  }
         1049  +  return rc;
         1050  +}
   985   1051   
   986   1052   /*
   987   1053   ** Move the iterator passed as the first argument to the next term in the
   988   1054   ** segment. If successful, SQLITE_OK is returned. If there is no next term,
   989   1055   ** SQLITE_DONE. Otherwise, an SQLite error code.
   990   1056   */
   991         -static int fts3SegReaderNext(Fts3Table *p, Fts3SegReader *pReader){
         1057  +static int fts3SegReaderNext(
         1058  +  Fts3Table *p, 
         1059  +  Fts3SegReader *pReader,
         1060  +  int bIncr
         1061  +){
         1062  +  int rc;                         /* Return code of various sub-routines */
   992   1063     char *pNext;                    /* Cursor variable */
   993   1064     int nPrefix;                    /* Number of bytes in term prefix */
   994   1065     int nSuffix;                    /* Number of bytes in term suffix */
   995   1066   
   996   1067     if( !pReader->aDoclist ){
   997   1068       pNext = pReader->aNode;
   998   1069     }else{
   999   1070       pNext = &pReader->aDoclist[pReader->nDoclist];
  1000   1071     }
  1001   1072   
  1002   1073     if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){
  1003         -    int rc;                       /* Return code from Fts3ReadBlock() */
  1004   1074   
  1005   1075       if( fts3SegReaderIsPending(pReader) ){
  1006   1076         Fts3HashElem *pElem = *(pReader->ppNextElem);
  1007   1077         if( pElem==0 ){
  1008   1078           pReader->aNode = 0;
  1009   1079         }else{
  1010   1080           PendingList *pList = (PendingList *)fts3HashData(pElem);
................................................................................
  1016   1086           assert( pReader->aNode );
  1017   1087         }
  1018   1088         return SQLITE_OK;
  1019   1089       }
  1020   1090   
  1021   1091       if( !fts3SegReaderIsRootOnly(pReader) ){
  1022   1092         sqlite3_free(pReader->aNode);
         1093  +      sqlite3_blob_close(pReader->pBlob);
         1094  +      pReader->pBlob = 0;
  1023   1095       }
  1024   1096       pReader->aNode = 0;
  1025   1097   
  1026   1098       /* If iCurrentBlock>=iLeafEndBlock, this is an EOF condition. All leaf 
  1027   1099       ** blocks have already been traversed.  */
  1028   1100       assert( pReader->iCurrentBlock<=pReader->iLeafEndBlock );
  1029   1101       if( pReader->iCurrentBlock>=pReader->iLeafEndBlock ){
  1030   1102         return SQLITE_OK;
  1031   1103       }
  1032   1104   
  1033   1105       rc = sqlite3Fts3ReadBlock(
  1034         -        p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode
         1106  +        p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, 
         1107  +        (bIncr ? &pReader->nPopulate : 0)
  1035   1108       );
  1036   1109       if( rc!=SQLITE_OK ) return rc;
         1110  +    assert( pReader->pBlob==0 );
         1111  +    if( bIncr && pReader->nPopulate<pReader->nNode ){
         1112  +      pReader->pBlob = p->pSegments;
         1113  +      p->pSegments = 0;
         1114  +    }
  1037   1115       pNext = pReader->aNode;
  1038   1116     }
         1117  +
         1118  +  rc = fts3SegReaderRequire(pReader, pNext, FTS3_VARINT_MAX*2);
         1119  +  if( rc!=SQLITE_OK ) return rc;
  1039   1120     
  1040   1121     /* Because of the FTS3_NODE_PADDING bytes of padding, the following is 
  1041   1122     ** safe (no risk of overread) even if the node data is corrupted.  
  1042   1123     */
  1043   1124     pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
  1044   1125     pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
  1045   1126     if( nPrefix<0 || nSuffix<=0 
................................................................................
  1053   1134       char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
  1054   1135       if( !zNew ){
  1055   1136         return SQLITE_NOMEM;
  1056   1137       }
  1057   1138       pReader->zTerm = zNew;
  1058   1139       pReader->nTermAlloc = nNew;
  1059   1140     }
         1141  +
         1142  +  rc = fts3SegReaderRequire(pReader, pNext, nSuffix+FTS3_VARINT_MAX);
         1143  +  if( rc!=SQLITE_OK ) return rc;
         1144  +
  1060   1145     memcpy(&pReader->zTerm[nPrefix], pNext, nSuffix);
  1061   1146     pReader->nTerm = nPrefix+nSuffix;
  1062   1147     pNext += nSuffix;
  1063   1148     pNext += sqlite3Fts3GetVarint32(pNext, &pReader->nDoclist);
  1064   1149     pReader->aDoclist = pNext;
  1065   1150     pReader->pOffsetList = 0;
  1066   1151   
  1067   1152     /* Check that the doclist does not appear to extend past the end of the
  1068   1153     ** b-tree node. And that the final byte of the doclist is 0x00. If either 
  1069   1154     ** of these statements is untrue, then the data structure is corrupt.
  1070   1155     */
  1071   1156     if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] 
  1072         -   || pReader->aDoclist[pReader->nDoclist-1]
         1157  +   || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
  1073   1158     ){
  1074   1159       return SQLITE_CORRUPT_VTAB;
  1075   1160     }
  1076   1161     return SQLITE_OK;
  1077   1162   }
  1078   1163   
  1079   1164   /*
  1080   1165   ** Set the SegReader to point to the first docid in the doclist associated
  1081   1166   ** with the current term.
  1082   1167   */
  1083         -static void fts3SegReaderFirstDocid(Fts3SegReader *pReader){
  1084         -  int n;
         1168  +static int fts3SegReaderFirstDocid(Fts3SegReader *pReader){
         1169  +  int rc;
  1085   1170     assert( pReader->aDoclist );
  1086   1171     assert( !pReader->pOffsetList );
  1087         -  n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid);
  1088         -  pReader->pOffsetList = &pReader->aDoclist[n];
         1172  +  rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX);
         1173  +  if( rc==SQLITE_OK ){
         1174  +    int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid);
         1175  +    pReader->pOffsetList = &pReader->aDoclist[n];
         1176  +  }
         1177  +  return rc;
  1089   1178   }
  1090   1179   
  1091   1180   /*
  1092   1181   ** Advance the SegReader to point to the next docid in the doclist
  1093   1182   ** associated with the current term.
  1094   1183   ** 
  1095   1184   ** If arguments ppOffsetList and pnOffsetList are not NULL, then 
  1096   1185   ** *ppOffsetList is set to point to the first column-offset list
  1097   1186   ** in the doclist entry (i.e. immediately past the docid varint).
  1098   1187   ** *pnOffsetList is set to the length of the set of column-offset
  1099   1188   ** lists, not including the nul-terminator byte. For example:
  1100   1189   */
  1101         -static void fts3SegReaderNextDocid(
         1190  +static int fts3SegReaderNextDocid(
  1102   1191     Fts3SegReader *pReader,
  1103   1192     char **ppOffsetList,
  1104   1193     int *pnOffsetList
  1105   1194   ){
         1195  +  int rc = SQLITE_OK;
  1106   1196     char *p = pReader->pOffsetList;
  1107   1197     char c = 0;
  1108   1198   
  1109   1199     /* Pointer p currently points at the first byte of an offset list. The
  1110   1200     ** following two lines advance it to point one byte past the end of
  1111   1201     ** the same offset list.
  1112   1202     */
  1113         -  while( *p | c ) c = *p++ & 0x80;
         1203  +  while( 1 ){
         1204  +    int nRead;
         1205  +    int rc;
         1206  +
         1207  +    while( *p | c ) c = *p++ & 0x80;
         1208  +    assert( *p==0 );
         1209  +    if( pReader->pBlob==0 || (p - pReader->aNode)!=pReader->nPopulate ) break;
         1210  +    rc = fts3SegReaderIncrRead(pReader);
         1211  +    if( rc!=SQLITE_OK ) return rc;
         1212  +  }
  1114   1213     p++;
  1115   1214   
  1116   1215     /* If required, populate the output variables with a pointer to and the
  1117   1216     ** size of the previous offset-list.
  1118   1217     */
  1119   1218     if( ppOffsetList ){
  1120   1219       *ppOffsetList = pReader->pOffsetList;
................................................................................
  1125   1224     ** NULL. Otherwise, set Fts3SegReader.iDocid to the next docid and
  1126   1225     ** Fts3SegReader.pOffsetList to point to the next offset list before
  1127   1226     ** returning.
  1128   1227     */
  1129   1228     if( p>=&pReader->aDoclist[pReader->nDoclist] ){
  1130   1229       pReader->pOffsetList = 0;
  1131   1230     }else{
  1132         -    sqlite3_int64 iDelta;
  1133         -    pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta);
  1134         -    pReader->iDocid += iDelta;
         1231  +    rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX);
         1232  +    if( rc==SQLITE_OK ){
         1233  +      sqlite3_int64 iDelta;
         1234  +      pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta);
         1235  +      pReader->iDocid += iDelta;
         1236  +    }
  1135   1237     }
         1238  +
         1239  +  return SQLITE_OK;
  1136   1240   }
  1137   1241   
  1138   1242   /*
  1139   1243   ** This function is called to estimate the amount of data that will be 
  1140   1244   ** loaded from the disk If SegReaderIterate() is called on this seg-reader,
  1141   1245   ** in units of average document size.
  1142   1246   ** 
................................................................................
  1208   1312       }
  1209   1313   
  1210   1314       /* Assume that a blob flows over onto overflow pages if it is larger
  1211   1315       ** than (pgsz-35) bytes in size (the file-format documentation
  1212   1316       ** confirms this).
  1213   1317       */
  1214   1318       for(iBlock=pReader->iStartBlock; iBlock<=pReader->iLeafEndBlock; iBlock++){
  1215         -      rc = sqlite3Fts3ReadBlock(p, iBlock, 0, &nBlob);
         1319  +      rc = sqlite3Fts3ReadBlock(p, iBlock, 0, &nBlob, 0);
  1216   1320         if( rc!=SQLITE_OK ) break;
  1217   1321         if( (nBlob+35)>pgsz ){
  1218   1322           int nOvfl = (nBlob + 34)/pgsz;
  1219   1323           nCost += ((nOvfl + pCsr->nRowAvg - 1)/pCsr->nRowAvg);
  1220   1324         }
  1221   1325       }
  1222   1326     }
................................................................................
  1243   1347       Fts3SegReader *pReader = pMsr->apSegment[ii];
  1244   1348       if( !fts3SegReaderIsPending(pReader) 
  1245   1349        && !fts3SegReaderIsRootOnly(pReader) 
  1246   1350       ){
  1247   1351         int jj;
  1248   1352         for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){
  1249   1353           int nBlob;
  1250         -        rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob);
         1354  +        rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0);
  1251   1355           if( rc!=SQLITE_OK ) break;
  1252   1356           if( (nBlob+35)>pgsz ){
  1253   1357             nOvfl += (nBlob + 34)/pgsz;
  1254   1358           }
  1255   1359         }
  1256   1360       }
  1257   1361     }
................................................................................
  1264   1368   ** second argument.
  1265   1369   */
  1266   1370   void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
  1267   1371     if( pReader && !fts3SegReaderIsPending(pReader) ){
  1268   1372       sqlite3_free(pReader->zTerm);
  1269   1373       if( !fts3SegReaderIsRootOnly(pReader) ){
  1270   1374         sqlite3_free(pReader->aNode);
         1375  +      sqlite3_blob_close(pReader->pBlob);
  1271   1376       }
  1272   1377     }
  1273   1378     sqlite3_free(pReader);
  1274   1379   }
  1275   1380   
  1276   1381   /*
  1277   1382   ** Allocate a new SegReader object.
................................................................................
  2189   2294     assert( pCsr->pFilter==0 );
  2190   2295     assert( zTerm && nTerm>0 );
  2191   2296   
  2192   2297     /* Advance each segment iterator until it points to the term zTerm/nTerm. */
  2193   2298     for(i=0; i<nSegment; i++){
  2194   2299       Fts3SegReader *pSeg = pCsr->apSegment[i];
  2195   2300       do {
  2196         -      int rc = fts3SegReaderNext(p, pSeg);
         2301  +      int rc = fts3SegReaderNext(p, pSeg, 1);
  2197   2302         if( rc!=SQLITE_OK ) return rc;
  2198   2303       }while( fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 );
  2199   2304     }
  2200   2305     fts3SegReaderSort(pCsr->apSegment, nSegment, nSegment, fts3SegReaderCmp);
  2201   2306   
  2202   2307     /* Determine how many of the segments actually point to zTerm/nTerm. */
  2203   2308     for(i=0; i<nSegment; i++){
................................................................................
  2206   2311         break;
  2207   2312       }
  2208   2313     }
  2209   2314     pCsr->nAdvance = i;
  2210   2315   
  2211   2316     /* Advance each of the segments to point to the first docid. */
  2212   2317     for(i=0; i<pCsr->nAdvance; i++){
  2213         -    fts3SegReaderFirstDocid(pCsr->apSegment[i]);
         2318  +    int rc = fts3SegReaderFirstDocid(pCsr->apSegment[i]);
         2319  +    if( rc!=SQLITE_OK ) return rc;
  2214   2320     }
         2321  +  fts3SegReaderSort(pCsr->apSegment, i, i, fts3SegReaderDoclistCmp);
  2215   2322   
  2216   2323     assert( iCol<0 || iCol<p->nColumn );
  2217   2324     pCsr->iColFilter = iCol;
  2218   2325   
  2219   2326     return SQLITE_OK;
  2220   2327   }
  2221   2328   
................................................................................
  2222   2329   int sqlite3Fts3MsrIncrNext(
  2223   2330     Fts3Table *p,                   /* Virtual table handle */
  2224   2331     Fts3MultiSegReader *pMsr,       /* Multi-segment-reader handle */
  2225   2332     sqlite3_int64 *piDocid,         /* OUT: Docid value */
  2226   2333     char **paPoslist,               /* OUT: Pointer to position list */
  2227   2334     int *pnPoslist                  /* OUT: Size of position list in bytes */
  2228   2335   ){
  2229         -  int rc = SQLITE_OK;
  2230   2336     int nMerge = pMsr->nAdvance;
  2231   2337     Fts3SegReader **apSegment = pMsr->apSegment;
  2232   2338   
  2233   2339     if( nMerge==0 ){
  2234   2340       *paPoslist = 0;
  2235   2341       return SQLITE_OK;
  2236   2342     }
  2237   2343   
  2238   2344     while( 1 ){
         2345  +    int nSort;
  2239   2346       Fts3SegReader *pSeg;
  2240         -    fts3SegReaderSort(pMsr->apSegment, nMerge, nMerge, fts3SegReaderDoclistCmp);
  2241   2347       pSeg = pMsr->apSegment[0];
  2242   2348   
  2243   2349       if( pSeg->pOffsetList==0 ){
  2244   2350         *paPoslist = 0;
  2245   2351         break;
  2246   2352       }else{
         2353  +      int rc;
  2247   2354         char *pList;
  2248   2355         int nList;
  2249   2356         int j;
  2250   2357         sqlite3_int64 iDocid = apSegment[0]->iDocid;
  2251   2358   
  2252         -      fts3SegReaderNextDocid(apSegment[0], &pList, &nList);
         2359  +      rc = fts3SegReaderNextDocid(apSegment[0], &pList, &nList);
  2253   2360         j = 1;
  2254         -      while( j<nMerge
         2361  +      while( rc==SQLITE_OK 
         2362  +        && j<nMerge
  2255   2363           && apSegment[j]->pOffsetList
  2256   2364           && apSegment[j]->iDocid==iDocid
  2257   2365         ){
  2258   2366           fts3SegReaderNextDocid(apSegment[j], 0, 0);
         2367  +        j++;
  2259   2368         }
         2369  +      if( rc!=SQLITE_OK ) return rc;
         2370  +
         2371  +      fts3SegReaderSort(pMsr->apSegment, nMerge, j, fts3SegReaderDoclistCmp);
  2260   2372   
  2261   2373         if( pMsr->iColFilter>=0 ){
  2262   2374           fts3ColumnFilter(pMsr->iColFilter, &pList, &nList);
  2263   2375         }
  2264   2376   
  2265   2377         if( nList>0 ){
  2266   2378           *piDocid = iDocid;
  2267   2379           *paPoslist = pList;
  2268   2380           *pnPoslist = nList;
  2269   2381           break;
  2270   2382         }
  2271   2383       }
         2384  +    
  2272   2385     }
  2273   2386   
  2274         -  return rc;
         2387  +  return SQLITE_OK;
  2275   2388   }
  2276   2389   
  2277   2390   int sqlite3Fts3SegReaderStart(
  2278   2391     Fts3Table *p,                   /* Virtual table handle */
  2279   2392     Fts3MultiSegReader *pCsr,       /* Cursor object */
  2280   2393     Fts3SegFilter *pFilter          /* Restrictions on range of iteration */
  2281   2394   ){
................................................................................
  2291   2404     ** b-tree leaf nodes contain more than one term.
  2292   2405     */
  2293   2406     for(i=0; i<pCsr->nSegment; i++){
  2294   2407       int nTerm = pFilter->nTerm;
  2295   2408       const char *zTerm = pFilter->zTerm;
  2296   2409       Fts3SegReader *pSeg = pCsr->apSegment[i];
  2297   2410       do {
  2298         -      int rc = fts3SegReaderNext(p, pSeg);
         2411  +      int rc = fts3SegReaderNext(p, pSeg, 0);
  2299   2412         if( rc!=SQLITE_OK ) return rc;
  2300   2413       }while( zTerm && fts3SegReaderTermCmp(pSeg, zTerm, nTerm)<0 );
  2301   2414     }
  2302   2415     fts3SegReaderSort(
  2303   2416         pCsr->apSegment, pCsr->nSegment, pCsr->nSegment, fts3SegReaderCmp);
  2304   2417   
  2305   2418     return SQLITE_OK;
................................................................................
  2327   2440       int nMerge;
  2328   2441       int i;
  2329   2442     
  2330   2443       /* Advance the first pCsr->nAdvance entries in the apSegment[] array
  2331   2444       ** forward. Then sort the list in order of current term again.  
  2332   2445       */
  2333   2446       for(i=0; i<pCsr->nAdvance; i++){
  2334         -      rc = fts3SegReaderNext(p, apSegment[i]);
         2447  +      rc = fts3SegReaderNext(p, apSegment[i], 0);
  2335   2448         if( rc!=SQLITE_OK ) return rc;
  2336   2449       }
  2337   2450       fts3SegReaderSort(apSegment, nSegment, pCsr->nAdvance, fts3SegReaderCmp);
  2338   2451       pCsr->nAdvance = 0;
  2339   2452   
  2340   2453       /* If all the seg-readers are at EOF, we're finished. return SQLITE_OK. */
  2341   2454       assert( rc==SQLITE_OK );
................................................................................
  2776   2889   ** structures headed by 
  2777   2890   */
  2778   2891   static void fts3DeferredDoclistClear(Fts3Expr *pExpr){
  2779   2892     if( pExpr ){
  2780   2893       Fts3Phrase *pPhrase = pExpr->pPhrase;
  2781   2894       fts3DeferredDoclistClear(pExpr->pLeft);
  2782   2895       fts3DeferredDoclistClear(pExpr->pRight);
  2783         -    if( pPhrase ){
  2784         -      assert( pExpr->eType==FTSQUERY_PHRASE );
  2785         -      sqlite3_free(pPhrase->aDoclist);
  2786         -      pPhrase->isLoaded = 0;
  2787         -      pPhrase->aDoclist = 0;
  2788         -      pPhrase->nDoclist = 0;
  2789         -      pPhrase->pCurrent = 0;
  2790         -      pPhrase->iCurrent = 0;
  2791         -    }
  2792   2896     }
  2793   2897   }
  2794   2898   
  2795   2899   /*
  2796   2900   ** Delete all cached deferred doclists. Deferred doclists are cached
  2797   2901   ** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function.
  2798   2902   */