1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-01 06:27:03 +03:00

Speed up parsing of very long fts3 query expressions.

FossilOrigin-Name: 2dd5b6895a3b23c2b9cbf0c1c1e802faf8f2b41ef60819eea25d609755266e64
This commit is contained in:
dan
2025-03-15 16:58:39 +00:00
parent 9f8a238fb5
commit f212fb3362
3 changed files with 44 additions and 19 deletions

View File

@ -161,6 +161,23 @@ int sqlite3Fts3OpenTokenizer(
*/ */
static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
/*
** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis
** is defined, search for '(' and ')' as well. Return the index of the first
** such character in the buffer. If there is no such character, return -1.
*/
static int findBarredChar(const char *z, int n){
int ii;
for(ii=0; ii<n; ii++){
if( (z[ii]=='"')
|| (sqlite3_fts3_enable_parentheses && (z[ii]=='(' || z[ii]==')'))
){
return ii;
}
}
return -1;
}
/* /*
** Extract the next token from buffer z (length n) using the tokenizer ** Extract the next token from buffer z (length n) using the tokenizer
** and other information (column names etc.) in pParse. Create an Fts3Expr ** and other information (column names etc.) in pParse. Create an Fts3Expr
@ -185,16 +202,9 @@ static int getNextToken(
int rc; int rc;
sqlite3_tokenizer_cursor *pCursor; sqlite3_tokenizer_cursor *pCursor;
Fts3Expr *pRet = 0; Fts3Expr *pRet = 0;
int i = 0;
/* Set variable i to the maximum number of bytes of input to tokenize. */ *pnConsumed = n;
for(i=0; i<n; i++){ rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
if( z[i]=='"' ) break;
}
*pnConsumed = i;
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
const char *zToken; const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
@ -202,6 +212,18 @@ static int getNextToken(
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
/* Check that this tokenization did not gobble up any " characters. Or,
** if enable_parenthesis is true, that it did not gobble up any
** open or close parenthesis characters either. If it did, call
** getNextToken() again, but pass only that part of the input buffer
** up to the first such character. */
int iBarred = findBarredChar(z, iEnd);
if( iBarred>=0 ){
pModule->xClose(pCursor);
return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed);
}
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte);
if( !pRet ){ if( !pRet ){
@ -236,7 +258,11 @@ static int getNextToken(
} }
*pnConsumed = iEnd; *pnConsumed = iEnd;
}else if( i && rc==SQLITE_DONE ){ }else if( n && rc==SQLITE_DONE ){
int iBarred = findBarredChar(z, n);
if( iBarred>=0 ){
*pnConsumed = iBarred;
}
rc = SQLITE_OK; rc = SQLITE_OK;
} }
@ -1239,7 +1265,6 @@ static void fts3ExprTestCommon(
} }
if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){ if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
sqlite3Fts3ExprFree(pExpr);
sqlite3_result_error(context, "Error parsing expression", -1); sqlite3_result_error(context, "Error parsing expression", -1);
}else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){ }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
sqlite3_result_error_nomem(context); sqlite3_result_error_nomem(context);

View File

@ -1,5 +1,5 @@
C Configure-internal\sbuild\scleanups\s(no\sfunctional\schanges).\sAdd\sEXTRA_SRC\sto\sthe\sdeps\sof\ssqlite3.c. C Speed\sup\sparsing\sof\svery\slong\sfts3\squery\sexpressions.
D 2025-03-15T15:19:42.945 D 2025-03-15T16:58:39.639
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
@ -82,7 +82,7 @@ F ext/fts3/fts3.c fd2a8642fa4701ef5dd6bce7947ecb3c7ae472e1d44022772454a8b74a1315
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h 75b9cf37c93d3c56d8e569d64527c927cb54a5279afb3823740ca1e29e481c15 F ext/fts3/fts3Int.h 75b9cf37c93d3c56d8e569d64527c927cb54a5279afb3823740ca1e29e481c15
F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3
F ext/fts3/fts3_expr.c 673bf600655f5080239ff0e1e80eaae0176389f7e7d3af54c6d51491280ca360 F ext/fts3/fts3_expr.c b8ff0d3775f33eddae559b444df2000d48768d7d9bdb642e3f6434c9f2543ffc
F ext/fts3/fts3_hash.c d9dba473741445789330c7513d4f65737c92df23c3212784312931641814672a F ext/fts3/fts3_hash.c d9dba473741445789330c7513d4f65737c92df23c3212784312931641814672a
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116
@ -2213,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P fa6f6ccdffc50024624306900efd2538c7415d8bdd0f02835b2e9c05adab3cf1 P 8afb8bbce8654d6f76207fb136e79dc52b6724a71eae82a4c098690a68eb75a1
R fa3f42bd795b87d6c693892aa92ef559 R 1bd8f3cfa90570231383a500e0910fe3
U stephan U dan
Z 60eb85208863d91adaf5e3aa8394c9ef Z 1c83f58e6b1181c1bb790bbf7879f1cb
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
8afb8bbce8654d6f76207fb136e79dc52b6724a71eae82a4c098690a68eb75a1 2dd5b6895a3b23c2b9cbf0c1c1e802faf8f2b41ef60819eea25d609755266e64