From be90df0b3e06650f40572e14a1527d068e5e6846 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 2 Jan 2009 01:10:42 +0000 Subject: [PATCH] Do not display matches against the right-hand side of a NOT operator in the output of the FTS snippet() or offsets() functions. (CVS 6097) FossilOrigin-Name: d44c84c0f77bd0fc4a9942177b6cae6d109b89b7 --- ext/fts3/fts3.c | 57 ++++++++++++++++++++++++++++++++++++++----------- manifest | 14 ++++++------ manifest.uuid | 2 +- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 0c7db56c52..3ceadcfafa 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3136,8 +3136,13 @@ static void snippetAppendMatch( /* ** Function to iterate through the tokens of a compiled expression. +** +** Except, skip all tokens on the right-hand side of a NOT operator. +** This function is used to find tokens as part of snippet and offset +** generation and we do nt want snippets and offsets to report matches +** for tokens on the RHS of a NOT. */ -static int nextExprToken(Fts3Expr **ppExpr, int *piToken){ +static int fts3NextExprToken(Fts3Expr **ppExpr, int *piToken){ Fts3Expr *p = *ppExpr; int iToken = *piToken; if( iToken<0 ){ @@ -3160,6 +3165,7 @@ static int nextExprToken(Fts3Expr **ppExpr, int *piToken){ } p = p->pParent; if( p ){ + assert( p->pRight!=0 ); p = p->pRight; while( p->pLeft ){ p = p->pLeft; @@ -3173,16 +3179,32 @@ static int nextExprToken(Fts3Expr **ppExpr, int *piToken){ return p?1:0; } +/* +** Return TRUE if the expression node pExpr is located beneath the +** RHS of a NOT operator. +*/ +static int fts3ExprBeneathNot(Fts3Expr *p){ + Fts3Expr *pParent; + while( p ){ + pParent = p->pParent; + if( pParent && pParent->eType==FTSQUERY_NOT && pParent->pRight==p ){ + return 1; + } + p = pParent; + } + return 0; +} + /* ** Add entries to pSnippet->aMatch[] for every match that occurs against ** document zDoc[0..nDoc-1] which is stored in column iColumn. */ static void snippetOffsetsOfColumn( - fulltext_cursor *pCur, - Snippet *pSnippet, - int iColumn, - const char *zDoc, - int nDoc + fulltext_cursor *pCur, /* The fulltest search cursor */ + Snippet *pSnippet, /* The Snippet object to be filled in */ + int iColumn, /* Index of fulltext table column */ + const char *zDoc, /* Text of the fulltext table column */ + int nDoc /* Length of zDoc in bytes */ ){ const sqlite3_tokenizer_module *pTModule; /* The tokenizer module */ sqlite3_tokenizer *pTokenizer; /* The specific tokenizer */ @@ -3217,10 +3239,15 @@ static void snippetOffsetsOfColumn( iRotorBegin[iRotor&FTS3_ROTOR_MASK] = iBegin; iRotorLen[iRotor&FTS3_ROTOR_MASK] = iEnd-iBegin; match = 0; - for(i=0; i<(FTS3_ROTOR_SZ-1) && nextExprToken(&pIter, &iIter); i++){ - int nPhrase = pIter->pPhrase->nToken; /* Tokens in current phrase */ - struct PhraseToken *pToken = &pIter->pPhrase->aToken[iIter]; - int iCol = pIter->pPhrase->iColumn; + for(i=0; i<(FTS3_ROTOR_SZ-1) && fts3NextExprToken(&pIter, &iIter); i++){ + int nPhrase; /* Number of tokens in current phrase */ + struct PhraseToken *pToken; /* Current token */ + int iCol; /* Column index */ + + if( fts3ExprBeneathNot(pIter) ) continue; + nPhrase = pIter->pPhrase->nToken; + pToken = &pIter->pPhrase->aToken[iIter]; + iCol = pIter->pPhrase->iColumn; if( iCol>=0 && iColn>nToken ) continue; if( !pToken->isPrefix && pToken->npLeft, pSnippet, piLeft) ){ @@ -3385,9 +3414,11 @@ static void snippetAllOffsets(fulltext_cursor *p){ nColumn = pFts->nColumn; iColumn = (p->iCursorType - QUERY_FULLTEXT); if( iColumn<0 || iColumn>=nColumn ){ + /* Look for matches over all columns of the full-text index */ iFirst = 0; iLast = nColumn-1; }else{ + /* Look for matches in the iColumn-th column of the index only */ iFirst = iColumn; iLast = iColumn; } diff --git a/manifest b/manifest index 1e5a1e1108..125a606987 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\s(benign)\svalgrind\serror\sthat\scan\soccur\sfollowing\smalloc\sfailure\swhile\sexecuting\sa\s'ROLLBACK\sTO\ssavepoint'\scommand.\s(CVS\s6096) -D 2009-01-01T15:20:37 +C Do\snot\sdisplay\smatches\sagainst\r\nthe\sright-hand\sside\sof\sa\sNOT\soperator\sin\sthe\soutput\r\nof\sthe\sFTS\ssnippet()\sor\soffsets()\sfunctions.\s(CVS\s6097) +D 2009-01-02T01:10:42 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 77635d0909c2067cee03889a1e04ce910d8fb809 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -53,7 +53,7 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 3aa6aef1eadc44606f6ed3c841062735a5210077 +F ext/fts3/fts3.c 4e0d3b1b8ad133e0cd641e9eaa56015ad0466cd6 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3_expr.c 98fe92f6888c306734ed9332a24383dde77c25aa F ext/fts3/fts3_expr.h b5412dcf565c6d90d6a8c22090ceb9ed8c745634 @@ -690,7 +690,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P ccfe4580ac7ba9add0e69c786a9a3a43d69b7753 -R 55e5da6452ac7bf13b968c8f36ed538b -U danielk1977 -Z fe12888ee4a3f9d606558994dc2f8d82 +P 9ff8598f3be123a244f71b45e77af913b836504a +R 2cdfa5be7870dcec4ac66bcd1ad84dbe +U drh +Z a59547509372bc8abd2b95e6b7d6a629 diff --git a/manifest.uuid b/manifest.uuid index e0fe1155c1..3e62e6ac7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ff8598f3be123a244f71b45e77af913b836504a \ No newline at end of file +d44c84c0f77bd0fc4a9942177b6cae6d109b89b7 \ No newline at end of file