Index: ext/fts3/fts3.c ================================================================== --- ext/fts3/fts3.c +++ ext/fts3/fts3.c @@ -3340,25 +3340,10 @@ } return SQLITE_OK; } - -/* -** The following three functions: -** -** fts3EvalPhraseStart() -** fts3EvalPhraseNext() -** -** May be used with a phrase object after fts3EvalAllocateReaders() has been -** called to iterate through the set of docids that match the phrase. -** -** After a successful call to fts3EvalPhraseNext(), the following two -** functions may be called to access the current docid and position-list. -*/ - - /* ** This function is called for each Fts3Phrase in a full-text query ** expression to initialize the mechanism for returning rows. Once this ** function has been called successfully on an Fts3Phrase, it may be ** used with fts3EvalPhraseNext() to iterate through the matching docids. @@ -4156,16 +4141,20 @@ fts3EvalRestart(pCsr, pExpr->pLeft, pRc); fts3EvalRestart(pCsr, pExpr->pRight, pRc); } } -static void fts3EvalUpdateCounts( - Fts3Cursor *pCsr, - Fts3Expr *pExpr, - int *pRc -){ - if( pExpr && *pRc==SQLITE_OK ){ +/* +** After allocating the Fts3Expr.aMI[] array for each phrase in the +** expression rooted at pExpr, the cursor iterates through all rows matched +** by pExpr, calling this function for each row. This function increments +** the values in Fts3Expr.aMI[] according to the position-list currently +** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase +** expression nodes. +*/ +static void fts3EvalUpdateCounts(Fts3Expr *pExpr){ + if( pExpr ){ Fts3Phrase *pPhrase = pExpr->pPhrase; if( pPhrase && pPhrase->doclist.pList ){ int iCol = 0; char *p = pPhrase->doclist.pList; @@ -4187,18 +4176,29 @@ p++; p += sqlite3Fts3GetVarint32(p, &iCol); } } - fts3EvalUpdateCounts(pCsr, pExpr->pLeft, pRc); - fts3EvalUpdateCounts(pCsr, pExpr->pRight, pRc); + fts3EvalUpdateCounts(pExpr->pLeft); + fts3EvalUpdateCounts(pExpr->pRight); } } +/* +** Expression pExpr must be of type FTSQUERY_PHRASE. +** +** If it is not already allocated and populated, this function allocates and +** populates the Fts3Expr.aMI[] array for expression pExpr. If pExpr is part +** of a NEAR expression, then it also allocates and populates the same array +** for all other phrases that are part of the NEAR expression. +** +** SQLITE_OK is returned if the aMI[] array is successfully allocated and +** populated. Otherwise, if an error occurs, an SQLite error code is returned. +*/ static int fts3EvalGatherStats( - Fts3Cursor *pCsr, - Fts3Expr *pExpr + Fts3Cursor *pCsr, /* Cursor object */ + Fts3Expr *pExpr /* FTSQUERY_PHRASE expression */ ){ int rc = SQLITE_OK; /* Return code */ assert( pExpr->eType==FTSQUERY_PHRASE ); if( pExpr->aMI==0 ){ @@ -4246,12 +4246,12 @@ }while( pCsr->isEof==0 && pRoot->eType==FTSQUERY_NEAR && fts3EvalLoadDeferred(pCsr, &rc) ); - if( pCsr->isEof==0 ){ - fts3EvalUpdateCounts(pCsr, pRoot, &rc); + if( rc==SQLITE_OK && pCsr->isEof==0 ){ + fts3EvalUpdateCounts(pRoot); } } pCsr->isEof = 0; pCsr->iPrevId = iPrevId;