If a prefix index of size N is not present, use a prefix index of size N+1 along with the terms index for queries for prefixes of length N.

FossilOrigin-Name: cc83991caae7c7d647432d5711b6cd80228c3002
This commit is contained in:
dan 2011-05-25 19:17:32 +00:00
parent 73ae6e5e76
commit 98b08e71f2
5 changed files with 75 additions and 37 deletions

View File

@ -2237,11 +2237,7 @@ static int fts3SegReaderCursorAppend(
return SQLITE_OK;
}
/*
** Set up a cursor object for iterating through a full-text index or a
** single level therein.
*/
int sqlite3Fts3SegReaderCursor(
static int fts3SegReaderCursor(
Fts3Table *p, /* FTS3 table handle */
int iIndex, /* Index to search (from 0 to p->nIndex-1) */
int iLevel, /* Level of segments to scan */
@ -2253,25 +2249,8 @@ int sqlite3Fts3SegReaderCursor(
){
int rc = SQLITE_OK;
int rc2;
int iAge = 0;
sqlite3_stmt *pStmt = 0;
assert( iIndex>=0 && iIndex<p->nIndex );
assert( iLevel==FTS3_SEGCURSOR_ALL
|| iLevel==FTS3_SEGCURSOR_PENDING
|| iLevel>=0
);
assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
assert( FTS3_SEGCURSOR_ALL<0 && FTS3_SEGCURSOR_PENDING<0 );
assert( iLevel==FTS3_SEGCURSOR_ALL || (zTerm==0 && isPrefix==1) );
assert( isPrefix==0 || isScan==0 );
/* "isScan" is only set to true by the ft4aux module, an ordinary
** full-text tables. */
assert( isScan==0 || p->aIndex==0 );
memset(pCsr, 0, sizeof(Fts3SegReaderCursor));
/* If iLevel is less than 0 and this is not a scan, include a seg-reader
** for the pending-terms. If this is a scan, then this call must be being
** made by an fts4aux module, not an FTS table. In this case calling
@ -2310,12 +2289,11 @@ int sqlite3Fts3SegReaderCursor(
if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock;
}
rc = sqlite3Fts3SegReaderNew(iAge, iStartBlock, iLeavesEndBlock,
iEndBlock, zRoot, nRoot, &pSeg
rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1,
iStartBlock, iLeavesEndBlock, iEndBlock, zRoot, nRoot, &pSeg
);
if( rc!=SQLITE_OK ) goto finished;
rc = fts3SegReaderCursorAppend(pCsr, pSeg);
iAge++;
}
}
@ -2326,6 +2304,49 @@ int sqlite3Fts3SegReaderCursor(
return rc;
}
/*
** Set up a cursor object for iterating through a full-text index or a
** single level therein.
*/
int sqlite3Fts3SegReaderCursor(
Fts3Table *p, /* FTS3 table handle */
int iIndex, /* Index to search (from 0 to p->nIndex-1) */
int iLevel, /* Level of segments to scan */
const char *zTerm, /* Term to query for */
int nTerm, /* Size of zTerm in bytes */
int isPrefix, /* True for a prefix search */
int isScan, /* True to scan from zTerm to EOF */
Fts3SegReaderCursor *pCsr /* Cursor object to populate */
){
assert( iIndex>=0 && iIndex<p->nIndex );
assert( iLevel==FTS3_SEGCURSOR_ALL
|| iLevel==FTS3_SEGCURSOR_PENDING
|| iLevel>=0
);
assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
assert( FTS3_SEGCURSOR_ALL<0 && FTS3_SEGCURSOR_PENDING<0 );
assert( isPrefix==0 || isScan==0 );
/* "isScan" is only set to true by the ft4aux module, an ordinary
** full-text tables. */
assert( isScan==0 || p->aIndex==0 );
memset(pCsr, 0, sizeof(Fts3SegReaderCursor));
return fts3SegReaderCursor(
p, iIndex, iLevel, zTerm, nTerm, isPrefix, isScan, pCsr
);
}
static int fts3SegReaderCursorAddZero(
Fts3Table *p,
const char *zTerm,
int nTerm,
Fts3SegReaderCursor *pCsr
){
return fts3SegReaderCursor(p, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0,pCsr);
}
static int fts3TermSegReaderCursor(
Fts3Cursor *pCsr, /* Virtual table cursor handle */
@ -2345,12 +2366,23 @@ static int fts3TermSegReaderCursor(
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
if( isPrefix ){
for(i=1; i<p->nIndex; i++){
for(i=1; bFound==0 && i<p->nIndex; i++){
if( p->aIndex[i].nPrefix==nTerm ){
bFound = 1;
rc = sqlite3Fts3SegReaderCursor(
p, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr);
break;
}
}
for(i=1; bFound==0 && i<p->nIndex; i++){
if( p->aIndex[i].nPrefix==nTerm+1 ){
bFound = 1;
rc = sqlite3Fts3SegReaderCursor(
p, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr
);
if( rc==SQLITE_OK ){
rc = fts3SegReaderCursorAddZero(p, zTerm, nTerm, pSegcsr);
}
}
}
}

View File

@ -422,7 +422,7 @@ int sqlite3Fts3AllSegdirs(
assert( iLevel<FTS3_SEGDIR_MAXLEVEL );
assert( iIndex>=0 && iIndex<p->nIndex );
if( iLevel==FTS3_SEGCURSOR_ALL ){
if( iLevel<0 ){
/* "SELECT * FROM %_segdir WHERE level BETWEEN ? AND ? ORDER BY ..." */
rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0);
if( rc==SQLITE_OK ){

View File

@ -1,5 +1,5 @@
C Merge\strunk\schanges\sinto\sexperimental\sfts3-prefix-search\sbranch.
D 2011-05-25T18:47:26.259
C If\sa\sprefix\sindex\sof\ssize\sN\sis\snot\spresent,\suse\sa\sprefix\sindex\sof\ssize\sN+1\salong\swith\sthe\sterms\sindex\sfor\squeries\sfor\sprefixes\sof\slength\sN.
D 2011-05-25T19:17:32.713
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -61,7 +61,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 925360f6c043fb87719e56520470265d69c5f870
F ext/fts3/fts3.c b44e0abc7aaef8d5489533b3f0556b28097378f9
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h deeeac21d17da06683a79b40ae119b93cf86f90a
F ext/fts3/fts3_aux.c 2817a1ec9ffbad673cb1a1527ad807811bc7645b
@ -75,7 +75,7 @@ F ext/fts3/fts3_term.c 0ade1812c0e97f394b58299810dfd5d2fb7ba501
F ext/fts3/fts3_tokenizer.c 055f3dc7369585350b28db1ee0f3b214dca6724d
F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3
F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d
F ext/fts3/fts3_write.c 416b367f56f3100314fa76615535178718c645e1
F ext/fts3/fts3_write.c beaa93bcbe1664fcada75b70893f9b221acf2777
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
@ -473,7 +473,7 @@ F test/fts3fault2.test dc96203af6ba31ce20163fc35460e1556e8edf4d
F test/fts3malloc.test 9c8cc3f885bb4dfc66d0460c52f68f45e4710d1b
F test/fts3matchinfo.test cc0b009edbbf575283d5fdb53271179e0d8019ba
F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844
F test/fts3prefix.test c51b04f38ce232cd0c9edd3cc60dc981db5e2726
F test/fts3prefix.test 36246609111ec1683f7ea5ed27666ce2cefb5676
F test/fts3query.test ef79d31fdb355d094baec1c1b24b60439a1fb8a2
F test/fts3rnd.test 2b1a579be557ab8ac54a51b39caa4aa8043cc4ad
F test/fts3shared.test 8bb266521d7c5495c0ae522bb4d376ad5387d4a2
@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P be59bf49402d2e2f4b95fb6668849f3745cb7bf2 d807304a695fc85402b86e1cd32a6e3bbb2823c8
R 2e09e5d0236bf18c24c777dcd7acf739
P f0f0a03db214b68a37069f64c27ae8520220c900
R 95d28d5ab6425c93022acec043aee69b
U dan
Z fd8764569a495dba32fc732cd25f7598
Z 2f1dd28b688335ffa6210dbb33afadf5

View File

@ -1 +1 @@
f0f0a03db214b68a37069f64c27ae8520220c900
cc83991caae7c7d647432d5711b6cd80228c3002

View File

@ -193,5 +193,11 @@ do_execsql_test 4.3 {
do_execsql_test 4.4 {
SELECT * FROM t3 WHERE t3 MATCH 's*'
} {{four five six} {seven eight nine}}
do_execsql_test 4.5 {
SELECT * FROM t3 WHERE t3 MATCH 'sev*'
} {{seven eight nine}}
do_execsql_test 4.6 {
SELECT * FROM t3 WHERE t3 MATCH 'one*'
} {{one two three}}
finish_test