From 788ade3487252c4de2da94a2b8f9ec7ebdd83c95 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 8 May 2024 17:42:13 +0000 Subject: [PATCH 1/7] Allow arbitrary expressions as the second argument to RAISE(). FossilOrigin-Name: 003e1c8c27824cb917b3869bdf9000f32ff0b6887a2aff8516712cfe865cf34d --- manifest | 27 +++++++++++++++------------ manifest.uuid | 2 +- src/expr.c | 9 ++++----- src/fkey.c | 3 ++- src/parse.y | 4 ++-- src/treeview.c | 3 ++- src/vdbe.c | 26 +++++++++++++++++++------- test/colname.test | 2 +- test/trigger1.test | 13 +++++++++++++ 9 files changed, 59 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index 32bc04aaf5..2c7cfc8e18 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\shyperlink\stypo\sin\ssession\sdocumentation. -D 2024-05-08T11:51:56.927 +C Allow\sarbitrary\sexpressions\sas\sthe\ssecond\sargument\sto\sRAISE(). +D 2024-05-08T17:42:13.761 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -703,9 +703,9 @@ F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875 F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782 F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43 F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 -F src/expr.c 3428b046cb731be83770eaa34317d0ae5bdf8f5e7c3a0abd57528d0a03a8f9f9 +F src/expr.c dff4775b9aa9e6a397b37dda601207c6c0024df8cb5ec43e66fd07f5efd9bd6c F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00 +F src/fkey.c 852f93c0ef995e0c2b8983059a2b97151c194cc8259e21f5bc2b7ac508348c2a F src/func.c 283d4f3b2751a1d9339fd93a8a013d1948fd5f4474a3cab0955eb4fafd445d0f F src/global.c 61a419dd9e993b9be0f91de4c4ccf322b053eb829868e089f0321dd669be3b90 F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 @@ -742,7 +742,7 @@ F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9beb80f6e330dd63c5d8ba0f7a7f3a55fff22067a68d424949c389bfc6fa0c56 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y 50516253433303673ff6b009983bb246d1527415e5a9af22acc51b0eedb9a10d +F src/parse.y de2da0ffd33f6532c1640e7c6a6c6d8ac5ae85b0dbb0b1d7c3194d243a4c1e6a F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00 @@ -816,14 +816,14 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68 -F src/treeview.c 4f9ba6c1c7c9893fc046fdb0bc1f6bdec7660122b1ae37e51fb9b64c286caafd +F src/treeview.c 5538cc0e88cb87c55e26326c7a02d5fe45deaeb2edbd5436af7a674ed6491ff2 F src/trigger.c 0858f75818ed1580332db274f1032bcc5effe567cb132df5c5be8b1d800ca97f F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7 F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65 F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e F src/util.c 4d6d7ebfe6772a1b950c97bbb1d1a72ad4874617ec498ab8aa73b7f5a43e44bb F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104 -F src/vdbe.c 3b1793c5d2235ae89b01ef051a33d7d2ad3704c71799653b112686735ad401ff +F src/vdbe.c 2fdfe0535fa517fb4590144121c040c5703db318e7479d6d62ba6ab2e699e001 F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df @@ -997,7 +997,7 @@ F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 -F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e +F test/colname.test 387e880eeac0889900f7b3e9703c375515f5d323f71fd4f2bb5428a4ac8e2023 F test/columncount.test 6fe99c2f35738b0129357a1cf3fa483f76140f4cd8a89014c88c33c876d2638f F test/conflict.test b705cddf025a675d3c13d62fa78ab1e2696fb8e07a3d7cccce1596ff8b301492 F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1 @@ -1866,7 +1866,7 @@ F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f4 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a -F test/trigger1.test 02cc64dc98278816c1c1ed8e472e18db8edbad88f37018bf46223e9614831963 +F test/trigger1.test 2834f8830a1ae338d95c2e3ea0c2a7bc4cda126cdeb715004cf0fd071892e44f F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 @@ -2189,8 +2189,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e29decb8b1991bb586f41fd74bbaa4d6c4bd63e22617145828b2500d697d7869 -R bd6c2a6994b109d4181b29475acc71ca +P 42d67c6fed3a5f21d7b71515aca471ba61d387e620022735a2e7929fa3a237cf +R 2f3bd2a16acd125a41b6775ce57250d9 +T *branch * enhanced-raise +T *sym-enhanced-raise * +T -sym-trunk * U drh -Z b1677682f99b4b1ca04906a7901df3be +Z 0fd130dec139b10d531d7d8015ffe4ed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d0915126d9..6014fe7714 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42d67c6fed3a5f21d7b71515aca471ba61d387e620022735a2e7929fa3a237cf \ No newline at end of file +003e1c8c27824cb917b3869bdf9000f32ff0b6887a2aff8516712cfe865cf34d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a5272df7c9..2157cf4ed8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5306,15 +5306,14 @@ expr_code_doover: } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ - sqlite3VdbeAddOp4( - v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, OE_Ignore); VdbeCoverage(v); }else{ - sqlite3HaltConstraint(pParse, + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp3(v, OP_Halt, pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR, - pExpr->affExpr, pExpr->u.zToken, 0, 0); + pExpr->affExpr, r1); } - break; } #endif diff --git a/src/fkey.c b/src/fkey.c index bace1ae5e2..1efdc0bba1 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1328,7 +1328,8 @@ static Trigger *fkActionTrigger( SrcList *pSrc; Expr *pRaise; - pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); + pRaise = sqlite3Expr(db, TK_STRING, "FOREIGN KEY constraint failed"), + pRaise = sqlite3PExpr(pParse, TK_RAISE, pRaise, 0); if( pRaise ){ pRaise->affExpr = OE_Abort; } diff --git a/src/parse.y b/src/parse.y index 071e10abd4..90277f9c0c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1658,8 +1658,8 @@ expr(A) ::= RAISE LP IGNORE RP. { A->affExpr = OE_Ignore; } } -expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. { - A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1); +expr(A) ::= RAISE LP raisetype(T) COMMA expr(Z) RP. { + A = sqlite3PExpr(pParse, TK_RAISE, Z, 0); if( A ) { A->affExpr = (char)T; } diff --git a/src/treeview.c b/src/treeview.c index d3346b4686..586106cada 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -818,7 +818,8 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ case OE_Ignore: zType = "ignore"; break; } assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); + sqlite3TreeViewLine(pView, "RAISE %s", zType); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } #endif diff --git a/src/vdbe.c b/src/vdbe.c index d8b471de2e..f06a71da40 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1214,7 +1214,7 @@ case OP_HaltIfNull: { /* in3 */ /* no break */ deliberate_fall_through } -/* Opcode: Halt P1 P2 * P4 P5 +/* Opcode: Halt P1 P2 P3 P4 P5 ** ** Exit immediately. All open cursors, etc are closed ** automatically. @@ -1227,18 +1227,22 @@ case OP_HaltIfNull: { /* in3 */ ** then back out all changes that have occurred during this execution of the ** VDBE, but do not rollback the transaction. ** -** If P4 is not null then it is an error message string. +** If P3 is not zero and P4 is NULL, then P3 is a register that holds the +** text of an error message. ** -** P5 is a value between 0 and 4, inclusive, that modifies the P4 string. +** If P3 is zero and P4 is not null then the error message string is held +** in P4. +** +** P5 is a value between 1 and 4, inclusive, then the P4 error message +** string is modified as follows: ** -** 0: (no change) ** 1: NOT NULL constraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 ** -** If P5 is not zero and P4 is NULL, then everything after the ":" is -** omitted. +** If P3 is zero and P5 is not zero and P4 is NULL, then everything after +** the ":" is omitted. ** ** There is an implied "Halt 0 0 0" instruction inserted at the very end of ** every program. So a jump past the last instruction of the program @@ -1251,6 +1255,9 @@ case OP_Halt: { #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif + assert( pOp->p4type==P4_NOTUSED + || pOp->p4type==P4_STATIC + || pOp->p4type==P4_DYNAMIC ); /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates ** something is wrong with the code generator. Raise an assertion in order @@ -1281,7 +1288,12 @@ case OP_Halt: { p->errorAction = (u8)pOp->p2; assert( pOp->p5<=4 ); if( p->rc ){ - if( pOp->p5 ){ + if( pOp->p3>0 && pOp->p4type==P4_NOTUSED ){ + const char *zErr; + assert( pOp->p3<=(p->nMem + 1 - p->nCursor) ); + zErr = sqlite3ValueText(&aMem[pOp->p3], SQLITE_UTF8); + sqlite3VdbeError(p, "%s", zErr); + }else if( pOp->p5 ){ static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK", "FOREIGN KEY" }; testcase( pOp->p5==1 ); diff --git a/test/colname.test b/test/colname.test index 5fa0b601f9..24fb51acfc 100644 --- a/test/colname.test +++ b/test/colname.test @@ -424,7 +424,7 @@ do_catchsql_test colname-9.400 { # do_catchsql_test colname-9.410 { CREATE TABLE t5 AS SELECT RAISE(abort,a); -} {1 {RAISE() may only be used within a trigger-program}} +} {1 {no such column: a}} # Make sure the quotation marks get removed from the column names # when constructing a new table from an aggregate SELECT. diff --git a/test/trigger1.test b/test/trigger1.test index 6de121fa9c..afeb7ddccb 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -838,4 +838,17 @@ do_catchsql_test trigger1-23.1 { END; } {1 {near "#1": syntax error}} +# 2024-05-08 Allow arbitrary expressions as the 2nd argument to RAISE(). +# +do_catchsql_test trigger1-24.1 { + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + SELECT raise(abort,format('attempt to insert %d where is not a power of 2',new.a)) + WHERE (new.a & (new.a-1))!=0; + END; + INSERT INTO t1 VALUES(0),(1),(2),(4),(8),(65536); +} {0 {}} +do_catchsql_test trigger1-24.2 { + INSERT INTO t1 VALUES(9876); +} {1 {attempt to insert 9876 where is not a power of 2}} + finish_test From 4f59d0964869e27daca41035125759e96142bc19 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 12 May 2024 00:26:08 +0000 Subject: [PATCH 2/7] Optimization in the implementation of OP_OpenRead and OP_OpenWrite FossilOrigin-Name: 3a256a1667b15702dc5048fdf2fdba9c1e551106ce8cf391360f156fab35ecc5 --- manifest | 16 +++++++++------- manifest.uuid | 2 +- src/vdbe.c | 30 +++++++++++++++--------------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index eceb5d9184..3cb7a0d73a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\saggregate\sfunction\sprocessing\sto\scorrectly\sdeal\swith\sOOMs\sinside\sof\nsqlite3ParserAddCleanup().\s\n(dbsqlfuzz\sb2d11ca70e55ee8bde48ae0b53fa3e9355812f95).\nAlso\sadd\simproved\stesting\ssupport\sby\scausing\ssqlite3FaultSim(300)\sto\nsimulate\san\sOOM\sinside\sof\ssqlite3ParserAddCleanup()\sand\sby\sadding\nimproved\sfault-sim\ssupport\sto\sthe\sCLI. -D 2024-05-10T18:24:15.938 +C Optimization\sin\sthe\simplementation\sof\sOP_OpenRead\sand\sOP_OpenWrite +D 2024-05-12T00:26:08.975 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -823,7 +823,7 @@ F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65 F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e F src/util.c 4d6d7ebfe6772a1b950c97bbb1d1a72ad4874617ec498ab8aa73b7f5a43e44bb F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104 -F src/vdbe.c 3b1793c5d2235ae89b01ef051a33d7d2ad3704c71799653b112686735ad401ff +F src/vdbe.c cddb27d049602441e635e5301d5c6301af287fd8298fa3cfd71fbd4497c80364 F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df @@ -2190,9 +2190,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1d6716054d7fc50df237996c3db30e5fb8e32acbf48cb8b9af472360515945c4 716088d673b80446ea5f9cb83f6aad8a9ea2ec769d4894e02ab916930e4cf169 -R 19835e40d33408ef0911b62a1ca97162 -T +closed 716088d673b80446ea5f9cb83f6aad8a9ea2ec769d4894e02ab916930e4cf169 +P c6fd70b3c23fa00eaac9286d4a67e5c8ac76f926c11c220250c34032647bedc1 +R 94b8709f5c282eb8bc9897cb13e98353 +T *branch * faster-openread +T *sym-faster-openread * +T -sym-trunk * U drh -Z 7c60328ccced7c5397c63b972a68b6fa +Z 9b80a9cf5df794917ed8b64261d9c345 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b3549e902d..d67b982a54 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6fd70b3c23fa00eaac9286d4a67e5c8ac76f926c11c220250c34032647bedc1 \ No newline at end of file +3a256a1667b15702dc5048fdf2fdba9c1e551106ce8cf391360f156fab35ecc5 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index d8b471de2e..257c319c7e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4324,23 +4324,23 @@ case OP_OpenWrite: if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; } + if( pOp->p5 & OPFLAG_P2ISREG ){ + assert( p2>0 ); + assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); + pIn2 = &aMem[p2]; + assert( memIsValid(pIn2) ); + assert( (pIn2->flags & MEM_Int)!=0 ); + sqlite3VdbeMemIntegerify(pIn2); + p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateBtree opcode and + ** that opcode will always set the p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + assert( p2>=2 ); + } }else{ wrFlag = 0; - } - if( pOp->p5 & OPFLAG_P2ISREG ){ - assert( p2>0 ); - assert( p2<=(u32)(p->nMem+1 - p->nCursor) ); - assert( pOp->opcode==OP_OpenWrite ); - pIn2 = &aMem[p2]; - assert( memIsValid(pIn2) ); - assert( (pIn2->flags & MEM_Int)!=0 ); - sqlite3VdbeMemIntegerify(pIn2); - p2 = (int)pIn2->u.i; - /* The p2 value always comes from a prior OP_CreateBtree opcode and - ** that opcode will always set the p2 value to 2 or more or else fail. - ** If there were a failure, the prepared statement would have halted - ** before reaching this instruction. */ - assert( p2>=2 ); + assert( (pOp->p5 & OPFLAG_P2ISREG)==0 ); } if( pOp->p4type==P4_KEYINFO ){ pKeyInfo = pOp->p4.pKeyInfo; From 12b205c637804c43cd9c991d8583085a523698b4 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 13 May 2024 20:06:08 +0000 Subject: [PATCH 3/7] Allow existing fts5 tables to be dropped even if the associated tokenizer is not available. FossilOrigin-Name: 69ef47eeee8b53684c321393be34f03600694fbc86377f8720ff80307846aff6 --- ext/fts5/fts5Int.h | 22 ++++++------ ext/fts5/fts5_config.c | 58 +++++++++++++------------------- ext/fts5/fts5_main.c | 46 ++++++++++++++++++------- ext/fts5/test/fts5tokenizer.test | 43 +++++++++++++++++++++++ ext/fts5/test/fts5trigram2.test | 13 ++++++- manifest | 23 +++++++------ manifest.uuid | 2 +- 7 files changed, 139 insertions(+), 68 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 9beb26e056..f1a02c1841 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -142,6 +142,15 @@ struct Fts5Colset { */ typedef struct Fts5Config Fts5Config; +typedef struct Fts5TokenizerConfig Fts5TokenizerConfig; + +struct Fts5TokenizerConfig { + Fts5Tokenizer *pTok; + fts5_tokenizer *pTokApi; + const char **azArg; + int nArg; + int ePattern; /* FTS_PATTERN_XXX constant */ +}; /* ** An instance of the following structure encodes all information that can @@ -184,6 +193,7 @@ typedef struct Fts5Config Fts5Config; */ struct Fts5Config { sqlite3 *db; /* Database handle */ + Fts5Global *pGlobal; /* Global fts5 object for handle db */ char *zDb; /* Database holding FTS index (e.g. "main") */ char *zName; /* Name of FTS index */ int nCol; /* Number of columns */ @@ -199,10 +209,8 @@ struct Fts5Config { int bTokendata; /* "tokendata=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; - Fts5Tokenizer *pTok; - fts5_tokenizer *pTokApi; + Fts5TokenizerConfig t; int bLock; /* True when table is preparing statement */ - int ePattern; /* FTS_PATTERN_XXX constant */ /* Values loaded from the %_config table */ int iVersion; /* fts5 file format 'version' */ @@ -597,13 +605,7 @@ struct Fts5Table { Fts5Index *pIndex; /* Full-text index */ }; -int sqlite3Fts5GetTokenizer( - Fts5Global*, - const char **azArg, - int nArg, - Fts5Config*, - char **pzErr -); +int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig); Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index d2e8309cd2..32f52a6cab 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -298,12 +298,11 @@ static int fts5ConfigParseSpecial( if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; sqlite3_int64 nArg = strlen(zArg) + 1; - char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); - char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); - char *pSpace = pDel; + char **azArg = sqlite3Fts5MallocZero(&rc, (sizeof(char*) + 2) * nArg); - if( azArg && pSpace ){ - if( pConfig->pTok ){ + if( azArg ){ + char *pSpace = (char*)&azArg[nArg]; + if( pConfig->t.azArg ){ *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); rc = SQLITE_ERROR; }else{ @@ -326,16 +325,14 @@ static int fts5ConfigParseSpecial( *pzErr = sqlite3_mprintf("parse error in tokenize directive"); rc = SQLITE_ERROR; }else{ - rc = sqlite3Fts5GetTokenizer(pGlobal, - (const char**)azArg, (int)nArg, pConfig, - pzErr - ); + pConfig->t.azArg = (const char**)azArg; + pConfig->t.nArg = nArg; + azArg = 0; } } } - sqlite3_free(azArg); - sqlite3_free(pDel); + return rc; } @@ -412,16 +409,6 @@ static int fts5ConfigParseSpecial( return SQLITE_ERROR; } -/* -** Allocate an instance of the default tokenizer ("simple") at -** Fts5Config.pTokenizer. Return SQLITE_OK if successful, or an SQLite error -** code if an error occurs. -*/ -static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ - assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); - return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0); -} - /* ** Gobble up the first bareword or quoted word from the input buffer zIn. ** Return a pointer to the character immediately following the last in @@ -554,6 +541,7 @@ int sqlite3Fts5ConfigParse( *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); + pRet->pGlobal = pGlobal; pRet->db = db; pRet->iCookie = -1; @@ -640,13 +628,6 @@ int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; } - /* If a tokenizer= option was successfully parsed, the tokenizer has - ** already been allocated. Otherwise, allocate an instance of the default - ** tokenizer (unicode61) now. */ - if( rc==SQLITE_OK && pRet->pTok==0 ){ - rc = fts5ConfigDefaultTokenizer(pGlobal, pRet); - } - /* If no zContent option was specified, fill in the default values. */ if( rc==SQLITE_OK && pRet->zContent==0 ){ const char *zTail = 0; @@ -688,9 +669,10 @@ int sqlite3Fts5ConfigParse( void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; - if( pConfig->pTok ){ - pConfig->pTokApi->xDelete(pConfig->pTok); + if( pConfig->t.pTok ){ + pConfig->t.pTokApi->xDelete(pConfig->t.pTok); } + sqlite3_free(pConfig->t.azArg); sqlite3_free(pConfig->zDb); sqlite3_free(pConfig->zName); for(i=0; inCol; i++){ @@ -765,10 +747,18 @@ int sqlite3Fts5Tokenize( void *pCtx, /* Context passed to xToken() */ int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ){ - if( pText==0 ) return SQLITE_OK; - return pConfig->pTokApi->xTokenize( - pConfig->pTok, pCtx, flags, pText, nText, xToken - ); + int rc = SQLITE_OK; + if( pText ){ + if( pConfig->t.pTok==0 ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } + if( rc==SQLITE_OK ){ + rc = pConfig->t.pTokApi->xTokenize( + pConfig->t.pTok, pCtx, flags, pText, nText, xToken + ); + } + } + return rc; } /* diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index f609f7f34a..0155a27f4c 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -377,8 +377,12 @@ static int fts5InitVtab( assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ + pConfig->pzErrmsg = pzErr; pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; + if( bCreate ){ + rc = sqlite3Fts5LoadTokenizer(pConfig); + } } /* Open the index sub-system */ @@ -400,11 +404,8 @@ static int fts5InitVtab( /* Load the initial configuration */ if( rc==SQLITE_OK ){ - assert( pConfig->pzErrmsg==0 ); - pConfig->pzErrmsg = pzErr; rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); sqlite3Fts5IndexRollback(pTab->p.pIndex); - pConfig->pzErrmsg = 0; } if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -414,6 +415,7 @@ static int fts5InitVtab( rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } + if( pConfig ) pConfig->pzErrmsg = 0; if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; @@ -481,10 +483,10 @@ static int fts5UsePatternMatch( ){ assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); - if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ + if( pConfig->t.ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ return 1; } - if( pConfig->ePattern==FTS5_PATTERN_LIKE + if( pConfig->t.ePattern==FTS5_PATTERN_LIKE && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) ){ return 1; @@ -584,6 +586,14 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ return SQLITE_ERROR; } + if( pConfig->t.pTok==0 ){ + int rc; + pConfig->pzErrmsg = &pVTab->zErrMsg; + rc = sqlite3Fts5LoadTokenizer(pConfig); + pConfig->pzErrmsg = 0; + if( rc!=SQLITE_OK ) return rc; + } + idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1); if( idxStr==0 ) return SQLITE_NOMEM; pInfo->idxStr = idxStr; @@ -626,6 +636,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ idxStr += strlen(&idxStr[iIdxStr]); pInfo->aConstraintUsage[i].argvIndex = ++iCons; assert( idxStr[iIdxStr]=='\0' ); + bSeenMatch = 1; }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ idxStr[iIdxStr++] = '='; bSeenEq = 1; @@ -2860,7 +2871,7 @@ static int fts5FindTokenizer( return rc; } -int sqlite3Fts5GetTokenizer( +int fts5GetTokenizer( Fts5Global *pGlobal, const char **azArg, int nArg, @@ -2877,26 +2888,37 @@ int sqlite3Fts5GetTokenizer( *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ rc = pMod->x.xCreate( - pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok + pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->t.pTok ); - pConfig->pTokApi = &pMod->x; + pConfig->t.pTokApi = &pMod->x; if( rc!=SQLITE_OK ){ if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor"); }else{ - pConfig->ePattern = sqlite3Fts5TokenizerPattern( - pMod->x.xCreate, pConfig->pTok + pConfig->t.ePattern = sqlite3Fts5TokenizerPattern( + pMod->x.xCreate, pConfig->t.pTok ); } } if( rc!=SQLITE_OK ){ - pConfig->pTokApi = 0; - pConfig->pTok = 0; + pConfig->t.pTokApi = 0; + pConfig->t.pTok = 0; } return rc; } +/* +** Attempt to instantiate the tokenizer. +*/ +int sqlite3Fts5LoadTokenizer(Fts5Config *pConfig){ + return fts5GetTokenizer( + pConfig->pGlobal, pConfig->t.azArg, pConfig->t.nArg, + pConfig, pConfig->pzErrmsg + ); +} + + static void fts5ModuleDestroy(void *pCtx){ Fts5TokenizerModule *pTok, *pNextTok; Fts5Auxiliary *pAux, *pNextAux; diff --git a/ext/fts5/test/fts5tokenizer.test b/ext/fts5/test/fts5tokenizer.test index 27370657ed..f469a98888 100644 --- a/ext/fts5/test/fts5tokenizer.test +++ b/ext/fts5/test/fts5tokenizer.test @@ -300,5 +300,48 @@ set ::flags [list] do_execsql_test 9.5.1 { SELECT * FROM t1('"abc xyz*"'); } {} do_test 9.5.2 { set ::flags } {query} +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 10.1 { + CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize=unicode61); + PRAGMA writable_schema = 1; + UPDATE sqlite_schema + SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize="unicode61 error");' + WHERE name = 'x1'; +} + +db close +sqlite3 db test.db + +do_catchsql_test 10.2 { + SELECT * FROM x1 +} {1 {error in tokenizer constructor}} + +do_catchsql_test 10.3 { + INSERT INTO x1 VALUES('abc'); +} {1 {error in tokenizer constructor}} + +do_execsql_test 10.4 { + PRAGMA writable_schema = 1; + UPDATE sqlite_schema + SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize="nosuch error");' + WHERE name = 'x1'; +} + +db close +sqlite3 db test.db + +do_catchsql_test 10.5 { + SELECT * FROM x1 +} {1 {no such tokenizer: nosuch}} +do_catchsql_test 10.6 { + INSERT INTO x1 VALUES('abc'); +} {1 {no such tokenizer: nosuch}} + +do_execsql_test 10.7 { + DROP TABLE x1; + SELECT * FROM sqlite_schema; +} finish_test diff --git a/ext/fts5/test/fts5trigram2.test b/ext/fts5/test/fts5trigram2.test index f5beae5b28..00f6d43952 100644 --- a/ext/fts5/test/fts5trigram2.test +++ b/ext/fts5/test/fts5trigram2.test @@ -101,9 +101,20 @@ do_execsql_test 4.0 { CREATE VIRTUAL TABLE t4 USING fts5(z, tokenize=trigram); } {} -breakpoint do_execsql_test 4.1 { INSERT INTO t4 VALUES('ABCD'); + INSERT INTO t4 VALUES('DEFG'); } {} +db close +sqlite3 db test.db + +do_eqp_test 4.1 { + SELECT rowid FROM t4 WHERE z LIKE '%abc%' +} {VIRTUAL TABLE INDEX 0:L0} + +do_execsql_test 4.2 { + SELECT rowid FROM t4 WHERE z LIKE '%abc%' +} {1} + finish_test diff --git a/manifest b/manifest index 1c2904f809..3c967f0f90 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\sbestindexC.test.\sNo\schanges\sto\scode. -D 2024-05-11T16:44:56.528 +C Allow\sexisting\sfts5\stables\sto\sbe\sdropped\seven\sif\sthe\sassociated\stokenizer\sis\snot\savailable. +D 2024-05-13T20:06:08.273 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -93,14 +93,14 @@ F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6d F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl bc3a0ca78be7d3df08e7602c00ca48021ebae40682d75eb001bfdf6e54ffb44e F ext/fts5/fts5.h 8856e11a5f0269cd346754cea0765efe8089635b80cad3222e8bfdb08cd5348a -F ext/fts5/fts5Int.h defa43c0932265138ee910ca416e6baccf8b774e0f3d610e74be1ab2880e9834 +F ext/fts5/fts5Int.h 965ded9eedfa4bbe6b39048d4b0cce804a13ec954f11a088d1205a48703ce03f F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 -F ext/fts5/fts5_config.c 8072a207034b51ae9b7694121d1b5715c794e94b275e088f70ae532378ca5cdf +F ext/fts5/fts5_config.c 74093394dc26750becc302922e5fe308a8597a70e6e83e66c892242952468163 F ext/fts5/fts5_expr.c e91156ebdcc08d837f4f324168f69f3c0d7fdef0e521fd561efb48ef3297b696 F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_index.c ee0f4d50bc0c58a7c5ef7d645e7e38e1e59315b8ea9d722ae00c5f949ee65379 -F ext/fts5/fts5_main.c d68bd9533d5a638b7f6fae61c3cb0a15257dcdcccedaf3d0b3c9f55940c85048 +F ext/fts5/fts5_main.c 942fea921d67f75f745d02bf383e5b949bf96a8b78bcfffca40f06439d252fae F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934 F ext/fts5/fts5_tcl.c fdf7e2bb9a9186cfcaf2d2ce11d338309342b7a7593c2812bc54455db53da5d2 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -227,10 +227,10 @@ F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074 F ext/fts5/test/fts5synonym2.test e2f6ff68c4fbe12a866a3a87510f553d9dac99bcb74c10b56487c4c0a562fcf5 F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 -F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43 +F ext/fts5/test/fts5tokenizer.test e5ff1fa93ae267592ad2280ae545133ac24d19cf44116c736e7ece9c02285b5b F ext/fts5/test/fts5tokenizer2.test cb5428c7cfb3b6a74b7adfcde65506e329112003e8dffa7501d01c2d18d02569 F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0 -F ext/fts5/test/fts5trigram2.test 9fe4207f8a4241747aff1005258b564958588d21bfd240d6cd4c2e955d31c156 +F ext/fts5/test/fts5trigram2.test c91f0a94f7e1ff859682228646abeab4c0eba2effc46af2cbc8f0f48b05a0566 F ext/fts5/test/fts5ubsan.test 783d5a8d13ebfa169e634940228db54540780e3ba7a87ad1e4510e61440bf64b F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602 F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9 @@ -2190,8 +2190,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c6fd70b3c23fa00eaac9286d4a67e5c8ac76f926c11c220250c34032647bedc1 -R da518a0d510ea768080aa36a2357bedd +P 58d938c0e03c3c8d8796c537f89e69734ba6263d60ba37e345259cb6fdffbea5 +R 8cd6e7131b6ecbfb841a3c6de5597a39 +T *branch * fts5-delay-tokenizer +T *sym-fts5-delay-tokenizer * +T -sym-trunk * U dan -Z 00211d5eb53202476ca10f2c5f60b56e +Z f97ec1a719d45c2730606c10145cb9ed # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1e5e1fe061..a91811beb8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -58d938c0e03c3c8d8796c537f89e69734ba6263d60ba37e345259cb6fdffbea5 \ No newline at end of file +69ef47eeee8b53684c321393be34f03600694fbc86377f8720ff80307846aff6 \ No newline at end of file From 32ca0dbcdff617fb4fe15a454191e74a8edce599 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 May 2024 17:16:09 +0000 Subject: [PATCH 4/7] Have fts5 tables delay initializing the tokenizer until it is first used in all cases where the tokenizer is not "trigram". FossilOrigin-Name: ca4fdcb8ae95d2a61236b949f852d2bf25ea2dbbff7eedafbd8eb84e8fd96687 --- ext/fts5/fts5Int.h | 1 + ext/fts5/fts5_expr.c | 2 +- ext/fts5/fts5_main.c | 10 +--------- ext/fts5/fts5_tokenize.c | 10 ++++++++++ ext/fts5/fts5_vocab.c | 2 +- ext/fts5/test/fts5tokenizer.test | 31 +++++++++++++++++++++++++++++-- manifest | 25 +++++++++++-------------- manifest.uuid | 2 +- 8 files changed, 55 insertions(+), 28 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index f1a02c1841..0ed291c955 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -868,6 +868,7 @@ int sqlite3Fts5TokenizerPattern( int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), Fts5Tokenizer *pTok ); +int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig*); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 05c1b59c14..7180e22f8a 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -324,7 +324,7 @@ int sqlite3Fts5ExprNew( } sqlite3_free(sParse.apPhrase); - *pzErr = sParse.zErr; + if( 0==*pzErr ) *pzErr = sParse.zErr; return sParse.rc; } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 0155a27f4c..384fdc1c19 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -380,7 +380,7 @@ static int fts5InitVtab( pConfig->pzErrmsg = pzErr; pTab->p.pConfig = pConfig; pTab->pGlobal = pGlobal; - if( bCreate ){ + if( bCreate || sqlite3Fts5TokenizerPreload(&pConfig->t) ){ rc = sqlite3Fts5LoadTokenizer(pConfig); } } @@ -586,14 +586,6 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ return SQLITE_ERROR; } - if( pConfig->t.pTok==0 ){ - int rc; - pConfig->pzErrmsg = &pVTab->zErrMsg; - rc = sqlite3Fts5LoadTokenizer(pConfig); - pConfig->pzErrmsg = 0; - if( rc!=SQLITE_OK ) return rc; - } - idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1); if( idxStr==0 ) return SQLITE_NOMEM; pInfo->idxStr = idxStr; diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c index f12056170f..3e9fdff3eb 100644 --- a/ext/fts5/fts5_tokenize.c +++ b/ext/fts5/fts5_tokenize.c @@ -1428,6 +1428,16 @@ int sqlite3Fts5TokenizerPattern( return FTS5_PATTERN_NONE; } +/* +** Return true if the tokenizer described by p->azArg[] is the trigram +** tokenizer. This tokenizer needs to be loaded before xBestIndex is +** called for the first time in order to correctly handle LIKE/GLOB. +*/ +int sqlite3Fts5TokenizerPreload(Fts5TokenizerConfig *p){ + return (p->nArg>=1 && 0==sqlite3_stricmp(p->azArg[0], "trigram")); +} + + /* ** Register all built-in tokenizers with FTS5. */ diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 4782d0fb94..086ef42e09 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -365,7 +365,7 @@ static int fts5VocabOpenMethod( if( rc==SQLITE_OK ){ pVTab->zErrMsg = sqlite3_mprintf( "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl - ); + ); rc = SQLITE_ERROR; } }else{ diff --git a/ext/fts5/test/fts5tokenizer.test b/ext/fts5/test/fts5tokenizer.test index f469a98888..7497024dca 100644 --- a/ext/fts5/test/fts5tokenizer.test +++ b/ext/fts5/test/fts5tokenizer.test @@ -315,7 +315,7 @@ db close sqlite3 db test.db do_catchsql_test 10.2 { - SELECT * FROM x1 + SELECT * FROM x1('abc'); } {1 {error in tokenizer constructor}} do_catchsql_test 10.3 { @@ -333,7 +333,7 @@ db close sqlite3 db test.db do_catchsql_test 10.5 { - SELECT * FROM x1 + SELECT * FROM x1('abc'); } {1 {no such tokenizer: nosuch}} do_catchsql_test 10.6 { INSERT INTO x1 VALUES('abc'); @@ -344,4 +344,31 @@ do_execsql_test 10.7 { SELECT * FROM sqlite_schema; } +reset_db +do_execsql_test 10.8 { + CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize=unicode61); + INSERT INTO x1 VALUES('a b c'), ('d e f'), ('a b c'); + CREATE VIRTUAL TABLE x1v USING fts5vocab(x1, row); + + PRAGMA writable_schema = 1; + UPDATE sqlite_schema + SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(x, tokenize=simplify);' + WHERE name = 'x1'; +} + +do_execsql_test 10.9 { + SELECT * FROM x1v +} { + a 2 2 b 2 2 c 2 2 d 1 1 e 1 1 f 1 1 +} + +db close +sqlite3 db test.db + +do_execsql_test 10.10 { + SELECT * FROM x1v +} { + a 2 2 b 2 2 c 2 2 d 1 1 e 1 1 f 1 1 +} + finish_test diff --git a/manifest b/manifest index 3c967f0f90..e1799ea541 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sexisting\sfts5\stables\sto\sbe\sdropped\seven\sif\sthe\sassociated\stokenizer\sis\snot\savailable. -D 2024-05-13T20:06:08.273 +C Have\sfts5\stables\sdelay\sinitializing\sthe\stokenizer\suntil\sit\sis\sfirst\sused\sin\sall\scases\swhere\sthe\stokenizer\sis\snot\s"trigram". +D 2024-05-14T17:16:09.294 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -93,22 +93,22 @@ F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6d F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl bc3a0ca78be7d3df08e7602c00ca48021ebae40682d75eb001bfdf6e54ffb44e F ext/fts5/fts5.h 8856e11a5f0269cd346754cea0765efe8089635b80cad3222e8bfdb08cd5348a -F ext/fts5/fts5Int.h 965ded9eedfa4bbe6b39048d4b0cce804a13ec954f11a088d1205a48703ce03f +F ext/fts5/fts5Int.h 407ee36addad0ae6df5d37a811f0bd509ab6708b29640884ed5c7509e5f75143 F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 F ext/fts5/fts5_config.c 74093394dc26750becc302922e5fe308a8597a70e6e83e66c892242952468163 -F ext/fts5/fts5_expr.c e91156ebdcc08d837f4f324168f69f3c0d7fdef0e521fd561efb48ef3297b696 +F ext/fts5/fts5_expr.c a84df51a1d178fe38a89c0feb9ee6da3e5b98d204dde4d241fc8115464987d7a F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 F ext/fts5/fts5_index.c ee0f4d50bc0c58a7c5ef7d645e7e38e1e59315b8ea9d722ae00c5f949ee65379 -F ext/fts5/fts5_main.c 942fea921d67f75f745d02bf383e5b949bf96a8b78bcfffca40f06439d252fae +F ext/fts5/fts5_main.c dc6938b7233e9d88b3612fe2e88ce0a62130c43083be59beab8e6f01aa496689 F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934 F ext/fts5/fts5_tcl.c fdf7e2bb9a9186cfcaf2d2ce11d338309342b7a7593c2812bc54455db53da5d2 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b -F ext/fts5/fts5_tokenize.c 83cfcede3898001cab84432a36ce1503e3080cf9b1c682b022ec82e267ea4c13 +F ext/fts5/fts5_tokenize.c fa5493075101540270f572038fc1723d44fcc97bfbf237c8530013b8a27860be F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 -F ext/fts5/fts5_vocab.c 209e0c151e108d5f3621fa24b91e9b02f3750ee6c3f9ccec312df39481b68a09 +F ext/fts5/fts5_vocab.c 00a098ee63290d7f6e3711f14e56f0d77f3a7c07c0a3909843fcf9826aea5b5f F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 3378732aae2a7d9a4b9b5c40bde678d4259ca16bd490883325aecc4747bcb384 @@ -227,7 +227,7 @@ F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074 F ext/fts5/test/fts5synonym2.test e2f6ff68c4fbe12a866a3a87510f553d9dac99bcb74c10b56487c4c0a562fcf5 F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 -F ext/fts5/test/fts5tokenizer.test e5ff1fa93ae267592ad2280ae545133ac24d19cf44116c736e7ece9c02285b5b +F ext/fts5/test/fts5tokenizer.test abeb8b2d00415e5c8eae48d2dcb91357b7f7e1fddbb2b650f00b589a7bea9659 F ext/fts5/test/fts5tokenizer2.test cb5428c7cfb3b6a74b7adfcde65506e329112003e8dffa7501d01c2d18d02569 F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0 F ext/fts5/test/fts5trigram2.test c91f0a94f7e1ff859682228646abeab4c0eba2effc46af2cbc8f0f48b05a0566 @@ -2190,11 +2190,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 58d938c0e03c3c8d8796c537f89e69734ba6263d60ba37e345259cb6fdffbea5 -R 8cd6e7131b6ecbfb841a3c6de5597a39 -T *branch * fts5-delay-tokenizer -T *sym-fts5-delay-tokenizer * -T -sym-trunk * +P 69ef47eeee8b53684c321393be34f03600694fbc86377f8720ff80307846aff6 +R db8162066c5e98d7999ebd78f85cf216 U dan -Z f97ec1a719d45c2730606c10145cb9ed +Z 6313824362f7fdc689bb0b31fedc6732 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a91811beb8..ec9f975d50 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69ef47eeee8b53684c321393be34f03600694fbc86377f8720ff80307846aff6 \ No newline at end of file +ca4fdcb8ae95d2a61236b949f852d2bf25ea2dbbff7eedafbd8eb84e8fd96687 \ No newline at end of file From 433af7ab9384f30f862911fd803985b0416ad005 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 May 2024 19:09:54 +0000 Subject: [PATCH 5/7] Avoid calculating the value of the "cnt" column for fts5vocab(row) queries that do not use it. FossilOrigin-Name: c0c91e306c252ce1b398e92ab958e2a3de0fc43db05cfdffc548380654fc9f13 --- ext/fts5/fts5_vocab.c | 18 +++++++++++++----- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 086ef42e09..f0730ff389 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -64,6 +64,7 @@ struct Fts5VocabCursor { int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ + int colUsed; /* Copy of sqlite3_index_info.colUsed */ /* These are used by 'col' tables only */ int iCol; @@ -90,9 +91,11 @@ struct Fts5VocabCursor { /* ** Bits for the mask used as the idxNum value by xBestIndex/xFilter. */ -#define FTS5_VOCAB_TERM_EQ 0x01 -#define FTS5_VOCAB_TERM_GE 0x02 -#define FTS5_VOCAB_TERM_LE 0x04 +#define FTS5_VOCAB_TERM_EQ 0x0100 +#define FTS5_VOCAB_TERM_GE 0x0200 +#define FTS5_VOCAB_TERM_LE 0x0400 + +#define FTS5_VOCAB_COLUSED_MASK 0xFF /* @@ -269,11 +272,13 @@ static int fts5VocabBestIndexMethod( int iTermEq = -1; int iTermGe = -1; int iTermLe = -1; - int idxNum = 0; + int idxNum = (int)pInfo->colUsed; int nArg = 0; UNUSED_PARAM(pUnused); + assert( (pInfo->colUsed & FTS5_VOCAB_COLUSED_MASK)==pInfo->colUsed ); + for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; @@ -525,7 +530,9 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ switch( pTab->eType ){ case FTS5_VOCAB_ROW: - if( eDetail==FTS5_DETAIL_FULL ){ + /* Do not bother counting the number of instances if the "cnt" + ** column is not being read (according to colUsed). */ + if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ pCsr->aCnt[0]++; } @@ -625,6 +632,7 @@ static int fts5VocabFilterMethod( if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; + pCsr->colUsed = (idxNum & FTS5_VOCAB_COLUSED_MASK); if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq); diff --git a/manifest b/manifest index e1799ea541..e40addb45d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sfts5\stables\sdelay\sinitializing\sthe\stokenizer\suntil\sit\sis\sfirst\sused\sin\sall\scases\swhere\sthe\stokenizer\sis\snot\s"trigram". -D 2024-05-14T17:16:09.294 +C Avoid\scalculating\sthe\svalue\sof\sthe\s"cnt"\scolumn\sfor\sfts5vocab(row)\squeries\sthat\sdo\snot\suse\sit. +D 2024-05-14T19:09:54.416 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -108,7 +108,7 @@ F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a F ext/fts5/fts5_tokenize.c fa5493075101540270f572038fc1723d44fcc97bfbf237c8530013b8a27860be F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 -F ext/fts5/fts5_vocab.c 00a098ee63290d7f6e3711f14e56f0d77f3a7c07c0a3909843fcf9826aea5b5f +F ext/fts5/fts5_vocab.c faa8c6d8e0102037694165734a46b94d06f4460bde797af7486ed62c05764e35 F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 3378732aae2a7d9a4b9b5c40bde678d4259ca16bd490883325aecc4747bcb384 @@ -2190,8 +2190,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 69ef47eeee8b53684c321393be34f03600694fbc86377f8720ff80307846aff6 -R db8162066c5e98d7999ebd78f85cf216 +P ca4fdcb8ae95d2a61236b949f852d2bf25ea2dbbff7eedafbd8eb84e8fd96687 +R 17e05953d472a335ac30c411c88ba602 U dan -Z 6313824362f7fdc689bb0b31fedc6732 +Z 6157f839a4ddd69a6600b93afee6568d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ec9f975d50..125d507b0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca4fdcb8ae95d2a61236b949f852d2bf25ea2dbbff7eedafbd8eb84e8fd96687 \ No newline at end of file +c0c91e306c252ce1b398e92ab958e2a3de0fc43db05cfdffc548380654fc9f13 \ No newline at end of file From a0693f21fc90ece0061e7307b657d29fa37fb233 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 May 2024 19:41:19 +0000 Subject: [PATCH 6/7] Optimize queries against fts5vocab(row) tables that do use the "cnt" column. FossilOrigin-Name: 96a591c202cb4218999ece3de063bf466b6fd81bd23383893f3913ecb52dda36 --- ext/fts5/fts5_vocab.c | 12 ++++++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index f0730ff389..fb280567f4 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -533,8 +533,16 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ /* Do not bother counting the number of instances if the "cnt" ** column is not being read (according to colUsed). */ if( eDetail==FTS5_DETAIL_FULL && (pCsr->colUsed & 0x04) ){ - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - pCsr->aCnt[0]++; + while( iPosaCnt[] */ + pCsr->aCnt[0]++; + } } } pCsr->aDoc[0]++; diff --git a/manifest b/manifest index e40addb45d..ce12661dbc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\scalculating\sthe\svalue\sof\sthe\s"cnt"\scolumn\sfor\sfts5vocab(row)\squeries\sthat\sdo\snot\suse\sit. -D 2024-05-14T19:09:54.416 +C Optimize\squeries\sagainst\sfts5vocab(row)\stables\sthat\sdo\suse\sthe\s"cnt"\scolumn. +D 2024-05-14T19:41:19.118 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -108,7 +108,7 @@ F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a F ext/fts5/fts5_tokenize.c fa5493075101540270f572038fc1723d44fcc97bfbf237c8530013b8a27860be F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 -F ext/fts5/fts5_vocab.c faa8c6d8e0102037694165734a46b94d06f4460bde797af7486ed62c05764e35 +F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0 F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 3378732aae2a7d9a4b9b5c40bde678d4259ca16bd490883325aecc4747bcb384 @@ -2190,8 +2190,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ca4fdcb8ae95d2a61236b949f852d2bf25ea2dbbff7eedafbd8eb84e8fd96687 -R 17e05953d472a335ac30c411c88ba602 +P c0c91e306c252ce1b398e92ab958e2a3de0fc43db05cfdffc548380654fc9f13 +R c8ee37ea6d4a33968236083c174d19e7 U dan -Z 6157f839a4ddd69a6600b93afee6568d +Z 493cbd0a2ca537422c58bc5b9554c10a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 125d507b0d..84c463d5a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0c91e306c252ce1b398e92ab958e2a3de0fc43db05cfdffc548380654fc9f13 \ No newline at end of file +96a591c202cb4218999ece3de063bf466b6fd81bd23383893f3913ecb52dda36 \ No newline at end of file From 0445cd102020dd34c70364aef9c10249dcfd985d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 17 May 2024 13:56:38 +0000 Subject: [PATCH 7/7] Fix a problem in where.c preventing SQLite from identifying some ONEROW scans, leading to (slightly) sub-optimal byte-code. FossilOrigin-Name: b41e71208abcdf988f57c3fd7e6a372bbaf442c32a8e2c051beb8d45c8001e0f --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ea1aa1987f..1546c38dec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stests\sfor\sthe\serror\smessages\sgenerated\sby\ssqlite3_declare_vtab()\swhen\spassed\ssomething\sother\sthan\sa\swell-formed\sCREATE\sTABLE\sstatement. -D 2024-05-16T16:22:51.903 +C Fix\sa\sproblem\sin\swhere.c\spreventing\sSQLite\sfrom\sidentifying\ssome\sONEROW\sscans,\sleading\sto\s(slightly)\ssub-optimal\sbyte-code. +D 2024-05-17T13:56:38.514 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -839,7 +839,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 -F src/where.c d235ba520b0147f60732b3bd411e119b43be33d348251edaa6e304a8ad52c511 +F src/where.c 211c073b4295cf3087fca78d77aff8309cf6ec8267a510f38336080740fb3bb1 F src/whereInt.h 82a13766f13d1a53b05387c2e60726289ef26404bc7b9b1f7770204d97357fb8 F src/wherecode.c b9908c0a1aab095822a1e7032556bedc03b6d29641191e9ca535fb2307cd733d F src/whereexpr.c 67d15caf88a1a9528283d68ff578e024cf9fe810b517bb0343e5aaf695ad97dd @@ -2191,8 +2191,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1ec2961a0341619ae88832942b52606b3246fc0de07ca6da0300e4bfc656ecf0 -R 3e80a1a8d16383b10a9edc0a3a535e00 +P 5fa0c2a026f0467af3a76ea80cee8168b7a49553c350f642d1dff02ff9e7aeed +R 2eb5df88e143b963f30ca5abd4335fa3 +T *branch * fix-onerow-opt +T *sym-fix-onerow-opt * +T -sym-trunk * U dan -Z 4379dfd9de0672673743bdb6b799c4de +Z 4e3116b49700fa7a9c75b5f5cd140ab3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5851bda00f..d7af65ac77 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5fa0c2a026f0467af3a76ea80cee8168b7a49553c350f642d1dff02ff9e7aeed \ No newline at end of file +b41e71208abcdf988f57c3fd7e6a372bbaf442c32a8e2c051beb8d45c8001e0f \ No newline at end of file diff --git a/src/where.c b/src/where.c index 13a362dcca..07c5b9cf97 100644 --- a/src/where.c +++ b/src/where.c @@ -3170,7 +3170,7 @@ static int whereLoopAddBtreeIndex( || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ if( iCol==XN_ROWID || pProbe->uniqNotNull - || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) + || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ)) ){ pNew->wsFlags |= WHERE_ONEROW; }else{