/ Check-in [567be3bb]
Login

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

Overview
Comment:Improved shadow table corruption detection in the matchinfo() function of FTS3.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:567be3bb1e8b6477f3bf1c7b4cd6ec066fba69d0dcf8785632e244ce25db639f
User & Date: drh 2019-01-12 00:12:33
Context
2019-01-12
00:45
Improved detection of shadow table corruption in the fts5_decode() SQL function. check-in: b74e5f3f user: drh tags: trunk
00:12
Improved shadow table corruption detection in the matchinfo() function of FTS3. check-in: 567be3bb user: drh tags: trunk
00:07
Indicate that the database may be corrupt in the fts3corrupt4.test test script. check-in: 473626d5 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

  5595   5595   ** After allocating the Fts3Expr.aMI[] array for each phrase in the 
  5596   5596   ** expression rooted at pExpr, the cursor iterates through all rows matched
  5597   5597   ** by pExpr, calling this function for each row. This function increments
  5598   5598   ** the values in Fts3Expr.aMI[] according to the position-list currently
  5599   5599   ** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase 
  5600   5600   ** expression nodes.
  5601   5601   */
  5602         -static void fts3EvalUpdateCounts(Fts3Expr *pExpr){
         5602  +static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){
  5603   5603     if( pExpr ){
  5604   5604       Fts3Phrase *pPhrase = pExpr->pPhrase;
  5605   5605       if( pPhrase && pPhrase->doclist.pList ){
  5606   5606         int iCol = 0;
  5607   5607         char *p = pPhrase->doclist.pList;
  5608   5608   
  5609   5609         assert( *p );
  5610         -      while( 1 ){
         5610  +      do{
  5611   5611           u8 c = 0;
  5612   5612           int iCnt = 0;
  5613   5613           while( 0xFE & (*p | c) ){
  5614   5614             if( (c&0x80)==0 ) iCnt++;
  5615   5615             c = *p++ & 0x80;
  5616   5616           }
  5617   5617   
................................................................................
  5619   5619           ** aMI[iCol*3 + 2] = Number of rows containing at least one instance
  5620   5620           */
  5621   5621           pExpr->aMI[iCol*3 + 1] += iCnt;
  5622   5622           pExpr->aMI[iCol*3 + 2] += (iCnt>0);
  5623   5623           if( *p==0x00 ) break;
  5624   5624           p++;
  5625   5625           p += fts3GetVarint32(p, &iCol);
  5626         -      }
         5626  +      }while( iCol<nCol );
  5627   5627       }
  5628   5628   
  5629         -    fts3EvalUpdateCounts(pExpr->pLeft);
  5630         -    fts3EvalUpdateCounts(pExpr->pRight);
         5629  +    fts3EvalUpdateCounts(pExpr->pLeft, nCol);
         5630  +    fts3EvalUpdateCounts(pExpr->pRight, nCol);
  5631   5631     }
  5632   5632   }
  5633   5633   
  5634   5634   /*
  5635   5635   ** Expression pExpr must be of type FTSQUERY_PHRASE.
  5636   5636   **
  5637   5637   ** If it is not already allocated and populated, this function allocates and
................................................................................
  5693   5693           pCsr->iPrevId = pRoot->iDocid;
  5694   5694         }while( pCsr->isEof==0 
  5695   5695              && pRoot->eType==FTSQUERY_NEAR 
  5696   5696              && sqlite3Fts3EvalTestDeferred(pCsr, &rc) 
  5697   5697         );
  5698   5698   
  5699   5699         if( rc==SQLITE_OK && pCsr->isEof==0 ){
  5700         -        fts3EvalUpdateCounts(pRoot);
         5700  +        fts3EvalUpdateCounts(pRoot, pTab->nColumn);
  5701   5701         }
  5702   5702       }
  5703   5703   
  5704   5704       pCsr->isEof = 0;
  5705   5705       pCsr->iPrevId = iPrevId;
  5706   5706   
  5707   5707       if( bEof ){