| https://sqlite.org/src/info/893e6089c875e947 |
| https://sqlite.org/src/info/576a8f69ae25883f |
| https://sqlite.org/src/info/de508e831a43f02c |
| |
| --- /ext/fts3/fts3.c |
| +++ /ext/fts3/fts3.c |
| @@ -3963,7 +3963,7 @@ |
| |
| #ifdef SQLITE_TEST |
| if( rc==SQLITE_OK ){ |
| - rc = sqlite3Fts3ExprInitTestInterface(db); |
| + rc = sqlite3Fts3ExprInitTestInterface(db, pHash); |
| } |
| #endif |
| |
| --- /ext/fts3/fts3Int.h |
| +++ /ext/fts3/fts3Int.h |
| @@ -584,7 +584,7 @@ |
| ); |
| void sqlite3Fts3ExprFree(Fts3Expr *); |
| #ifdef SQLITE_TEST |
| -int sqlite3Fts3ExprInitTestInterface(sqlite3 *db); |
| +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*); |
| int sqlite3Fts3InitTerm(sqlite3 *db); |
| #endif |
| |
| --- /ext/fts3/fts3_expr.c |
| +++ /ext/fts3/fts3_expr.c |
| @@ -1109,34 +1109,6 @@ |
| #include <stdio.h> |
| |
| /* |
| -** Function to query the hash-table of tokenizers (see README.tokenizers). |
| -*/ |
| -static int queryTestTokenizer( |
| - sqlite3 *db, |
| - const char *zName, |
| - const sqlite3_tokenizer_module **pp |
| -){ |
| - int rc; |
| - sqlite3_stmt *pStmt; |
| - const char zSql[] = "SELECT fts3_tokenizer(?)"; |
| - |
| - *pp = 0; |
| - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
| - if( rc!=SQLITE_OK ){ |
| - return rc; |
| - } |
| - |
| - sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); |
| - if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| - if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){ |
| - memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); |
| - } |
| - } |
| - |
| - return sqlite3_finalize(pStmt); |
| -} |
| - |
| -/* |
| ** Return a pointer to a buffer containing a text representation of the |
| ** expression passed as the first argument. The buffer is obtained from |
| ** sqlite3_malloc(). It is the responsibility of the caller to use |
| @@ -1203,12 +1175,12 @@ |
| ** |
| ** SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2'); |
| */ |
| -static void fts3ExprTest( |
| +static void fts3ExprTestCommon( |
| + int bRebalance, |
| sqlite3_context *context, |
| int argc, |
| sqlite3_value **argv |
| ){ |
| - sqlite3_tokenizer_module const *pModule = 0; |
| sqlite3_tokenizer *pTokenizer = 0; |
| int rc; |
| char **azCol = 0; |
| @@ -1218,7 +1190,9 @@ |
| int ii; |
| Fts3Expr *pExpr; |
| char *zBuf = 0; |
| - sqlite3 *db = sqlite3_context_db_handle(context); |
| + Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context); |
| + const char *zTokenizer = 0; |
| + char *zErr = 0; |
| |
| if( argc<3 ){ |
| sqlite3_result_error(context, |
| @@ -1227,23 +1201,17 @@ |
| return; |
| } |
| |
| - rc = queryTestTokenizer(db, |
| - (const char *)sqlite3_value_text(argv[0]), &pModule); |
| - if( rc==SQLITE_NOMEM ){ |
| - sqlite3_result_error_nomem(context); |
| - goto exprtest_out; |
| - }else if( !pModule ){ |
| - sqlite3_result_error(context, "No such tokenizer module", -1); |
| - goto exprtest_out; |
| - } |
| - |
| - rc = pModule->xCreate(0, 0, &pTokenizer); |
| - assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); |
| - if( rc==SQLITE_NOMEM ){ |
| - sqlite3_result_error_nomem(context); |
| - goto exprtest_out; |
| + zTokenizer = (const char*)sqlite3_value_text(argv[0]); |
| + rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr); |
| + if( rc!=SQLITE_OK ){ |
| + if( rc==SQLITE_NOMEM ){ |
| + sqlite3_result_error_nomem(context); |
| + }else{ |
| + sqlite3_result_error(context, zErr, -1); |
| + } |
| + sqlite3_free(zErr); |
| + return; |
| } |
| - pTokenizer->pModule = pModule; |
| |
| zExpr = (const char *)sqlite3_value_text(argv[1]); |
| nExpr = sqlite3_value_bytes(argv[1]); |
| @@ -1257,7 +1225,7 @@ |
| azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]); |
| } |
| |
| - if( sqlite3_user_data(context) ){ |
| + if( bRebalance ){ |
| char *zDummy = 0; |
| rc = sqlite3Fts3ExprParse( |
| pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy |
| @@ -1283,23 +1251,38 @@ |
| sqlite3Fts3ExprFree(pExpr); |
| |
| exprtest_out: |
| - if( pModule && pTokenizer ){ |
| - rc = pModule->xDestroy(pTokenizer); |
| + if( pTokenizer ){ |
| + rc = pTokenizer->pModule->xDestroy(pTokenizer); |
| } |
| sqlite3_free(azCol); |
| } |
| |
| +static void fts3ExprTest( |
| + sqlite3_context *context, |
| + int argc, |
| + sqlite3_value **argv |
| +){ |
| + fts3ExprTestCommon(0, context, argc, argv); |
| +} |
| +static void fts3ExprTestRebalance( |
| + sqlite3_context *context, |
| + int argc, |
| + sqlite3_value **argv |
| +){ |
| + fts3ExprTestCommon(1, context, argc, argv); |
| +} |
| + |
| /* |
| ** Register the query expression parser test function fts3_exprtest() |
| ** with database connection db. |
| */ |
| -int sqlite3Fts3ExprInitTestInterface(sqlite3* db){ |
| +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){ |
| int rc = sqlite3_create_function( |
| - db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0 |
| + db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0 |
| ); |
| if( rc==SQLITE_OK ){ |
| rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", |
| - -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0 |
| + -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0 |
| ); |
| } |
| return rc; |
| --- /test/fts3expr.test |
| +++ /test/fts3expr.test |
| @@ -409,7 +409,7 @@ |
| } {1 {Usage: fts3_exprtest(tokenizer, expr, col1, ...}} |
| do_test fts3expr-5.2 { |
| catchsql { SELECT fts3_exprtest('doesnotexist', 'a b', 'c') } |
| -} {1 {No such tokenizer module}} |
| +} {1 {unknown tokenizer: doesnotexist}} |
| do_test fts3expr-5.3 { |
| catchsql { SELECT fts3_exprtest('simple', 'a b OR', 'c') } |
| } {1 {Error parsing expression}} |
| --- /test/fts3expr4.test |
| +++ /test/fts3expr4.test |
| @@ -29,7 +29,8 @@ |
| } |
| |
| proc do_icu_expr_test {tn expr res} { |
| - uplevel [list do_test $tn [list test_fts3expr icu $expr] [list {*}$res]] |
| + set res2 [list {*}$res] |
| + uplevel [list do_test $tn [list test_fts3expr "icu en_US" $expr] $res2] |
| } |
| |
| proc do_simple_expr_test {tn expr res} { |
| --- /test/zipfile2.test |
| +++ /test/zipfile2.test |
| @@ -52,17 +52,15 @@ |
| CREATE VIRTUAL TABLE fff USING zipfile('test''zip'); |
| } |
| |
| -if {$::tcl_platform(platform)=="windows"} { |
| - set res {1 {cannot open file: testdir}} |
| -} else { |
| - set res {1 {error in fread()}} |
| -} |
| do_test 2.0 { |
| forcedelete testdir |
| file mkdir testdir |
| execsql { CREATE VIRTUAL TABLE hhh USING zipfile('testdir') } |
| - catchsql { SELECT * FROM hhh } |
| -} $res |
| + lindex [catchsql { |
| + SELECT * FROM hhh; |
| + INSERT INTO hhh(name, data) VALUES('1.txt', 'file data'); |
| + }] 0 |
| +} 1 |
| |
| |
| set archive { |