| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.8.8.2. By combining all the individual C code files into this |
| 3 | +** version 3.8.8.3. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -276,13 +276,13 @@ |
| 276 | 276 | ** |
| 277 | 277 | ** See also: [sqlite3_libversion()], |
| 278 | 278 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 279 | 279 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 280 | 280 | */ |
| 281 | | -#define SQLITE_VERSION "3.8.8.2" |
| 281 | +#define SQLITE_VERSION "3.8.8.3" |
| 282 | 282 | #define SQLITE_VERSION_NUMBER 3008008 |
| 283 | | -#define SQLITE_SOURCE_ID "2015-01-30 14:30:45 7757fc721220e136620a89c9d28247f28bbbc098" |
| 283 | +#define SQLITE_SOURCE_ID "2015-02-25 13:29:11 9d6c1880fb75660bbabd693175579529785f8a6b" |
| 284 | 284 | |
| 285 | 285 | /* |
| 286 | 286 | ** CAPI3REF: Run-Time Library Version Numbers |
| 287 | 287 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 288 | 288 | ** |
| | @@ -116549,10 +116549,11 @@ |
| 116549 | 116549 | pLoop = pLevel->pWLoop; |
| 116550 | 116550 | idxCols = 0; |
| 116551 | 116551 | for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){ |
| 116552 | 116552 | if( pLoop->prereq==0 |
| 116553 | 116553 | && (pTerm->wtFlags & TERM_VIRTUAL)==0 |
| 116554 | + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) |
| 116554 | 116555 | && sqlite3ExprIsTableConstant(pTerm->pExpr, pSrc->iCursor) ){ |
| 116555 | 116556 | pPartial = sqlite3ExprAnd(pParse->db, pPartial, |
| 116556 | 116557 | sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); |
| 116557 | 116558 | } |
| 116558 | 116559 | if( termCanDriveIndex(pTerm, pSrc, notReady) ){ |
| | @@ -119629,11 +119630,15 @@ |
| 119629 | 119630 | */ |
| 119630 | 119631 | static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ |
| 119631 | 119632 | int i; |
| 119632 | 119633 | WhereTerm *pTerm; |
| 119633 | 119634 | for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){ |
| 119634 | | - if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1; |
| 119635 | + if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) |
| 119636 | + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) |
| 119637 | + ){ |
| 119638 | + return 1; |
| 119639 | + } |
| 119635 | 119640 | } |
| 119636 | 119641 | return 0; |
| 119637 | 119642 | } |
| 119638 | 119643 | |
| 119639 | 119644 | /* |
| | @@ -131384,10 +131389,15 @@ |
| 131384 | 131389 | struct Fts3Phrase { |
| 131385 | 131390 | /* Cache of doclist for this phrase. */ |
| 131386 | 131391 | Fts3Doclist doclist; |
| 131387 | 131392 | int bIncr; /* True if doclist is loaded incrementally */ |
| 131388 | 131393 | int iDoclistToken; |
| 131394 | + |
| 131395 | + /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an |
| 131396 | + ** OR condition. */ |
| 131397 | + char *pOrPoslist; |
| 131398 | + i64 iOrDocid; |
| 131389 | 131399 | |
| 131390 | 131400 | /* Variables below this point are populated by fts3_expr.c when parsing |
| 131391 | 131401 | ** a MATCH expression. Everything above is part of the evaluation phase. |
| 131392 | 131402 | */ |
| 131393 | 131403 | int nToken; /* Number of tokens in the phrase */ |
| | @@ -136335,10 +136345,26 @@ |
| 136335 | 136345 | fts3EvalNextRow(pCsr, pRight, pRc); |
| 136336 | 136346 | } |
| 136337 | 136347 | } |
| 136338 | 136348 | pExpr->iDocid = pLeft->iDocid; |
| 136339 | 136349 | pExpr->bEof = (pLeft->bEof || pRight->bEof); |
| 136350 | + if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){ |
| 136351 | + if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){ |
| 136352 | + Fts3Doclist *pDl = &pRight->pPhrase->doclist; |
| 136353 | + while( *pRc==SQLITE_OK && pRight->bEof==0 ){ |
| 136354 | + memset(pDl->pList, 0, pDl->nList); |
| 136355 | + fts3EvalNextRow(pCsr, pRight, pRc); |
| 136356 | + } |
| 136357 | + } |
| 136358 | + if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){ |
| 136359 | + Fts3Doclist *pDl = &pLeft->pPhrase->doclist; |
| 136360 | + while( *pRc==SQLITE_OK && pLeft->bEof==0 ){ |
| 136361 | + memset(pDl->pList, 0, pDl->nList); |
| 136362 | + fts3EvalNextRow(pCsr, pLeft, pRc); |
| 136363 | + } |
| 136364 | + } |
| 136365 | + } |
| 136340 | 136366 | } |
| 136341 | 136367 | break; |
| 136342 | 136368 | } |
| 136343 | 136369 | |
| 136344 | 136370 | case FTSQUERY_OR: { |
| | @@ -136707,10 +136733,11 @@ |
| 136707 | 136733 | } |
| 136708 | 136734 | *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); |
| 136709 | 136735 | } |
| 136710 | 136736 | pPhrase->doclist.pNextDocid = 0; |
| 136711 | 136737 | pPhrase->doclist.iDocid = 0; |
| 136738 | + pPhrase->pOrPoslist = 0; |
| 136712 | 136739 | } |
| 136713 | 136740 | |
| 136714 | 136741 | pExpr->iDocid = 0; |
| 136715 | 136742 | pExpr->bEof = 0; |
| 136716 | 136743 | pExpr->bStart = 0; |
| | @@ -136952,10 +136979,11 @@ |
| 136952 | 136979 | } |
| 136953 | 136980 | |
| 136954 | 136981 | iDocid = pExpr->iDocid; |
| 136955 | 136982 | pIter = pPhrase->doclist.pList; |
| 136956 | 136983 | if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ |
| 136984 | + int rc = SQLITE_OK; |
| 136957 | 136985 | int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ |
| 136958 | 136986 | int iMul; /* +1 if csr dir matches index dir, else -1 */ |
| 136959 | 136987 | int bOr = 0; |
| 136960 | 136988 | u8 bEof = 0; |
| 136961 | 136989 | u8 bTreeEof = 0; |
| | @@ -136977,76 +137005,47 @@ |
| 136977 | 137005 | |
| 136978 | 137006 | /* This is the descendent of an OR node. In this case we cannot use |
| 136979 | 137007 | ** an incremental phrase. Load the entire doclist for the phrase |
| 136980 | 137008 | ** into memory in this case. */ |
| 136981 | 137009 | if( pPhrase->bIncr ){ |
| 136982 | | - int rc = SQLITE_OK; |
| 136983 | | - int bEofSave = pExpr->bEof; |
| 136984 | | - fts3EvalRestart(pCsr, pExpr, &rc); |
| 136985 | | - while( rc==SQLITE_OK && !pExpr->bEof ){ |
| 136986 | | - fts3EvalNextRow(pCsr, pExpr, &rc); |
| 136987 | | - if( bEofSave==0 && pExpr->iDocid==iDocid ) break; |
| 136988 | | - } |
| 136989 | | - pIter = pPhrase->doclist.pList; |
| 137010 | + int bEofSave = pNear->bEof; |
| 137011 | + fts3EvalRestart(pCsr, pNear, &rc); |
| 137012 | + while( rc==SQLITE_OK && !pNear->bEof ){ |
| 137013 | + fts3EvalNextRow(pCsr, pNear, &rc); |
| 137014 | + if( bEofSave==0 && pNear->iDocid==iDocid ) break; |
| 137015 | + } |
| 136990 | 137016 | assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); |
| 136991 | | - if( rc!=SQLITE_OK ) return rc; |
| 136992 | | - } |
| 136993 | | - |
| 136994 | | - iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1); |
| 136995 | | - while( bTreeEof==1 |
| 136996 | | - && pNear->bEof==0 |
| 136997 | | - && (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0 |
| 136998 | | - ){ |
| 136999 | | - int rc = SQLITE_OK; |
| 137000 | | - fts3EvalNextRow(pCsr, pExpr, &rc); |
| 137001 | | - if( rc!=SQLITE_OK ) return rc; |
| 137002 | | - iDocid = pExpr->iDocid; |
| 137003 | | - pIter = pPhrase->doclist.pList; |
| 137004 | | - } |
| 137005 | | - |
| 137006 | | - bEof = (pPhrase->doclist.nAll==0); |
| 137007 | | - assert( bDescDoclist==0 || bDescDoclist==1 ); |
| 137008 | | - assert( pCsr->bDesc==0 || pCsr->bDesc==1 ); |
| 137009 | | - |
| 137010 | | - if( bEof==0 ){ |
| 137011 | | - if( pCsr->bDesc==bDescDoclist ){ |
| 137017 | + } |
| 137018 | + if( bTreeEof ){ |
| 137019 | + while( rc==SQLITE_OK && !pNear->bEof ){ |
| 137020 | + fts3EvalNextRow(pCsr, pNear, &rc); |
| 137021 | + } |
| 137022 | + } |
| 137023 | + if( rc!=SQLITE_OK ) return rc; |
| 137024 | + |
| 137025 | + pIter = pPhrase->pOrPoslist; |
| 137026 | + iDocid = pPhrase->iOrDocid; |
| 137027 | + if( pCsr->bDesc==bDescDoclist ){ |
| 137028 | + bEof = (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll)); |
| 137029 | + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ |
| 137030 | + sqlite3Fts3DoclistNext( |
| 137031 | + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 137032 | + &pIter, &iDocid, &bEof |
| 137033 | + ); |
| 137034 | + } |
| 137035 | + }else{ |
| 137036 | + bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll); |
| 137037 | + while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ |
| 137012 | 137038 | int dummy; |
| 137013 | | - if( pNear->bEof ){ |
| 137014 | | - /* This expression is already at EOF. So position it to point to the |
| 137015 | | - ** last entry in the doclist at pPhrase->doclist.aAll[]. Variable |
| 137016 | | - ** iDocid is already set for this entry, so all that is required is |
| 137017 | | - ** to set pIter to point to the first byte of the last position-list |
| 137018 | | - ** in the doclist. |
| 137019 | | - ** |
| 137020 | | - ** It would also be correct to set pIter and iDocid to zero. In |
| 137021 | | - ** this case, the first call to sqltie3Fts4DoclistPrev() below |
| 137022 | | - ** would also move the iterator to point to the last entry in the |
| 137023 | | - ** doclist. However, this is expensive, as to do so it has to |
| 137024 | | - ** iterate through the entire doclist from start to finish (since |
| 137025 | | - ** it does not know the docid for the last entry). */ |
| 137026 | | - pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1]; |
| 137027 | | - fts3ReversePoslist(pPhrase->doclist.aAll, &pIter); |
| 137028 | | - } |
| 137029 | | - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ |
| 137030 | | - sqlite3Fts3DoclistPrev( |
| 137031 | | - bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 137032 | | - &pIter, &iDocid, &dummy, &bEof |
| 137033 | | - ); |
| 137034 | | - } |
| 137035 | | - }else{ |
| 137036 | | - if( pNear->bEof ){ |
| 137037 | | - pIter = 0; |
| 137038 | | - iDocid = 0; |
| 137039 | | - } |
| 137040 | | - while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ |
| 137041 | | - sqlite3Fts3DoclistNext( |
| 137042 | | - bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 137043 | | - &pIter, &iDocid, &bEof |
| 137044 | | - ); |
| 137045 | | - } |
| 137046 | | - } |
| 137047 | | - } |
| 137039 | + sqlite3Fts3DoclistPrev( |
| 137040 | + bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, |
| 137041 | + &pIter, &iDocid, &dummy, &bEof |
| 137042 | + ); |
| 137043 | + } |
| 137044 | + } |
| 137045 | + pPhrase->pOrPoslist = pIter; |
| 137046 | + pPhrase->iOrDocid = iDocid; |
| 137048 | 137047 | |
| 137049 | 137048 | if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0; |
| 137050 | 137049 | } |
| 137051 | 137050 | if( pIter==0 ) return SQLITE_OK; |
| 137052 | 137051 | |
| | @@ -137056,13 +137055,16 @@ |
| 137056 | 137055 | }else{ |
| 137057 | 137056 | iThis = 0; |
| 137058 | 137057 | } |
| 137059 | 137058 | while( iThis<iCol ){ |
| 137060 | 137059 | fts3ColumnlistCopy(0, &pIter); |
| 137061 | | - if( *pIter==0x00 ) return 0; |
| 137060 | + if( *pIter==0x00 ) return SQLITE_OK; |
| 137062 | 137061 | pIter++; |
| 137063 | 137062 | pIter += fts3GetVarint32(pIter, &iThis); |
| 137063 | + } |
| 137064 | + if( *pIter==0x00 ){ |
| 137065 | + pIter = 0; |
| 137064 | 137066 | } |
| 137065 | 137067 | |
| 137066 | 137068 | *ppOut = ((iCol==iThis)?pIter:0); |
| 137067 | 137069 | return SQLITE_OK; |
| 137068 | 137070 | } |
| | @@ -147286,41 +147288,43 @@ |
| 147286 | 147288 | sIter.pCsr = pCsr; |
| 147287 | 147289 | sIter.iCol = iCol; |
| 147288 | 147290 | sIter.nSnippet = nSnippet; |
| 147289 | 147291 | sIter.nPhrase = nList; |
| 147290 | 147292 | sIter.iCurrent = -1; |
| 147291 | | - (void)fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter); |
| 147292 | | - |
| 147293 | | - /* Set the *pmSeen output variable. */ |
| 147294 | | - for(i=0; i<nList; i++){ |
| 147295 | | - if( sIter.aPhrase[i].pHead ){ |
| 147296 | | - *pmSeen |= (u64)1 << i; |
| 147297 | | - } |
| 147298 | | - } |
| 147299 | | - |
| 147300 | | - /* Loop through all candidate snippets. Store the best snippet in |
| 147301 | | - ** *pFragment. Store its associated 'score' in iBestScore. |
| 147302 | | - */ |
| 147303 | | - pFragment->iCol = iCol; |
| 147304 | | - while( !fts3SnippetNextCandidate(&sIter) ){ |
| 147305 | | - int iPos; |
| 147306 | | - int iScore; |
| 147307 | | - u64 mCover; |
| 147308 | | - u64 mHighlight; |
| 147309 | | - fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover, &mHighlight); |
| 147310 | | - assert( iScore>=0 ); |
| 147311 | | - if( iScore>iBestScore ){ |
| 147312 | | - pFragment->iPos = iPos; |
| 147313 | | - pFragment->hlmask = mHighlight; |
| 147314 | | - pFragment->covered = mCover; |
| 147315 | | - iBestScore = iScore; |
| 147316 | | - } |
| 147317 | | - } |
| 147318 | | - |
| 147293 | + rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter); |
| 147294 | + if( rc==SQLITE_OK ){ |
| 147295 | + |
| 147296 | + /* Set the *pmSeen output variable. */ |
| 147297 | + for(i=0; i<nList; i++){ |
| 147298 | + if( sIter.aPhrase[i].pHead ){ |
| 147299 | + *pmSeen |= (u64)1 << i; |
| 147300 | + } |
| 147301 | + } |
| 147302 | + |
| 147303 | + /* Loop through all candidate snippets. Store the best snippet in |
| 147304 | + ** *pFragment. Store its associated 'score' in iBestScore. |
| 147305 | + */ |
| 147306 | + pFragment->iCol = iCol; |
| 147307 | + while( !fts3SnippetNextCandidate(&sIter) ){ |
| 147308 | + int iPos; |
| 147309 | + int iScore; |
| 147310 | + u64 mCover; |
| 147311 | + u64 mHighlite; |
| 147312 | + fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite); |
| 147313 | + assert( iScore>=0 ); |
| 147314 | + if( iScore>iBestScore ){ |
| 147315 | + pFragment->iPos = iPos; |
| 147316 | + pFragment->hlmask = mHighlite; |
| 147317 | + pFragment->covered = mCover; |
| 147318 | + iBestScore = iScore; |
| 147319 | + } |
| 147320 | + } |
| 147321 | + |
| 147322 | + *piScore = iBestScore; |
| 147323 | + } |
| 147319 | 147324 | sqlite3_free(sIter.aPhrase); |
| 147320 | | - *piScore = iBestScore; |
| 147321 | | - return SQLITE_OK; |
| 147325 | + return rc; |
| 147322 | 147326 | } |
| 147323 | 147327 | |
| 147324 | 147328 | |
| 147325 | 147329 | /* |
| 147326 | 147330 | ** Append a string to the string-buffer passed as the first argument. |
| 147327 | 147331 | |