Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a performance problem in queries that use "ORDER BY rowid DESC" and one or more FTS auxiliary functions. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | vtab-conflict |
Files: | files | file ages | folders |
SHA1: |
95e09b20e9aad28f829c8950f3632deb |
User & Date: | dan 2011-05-04 15:41:18.367 |
Context
2011-05-04
| ||
16:30 | Fix a couple of compiler warnings in the FTS code. (Closed-Leaf check-in: 1a11335970 user: dan tags: vtab-conflict) | |
15:41 | Fix a performance problem in queries that use "ORDER BY rowid DESC" and one or more FTS auxiliary functions. (check-in: 95e09b20e9 user: dan tags: vtab-conflict) | |
12:52 | Optimize "ORDER BY rowid/docid DESC/ASC" clauses on FTS tables. (check-in: 13395121e3 user: dan tags: vtab-conflict) | |
Changes
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 | assert( pCsr->eEvalmode==FTS3_EVAL_NEXT ); assert( pExpr->eType==FTSQUERY_PHRASE && pExpr->pPhrase ); pCsr->eEvalmode = FTS3_EVAL_MATCHINFO; rc = fts3EvalExpr(pCsr, pExpr, paDoclist, pnDoclist, 1); pCsr->eEvalmode = FTS3_EVAL_NEXT; return rc; } /* ** After ExprLoadDoclist() (see above) has been called, this function is ** used to iterate/search through the position lists that make up the doclist ** stored in pExpr->aDoclist. */ char *sqlite3Fts3FindPositions( Fts3Cursor *pCursor, /* Associate FTS3 cursor */ Fts3Expr *pExpr, /* Access this expressions doclist */ sqlite3_int64 iDocid, /* Docid associated with requested pos-list */ int iCol /* Column of requested pos-list */ ){ assert( pExpr->isLoaded ); if( pExpr->aDoclist ){ char *pEnd = &pExpr->aDoclist[pExpr->nDoclist]; char *pCsr; | > > > > > > > > > > > > > > > > > > > | > | | > > > > > > > > | > | > > | > > > > | 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 | assert( pCsr->eEvalmode==FTS3_EVAL_NEXT ); assert( pExpr->eType==FTSQUERY_PHRASE && pExpr->pPhrase ); pCsr->eEvalmode = FTS3_EVAL_MATCHINFO; rc = fts3EvalExpr(pCsr, pExpr, paDoclist, pnDoclist, 1); pCsr->eEvalmode = FTS3_EVAL_NEXT; return rc; } /* ** When called, *ppPoslist must point to the byte immediately following the ** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function ** moves *ppPoslist so that it instead points to the first byte of the ** position list. */ static void fts3ReversePoslist(char *pStart, char **ppPoslist){ char *p = &(*ppPoslist)[-3]; char c = p[1]; while( p>=pStart && (*p & 0x80) | c ){ c = *p--; } if( p>pStart ){ p = &p[2]; } while( *p++&0x80 ); *ppPoslist = p; } /* ** After ExprLoadDoclist() (see above) has been called, this function is ** used to iterate/search through the position lists that make up the doclist ** stored in pExpr->aDoclist. */ char *sqlite3Fts3FindPositions( Fts3Cursor *pCursor, /* Associate FTS3 cursor */ Fts3Expr *pExpr, /* Access this expressions doclist */ sqlite3_int64 iDocid, /* Docid associated with requested pos-list */ int iCol /* Column of requested pos-list */ ){ assert( pExpr->isLoaded ); if( pExpr->aDoclist ){ char *pEnd = &pExpr->aDoclist[pExpr->nDoclist]; char *pCsr; if( pExpr->pCurrent==0 ){ if( pCursor->desc==0 ){ pExpr->pCurrent = pExpr->aDoclist; pExpr->iCurrent = 0; fts3GetDeltaVarint(&pExpr->pCurrent, &pExpr->iCurrent); }else{ pCsr = pExpr->aDoclist; while( pCsr<pEnd ){ fts3GetDeltaVarint(&pCsr, &pExpr->iCurrent); fts3PoslistCopy(0, &pCsr); } fts3ReversePoslist(pExpr->aDoclist, &pCsr); pExpr->pCurrent = pCsr; } } pCsr = pExpr->pCurrent; assert( pCsr ); while( (pCursor->desc==0 && pCsr<pEnd) || (pCursor->desc && pCsr>pExpr->aDoclist) ){ if( pCursor->desc==0 && pExpr->iCurrent<iDocid ){ fts3PoslistCopy(0, &pCsr); if( pCsr<pEnd ){ fts3GetDeltaVarint(&pCsr, &pExpr->iCurrent); } pExpr->pCurrent = pCsr; }else if( pCursor->desc && pExpr->iCurrent>iDocid ){ fts3GetReverseDeltaVarint(&pCsr, pExpr->aDoclist, &pExpr->iCurrent); fts3ReversePoslist(pExpr->aDoclist, &pCsr); pExpr->pCurrent = pCsr; }else{ if( pExpr->iCurrent==iDocid ){ int iThis = 0; if( iCol<0 ){ /* If iCol is negative, return a pointer to the start of the ** position-list (instead of a pointer to the start of a list |
︙ | ︙ |
Changes to test/fts3sort.test.
︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | 3 "SELECT docid, * FROM t1 WHERE t1 MATCH 'a*'" 4 "SELECT docid, quote(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'a*'" 5 "SELECT docid, quote(matchinfo(t1,'pcnxals')) FROM t1 WHERE t1 MATCH 'b*'" 6 "SELECT docid, * FROM t1 WHERE t1 MATCH 'a* b* c*'" 7 "SELECT docid, * FROM t1 WHERE t1 MATCH 'aa OR da'" 8 "SELECT docid, * FROM t1 WHERE t1 MATCH 'nosuchtoken'" 9 "SELECT docid, snippet(t1) FROM t1 WHERE t1 MATCH 'aa OR da'" } { unset -nocomplain A B C D set A_list [list] set B_list [list] set C_list [list] set D_list [list] | > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 3 "SELECT docid, * FROM t1 WHERE t1 MATCH 'a*'" 4 "SELECT docid, quote(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'a*'" 5 "SELECT docid, quote(matchinfo(t1,'pcnxals')) FROM t1 WHERE t1 MATCH 'b*'" 6 "SELECT docid, * FROM t1 WHERE t1 MATCH 'a* b* c*'" 7 "SELECT docid, * FROM t1 WHERE t1 MATCH 'aa OR da'" 8 "SELECT docid, * FROM t1 WHERE t1 MATCH 'nosuchtoken'" 9 "SELECT docid, snippet(t1) FROM t1 WHERE t1 MATCH 'aa OR da'" 10 "SELECT docid, snippet(t1) FROM t1 WHERE t1 MATCH 'aa OR nosuchtoken'" } { unset -nocomplain A B C D set A_list [list] set B_list [list] set C_list [list] set D_list [list] |
︙ | ︙ |