From b163f66de0a153495970c952fdaafb0df05f739b Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 May 2025 17:46:34 +0000 Subject: [PATCH 01/35] Fix a goofy hash function in Lemon. No changes to SQLite itself. FossilOrigin-Name: d6cbabe23d3919d5bde6a83421cdae92125caec09d5c39a648d0305878c6a1dc --- manifest | 16 ++++++---------- manifest.uuid | 2 +- tool/lemon.c | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e40c550bc5..d60e438ca5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.50.0 -D 2025-05-29T14:26:00.000 +C Fix\sa\sgoofy\shash\sfunction\sin\sLemon.\s\sNo\schanges\sto\sSQLite\sitself. +D 2025-05-29T17:46:34.006 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -2143,7 +2143,7 @@ F tool/genfkey.README e550911fa984c8255ebed2ef97824125d83806eb5232582700de949edf F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a5a4f F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 -F tool/lemon.c 00535f27e61ae8200ba8402c1753483de39eef2f59b60da8b7951c458a32e017 +F tool/lemon.c d39ad5c209c2dc765fa2841ccfc4c54e656d3e6b645df91c8c8a94e81a1b1de5 F tool/lempar.c bdffd3b233a4e4e78056c9c01fadd2bb3fe902435abde3bce3d769fdf0d5cca2 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -2207,12 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f037ca064daeb81cb386da2a372d8e2d2dce55a3a13bc7bea4968ca51bf2843a -R fc3e14ac4195ac71d03a1c1ffcef6f5e -T +bgcolor * green -T +sym-major-release * -T +sym-release * -T +sym-version-3.50.0 * +P dfc790f998f450d9c35e3ba1c8c89c17466cb559f87b0239e4aab9d34e28f742 +R 00d562dd162741cb934f046e1395a93b U drh -Z 5eb6447fe81d0ef07434d8f3c30d7b86 +Z 2202324fba24e3c33bb1df72de3bd912 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 819b683fc3..45d7bb57a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfc790f998f450d9c35e3ba1c8c89c17466cb559f87b0239e4aab9d34e28f742 +d6cbabe23d3919d5bde6a83421cdae92125caec09d5c39a648d0305878c6a1dc diff --git a/tool/lemon.c b/tool/lemon.c index 795c3a2166..0aa6ff23a1 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -5925,7 +5925,7 @@ struct state **State_arrayof(void) PRIVATE unsigned confighash(struct config *a) { unsigned h=0; - h = h*571 + a->rp->index*37 + a->dot; + h = a->rp->index*37 + a->dot; return h; } From f429845a601114c559593f98d087f47a567e7dc4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 29 May 2025 18:44:41 +0000 Subject: [PATCH 02/35] Extend the fix for ticket [623eff57e76d45f6] so that it covers RIGHT JOIN in addition to LEFT JOIN. Problem reported by [forum:/forumpost/7dee41d32506c4ae|forum post 2025-05-29T15:10:14Z]. FossilOrigin-Name: 29b1e1b97619d03a97ef562a5707929e241d019179b4ff1d0bc2a8c008441431 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 9 +++++---- test/join.test | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d60e438ca5..13d7d037d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sgoofy\shash\sfunction\sin\sLemon.\s\sNo\schanges\sto\sSQLite\sitself. -D 2025-05-29T17:46:34.006 +C Extend\sthe\sfix\sfor\sticket\s[623eff57e76d45f6]\sso\sthat\sit\scovers\sRIGHT\sJOIN\nin\saddition\sto\sLEFT\sJOIN.\s\sProblem\sreported\sby\s\n[forum:/forumpost/7dee41d32506c4ae|forum\spost\s2025-05-29T15:10:14Z]. +D 2025-05-29T18:44:41.902 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -871,7 +871,7 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 45a3b496248a0b36d91ce34da3278d54f8fa20e9d3fbd36d45a42051d1118137 F src/whereInt.h ecdbfb5551cf394f04ec7f0bc7ad963146d80eee3071405ac29aa84950128b8e -F src/wherecode.c 8825756ea7b1a49ac830719d28557c638520bb2434fe9c2dd6c7f584034bfe32 +F src/wherecode.c 65670d1ef85ef54a4db3826d63be8b646c9ac280962166b645950901ed1bda29 F src/whereexpr.c 2415c8eee5ff89a8b709d7d83d71c1ff986cd720d0520057e1d8a5371339012a F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1361,7 +1361,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 5984da7bf74b6540aa356f2ab0c6ae68a6d12039a3d798a9ac6a100abc17d520 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test 0cc86e5fd579780b98cc01c9d6fc5b69f6ecc777f1c4daa501a14d1a74f56a6b +F test/join.test aca62194ad41b522c55577e0e1bd99da6d5436827225aa850801c36e5f4cc914 F test/join2.test f59d63264fb24784ae9c3bc9d867eb569cd6d442da5660f8852effe5c1938c27 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P dfc790f998f450d9c35e3ba1c8c89c17466cb559f87b0239e4aab9d34e28f742 -R 00d562dd162741cb934f046e1395a93b +P d6cbabe23d3919d5bde6a83421cdae92125caec09d5c39a648d0305878c6a1dc +R 28a9e68992443d1bb44866db16596344 U drh -Z 2202324fba24e3c33bb1df72de3bd912 +Z c4a3c019e57515755a30d30cb56ed7c7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 45d7bb57a3..a85c4fce99 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6cbabe23d3919d5bde6a83421cdae92125caec09d5c39a648d0305878c6a1dc +29b1e1b97619d03a97ef562a5707929e241d019179b4ff1d0bc2a8c008441431 diff --git a/src/wherecode.c b/src/wherecode.c index 95b12b77ae..8e3e56cb18 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2201,12 +2201,13 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pLevel->iLeftJoin==0 ){ /* If a partial index is driving the loop, try to eliminate WHERE clause ** terms from the query that must be true due to the WHERE clause of - ** the partial index. + ** the partial index. This optimization does not work on an outer join, + ** as shown by: ** - ** 2019-11-02 ticket 623eff57e76d45f6: This optimization does not work - ** for a LEFT JOIN. + ** 2019-11-02 ticket 623eff57e76d45f6 (LEFT JOIN) + ** 2025-05-29 forum post 7dee41d32506c4ae (RIGHT JOIN) */ - if( pIdx->pPartIdxWhere ){ + if( pIdx->pPartIdxWhere && pLevel->pRJ==0 ){ whereApplyPartialIndexConstraints(pIdx->pPartIdxWhere, iCur, pWC); } }else{ diff --git a/test/join.test b/test/join.test index b34136f5dd..ecd7bb2b5d 100644 --- a/test/join.test +++ b/test/join.test @@ -1002,6 +1002,21 @@ do_execsql_test join-20.2 { SELECT * FROM t0 LEFT JOIN t1 WHERE NULL IN (c1); } {} +# 2025-05-29 forum post 7dee41d32506c4ae +# The complaint in the forum post appears to be the same as for the +# ticket on 2019-11-02, only for RIGHT JOIN instead of LEFT JOIN. Note +# that RIGHT JOIN did not yet exist in SQLite when the ticket was +# written and fixed. +# +do_execsql_test join-20.3 { + DROP TABLE t1; + CREATE TABLE t1(x INT); INSERT INTO t1(x) VALUES(1); + CREATE TABLE t2(y BOOLEAN); INSERT INTO t2(y) VALUES(false); + CREATE TABLE t3(z INT); INSERT INTO t3(z) VALUES(3); + CREATE INDEX t2y ON t2(y) WHERE y; + SELECT quote(z) FROM t1 RIGHT JOIN t2 ON y LEFT JOIN t3 ON y; +} {NULL} + # 2019-11-30 ticket 7f39060a24b47353 # Do not allow a WHERE clause term to qualify a partial index on the # right table of a LEFT JOIN. From d2b230a48897e3ab61c969ba29706535d8978b21 Mon Sep 17 00:00:00 2001 From: stephan Date: Thu, 29 May 2025 20:29:13 +0000 Subject: [PATCH 03/35] Fix the missing -lm link flag for the sqlite3 shell when building the autoconf bundle with --disable-static-shell, as reported in [forum:5adf1c932a | forum post 5adf1c932a]. FossilOrigin-Name: f6318c4a6b5a133657741c066ef2c76a71880dbc98cfff1fdd632637daf002dc --- autoconf/Makefile.in | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/autoconf/Makefile.in b/autoconf/Makefile.in index aaa23b7def..a77386faed 100644 --- a/autoconf/Makefile.in +++ b/autoconf/Makefile.in @@ -224,7 +224,7 @@ install: install-lib # ENABLE_STATIC_SHELL = @ENABLE_STATIC_SHELL@ sqlite3-shell-link-flags.1 = $(TOP)/sqlite3.c $(LDFLAGS.libsqlite3) -sqlite3-shell-link-flags.0 = -L. -lsqlite3 $(LDFLAGS.zlib) +sqlite3-shell-link-flags.0 = -L. -lsqlite3 $(LDFLAGS.zlib) $(LDFLAGS.math) sqlite3-shell-deps.1 = $(TOP)/sqlite3.c sqlite3-shell-deps.0 = $(libsqlite3.DLL) # diff --git a/manifest b/manifest index 13d7d037d9..07b1489400 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extend\sthe\sfix\sfor\sticket\s[623eff57e76d45f6]\sso\sthat\sit\scovers\sRIGHT\sJOIN\nin\saddition\sto\sLEFT\sJOIN.\s\sProblem\sreported\sby\s\n[forum:/forumpost/7dee41d32506c4ae|forum\spost\s2025-05-29T15:10:14Z]. -D 2025-05-29T18:44:41.902 +C Fix\sthe\smissing\s-lm\slink\sflag\sfor\sthe\ssqlite3\sshell\swhen\sbuilding\sthe\sautoconf\sbundle\swith\s--disable-static-shell,\sas\sreported\sin\s[forum:5adf1c932a\s|\sforum\spost\s5adf1c932a]. +D 2025-05-29T20:29:13.320 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -17,7 +17,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F art/sqlite370.svg 40b7e2fe8aac3add5d56dd86ab8d427a4eca5bcb3fe4f8946cb3794e1821d531 F auto.def 82c32443a91c1062f7a48beec37dbb2d8d03447b1286bce8df5ebb6d8d353f8a F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.in 36516827bb5d2309422bbcbf53e873fa22ef179f5c25b1d3dc6a7255e63270b7 +F autoconf/Makefile.in d0926d2309e563b5ebdfd711e5c218533acab79829a05eef4e97c3a92e17bf42 F autoconf/Makefile.msc f15ad424ca2820df8e39d9157965710af0a64d87773706706a12ea4f96e3a0d8 F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136 F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P d6cbabe23d3919d5bde6a83421cdae92125caec09d5c39a648d0305878c6a1dc -R 28a9e68992443d1bb44866db16596344 -U drh -Z c4a3c019e57515755a30d30cb56ed7c7 +P 29b1e1b97619d03a97ef562a5707929e241d019179b4ff1d0bc2a8c008441431 +R 4762cb2ddb67d85a8f20bad68e159f3b +U stephan +Z a42949933613c0efadc0aa60dcb9ee1d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a85c4fce99..b48140dfdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29b1e1b97619d03a97ef562a5707929e241d019179b4ff1d0bc2a8c008441431 +f6318c4a6b5a133657741c066ef2c76a71880dbc98cfff1fdd632637daf002dc From 0148820fd740b0786f703703ba49bbeb6889c9bf Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 30 May 2025 10:18:09 +0000 Subject: [PATCH 04/35] Squelch an interesting but harmless struct initialization warning emitted after an emsdk update. Fix JS breakage introduced by changes in Emscripten 4.0.7: manually export the HEAPxyz symbols which used to be exposed by default. FossilOrigin-Name: 10d0897cc9a5998fe1344cfbb242a78b59012e29aa3b1993895dfac26721b053 --- ext/wasm/GNUmakefile | 8 +++++--- ext/wasm/api/sqlite3-wasm.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index ec258099fc..6470fd6308 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -410,7 +410,7 @@ DISTCLEAN_FILES += $(bin.stripccomments) # -D... flags which should be included in all invocations should be # appended to $(SQLITE.CALL.C-PP.FILTER.global). bin.c-pp := ./c-pp -$(bin.c-pp): c-pp.c $(sqlite3.c) $(MAKEFILE) +$(bin.c-pp): c-pp.c $(sqlite3.c) # $(MAKEFILE) $(CC) -O0 -o $@ c-pp.c $(sqlite3.c) '-DCMPP_DEFAULT_DELIM="//#"' -I$(dir.top) \ -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_UTF16 \ -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_WAL -DSQLITE_THREADSAFE=0 \ @@ -597,6 +597,9 @@ emcc.flags += -v # -v is _very_ loud but also informative about what it's doing endif + +# wasmMemory ==> required by our code for use with -sIMPORTED_MEMORY +# Emscripten 4.0.7 (2025-04-15) stops exporting HEAP* by default ######################################################################## # emcc flags for .c/.o. emcc.cflags := @@ -615,8 +618,7 @@ emcc.jsflags += -sDYNAMIC_EXECUTION=0 emcc.jsflags += -sNO_POLYFILL emcc.jsflags += -sEXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS.api) emcc.exportedRuntimeMethods := \ - -sEXPORTED_RUNTIME_METHODS=wasmMemory - # wasmMemory ==> required by our code for use with -sIMPORTED_MEMORY + -sEXPORTED_RUNTIME_METHODS=wasmMemory,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAP64,HEAPU64 emcc.jsflags += $(emcc.exportedRuntimeMethods) emcc.jsflags += -sUSE_CLOSURE_COMPILER=0 emcc.jsflags += -sIMPORTED_MEMORY diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index d9f0f08ebd..1850d313cb 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -1157,7 +1157,7 @@ const char * sqlite3__wasm_enum_json(void){ { /* Validate that the above struct sizeof()s match ** expectations. We could improve upon this by ** checking the offsetof() for each member. */ - const sqlite3_index_info siiCheck; + const sqlite3_index_info siiCheck = {0}; #define IndexSzCheck(T,M) \ (sizeof(T) == sizeof(*siiCheck.M)) if(!IndexSzCheck(sqlite3_index_constraint,aConstraint) diff --git a/manifest b/manifest index 07b1489400..c97c83fa90 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\smissing\s-lm\slink\sflag\sfor\sthe\ssqlite3\sshell\swhen\sbuilding\sthe\sautoconf\sbundle\swith\s--disable-static-shell,\sas\sreported\sin\s[forum:5adf1c932a\s|\sforum\spost\s5adf1c932a]. -D 2025-05-29T20:29:13.320 +C Squelch\san\sinteresting\sbut\sharmless\sstruct\sinitialization\swarning\semitted\safter\san\semsdk\supdate.\sFix\sJS\sbreakage\sintroduced\sby\schanges\sin\sEmscripten\s4.0.7:\smanually\sexport\sthe\sHEAPxyz\ssymbols\swhich\sused\sto\sbe\sexposed\sby\sdefault. +D 2025-05-30T10:18:09.731 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -621,7 +621,7 @@ F ext/session/sqlite3session.c 6b0877fe1ab832aa4b85eaca72606dfd1630a1363a1be7af1 F ext/session/sqlite3session.h 9bb1a6687b467764b35178dc29bbd2c57ab8cd3acdc8a62f088c34ad17e4fe2b F ext/session/test_session.c 2ddff73ea368d827028c32851b291416e1008845832feb27b751d15e57e13cc3 F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 24d7e6f446528fa67f5ade6c3c7d7e46e1ac52649d6264cbe24539c1dab608e1 +F ext/wasm/GNUmakefile d6b869cf3d3eaaec8cf56adf925910c3e443f455562bcb4a4cd2d1e43c933d8d F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -650,7 +650,7 @@ F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 0f68a64e508598910e7c01214ae27d603dfc8baec6a184506fafac603a901931 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4ab0704ee198de7d1059eccedc7703c931510b588d10af0ee36ea5b3ebbac284 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616 -F ext/wasm/api/sqlite3-wasm.c 6a4cd40267eaf08400895c5b9de39c56976c3b97b3c1bbe53fc2e80fa074e9c7 +F ext/wasm/api/sqlite3-wasm.c 7ea3d4a286a2241f6fcc65c9ff10fc04ee5590f80f40763a57001dd5e93aa4c4 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc65debfe43b81fc39fb25c40ad0cc1946bd82580fbf644351107b544d6177ee F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5 F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 29b1e1b97619d03a97ef562a5707929e241d019179b4ff1d0bc2a8c008441431 -R 4762cb2ddb67d85a8f20bad68e159f3b +P f6318c4a6b5a133657741c066ef2c76a71880dbc98cfff1fdd632637daf002dc +R 8bd2aba5086b16f1f67743ad460c6fa0 U stephan -Z a42949933613c0efadc0aa60dcb9ee1d +Z 45f2ae1b421158f9c9afd5b26cdd1391 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b48140dfdf..63a37f1583 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6318c4a6b5a133657741c066ef2c76a71880dbc98cfff1fdd632637daf002dc +10d0897cc9a5998fe1344cfbb242a78b59012e29aa3b1993895dfac26721b053 From b65326f51a2c8c9fcb5331cde36d55aa7d209a27 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 May 2025 11:14:11 +0000 Subject: [PATCH 05/35] Add "include " to fts5 and rtree to ensure that they use the system version of the offsetof() macro when it is available, as the built-in version triggers ubsan errors with clang. FossilOrigin-Name: 838deb7f3423df84061a043928ed34e1d74e2e7d57ef1a9519bb32fea82e4352 --- ext/fts5/fts5Int.h | 1 + ext/rtree/rtree.c | 2 ++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 2da347862e..7ad1cc16bd 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -20,6 +20,7 @@ SQLITE_EXTENSION_INIT1 #include #include +#include #ifndef SQLITE_AMALGAMATION diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index f90fd5a0ab..d8567b65ac 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -64,6 +64,8 @@ #endif int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */ +#include + /* ** If building separately, we will need some setup that is normally ** found in sqliteInt.h diff --git a/manifest b/manifest index c97c83fa90..edfc16cb16 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Squelch\san\sinteresting\sbut\sharmless\sstruct\sinitialization\swarning\semitted\safter\san\semsdk\supdate.\sFix\sJS\sbreakage\sintroduced\sby\schanges\sin\sEmscripten\s4.0.7:\smanually\sexport\sthe\sHEAPxyz\ssymbols\swhich\sused\sto\sbe\sexposed\sby\sdefault. -D 2025-05-30T10:18:09.731 +C Add\s"include\s"\sto\sfts5\sand\srtree\sto\sensure\sthat\sthey\suse\sthe\ssystem\sversion\sof\sthe\soffsetof()\smacro\swhen\sit\sis\savailable,\sas\sthe\sbuilt-in\sversion\striggers\subsan\serrors\swith\sclang. +D 2025-05-30T11:14:11.545 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -108,7 +108,7 @@ F ext/fts3/unicode/mkunicode.tcl cbf5f7b5c8ce8014bad731f246f2e520eece908465de477 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15 F ext/fts5/fts5.h ff5d3cc88b29e41612bfb29eb723e29e38973de62ca75ba3e8f94ccb67f5b5f2 -F ext/fts5/fts5Int.h bffbd0acdcdf509899681f4e1cfeef1c955030acd9fe15ff9082410f80c3bead +F ext/fts5/fts5Int.h 4c7380ce83e8f6b5b3216ebe2b33093a20fa72e832a88d14023f827b7d8b9933 F ext/fts5/fts5_aux.c da4a7a9a11ec15c6df0699d908915a209bcde48f0b04101461316b59f71abffb F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d7c53066c7 F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 @@ -539,7 +539,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 734aa36238bcd2dee91db5dba107d5fcbdb02396612811377a8ad50f1272b1c1 F ext/rtree/geopoly.c f0573d5109fdc658a180db0db6eec86ab2a1cf5ce58ec66cbf3356167ea757eb -F ext/rtree/rtree.c f12180fbc79f4de3dcb93afe55a64703481a23af7f80d1e988d2cb97afd07b6b +F ext/rtree/rtree.c 811edc5c2f3e13dcee825a8ec6f2ebe29b34bdb0186184d75d461621173638fa F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f6318c4a6b5a133657741c066ef2c76a71880dbc98cfff1fdd632637daf002dc -R 8bd2aba5086b16f1f67743ad460c6fa0 -U stephan -Z 45f2ae1b421158f9c9afd5b26cdd1391 +P 10d0897cc9a5998fe1344cfbb242a78b59012e29aa3b1993895dfac26721b053 +R 1dcfe8c63509fb843f7cb99753e48416 +U dan +Z de257d291b8e704afcab14c5e293267b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 63a37f1583..1938e46d3d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10d0897cc9a5998fe1344cfbb242a78b59012e29aa3b1993895dfac26721b053 +838deb7f3423df84061a043928ed34e1d74e2e7d57ef1a9519bb32fea82e4352 From 8ae57fab64aa1e16596763b9d9435aa1f7e9933d Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 30 May 2025 15:43:04 +0000 Subject: [PATCH 06/35] Use a more robust backup definition for offsetof(). FossilOrigin-Name: 22441955e03df07903b98832a60c05c53721cd67c667f6c83d5e97fcc62735ee --- ext/fts3/fts3Int.h | 2 +- ext/fts5/fts5Int.h | 2 +- ext/rtree/rtree.c | 2 +- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/sqliteInt.h | 9 ++++++++- src/vdbeInt.h | 2 +- 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index d438549de1..bd4666253c 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -213,7 +213,7 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */ ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 7ad1cc16bd..dbab6546ce 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -80,7 +80,7 @@ typedef sqlite3_uint64 u64; ** Macros needed to provide flexible arrays in a portable way */ #ifndef offsetof -# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index d8567b65ac..f7d3bda01a 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -97,7 +97,7 @@ typedef unsigned int u32; # define NEVER(X) (X) #endif #ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # define FLEXARRAY diff --git a/manifest b/manifest index edfc16cb16..d86a409642 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s"include\s"\sto\sfts5\sand\srtree\sto\sensure\sthat\sthey\suse\sthe\ssystem\sversion\sof\sthe\soffsetof()\smacro\swhen\sit\sis\savailable,\sas\sthe\sbuilt-in\sversion\striggers\subsan\serrors\swith\sclang. -D 2025-05-30T11:14:11.545 +C Use\sa\smore\srobust\sbackup\sdefinition\sfor\soffsetof(). +D 2025-05-30T15:43:04.641 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -82,7 +82,7 @@ F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts3/fts3.c 4f02858ab845a97bedf06e6cc1fba49a81fe5e00a26df68d0ad0f00a5814fa70 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h 53f00a0d037c81174af1089ad7776563dcbccb5ed4697405256d3d4260d9fccc +F ext/fts3/fts3Int.h d0f70d602be987501cf6eff86a06a0b5d0389929c6abe24972d59594e6f4cb03 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 F ext/fts3/fts3_expr.c 5c13796638d8192c388777166075cdc8bc4b6712024cd5b72c31acdbefce5984 F ext/fts3/fts3_hash.c d9dba473741445789330c7513d4f65737c92df23c3212784312931641814672a @@ -108,7 +108,7 @@ F ext/fts3/unicode/mkunicode.tcl cbf5f7b5c8ce8014bad731f246f2e520eece908465de477 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15 F ext/fts5/fts5.h ff5d3cc88b29e41612bfb29eb723e29e38973de62ca75ba3e8f94ccb67f5b5f2 -F ext/fts5/fts5Int.h 4c7380ce83e8f6b5b3216ebe2b33093a20fa72e832a88d14023f827b7d8b9933 +F ext/fts5/fts5Int.h cc1e6ed28e1fbde71e4427ba6d15b0c73a4f8f119adeb4f7bcc97e3336fbbeac F ext/fts5/fts5_aux.c da4a7a9a11ec15c6df0699d908915a209bcde48f0b04101461316b59f71abffb F ext/fts5/fts5_buffer.c f1e6d0324d7c55329d340673befc26681a372a4d36086caa8d1ec7d7c53066c7 F ext/fts5/fts5_config.c e7d8dd062b44a66cd77e5a0f74f23a2354cd1f3f8575afb967b2773c3384f7f8 @@ -539,7 +539,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 734aa36238bcd2dee91db5dba107d5fcbdb02396612811377a8ad50f1272b1c1 F ext/rtree/geopoly.c f0573d5109fdc658a180db0db6eec86ab2a1cf5ce58ec66cbf3356167ea757eb -F ext/rtree/rtree.c 811edc5c2f3e13dcee825a8ec6f2ebe29b34bdb0186184d75d461621173638fa +F ext/rtree/rtree.c a1f04a2013bc8f982307760615d1cee591355ac4723c74c3761c128d5c6954ab F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d @@ -790,7 +790,7 @@ F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8 F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e -F src/sqliteInt.h ded2e1527c84603d9d91adccb63dda460d96a2e2f98111d0438a479aa0dbe4e3 +F src/sqliteInt.h bb9137b860b2416b12788f09b32384ceab96b720aae07a6e9afacc545e43619a F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -856,7 +856,7 @@ F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 F src/vacuum.c d580ceb395c1ae3d59da41cbfea60683ff7dd2b94ddf4d0f5657620159e2eeb7 F src/vdbe.c 0feab5781141acca67bd5de84172fff902304274ec5cfe58609f005b8d160050 F src/vdbe.h 31eddcffc1d14c76c2a20fe4e137e1ee43d44f370896fae14a067052801a3625 -F src/vdbeInt.h 5446f60e89b2aa7cdf3ab0ec4e7b01b8732cd9d52d9092a0b8b1bf700768f784 +F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e F src/vdbeapi.c 28fab30ed0acc981aecfdcaab0a421503609078e29850eb28494816682baf0a7 F src/vdbeaux.c 948c379976885a073b54cc7d8ffda087dc1a1095d1f5bb8df218796f8c933ac3 F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 10d0897cc9a5998fe1344cfbb242a78b59012e29aa3b1993895dfac26721b053 -R 1dcfe8c63509fb843f7cb99753e48416 -U dan -Z de257d291b8e704afcab14c5e293267b +P 838deb7f3423df84061a043928ed34e1d74e2e7d57ef1a9519bb32fea82e4352 +R f90e835fc47fd28633f6ea822565f1aa +U drh +Z 7aebbf3ed91eff2f4d9c6af4a39f70fc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1938e46d3d..5e80e01b63 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -838deb7f3423df84061a043928ed34e1d74e2e7d57ef1a9519bb32fea82e4352 +22441955e03df07903b98832a60c05c53721cd67c667f6c83d5e97fcc62735ee diff --git a/src/sqliteInt.h b/src/sqliteInt.h index af7ed4a4c8..994a3864c1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -765,7 +765,7 @@ ** ourselves. */ #ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD)) +# define offsetof(ST,M) ((size_t)((char*)&((ST*)0)->M - (char*)0)) #endif /* @@ -2661,6 +2661,13 @@ struct KeyInfo { /* The size (in bytes) of a KeyInfo object with up to N fields */ #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) +/* The size of a bare KeyInfo with no aColl[] entries */ +#if FLEXARRAY+1 > 1 +# define SZ_KEYINFO_0 offsetof(KeyInfo,aColl) +#else +# define SZ_KEYINFO_0 sizeof(KeyInfo) +#endif + /* ** Allowed bit values for entries in the KeyInfo.aSortFlags[] array. */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 13262cd4e2..0faa327472 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -557,7 +557,7 @@ struct PreUpdate { Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ sqlite3_value **apDflt; /* Array of default values, if required */ - u8 keyinfoSpace[SZ_KEYINFO(0)]; /* Space to hold pKeyinfo[0] content */ + u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */ }; /* From 7ac10ec8b5d03766da0deaebbf5e7c7199617d7c Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 30 May 2025 15:46:52 +0000 Subject: [PATCH 07/35] Random typo fixes in JNI docs. FossilOrigin-Name: f63608a3847469b130e029cc569fe6f03a9053352ec43c10d69849cbab4f61c5 --- .../src/org/sqlite/jni/capi/AggregateFunction.java | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java b/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java index 1fa6c6b805..912f6ed5b5 100644 --- a/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java +++ b/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java @@ -120,7 +120,7 @@ public abstract class AggregateFunction implements SQLFunction { argument, the context is set to the given initial value. On all other calls, the 2nd argument is ignored. - @see SQLFunction.PerContextState#getAggregateState + @see AggregateFunction.PerContextState#getAggregateState */ protected final ValueHolder getAggregateState(sqlite3_context cx, T initialValue){ return map.getAggregateState(cx, initialValue); @@ -130,7 +130,7 @@ public abstract class AggregateFunction implements SQLFunction { To be called from the implementation's xFinal() method to fetch the final state of the UDF and remove its mapping. - see SQLFunction.PerContextState#takeAggregateState + see AggregateFunction.PerContextState#takeAggregateState */ protected final T takeAggregateState(sqlite3_context cx){ return map.takeAggregateState(cx); diff --git a/manifest b/manifest index d86a409642..d84021d640 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sa\smore\srobust\sbackup\sdefinition\sfor\soffsetof(). -D 2025-05-30T15:43:04.641 +C Random\stypo\sfixes\sin\sJNI\sdocs. +D 2025-05-30T15:46:52.989 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -296,7 +296,7 @@ F ext/jni/src/org/sqlite/jni/annotation/NotNull.java be6cc3e8e114485822331630097 F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 56e3dee1f3f703a545dfdeddc1c3d64d1581172b1ad01ffcae95c18547fafd90 F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca F ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java 1afa90d3f236f79cc7fcd2497e111992644f7596fbc8e8bcf7f1908ae00acd6c -F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0b72cdff61533b564d65b63418129656daa9a9f30e7e7be982bd5ab394b1dbd0 +F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 0e28a0df51368c7127e505f1e9acd92a7e66e035bcd6288463aa691cb300c9af F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java c045a5b47e02bb5f1af91973814a905f12048c428a3504fbc5266d1c1be3de5a F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759 F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 838deb7f3423df84061a043928ed34e1d74e2e7d57ef1a9519bb32fea82e4352 -R f90e835fc47fd28633f6ea822565f1aa -U drh -Z 7aebbf3ed91eff2f4d9c6af4a39f70fc +P 22441955e03df07903b98832a60c05c53721cd67c667f6c83d5e97fcc62735ee +R 1edac9bbd25a5eccbabbe70c4bbe99ec +U stephan +Z 90faa1c75772444c7902de216c0e90a8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5e80e01b63..4b36985f37 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22441955e03df07903b98832a60c05c53721cd67c667f6c83d5e97fcc62735ee +f63608a3847469b130e029cc569fe6f03a9053352ec43c10d69849cbab4f61c5 From f42ceb9075c6dc64e36c17a1836ea3a0a2b4e8f6 Mon Sep 17 00:00:00 2001 From: stephan Date: Fri, 30 May 2025 16:08:31 +0000 Subject: [PATCH 08/35] Configure-related fixes and additions, most notably integration of self-tests for proj.tcl's APIs. Teaish make-install fixes based on the discussion in [forum:87e6660191a472c5 | forum thread 87e6660191a472c5]. FossilOrigin-Name: 2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 --- autoconf/tea/Makefile.in | 79 +++-- autoconf/tea/_teaish.tester.tcl.in | 3 +- autoconf/tea/teaish.tcl | 3 +- autosetup/proj.tcl | 493 ++++++++++++++++++++++------- autosetup/teaish/core.tcl | 133 ++++---- autosetup/teaish/tester.tcl | 71 ++++- manifest | 22 +- manifest.uuid | 2 +- 8 files changed, 593 insertions(+), 213 deletions(-) diff --git a/autoconf/tea/Makefile.in b/autoconf/tea/Makefile.in index 5b2ad4c699..ccf9a7b945 100644 --- a/autoconf/tea/Makefile.in +++ b/autoconf/tea/Makefile.in @@ -146,7 +146,7 @@ LDFLAGS.shlib = @SH_LDFLAGS@ # sources passed to [teaish-src-add], but may also be appended to by # teaish.make. # -tx.src =@TEAISH_EXT_SRC@ +tx.src = @TEAISH_EXT_SRC@ # # tx.CFLAGS is typically set by teaish.make, whereas TEAISH_CFLAGS @@ -167,6 +167,11 @@ tx.LDFLAGS = # tx.dist.files = @TEAISH_DIST_FILES@ +# +# The base name for a distribution tar/zip file. +# +tx.dist.basename = $(tx.name.dist)-$(tx.version) + # List of deps which may trigger an auto-reconfigure. # teaish__autogen.deps = \ @@ -199,9 +204,14 @@ $(teaish.makefile): $(teaish__auto.def) $(teaish.makefile.in) \ @AUTODEPS@ @if TEAISH_TESTER_TCL_IN -@TEAISH_TESTER_TCL_IN@: -@TEAISH_TESTER_TCL@: @TEAISH_TESTER_TCL_IN@ -config.log: @TEAISH_TESTER_TCL@ +@TEAISH_TESTER_TCL_IN@: $(teaish__autogen.deps) +config.log: @TEAISH_TESTER_TCL_IN@ +@TEAISH_TESTER_TCL@: @TEAISH_TESTER_TCL_IN@ +@endif +@if TEAISH_TEST_TCL_IN +@TEAISH_TEST_TCL_IN@: $(teaish__autogen.deps) +config.log: @TEAISH_TEST_TCL_IN@ +@TEAISH_TEST_TCL@: @TEAISH_TEST_TCL_IN@ @endif # @@ -217,7 +227,7 @@ CC.tcl = \ # CC.dll = \ $(CC.tcl) $(tx.src) $(LDFLAGS.shlib) \ - $(LDFLAGS.configure) $(LDFLAGS) $(tx.LDFLAGS) $(TCL_STUB_LIB_SPEC) + $(tx.LDFLAGS) $(LDFLAGS.configure) $(LDFLAGS) $(TCL_STUB_LIB_SPEC) @if TEAISH_ENABLE_DLL # @@ -248,16 +258,25 @@ test-extension: # this name is reserved for use by teaish.make[.in] test-prepre: $(tx.dll) @endif @if TEAISH_TESTER_TCL -test-core.args = @TEAISH_TESTER_TCL@ +teaish.tester.tcl = @TEAISH_TESTER_TCL@ +test-core.args = $(teaish.tester.tcl) @if TEAISH_ENABLE_DLL test-core.args += '$(tx.dll)' '$(tx.loadPrefix)' @else test-core.args += '' '' @endif test-core.args += @TEAISH_TESTUTIL_TCL@ +# Clients may pass additional args via test.args=... +# and ::argv will be rewritten before the test script loads, to +# remove $(test-core.args) +test.args ?= test-core: test-pre - $(TCLSH) $(test-core.args) -test-prepre: @TEAISH_TESTER_TCL@ + $(TCLSH) $(test-core.args) $(test.args) +test-gdb: $(teaish.tester.tcl) + gdb --args $(TCLSH) $(test-core.args) $(test.args) +test-vg.flags ?= --leak-check=full -v --show-reachable=yes --track-origins=yes +test-vg: $(teaish.tester.tcl) + valgrind $(test-vg.flags) $(TCLSH) $(test-core.args) $(test.args) @else # !TEAISH_TESTER_TCL test-prepre: @endif # TEAISH_TESTER_TCL @@ -288,7 +307,7 @@ distclean-core: distclean-pre @endif @endif @if TEAISH_TESTER_TCL_IN - rm -f @TEAISH_TESTER_TCL@ + rm -f $(teaish.tester.tcl) @endif @if TEAISH_PKGINDEX_TCL_IN rm -f @TEAISH_PKGINDEX_TCL@ @@ -355,10 +374,15 @@ install-core: install-pre @endif install-test: install-core @echo "Post-install test of [package require $(tx.name.pkg) $(tx.version)]..."; \ + set xtra=""; \ + if [ x != "x$(DESTDIR)" ]; then \ + xtra='set ::auto_path [linsert $$::auto_path 0 [file normalize $(DESTDIR)$(TCLLIBDIR)/..]];'; \ + fi; \ if echo \ - 'set c 0; ' \ + 'set c 0; ' $$xtra \ '@TEAISH_POSTINST_PREREQUIRE@' \ - 'if {[catch {package require $(tx.name.pkg) $(tx.version)}]} {incr c};' \ + 'if {[catch {package require $(tx.name.pkg) $(tx.version)} xc]} {incr c};' \ + 'if {$$c && "" ne $$xc} {puts $$xc; puts "auto_path=$$::auto_path"};' \ 'exit $$c' \ | $(TCLSH) ; then \ echo "passed"; \ @@ -406,7 +430,7 @@ config.log: $(teaish.makefile.in) # recognized when running in --teaish-install mode, causing # the sub-configure to fail. dist.flags = --with-tclsh=$(TCLSH) -dist.reconfig = $(teaish.dir)/configure $(dist.flags) +dist.reconfig = $(teaish.dir)/configure $(tx.dist.reconfig-flags) $(dist.flags) # Temp dir for dist.zip. Must be different than dist.tgz or else # parallel builds may hose the dist. @@ -414,24 +438,23 @@ teaish__dist.tmp.zip = teaish__dist_zip # # Make a distribution zip file... # -dist.basename = $(tx.name.dist)-$(tx.version) -dist.zip = $(dist.basename).zip +dist.zip = $(tx.dist.basename).zip .PHONY: dist.zip dist.zip-core dist.zip-post #dist.zip-pre: # We apparently can't add a pre-hook here, else "make dist" rebuilds # the archive each time it's run. $(dist.zip): $(tx.dist.files) @rm -fr $(teaish__dist.tmp.zip) - @mkdir -p $(teaish__dist.tmp.zip)/$(dist.basename) + @mkdir -p $(teaish__dist.tmp.zip)/$(tx.dist.basename) @tar cf $(teaish__dist.tmp.zip)/tmp.tar $(tx.dist.files) - @tar xf $(teaish__dist.tmp.zip)/tmp.tar -C $(teaish__dist.tmp.zip)/$(dist.basename) + @tar xf $(teaish__dist.tmp.zip)/tmp.tar -C $(teaish__dist.tmp.zip)/$(tx.dist.basename) @if TEAISH_DIST_FULL @$(dist.reconfig) \ - --teaish-install=$(teaish__dist.tmp.zip)/$(dist.basename) \ - --t-e-d=$(teaish__dist.tmp.zip)/$(dist.basename) >/dev/null + --teaish-install=$(teaish__dist.tmp.zip)/$(tx.dist.basename) \ + --t-e-d=$(teaish__dist.tmp.zip)/$(tx.dist.basename) >/dev/null @endif - @rm -f $(dist.basename)/tmp.tar $(dist.zip) - @cd $(teaish__dist.tmp.zip) && zip -q -r ../$(dist.zip) $(dist.basename) + @rm -f $(tx.dist.basename)/tmp.tar $(dist.zip) + @cd $(teaish__dist.tmp.zip) && zip -q -r ../$(dist.zip) $(tx.dist.basename) @rm -fr $(teaish__dist.tmp.zip) @ls -la $(dist.zip) dist.zip-core: $(dist.zip) @@ -447,23 +470,23 @@ undist: undist-zip # Make a distribution tarball... # teaish__dist.tmp.tgz = teaish__dist_tgz -dist.tgz = $(dist.basename).tar.gz +dist.tgz = $(tx.dist.basename).tar.gz .PHONY: dist.tgz dist.tgz-core dist.tgz-post # dist.tgz-pre: # see notes in dist.zip $(dist.tgz): $(tx.dist.files) @rm -fr $(teaish__dist.tmp.tgz) - @mkdir -p $(teaish__dist.tmp.tgz)/$(dist.basename) + @mkdir -p $(teaish__dist.tmp.tgz)/$(tx.dist.basename) @tar cf $(teaish__dist.tmp.tgz)/tmp.tar $(tx.dist.files) - @tar xf $(teaish__dist.tmp.tgz)/tmp.tar -C $(teaish__dist.tmp.tgz)/$(dist.basename) + @tar xf $(teaish__dist.tmp.tgz)/tmp.tar -C $(teaish__dist.tmp.tgz)/$(tx.dist.basename) @if TEAISH_DIST_FULL - @rm -f $(teaish__dist.tmp.tgz)/$(dist.basename)/pkgIndex.tcl.in; # kludge + @rm -f $(teaish__dist.tmp.tgz)/$(tx.dist.basename)/pkgIndex.tcl.in; # kludge @$(dist.reconfig) \ - --teaish-install=$(teaish__dist.tmp.tgz)/$(dist.basename) \ - --t-e-d=$(teaish__dist.tmp.zip)/$(dist.basename) >/dev/null + --teaish-install=$(teaish__dist.tmp.tgz)/$(tx.dist.basename) \ + --t-e-d=$(teaish__dist.tmp.zip)/$(tx.dist.basename) >/dev/null @endif - @rm -f $(dist.basename)/tmp.tar $(dist.tgz) - @cd $(teaish__dist.tmp.tgz) && tar czf ../$(dist.tgz) $(dist.basename) + @rm -f $(tx.dist.basename)/tmp.tar $(dist.tgz) + @cd $(teaish__dist.tmp.tgz) && tar czf ../$(dist.tgz) $(tx.dist.basename) @rm -fr $(teaish__dist.tmp.tgz) @ls -la $(dist.tgz) dist.tgz-core: $(dist.tgz) diff --git a/autoconf/tea/_teaish.tester.tcl.in b/autoconf/tea/_teaish.tester.tcl.in index 59d11f0a8f..e04d8e63e7 100644 --- a/autoconf/tea/_teaish.tester.tcl.in +++ b/autoconf/tea/_teaish.tester.tcl.in @@ -21,7 +21,8 @@ if {[llength [lindex $::argv 0]] > 0} { # ----^^^^^^^ needed on Haiku when argv 0 is just a filename, else # load cannot find the file. } -source -encoding utf-8 [lindex $::argv 2]; # teaish/tester.tcl +set ::argv [lassign $argv - -] +source -encoding utf-8 [lindex $::argv 0]; # teaish/tester.tcl @if TEAISH_PKGINIT_TCL apply {{file} { set dir [file dirname $::argv0] diff --git a/autoconf/tea/teaish.tcl b/autoconf/tea/teaish.tcl index 9333495aa3..c52d58f073 100644 --- a/autoconf/tea/teaish.tcl +++ b/autoconf/tea/teaish.tcl @@ -67,6 +67,7 @@ apply {{dir} { -vsatisfies 8.6- -libDir sqlite$version -pragmas $pragmas + -src generic/tclsqlite3.c } }} [teaish-get -dir] @@ -119,8 +120,6 @@ proc teaish-options {} { proc teaish-configure {} { use teaish/feature - teaish-src-add -dist -dir generic/tclsqlite3.c - if {[proj-opt-was-provided override-sqlite-version]} { teaish-pkginfo-set -version [opt-val override-sqlite-version] proj-warn "overriding sqlite version number:" [teaish-pkginfo-get -version] diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 1335567064..1a90b479a3 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -60,10 +60,11 @@ # $proj__Config is an internal-use-only array for storing whatever generic # internal stuff we need stored. # -array set ::proj__Config { - self-tests 1 -} - +array set ::proj__Config [subst { + self-tests [get-env proj.self-tests 0] + verbose-assert [get-env proj.assert-verbose 0] + isatty [isatty? stdout] +}] # # List of dot-in files to filter in the final stages of @@ -75,7 +76,6 @@ array set ::proj__Config { # See: proj-dot-ins-append and proj-dot-ins-process # set ::proj__Config(dot-in-files) [list] -set ::proj__Config(isatty) [isatty? stdout] # # @proj-warn msg @@ -85,28 +85,29 @@ set ::proj__Config(isatty) [isatty? stdout] # proc proj-warn {args} { show-notices - puts stderr [join [list "WARNING: \[[proj-scope 1]\]: " {*}$args] " "] + puts stderr [join [list "WARNING:" \[ [proj-scope 1] \]: {*}$args] " "] } +# # Internal impl of [proj-fatal] and [proj-error]. It must be called # using tailcall. -proc proj__faterr {failMode argv} { +# +proc proj__faterr {failMode args} { show-notices set lvl 1 - while {"-up" eq [lindex $argv 0]} { - set argv [lassign $argv -] + while {"-up" eq [lindex $args 0]} { + set args [lassign $args -] incr lvl } if {$failMode} { - puts stderr [join [list "FATAL: \[[proj-scope $lvl]]: " {*}$argv]] + puts stderr [join [list "FATAL:" \[ [proj-scope $lvl] \]: {*}$args]] exit 1 } else { - error [join [list "\[[proj-scope $lvl]]:" {*}$argv]] + error [join [list in \[ [proj-scope $lvl] \]: {*}$args]] } } - # # @proj-fatal ?-up...? msg... # @@ -118,7 +119,7 @@ proc proj__faterr {failMode argv} { # additional level. # proc proj-fatal {args} { - tailcall proj__faterr 1 $args + tailcall proj__faterr 1 {*}$args } # @@ -127,10 +128,9 @@ proc proj-fatal {args} { # Works like proj-fatal but uses [error] intead of [exit]. # proc proj-error {args} { - tailcall proj__faterr 0 $args + tailcall proj__faterr 0 {*}$args } -set ::proj__Config(verbose-assert) [get-env proj-assert-verbose 0] # # @proj-assert script ?message? # @@ -147,7 +147,7 @@ proc proj-assert {script {msg ""}} { if {"" eq $msg} { set msg $script } - proj-fatal "Assertion failed in \[[proj-scope 1]\]: $msg" + tailcall proj__faterr 1 "Assertion failed:" $msg } } @@ -1665,7 +1665,7 @@ proc proj-dot-ins-append {fileIn args} { proj-fatal "Too many arguments: $fileIn $args" } } - #puts "******* [proj-scope]: adding $fileIn" + #puts "******* [proj-scope]: adding [llength $fileIn]-length item: $fileIn" lappend ::proj__Config(dot-in-files) $fileIn } @@ -1703,17 +1703,18 @@ proc proj-dot-ins-list {} { # makes proj-dot-ins-append available for re-use. # proc proj-dot-ins-process {args} { - proj-parse-simple-flags args flags { + proj-parse-flags args flags { -touch "" {return "-touch"} -clear 0 {expr 1} -validate 0 {expr 1} } + #puts "args=$args"; parray flags if {[llength $args] > 0} { error "Invalid argument to [proj-scope]: $args" } foreach f $::proj__Config(dot-in-files) { proj-assert {3==[llength $f]} \ - "Expecting proj-dot-ins-list to be stored in 3-entry lists" + "Expecting proj-dot-ins-list to be stored in 3-entry lists. Got: $f" lassign $f fIn fOut fScript #puts "DOING $fIn ==> $fOut" proj-make-from-dot-in {*}$flags(-touch) $fIn $fOut @@ -1753,7 +1754,7 @@ proc proj-validate-no-unresolved-ats {args} { set isMake [string match {*[Mm]ake*} $f] foreach line [proj-file-content-list $f] { if {!$isMake || ![string match "#*" [string trimleft $line]]} { - if {[regexp {(@[A-Za-z0-9_]+@)} $line match]} { + if {[regexp {(@[A-Za-z0-9_\.]+@)} $line match]} { error "Unresolved reference to $match at line $lnno of $f" } } @@ -1893,7 +1894,7 @@ proc proj-define-amend {args} { # proc proj-define-to-cflag {args} { set rv {} - proj-parse-simple-flags args flags { + proj-parse-flags args flags { -list 0 {expr 1} -quote 0 {expr 1} -zero-undef 0 {expr 1} @@ -2001,7 +2002,7 @@ proc proj-cache-key {arg {addLevel 0}} { # See proj-cache-key for -key's and -level's semantics, noting that # this function adds one to -level for purposes of that call. proc proj-cache-set {args} { - proj-parse-simple-flags args flags { + proj-parse-flags args flags { -key => 0 -level => 0 } @@ -2037,7 +2038,7 @@ proc proj-cache-remove {{key 0} {addLevel 0}} { # See proj-cache-key for $key's and $addLevel's semantics, noting that # this function adds one to $addLevel for purposes of that call. proc proj-cache-check {args} { - proj-parse-simple-flags args flags { + proj-parse-flags args flags { -key => 0 -level => 0 } @@ -2070,147 +2071,321 @@ proc proj-coalesce {args} { } # -# @proj-parse-simple-flags ... +# @proj-parse-flags argvListName targetArrayName {prototype} # # A helper to parse flags from proc argument lists. # -# Expects a list of arguments to parse, an array name to store any -# -flag values to, and a prototype object which declares the flags. +# The first argument is the name of a var holding the args to +# parse. It will be overwritten, possibly with a smaller list. # -# The prototype must be a list in one of the following forms: +# The second argument is the name of an array variable to create in +# the caller's scope. # -# -flag defaultValue {script} +# The third argument, $prototype, is a description of how to handle +# the flags. Each entry in that list must be in one of the +# following forms: # -# -flag => defaultValue -# -----^--^ (with spaces there!) +# -flag defaultValue ?-literal|-call|-apply? +# script|number|incr|proc-name|{apply $aLambda} # -# Repeated for each flag. +# -flag* ...as above... # -# The first form represents a basic flag with no associated -# following argument. The second form extracts its value -# from the following argument in $argvName. +# -flag => defaultValue ?-call proc-name-and-args|-apply lambdaExpr? # -# The first argument to this function is the name of a var holding the -# args to parse. It will be overwritten, possibly with a smaller list. +# -flag* => ...as above... # -# The second argument the name of an array variable to create in the -# caller's scope. (Pneumonic: => points to the next argument.) +# :PRAGMA # -# For the first form of flag, $script is run in the caller's scope if -# $argv contains -flag, and the result of that script is the new value -# for $tgtArrayName(-flag). This function intercepts [return $val] -# from $script. Any empty script will result in the flag having "" -# assigned to it. +# The first two forms represents a basic flag with no associated +# following argument. The third and fourth forms, called arg-consuming +# flags, extract the value from the following argument in $argvName +# (pneumonic: => points to the next argument.). The :PRAGMA form +# offers a way to configure certain aspects of this call. # -# The args list is only inspected until the first argument which is -# not described by $prototype. i.e. the first "non-flag" (not counting -# values consumed for flags defined like --flag=>default). +# If $argv contains any given flag from $prototype, its default value +# is overridden depending on several factors: +# +# - If the -literal flag is used, or the flag's script is a number, +# value is used verbatim. +# +# - Else if the -call flag is used, the argument must be a proc name +# and any leading arguments, e.g. {apply $myLambda}. The proc is passed +# the (flag, value) as arguments (non-consuming flags will get +# passed the flag's current/starting value and consuming flags will +# get the next argument). Its result becomes the result of the +# flag. +# +# - Else if -apply X is used, it's effectively shorthand for -call +# {apply X}. Its argument may either be a $lambaRef or a {{f v} +# {body}} construct. +# +# - Else if $script is one of the following values, it is treated as +# the result of... +# +# - incr: increments the current value of the flag. +# +# - Else $script is eval'd to get its result value. That result +# becomes the new flag value for $tgtArrayName(-flag). This +# function intercepts [return $val] from eval'ing $script. Any +# empty script will result in the flag having "" assigned to it. +# +# Unless the -flag has a trailing asterisk, e.g. -flag*, this function +# assumes that each flag is unique, and using a flag more than once +# causes an error to be triggered. the -flag* forms works similarly +# except that may appear in $argv any number of times: +# +# - For non-arg-consuming flags, each invocation of -flag causes the +# result of $script to overwrite the previous value. e.g. so +# {-flag* {x} {incr foo}} has a default value of x, but passing in +# -flag twice would change it to the result of incrementing foo +# twice. This form can be used to implement, e.g., increasing +# verbosity levels by passing -verbose multiple times. +# +# - For arg-consuming flags, the given flag starts with value X, but +# if the flag is provided in $argv, the default is cleared, then +# each instance of -flag causes its value to be appended to the +# result, so {-flag* => {a b c}} defaults to {a b c}, but passing +# in -flag y -flag z would change it to {y z}, not {a b c y z}.. +# +# By default, the args list is only inspected until the first argument +# which is not described by $prototype. i.e. the first "non-flag" (not +# counting values consumed for flags defined like -flag => default). +# The :all-flags pragma (see below) can modify this behavior. # # If a "--" flag is encountered, no more arguments are inspected as -# flags. If "--" is the first non-flag argument, the "--" flag is -# removed from the results but all remaining arguments are passed -# through. If "--" appears after the first non-flag, it is retained. +# flags unless the :all-flags pragma (see below) is in effect. The +# first instance of "--" is removed from the target result list but +# all remaining instances of "--" are are passed through. # -# This function assumes that each flag is unique, and using a flag -# more than once behaves in a last-one-wins fashion. +# Any argvName entries not described in $prototype are considered to +# be "non-flags" for purposes of this function, even if they +# ostensibly look like flags. # -# Any argvName entries not described in $prototype are not treated as -# flags. -# -# Returns the number of flags it processed in $argvName. +# Returns the number of flags it processed in $argvName, not counting +# "--". # # Example: # -# set args [list -foo -bar {blah} 8 9 10 -theEnd] -# proj-parse-simple-flags args flags { -# -foo 0 {expr 1} -# -bar => 0 -# -no-baz 2 {return 0} -# } +## set args [list -foo -bar {blah} -z 8 9 10 -theEnd] +## proj-parse-flags args flags { +## -foo 0 {expr 1} +## -bar => 0 +## -no-baz 1 {return 0} +## -z 0 2 +## } # -# After that $flags would contain {-foo 1 -bar {blah} -no-baz 2} +# After that $flags would contain {-foo 1 -bar {blah} -no-baz 1 -z 2} # and $args would be {8 9 10 -theEnd}. # -# Potential TODOs: consider using lappend instead of set so that any -# given flag can be used more than once. Or add a syntax to indicate -# that multiples are allowed. Also consider searching the whole -# argv list, rather than stopping at the first non-flag +# Pragmas: # -proc proj-parse-simple-flags {argvName tgtArrayName prototype} { +# Passing :PRAGMAS to this function may modify how it works. The +# following pragmas are supported (note the leading ":"): +# +# :all-flags indicates that the whole input list should be scanned, +# not stopping at the first non-flag or "--". +# +proc proj-parse-flags {argvName tgtArrayName prototype} { upvar $argvName argv - upvar $tgtArrayName tgt - array set dflt {} - array set scripts {} - array set consuming {} + upvar $tgtArrayName outFlags + array set flags {}; # staging area + array set scripts {}; # map of -flag=>script + array set consuming {}; # map of -flag=>1 for arg-consuming flags + array set multi {}; # map of -flag=>1 for multi-time flags + array set seen {}; # map of -flag=>number of times seen + array set call {}; # map of -flag=>1 for -call entries + set incrSkip 1; # 1 if we stop at the first non-flag, else 0 + # Parse $prototype for flag definitions... set n [llength $prototype] - # Figure out what our flags are... + set checkProtoFlag { + #puts "**** checkProtoFlag #$i of $n k=$k fv=$fv" + switch -exact -- $fv { + -literal { + proj-assert {![info exists consuming($k)]} + set scripts($k) [list expr [lindex $prototype [incr i]]] + } + -apply { + set fv [lindex $prototype [incr i]] + if {2 == [llength $fv]} { + # Treat this as a lambda literal + set fv [list $fv] + } + lappend call($k) "apply $fv" + } + -call { + # arg is either a proc name or {apply $aLambda} + set fv [lindex $prototype [incr i]] + lappend call($k) $fv + } + default { + proj-assert {![info exists consuming($k)]} + set scripts($k) $fv + } + } + if {$i >= $n} { + proj-error -up "[proj-scope]: Missing argument for $k flag" + } + } for {set i 0} {$i < $n} {incr i} { set k [lindex $prototype $i] #puts "**** #$i of $n k=$k" - proj-assert {[string match -* $k]} \ - "Invalid flag value: $k" - set v "" - set s "" - switch -exact -- [lindex $prototype [expr {$i + 1}]] { - => { - incr i 2 - if {$i >= $n} { - proj-error "Missing argument for $k => flag" - } - set consuming($k) 1 - set v [lindex $prototype $i] - } - default { - set v [lindex $prototype [incr i]] - set s [lindex $prototype [incr i]] - set scripts($k) $s + + # Check for :PRAGMA... + switch -exact -- $k { + :all-flags { + set incrSkip 0 + continue } } - #puts "**** #$i of $n k=$k v=$v s=$s" - set dflt($k) $v + + proj-assert {[string match -* $k]} \ + "Invalid argument: $k" + + if {[string match {*\*} $k]} { + # Re-map -foo* to -foo and flag -foo as a repeatable flag + set k [string map {* ""} $k] + incr multi($k) + } + + if {[info exists flags($k)]} { + proj-error -up "[proj-scope]: Duplicated prototype for flag $k" + } + + switch -exact -- [lindex $prototype [expr {$i + 1}]] { + => { + # -flag => DFLT ?-subflag arg? + incr i 2 + if {$i >= $n} { + proj-error -up "[proj-scope]: Missing argument for $k => flag" + } + incr consuming($k) + set vi [lindex $prototype $i] + if {$vi in {-apply -call}} { + proj-error -up "[proj-scope]: Missing default value for $k flag" + } else { + set fv [lindex $prototype [expr {$i + 1}]] + if {$fv in {-apply -call}} { + incr i + eval $checkProtoFlag + } + } + } + default { + # -flag VALUE ?flag? SCRIPT + set vi [lindex $prototype [incr i]] + set fv [lindex $prototype [incr i]] + eval $checkProtoFlag + } + } + #puts "**** #$i of $n k=$k vi=$vi" + set flags($k) $vi } - # Now look for those flags in the source list - array set tgt [array get dflt] - unset dflt + #puts "-- flags"; parray flags + #puts "-- scripts"; parray scripts + #puts "-- calls"; parray call set rc 0 set rv {} set skipMode 0 set n [llength $argv] + # Now look for those flags in $argv... for {set i 0} {$i < $n} {incr i} { set arg [lindex $argv $i] + #puts "-- [proj-scope] arg=$arg" if {$skipMode} { lappend rv $arg } elseif {"--" eq $arg} { - incr skipMode - } elseif {[info exists tgt($arg)]} { - if {[info exists consuming($arg)]} { - if {$i + 1 >= $n} { - proj-assert 0 {Cannot happen - bounds already checked} + # "--" is the conventional way to end processing of args + if {[incr seen(--)] > 1} { + # Elide only the first one + lappend rv $arg + } + incr skipMode $incrSkip + } elseif {[info exists flags($arg)]} { + # A known flag... + set isMulti [info exists multi($arg)] + incr seen($arg) + if {1 < $seen($arg) && !$isMulti} { + proj-error -up [proj-scope] "$arg flag was used multiple times" + } + set vMode 0; # 0=as-is, 1=eval, 2=call + set isConsuming [info exists consuming($arg)] + if {$isConsuming} { + incr i + if {$i >= $n} { + proj-error -up [proj-scope] "is missing argument for $arg flag" } - set tgt($arg) [lindex $argv [incr i]] - } elseif {"" eq $scripts($arg)} { - set tgt($arg) "" + set vv [lindex $argv $i] + } elseif {[info exists scripts($arg)]} { + set vMode 1 + set vv $scripts($arg) } else { - #puts "**** running scripts($arg) $scripts($arg)" - set code [catch {uplevel 1 $scripts($arg)} xrc xopt] - #puts "**** tgt($arg)=$scripts($arg) code=$code rc=$rc" - if {$code in {0 2}} { - set tgt($arg) $xrc - } else { - return {*}$xopt $xrc + set vv $flags($arg) + } + + if {[info exists call($arg)]} { + set vMode 2 + set vv [concat {*}$call($arg) $arg $vv] + } elseif {$isConsuming} { + proj-assert {!$vMode} + # fall through + } elseif {"" eq $vv || [string is double -strict $vv]} { + set vMode 0 + } elseif {$vv in {incr}} { + set vMode 0 + switch -exact $vv { + incr { + set xx $flags($k); incr xx; set vv $xx; unset xx + } + default { + proj-error "Unhandled \$vv value $vv" + } } + } else { + set vv [list eval $vv] + set vMode 1 + } + if {$vMode} { + set code [catch [list uplevel 1 $vv] vv xopt] + if {$code ni {0 2}} { + return {*}$xopt $vv + } + } + if {$isConsuming && $isMulti} { + if {1 == $seen($arg)} { + # On the first hit, overwrite the default with a new list. + set flags($arg) [list $vv] + } else { + # On subsequent hits, append to the list. + lappend flags($arg) $vv + } + } else { + set flags($arg) $vv } incr rc } else { - incr skipMode + # Non-flag + incr skipMode $incrSkip lappend rv $arg } } set argv $rv + array set outFlags [array get flags] + #puts "-- rv=$rv argv=$argv flags="; parray flags return $rc +}; # proj-parse-flags + +# +# Older (deprecated) name of proj-parse-flags. +# +proc proj-parse-simple-flags {args} { + tailcall proj-parse-flags {*}$args } if {$::proj__Config(self-tests)} { + set __ova $::proj__Config(verbose-assert); + set ::proj__Config(verbose-assert) 1 + puts "Running [info script] self-tests..." + # proj-cache... apply {{} { #proj-warn "Test code for proj-cache" proj-assert {![proj-cache-check -key here check]} @@ -2233,4 +2408,100 @@ if {$::proj__Config(self-tests)} { proj-assert {"" eq [proj-cache-remove]} proj-assert {"" eq $check} }} -} + + # proj-parse-flags ... + apply {{} { + set foo 3 + set argv {-a "hi - world" -b -b -b -- -a {bye bye} -- -d -D c -a "" --} + proj-parse-flags argv flags { + :all-flags + -a* => "gets overwritten" + -b* 7 {incr foo} + -d 1 0 + -D 0 1 + } + + #puts "-- argv = $argv"; parray flags; + proj-assert {"-- c --" eq $argv} + proj-assert {$flags(-a) eq "{hi - world} {bye bye} {}"} + proj-assert {$foo == 6} + proj-assert {$flags(-b) eq $foo} + proj-assert {$flags(-d) == 0} + proj-assert {$flags(-D) == 1} + set foo 0 + foreach x $flags(-a) { + proj-assert {$x in {{hi - world} {bye bye} {}}} + incr foo + } + proj-assert {3 == $foo} + + set argv {-a {hi world} -b -maybe -- -a {bye bye} -- -b c --} + set foo 0 + proj-parse-flags argv flags { + -a => "aaa" + -b 0 {incr foo} + -maybe no -literal yes + } + #parray flags; puts "--- argv = $argv" + proj-assert {"-a {bye bye} -- -b c --" eq $argv} + proj-assert {$flags(-a) eq "hi world"} + proj-assert {1 == $flags(-b)} + proj-assert {"yes" eq $flags(-maybe)} + + set argv {-f -g -a aaa -M -M -M -L -H -A AAA a b c} + set foo 0 + set myLambda {{flag val} { + proj-assert {$flag in {-f -g -M}} + #puts "myLambda flag=$flag val=$val" + incr val + }} + proc myNonLambda {flag val} { + proj-assert {$flag in {-A -a}} + #puts "myNonLambda flag=$flag val=$val" + concat $val $val + } + proj-parse-flags argv flags { + -f 0 -call {apply $myLambda} + -g 2 -apply $myLambda + -h 3 -apply $myLambda + -H 30 33 + -a => aAAAa -apply {{f v} { + set v + }} + -A => AaaaA -call myNonLambda + -B => 17 -call myNonLambda + -M* 0 -apply $myLambda + -L "" -literal $myLambda + } + rename myNonLambda "" + #puts "--- argv = $argv"; parray flags + proj-assert {$flags(-f) == 1} + proj-assert {$flags(-g) == 3} + proj-assert {$flags(-h) == 3} + proj-assert {$flags(-H) == 33} + proj-assert {$flags(-a) == {aaa}} + proj-assert {$flags(-A) eq "AAA AAA"} + proj-assert {$flags(-B) == 17} + proj-assert {$flags(-M) == 3} + proj-assert {$flags(-L) eq $myLambda} + + set argv {-touch -validate} + proj-parse-flags argv flags { + -touch "" {return "-touch"} + -validate 0 1 + } + #puts "----- argv = $argv"; parray flags + proj-assert {$flags(-touch) eq "-touch"} + proj-assert {$flags(-validate) == 1} + proj-assert {$argv eq {}} + + set argv {-i -i -i} + proj-parse-flags argv flags { + -i* 0 incr + } + proj-assert {3 == $flags(-i)} + }} + set ::proj__Config(verbose-assert) $__ova + unset __ova + puts "Done running [info script] self-tests." +}; # proj- API self-tests diff --git a/autosetup/teaish/core.tcl b/autosetup/teaish/core.tcl index 33c6e18984..307462ec3f 100644 --- a/autosetup/teaish/core.tcl +++ b/autosetup/teaish/core.tcl @@ -92,6 +92,7 @@ array set teaish__Config [proj-strip-hash-comments { -tm.tcl.in TEAISH_TM_TCL_IN -options {} -pragmas {} + -src {} } # @@ -331,29 +332,33 @@ proc teaish-configure-core {} { -url - -v "" -tm.tcl - -v "" -tm.tcl.in - -v "" + -src - -v "" } { + #proj-assert 0 {Just testing} set isPIFlag [expr {"-" ne $pflag}] if {$isPIFlag} { if {[info exists ::teaish__PkgInfo($pflag)]} { # Was already set - skip it. continue; } - proj-assert {{-} eq $key} + proj-assert {{-} eq $key};# "Unexpected pflag=$pflag key=$key type=$type val=$val" set key $f2d($pflag) } - proj-assert {"" ne $key} - set got [get-define $key ""] - if {"" ne $got} { - # Was already set - skip it. - continue + if {"" ne $key} { + if {"" ne [get-define $key ""]} { + # Was already set - skip it. + continue + } } switch -exact -- $type { -v {} -e { set val [eval $val] } default { proj-error "Invalid type flag: $type" } } - #puts "***** defining default $pflag $key {$val} isPIFlag=$isPIFlag got=$got" - define $key $val + #puts "***** defining default $pflag $key {$val} isPIFlag=$isPIFlag" + if {$key ne ""} { + define $key $val + } if {$isPIFlag} { set ::teaish__PkgInfo($pflag) $val } @@ -541,10 +546,10 @@ proc teaish__configure_phase1 {} { define TEAISH_VSATISFIES_CODE [join $code "\n"] }}; # vsatisfies - if {[proj-looks-like-windows] || [proj-looks-like-mac]} { + if {[proj-looks-like-windows]} { # Without this, linking of an extension will not work on Cygwin or # Msys2. - msg-result "Using USE_TCL_STUBS for this environment" + msg-result "Using USE_TCL_STUBS for Unix(ish)-on-Windows environment" teaish-cflags-add -DUSE_TCL_STUBS=1 } @@ -585,7 +590,8 @@ proc teaish__configure_phase1 {} { # if {0x0f & $::teaish__Config(pkginit-policy)} { file delete -force -- [get-define TEAISH_PKGINIT_TCL] - proj-dot-ins-append [get-define TEAISH_PKGINIT_TCL_IN] + proj-dot-ins-append [get-define TEAISH_PKGINIT_TCL_IN] \ + [get-define TEAISH_PKGINIT_TCL] } if {0x0f & $::teaish__Config(tm-policy)} { file delete -force -- [get-define TEAISH_TM_TCL] @@ -595,17 +601,20 @@ proc teaish__configure_phase1 {} { apply {{} { # Queue up any remaining dot-in files set dotIns [list] - foreach d { - TEAISH_TESTER_TCL_IN - TEAISH_TEST_TCL_IN - TEAISH_MAKEFILE_IN + foreach {dIn => dOut} { + TEAISH_TESTER_TCL_IN => TEAISH_TESTER_TCL + TEAISH_TEST_TCL_IN => TEAISH_TEST_TCL + TEAISH_MAKEFILE_IN => TEAISH_MAKEFILE } { - lappend dotIns [get-define $d ""] + lappend dotIns [get-define $dIn ""] [get-define $dOut ""] } - lappend dotIns $::autosetup(srcdir)/Makefile.in; # must be after TEAISH_MAKEFILE_IN - foreach f $dotIns { - if {"" ne $f} { - proj-dot-ins-append $f + lappend dotIns $::autosetup(srcdir)/Makefile.in Makefile; # must be after TEAISH_MAKEFILE_IN. + # Much later: probably because of timestamps for deps purposes :-? + #puts "dotIns=$dotIns" + foreach {i o} $dotIns { + if {"" ne $i && "" ne $o} { + #puts " pre-dot-ins-append: \[$i\] -> \[$o\]" + proj-dot-ins-append $i $o } } }} @@ -640,10 +649,10 @@ proc teaish__configure_phase1 {} { # # NO [define]s after this point! # - proj-dot-ins-process -validate proj-if-opt-truthy teaish-dump-defines { proj-file-write config.defines.txt $tdefs } + proj-dot-ins-process -validate }; # teaish__configure_phase1 @@ -1068,7 +1077,7 @@ If you are attempting an out-of-tree build, use ]]} { if {[string match *.in $extM]} { define TEAISH_MAKEFILE_IN $extM - define TEAISH_MAKEFILE [file rootname [file tail $extM]] + define TEAISH_MAKEFILE _[file rootname [file tail $extM]] } else { define TEAISH_MAKEFILE_IN "" define TEAISH_MAKEFILE $extM @@ -1136,8 +1145,8 @@ If you are attempting an out-of-tree build, use set flist [list $dirExt/teaish.test.tcl.in $dirExt/teaish.test.tcl] if {[proj-first-file-found ttt $flist]} { if {[string match *.in $ttt]} { - # Generate teaish.test.tcl from $ttt - set xt [file rootname [file tail $ttt]] + # Generate _teaish.test.tcl from $ttt + set xt _[file rootname [file tail $ttt]] file delete -force -- $xt; # ensure no stale copy is used define TEAISH_TEST_TCL $xt define TEAISH_TEST_TCL_IN $ttt @@ -1304,7 +1313,6 @@ proc teaish-ldflags-prepend {args} { # object files (which are typically in the build tree)). # proc teaish-src-add {args} { - set i 0 proj-parse-simple-flags args flags { -dist 0 {expr 1} -dir 0 {expr 1} @@ -1389,7 +1397,7 @@ proc teaish__cleanup_rule {{tgt clean}} { return ${tgt}-_${x}_ } -# @teaish-make-obj objfile srcfile ?...args? +# @teaish-make-obj ?flags? ?...args? # # Uses teaish-make-add to inject makefile rules for $objfile from # $srcfile, which is assumed to be C code which uses libtcl. Unless @@ -1403,43 +1411,45 @@ proc teaish__cleanup_rule {{tgt clean}} { # Any arguments after the 2nd may be flags described below or, if no # -recipe is provided, flags for the compiler call. # +# -obj obj-filename.o +# +# -src src-filename.c +# # -recipe {...} # Uses the trimmed value of {...} as the recipe, prefixing it with # a single hard-tab character. # # -deps {...} -# List of extra files to list as dependencies of $o. Good luck -# escaping non-trivial cases properly. +# List of extra files to list as dependencies of $o. # # -clean # Generate cleanup rules as well. -proc teaish-make-obj {o src args} { - set consume 0 - set clean 0 - set flag "" - array set flags {} - set xargs {} - foreach arg $args { - if {$consume} { - set consume 0 - set flags($flag) $arg - continue - } - switch -exact -- $arg { - -clean {incr clean} - -recipe - - -deps { - set flag $arg - incr consume - } - default { - lappend xargs $arg - } +proc teaish-make-obj {args} { + proj-parse-simple-flags args flags { + -clean 0 {expr 1} + -recipe => {} + -deps => {} + -obj => {} + -src => {} + } + #parray flags + if {"" eq $flags(-obj)} { + set args [lassign $args flags(-obj)] + if {"" eq $flags(-obj)} { + proj-error "Missing -obj flag." } } + foreach f {-deps -src} { + set flags($f) [string trim [string map {\n " "} $flags($f)]] + } + foreach f {-deps -src} { + set flags($f) [string trim $flags($f)] + } + #parray flags + #puts "-- args=$args" teaish-make-add \ - "# [proj-scope 1] -> [proj-scope] $o $src" -nl \ - "$o: $src $::teaish__Config(teaish.tcl)" + "# [proj-scope 1] -> [proj-scope] $flags(-obj) $flags(-src)" -nl \ + "$flags(-obj): $flags(-src) $::teaish__Config(teaish.tcl)" if {[info exists flags(-deps)]} { teaish-make-add " " [join $flags(-deps)] } @@ -1447,12 +1457,12 @@ proc teaish-make-obj {o src args} { if {[info exists flags(-recipe)]} { teaish-make-add [string trim $flags(-recipe)] -nl } else { - teaish-make-add [join [list \$(CC.tcl) -c $src {*}$xargs]] -nl + teaish-make-add [join [list \$(CC.tcl) -c $flags(-src) {*}$args]] -nl } - if {$clean} { + if {$flags(-clean)} { set rule [teaish__cleanup_rule] teaish-make-add \ - "clean: $rule\n$rule:\n\trm -f \"$o\"\n" + "clean: $rule\n$rule:\n\trm -f \"$flags(-obj)\"\n" } } @@ -2080,6 +2090,17 @@ proc teaish-pkginfo-set {args} { set v $x } + -src { + set d $::teaish__Config(extension-dir) + foreach f $v { + lappend ::teaish__Config(dist-files) $f + lappend ::teaish__Config(extension-src) $d/$f + lappend ::teaish__PkgInfo(-src) $f + # ^^^ so that default-value initialization in + # teaish-configure-core recognizes that it's been set. + } + } + -tm.tcl - -tm.tcl.in { if {0x30 & $::teaish__Config(pkgindex-policy)} { @@ -2517,7 +2538,7 @@ proc teaish__install {{dDest ""}} { ] { teaish__verbose 1 msg-result "Copying files to $destDir..." file mkdir $destDir - foreach f [glob -directory $srcDir *] { + foreach f [glob -nocomplain -directory $srcDir *] { if {[string match {*~} $f] || [string match "#*#" [file tail $f]]} { # Editor-generated backups and emacs lock files continue diff --git a/autosetup/teaish/tester.tcl b/autosetup/teaish/tester.tcl index d8b5f7a0e8..a25b366e8d 100644 --- a/autosetup/teaish/tester.tcl +++ b/autosetup/teaish/tester.tcl @@ -99,7 +99,7 @@ proc test__affert {failMode args} { lassign $args script msg } incr ::test__Counters($what) - if {![uplevel 1 [concat expr [list $script]]]} { + if {![uplevel 1 expr [list $script]]} { if {"" eq $msg} { set msg $script } @@ -136,6 +136,40 @@ proc assert {args} { tailcall test__affert 1 {*}$args } +# +# @assert-matches ?-e? pattern ?-e? rhs ?msg? +# +# Equivalent to assert {[string match $pattern $rhs]} except that +# if either of those are prefixed with an -e flag, they are eval'd +# and their results are used. +# +proc assert-matches {args} { + set evalLhs 0 + set evalRhs 0 + if {"-e" eq [lindex $args 0]} { + incr evalLhs + set args [lassign $args -] + } + set args [lassign $args pattern] + if {"-e" eq [lindex $args 0]} { + incr evalRhs + set args [lassign $args -] + } + set args [lassign $args rhs msg] + + if {$evalLhs} { + set pattern [uplevel 1 $pattern] + } + if {$evalRhs} { + set rhs [uplevel 1 $rhs] + } + #puts "***pattern=$pattern\n***rhs=$rhs" + tailcall test__affert 1 \ + [join [list \[ string match [list $pattern] [list $rhs] \]]] $msg + # why does this not work? [list \[ string match [list $pattern] [list $rhs] \]] $msg + # "\[string match [list $pattern] [list $rhs]\]" +} + # # @test-assert testId script ?msg? # @@ -157,7 +191,7 @@ proc test-expect {testId script result} { puts "test $testId" set x [string trim [uplevel 1 $script]] set result [string trim $result] - tailcall test__affert 0 [list $x eq $result] \ + tailcall test__affert 0 [list "{$x}" eq "{$result}"] \ "\nEXPECTED: <<$result>>\nGOT: <<$x>>" } @@ -169,7 +203,7 @@ proc test-expect {testId script result} { # proc test-catch {cmd args} { if {[catch { - $cmd {*}$args + uplevel 1 $cmd {*}$args } rc xopts]} { puts "[test-current-scope] ignoring failure of: $cmd [lindex $args 0]: $rc" return 1 @@ -177,6 +211,37 @@ proc test-catch {cmd args} { return 0 } +# +# @test-catch-matching pattern (script|cmd args...) +# +# Works like test-catch, but it expects its argument(s) to to throw an +# error matching the given string (checked with [string match]). If +# they do not throw, or the error does not match $pattern, this +# function throws, else it returns 1. +# +# If there is no second argument, the $cmd is assumed to be a script, +# and will be eval'd in the caller's scope. +# +# TODO: add -glob and -regex flags to control matching flavor. +# +proc test-catch-matching {pattern cmd args} { + if {[catch { + #puts "**** catch-matching cmd=$cmd args=$args" + if {0 == [llength $args]} { + uplevel 1 $cmd {*}$args + } else { + $cmd {*}$args + } + } rc xopts]} { + if {[string match $pattern $rc]} { + return 1 + } else { + error "[test-current-scope] exception does not match {$pattern}: {$rc}" + } + } + error "[test-current-scope] expecting to see an error matching {$pattern}" +} + if {![array exists ::teaish__BuildFlags]} { array set ::teaish__BuildFlags {} } diff --git a/manifest b/manifest index d84021d640..67810fc435 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Random\stypo\sfixes\sin\sJNI\sdocs. -D 2025-05-30T15:46:52.989 +C Configure-related\sfixes\sand\sadditions,\smost\snotably\sintegration\sof\sself-tests\sfor\sproj.tcl's\sAPIs.\sTeaish\smake-install\sfixes\sbased\son\sthe\sdiscussion\sin\s[forum:87e6660191a472c5\s|\sforum\sthread\s87e6660191a472c5]. +D 2025-05-30T16:08:31.088 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -22,15 +22,15 @@ F autoconf/Makefile.msc f15ad424ca2820df8e39d9157965710af0a64d87773706706a12ea4f F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136 F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807 F autoconf/auto.def 3d994f3a9cc9b712dbce92a5708570ddcf3b988141b6eb738f2ed16127a9f0ac -F autoconf/tea/Makefile.in 14c6a79ce87e10d8a35398f2d0e04e1d83a88eb52ee16ebf0eeaccf005ff84b3 +F autoconf/tea/Makefile.in bf6b43eafcd18766d81a8f0085cfc9cb051d8abae9031a8e7c3f5f1246e8f166 F autoconf/tea/README.txt 656d4686c509d375f5988ff3deda94f65fe6cd8358cd55d1f1dcc7b6e2ff73aa -F autoconf/tea/_teaish.tester.tcl.in ed5445512e91c12afbbb99771efb68a23be4a046d52d61213fb5b6f010118129 +F autoconf/tea/_teaish.tester.tcl.in 8253b44be88e2e3f21de95a65d3a90c2be8e70b7bdd08a5b80e337ba7402f8f1 F autoconf/tea/auto.def ce95b9450e2fa4ba5dc857e208fe10f4e6f2d737796ac3278aee6079db417529 F autoconf/tea/configure d0b12b984edca6030d1976375b80157ac78b5b90a5b4f0dcee39357f63f4a80b x F autoconf/tea/doc/sqlite3.n 9a97f4f717ceab73004ea412af7960625c1cb24b5c25e4ae4c8b5d8fa4300f4e F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in e07da6b94561f4aa382bab65b1ccceb04701b97bf59d007c1d1f20a222b22d07 -F autoconf/tea/teaish.tcl 81571a9f9ae5c70735595b05586cb2de9d2aea7e32aad10417c4982f2e2f01c8 +F autoconf/tea/teaish.tcl a2224762a039ed30c45cc1ce4b2fde5667fb0aa2569bb56590f5cb5d45d7410b F autoconf/tea/teaish.test.tcl cfe94e1fb79dd078f650295be59843d470125e0cc3a17a1414c1fb8d77f4aea6 F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e @@ -47,13 +47,13 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e F autosetup/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1821baf61bc86a7e F autosetup/jimsh0.c 563b966c137a4ce3c9333e5196723b7ac0919140a9d7989eb440463cd855c367 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl c4a77735b57f3c016a185bff048212a197b77723f9bea6cfafe396e4b542c666 +F autosetup/proj.tcl a4d7eb8d7e05328ac6202abe813da300db2fa89f1936a69f3f9d75300b4ff244 F autosetup/sqlite-config.tcl ccda82e43e377b832aae72a1678b1dc17dcaff36ed0ebbd8f0cfc88612ae8de3 F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/teaish/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca -F autosetup/teaish/core.tcl a37bd039881bc1b0adfa25808966e62108b1e8194e730f1d1e06aad7e57b1f6e +F autosetup/teaish/core.tcl 8824c4c37075814a1a7613ca30c0654460779b1765c091bf3600e378c8fdf3e0 F autosetup/teaish/feature.tcl 18194fb79a24d30e5bbdeab40999616f39278b53a27525349ded033af2fd73be -F autosetup/teaish/tester.tcl 091745984473faea6985254b9986c6dfd0cce06f68bc515ba4afc1e6b3742fa8 +F autosetup/teaish/tester.tcl 1799514c2652db49561b3386c5242b94534d1663f2cfac861a955e071895fdd0 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl eb4c6578e08dd353263958da0dc620f8400b869a50d06e271ab0be85a51a08d3 F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 22441955e03df07903b98832a60c05c53721cd67c667f6c83d5e97fcc62735ee -R 1edac9bbd25a5eccbabbe70c4bbe99ec +P f63608a3847469b130e029cc569fe6f03a9053352ec43c10d69849cbab4f61c5 +R 45ee8fcc96567a1f284bf3c5475d67ce U stephan -Z 90faa1c75772444c7902de216c0e90a8 +Z 1517f3bde51bc97155127eadd67c114a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4b36985f37..f3a66759ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f63608a3847469b130e029cc569fe6f03a9053352ec43c10d69849cbab4f61c5 +2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 From 88ed38ca6d4502959093a0e05d55a718369a0d9f Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 May 2025 18:23:03 +0000 Subject: [PATCH 09/35] Avoid invoking the busy-handler if a blocking lock times out while attempting to open a snapshot transaction. FossilOrigin-Name: fe11f85fd3283bb7002f43bd8b796e9e7b67f6d1a92eb676be06b46d1458fc1d --- manifest | 18 +++++--- manifest.uuid | 2 +- src/btree.c | 8 ++++ test/walsetlk_snapshot.test | 87 +++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 test/walsetlk_snapshot.test diff --git a/manifest b/manifest index 67810fc435..3893edf8b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Configure-related\sfixes\sand\sadditions,\smost\snotably\sintegration\sof\sself-tests\sfor\sproj.tcl's\sAPIs.\sTeaish\smake-install\sfixes\sbased\son\sthe\sdiscussion\sin\s[forum:87e6660191a472c5\s|\sforum\sthread\s87e6660191a472c5]. -D 2025-05-30T16:08:31.088 +C Avoid\sinvoking\sthe\sbusy-handler\sif\sa\sblocking\slock\stimes\sout\swhile\sattempting\sto\sopen\sa\ssnapshot\stransaction. +D 2025-05-30T18:23:03.081 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -726,7 +726,7 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 782cc29b42b47e7ec6348eb0aaf9ffe60063f498387e7249f458d445af4b53e9 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 00fcee37947641f48d4b529d96143e74d056b7afa8f26d61292c90ee59c056b2 +F src/btree.c 138e6b0df717244ba4591af5ba3cfb3f5032ea09a2f8449997329051155366c0 F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f @@ -2036,6 +2036,7 @@ F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533 F test/walsetlk.test 9079cd8ef82570b8cf0067f31e049a72bec353fb2d5f0cc88f1736dc42ba9704 F test/walsetlk2.test 9097083633cdf55bf1098b694fb8651d0356d38fef28b869481d18029d7ceaf4 F test/walsetlk3.test 1b82bd92dea7e58f498b4399b0b3d26773dd8ac5c74205ce4a23c207cb8e85fe +F test/walsetlk_snapshot.test 6376fc8a76da4571eb35cf4aef06105f716c5e52f991cefec44b9c7015aadf1e F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 @@ -2207,8 +2208,11 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f63608a3847469b130e029cc569fe6f03a9053352ec43c10d69849cbab4f61c5 -R 45ee8fcc96567a1f284bf3c5475d67ce -U stephan -Z 1517f3bde51bc97155127eadd67c114a +P 2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 +R 271c081be49b44d7c0913e445ea8afea +T *branch * setlk-snapshot-fix +T *sym-setlk-snapshot-fix * +T -sym-trunk * +U dan +Z 6fb6c5ab6f440154ac0955e521c66539 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f3a66759ea..b9ab8ad22f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 +fe11f85fd3283bb7002f43bd8b796e9e7b67f6d1a92eb676be06b46d1458fc1d diff --git a/src/btree.c b/src/btree.c index 1bd59a1b1f..0648566354 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3697,6 +3697,14 @@ static SQLITE_NOINLINE int btreeBeginTrans( (void)sqlite3PagerWalWriteLock(pPager, 0); unlockBtreeIfUnused(pBt); } +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_ENABLE_SNAPSHOT) + if( rc==SQLITE_BUSY_TIMEOUT ){ + /* If a blocking lock timed out, break out of the loop here so that + ** the busy-handler is not invoked. This can only happen when opening + ** a transaction on a snapshot. */ + break; + } +#endif }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && btreeInvokeBusyHandler(pBt) ); sqlite3PagerWalDb(pPager, 0); diff --git a/test/walsetlk_snapshot.test b/test/walsetlk_snapshot.test new file mode 100644 index 0000000000..35d70cd19a --- /dev/null +++ b/test/walsetlk_snapshot.test @@ -0,0 +1,87 @@ +# 2025 May 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# TESTRUNNER: slow +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +set testprefix walsetlk_snapshot + +ifcapable !wal {finish_test ; return } +ifcapable !setlk_timeout {finish_test ; return } +ifcapable !snapshot {finish_test; return} + +do_execsql_test 1.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); +} {wal} + +do_test 1.1 { + db eval BEGIN + set ::snap [sqlite3_snapshot_get db main] + db eval { + INSERT INTO t1 VALUES(7, 8); + COMMIT; + } +} {} + +testfixture_nb myvar { + + testvfs tvfs -fullshm 1 + sqlite3 db test.db -vfs tvfs + tvfs script vfs_callback + tvfs filter {xWrite} + + set ::done 0 + proc vfs_callback {args} { + if {$::done==0} { + after 4000 + set ::done 1 + } + return "SQLITE_OK" + } + + db eval { + PRAGMA wal_checkpoint; + } + + db close +} + +# Give the [testfixture_nb] command time to start +after 1000 + +db timeout 500 +set tm [lindex [time { + catch { + db eval BEGIN + sqlite3_snapshot_open db main $::snap + } msg +}] 0] + +do_test 1.2 { set ::msg } {SQLITE_BUSY} +do_test 1.3.($::tm) { expr $::tm<1000000 } 1 + +do_execsql_test 1.4 { + SELECT * FROM t1 +} {1 2 3 4 5 6 7 8} + +sqlite3_snapshot_free $::snap + +vwait myvar + +finish_test + From dd16539e71e375abbe2affa3b142f2454a3d9edc Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 30 May 2025 19:55:46 +0000 Subject: [PATCH 10/35] When synthesizing an ON constraint from a USING or NATURAL, if the left-hand side is coming from a RIGHT JOIN, be sure to set the EP_CanBeNull flag so that the optimizer knows to check for NULL even if the column has a NOT NULL constraint. Fix for the problem reported by [forum:/forumpost/4fc70203b61c7e12|forum post 4fc70203b61] FossilOrigin-Name: 60adc78a22956429d34ccc4e2c193c5994c11c3b3cff7901d47fad7d92dba935 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 4 +++- test/join.test | 28 ++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 67810fc435..2ab4f5294a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Configure-related\sfixes\sand\sadditions,\smost\snotably\sintegration\sof\sself-tests\sfor\sproj.tcl's\sAPIs.\sTeaish\smake-install\sfixes\sbased\son\sthe\sdiscussion\sin\s[forum:87e6660191a472c5\s|\sforum\sthread\s87e6660191a472c5]. -D 2025-05-30T16:08:31.088 +C When\ssynthesizing\san\sON\sconstraint\sfrom\sa\sUSING\sor\sNATURAL,\sif\sthe\sleft-hand\nside\sis\scoming\sfrom\sa\sRIGHT\sJOIN,\sbe\ssure\sto\sset\sthe\sEP_CanBeNull\sflag\sso\sthat\nthe\soptimizer\sknows\sto\scheck\sfor\sNULL\seven\sif\sthe\scolumn\shas\sa\sNOT\sNULL\nconstraint.\s\sFix\sfor\sthe\sproblem\sreported\sby\n[forum:/forumpost/4fc70203b61c7e12|forum\spost\s4fc70203b61] +D 2025-05-30T19:55:46.105 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 3b91c334f528359145f4dde0dedd945bbb21044d0825ea064934d7222d61662c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c ee072fe20566119a195a5a3df454479bb6e944de7aef7006ff0b4d4612f9cb86 +F src/select.c 571fff5cf453c3cafc122873b982dff39075e1edd1afec707216c9b534fde7bf F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8f F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -1361,7 +1361,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 5984da7bf74b6540aa356f2ab0c6ae68a6d12039a3d798a9ac6a100abc17d520 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test aca62194ad41b522c55577e0e1bd99da6d5436827225aa850801c36e5f4cc914 +F test/join.test 015ef539ea2b779d0a219f4c0f82f39bf20884aed42142165e56791094d1cf3d F test/join2.test f59d63264fb24784ae9c3bc9d867eb569cd6d442da5660f8852effe5c1938c27 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f63608a3847469b130e029cc569fe6f03a9053352ec43c10d69849cbab4f61c5 -R 45ee8fcc96567a1f284bf3c5475d67ce -U stephan -Z 1517f3bde51bc97155127eadd67c114a +P 2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 +R 4fc3d788e929e3ad2e87da5f4f76e5b7 +U drh +Z b8769468b1683decb71b7b0ba97e34bc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f3a66759ea..31fbda4e91 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 +60adc78a22956429d34ccc4e2c193c5994c11c3b3cff7901d47fad7d92dba935 diff --git a/src/select.c b/src/select.c index 3b951afffe..da0aa63e43 100644 --- a/src/select.c +++ b/src/select.c @@ -596,7 +596,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ } pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); - if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 && pParse->nErr==0 ){ /* This branch runs if the query contains one or more RIGHT or FULL ** JOINs. If only a single table on the left side of this join ** contains the zName column, then this branch is a no-op. @@ -612,6 +612,8 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ */ ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ static const Token tkCoalesce = { "coalesce", 8 }; + assert( pE1!=0 ); + ExprSetProperty(pE1, EP_CanBeNull); while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, pRight->fg.isSynthUsing)!=0 ){ if( pSrc->a[iLeft].fg.isUsing==0 diff --git a/test/join.test b/test/join.test index ecd7bb2b5d..789ae0124f 100644 --- a/test/join.test +++ b/test/join.test @@ -1304,4 +1304,32 @@ do_execsql_test join-30.3 { WHERE x <= y; } {} +# 2025-05-30 https://sqlite.org/forum/forumpost/4fc70203b61c7e12 +# +# When converting a USING(x) or NATURAL into the constraint expression +# t1.x==t2.x, mark the t1.x term as EP_CanBeNull if it is the left table +# of a RIGHT JOIN. +# +reset_db +db null NULL +do_execsql_test join-31.1 { + CREATE TABLE t1(c0 INT , c1 INT); INSERT INTO t1(c0, c1) VALUES(NULL,11); + CREATE TABLE t2(c0 INT NOT NULL); + CREATE TABLE t2n(c0 INT); + CREATE TABLE t3(x INT); INSERT INTO t3(x) VALUES(4); + CREATE TABLE t5(c0 INT, x INT); INSERT INTO t5 VALUES(NULL, 4); +} +do_execsql_test join-31.2 { + SELECT * FROM t2 RIGHT JOIN t3 ON true LEFT JOIN t1 USING(c0); +} {NULL 4 NULL} +do_execsql_test join-31.3 { + SELECT * FROM t2 RIGHT JOIN t3 ON true NATURAL LEFT JOIN t1; +} {NULL 4 NULL} +do_execsql_test join-31.4 { + SELECT * FROM t2n RIGHT JOIN t3 ON true LEFT JOIN t1 USING(c0); +} {NULL 4 NULL} +do_execsql_test join-31.5 { + SELECT * FROM t5 LEFT JOIN t1 USING(c0); +} {NULL 4 NULL} + finish_test From ded1959120db41174d720fc3a157cc648694d6f9 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 May 2025 20:52:18 +0000 Subject: [PATCH 11/35] If blocking locks are enabled, avoid using the busy handler when blocked by another process running recovery. FossilOrigin-Name: a35236757ab57c4c9b34e47c5dbc10d8f1220f8152955f5303cf9c3902ee169b --- manifest | 22 ++++----- manifest.uuid | 2 +- src/btree.c | 5 +- src/os_unix.c | 5 +- src/pager.c | 9 ++++ src/wal.c | 3 +- test/walsetlk_recover.test | 96 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 123 insertions(+), 19 deletions(-) create mode 100644 test/walsetlk_recover.test diff --git a/manifest b/manifest index 3893edf8b7..9f161b1800 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sinvoking\sthe\sbusy-handler\sif\sa\sblocking\slock\stimes\sout\swhile\sattempting\sto\sopen\sa\ssnapshot\stransaction. -D 2025-05-30T18:23:03.081 +C If\sblocking\slocks\sare\senabled,\savoid\susing\sthe\sbusy\shandler\swhen\sblocked\sby\sanother\sprocess\srunning\srecovery. +D 2025-05-30T20:52:18.193 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -726,7 +726,7 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 782cc29b42b47e7ec6348eb0aaf9ffe60063f498387e7249f458d445af4b53e9 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 138e6b0df717244ba4591af5ba3cfb3f5032ea09a2f8449997329051155366c0 +F src/btree.c da98489a981c347cc3a3982ea2810bbb583511a73cc34762547f30dbb4cda7f0 F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f @@ -770,10 +770,10 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 410185df4900817c218c0efdb8064b3481af88cb3f7cea7392f820b6eebc7889 +F src/os_unix.c 8d9b9efbf337b5d59dbb259b7a8ca745f68d4f15495dbe17737b3c325c226363 F src/os_win.c b39f31fb0b137d67091d21880f0fded6b1c3c8c59b9e24e42844a1c0070437d4 F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19 -F src/pager.c 9fbb541b46125dfa8914827575e6bb4d15048caa008073b1709112d495d7983b +F src/pager.c 23c0f17deb892da6b32fef1f465507df7ab5cd01d774288cb43695658a649259 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 F src/parse.y e426d7323311554c75b0aebc426d0fe3c88d9777ffefed236f343ad9e661dc4c F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 @@ -866,7 +866,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c bcf40795a09b699ad7e42624dd6282b13335164fbabcd5a98a717758cebef451 +F src/wal.c 78da33510b8cb1b096fb5ae9954be910998d2477ddb623e56f5df84e56b5814d F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 45a3b496248a0b36d91ce34da3278d54f8fa20e9d3fbd36d45a42051d1118137 @@ -2036,6 +2036,7 @@ F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533 F test/walsetlk.test 9079cd8ef82570b8cf0067f31e049a72bec353fb2d5f0cc88f1736dc42ba9704 F test/walsetlk2.test 9097083633cdf55bf1098b694fb8651d0356d38fef28b869481d18029d7ceaf4 F test/walsetlk3.test 1b82bd92dea7e58f498b4399b0b3d26773dd8ac5c74205ce4a23c207cb8e85fe +F test/walsetlk_recover.test f653e7c85f77ba51828ba64d2d98f42f4afaf26bbd82ac60fbf1c6c8063e370f F test/walsetlk_snapshot.test 6376fc8a76da4571eb35cf4aef06105f716c5e52f991cefec44b9c7015aadf1e F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 @@ -2208,11 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 -R 271c081be49b44d7c0913e445ea8afea -T *branch * setlk-snapshot-fix -T *sym-setlk-snapshot-fix * -T -sym-trunk * +P fe11f85fd3283bb7002f43bd8b796e9e7b67f6d1a92eb676be06b46d1458fc1d +R 23bc39f2089ecb41cbb93275af5fee9c U dan -Z 6fb6c5ab6f440154ac0955e521c66539 +Z d039c7225445fc871711c264f1609f48 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9ab8ad22f..eed93cc4a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fe11f85fd3283bb7002f43bd8b796e9e7b67f6d1a92eb676be06b46d1458fc1d +a35236757ab57c4c9b34e47c5dbc10d8f1220f8152955f5303cf9c3902ee169b diff --git a/src/btree.c b/src/btree.c index 0648566354..25a9b1b4ae 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3697,11 +3697,10 @@ static SQLITE_NOINLINE int btreeBeginTrans( (void)sqlite3PagerWalWriteLock(pPager, 0); unlockBtreeIfUnused(pBt); } -#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_ENABLE_SNAPSHOT) +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) if( rc==SQLITE_BUSY_TIMEOUT ){ /* If a blocking lock timed out, break out of the loop here so that - ** the busy-handler is not invoked. This can only happen when opening - ** a transaction on a snapshot. */ + ** the busy-handler is not invoked. */ break; } #endif diff --git a/src/os_unix.c b/src/os_unix.c index 1146545fea..5bbd7ceb6e 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5043,13 +5043,14 @@ static int unixShmLock( ** occur later in the above list than the lock being obtained may be ** held. ** - ** It is not permitted to block on the RECOVER lock. + ** It is not permitted to block on the RECOVER lock if any other + ** locks are held. */ #if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && defined(SQLITE_DEBUG) { u16 lockMask = (p->exclMask|p->sharedMask); assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2) /* not RECOVER */ + (ofst!=2 || lockMask==0) /* not RECOVER */ && (ofst!=1 || lockMask==0 || lockMask==2) && (ofst!=0 || lockMask<3) && (ofst<3 || lockMask<(1<fd, pPager->zWal, pPager->exclusiveMode, pPager->journalSizeLimit, &pPager->pWal ); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_OK ){ + sqlite3WalDb(pPager->pWal, pPager->dbWal); + } +#endif } pagerFixMaplimit(pPager); @@ -7700,6 +7708,7 @@ int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){ ** blocking locks are required. */ void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ + pPager->dbWal = db; if( pagerUseWal(pPager) ){ sqlite3WalDb(pPager->pWal, db); } diff --git a/src/wal.c b/src/wal.c index 5fe2296d6c..fc176988bd 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3062,7 +3062,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ rc = walIndexReadHdr(pWal, pChanged); } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - walDisableBlocking(pWal); if( rc==SQLITE_BUSY_TIMEOUT ){ rc = SQLITE_BUSY; *pCnt |= WAL_RETRY_BLOCKED_MASK; @@ -3077,6 +3076,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ ** WAL_RETRY this routine will be called again and will probably be ** right on the second iteration. */ + walEnableBlocking(pWal); if( pWal->apWiData[0]==0 ){ /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. ** We assume this is a transient condition, so return WAL_RETRY. The @@ -3093,6 +3093,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ rc = SQLITE_BUSY_RECOVERY; } } + walDisableBlocking(pWal); if( rc!=SQLITE_OK ){ return rc; } diff --git a/test/walsetlk_recover.test b/test/walsetlk_recover.test new file mode 100644 index 0000000000..3954cafff2 --- /dev/null +++ b/test/walsetlk_recover.test @@ -0,0 +1,96 @@ +# 2025 May 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# TESTRUNNER: slow +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +set testprefix walsetlk_recover + +ifcapable !wal {finish_test ; return } +ifcapable !setlk_timeout {finish_test ; return } +ifcapable !snapshot {finish_test; return} + +do_execsql_test 1.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); +} {wal} + +db_save_and_close +db_restore + +testfixture_nb myvar { + + testvfs tvfs -fullshm 1 + sqlite3 db test.db -vfs tvfs + tvfs script vfs_callback + tvfs filter xRead + + set ::done 0 + proc vfs_callback {method file args} { + if {$::done==0 && [string match *wal $file]} { + after 4000 + set ::done 1 + } + return "SQLITE_OK" + } + + db eval { + SELECT * FROM t1 + } + + db close +} + +# Give the [testfixture_nb] command time to start +after 1000 + +testvfs tvfs -fullshm 1 +sqlite3 db test.db -vfs tvfs + +tvfs script sleep_callback +tvfs filter xSleep +set ::sleep_count 0 +proc sleep_callback {args} { + incr ::sleep_count +} + +sqlite3 db test.db -vfs tvfs +sqlite3_setlk_timeout db 500 +set tm [lindex [time { + catch { + db eval {SELECT * FROM t1} + } msg +}] 0] + +do_test 1.2 { set ::msg } {database is locked} +do_test 1.3.($::tm) { expr $::tm>400000 && $::tm<1000000 } 1 + +vwait myvar + +do_execsql_test 1.4 { + SELECT * FROM t1 +} {1 2 3 4 5 6} + +db close +tvfs delete + +do_test 1.5 { + set ::sleep_count +} 0 + +finish_test + From d930d7ef14b2449bd9d8c18ed6aaf8a27a9f16d9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 30 May 2025 22:58:09 +0000 Subject: [PATCH 12/35] Follow-up to the previous: The same optimization suppression needs to happen if the left-hand side is coming from a LEFT JOIN. FossilOrigin-Name: cf5b37b3a39013d8ca9de92da2289346caf52b56daff59e19b140cc586a3421f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 3 +++ test/join.test | 22 ++++++++++++++++------ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 2ab4f5294a..97b099429a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\ssynthesizing\san\sON\sconstraint\sfrom\sa\sUSING\sor\sNATURAL,\sif\sthe\sleft-hand\nside\sis\scoming\sfrom\sa\sRIGHT\sJOIN,\sbe\ssure\sto\sset\sthe\sEP_CanBeNull\sflag\sso\sthat\nthe\soptimizer\sknows\sto\scheck\sfor\sNULL\seven\sif\sthe\scolumn\shas\sa\sNOT\sNULL\nconstraint.\s\sFix\sfor\sthe\sproblem\sreported\sby\n[forum:/forumpost/4fc70203b61c7e12|forum\spost\s4fc70203b61] -D 2025-05-30T19:55:46.105 +C Follow-up\sto\sthe\sprevious:\s\sThe\ssame\soptimization\ssuppression\sneeds\sto\nhappen\sif\sthe\sleft-hand\sside\sis\scoming\sfrom\sa\sLEFT\sJOIN. +D 2025-05-30T22:58:09.842 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 3b91c334f528359145f4dde0dedd945bbb21044d0825ea064934d7222d61662c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 571fff5cf453c3cafc122873b982dff39075e1edd1afec707216c9b534fde7bf +F src/select.c fd56257d2539dc21d68000ca97f6312c99942fed56833234827d42f6443014dd F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8f F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -1361,7 +1361,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 5984da7bf74b6540aa356f2ab0c6ae68a6d12039a3d798a9ac6a100abc17d520 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test 015ef539ea2b779d0a219f4c0f82f39bf20884aed42142165e56791094d1cf3d +F test/join.test 255c1f42b7fe027b518cadb2bf40f41a793a95e7f8db2bceb54faaf59ff19c6c F test/join2.test f59d63264fb24784ae9c3bc9d867eb569cd6d442da5660f8852effe5c1938c27 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2e486f8fd011d28fdd7e59ff34f7f04374019932eb160a8c4de56a5ce01e5782 -R 4fc3d788e929e3ad2e87da5f4f76e5b7 +P 60adc78a22956429d34ccc4e2c193c5994c11c3b3cff7901d47fad7d92dba935 +R 97620573742ac25256c1feca444af822 U drh -Z b8769468b1683decb71b7b0ba97e34bc +Z 1fe0e4eaf3e0e7c16ee0e5bb057e90f7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 31fbda4e91..b8fffa363c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60adc78a22956429d34ccc4e2c193c5994c11c3b3cff7901d47fad7d92dba935 +cf5b37b3a39013d8ca9de92da2289346caf52b56daff59e19b140cc586a3421f diff --git a/src/select.c b/src/select.c index da0aa63e43..81cb1184ed 100644 --- a/src/select.c +++ b/src/select.c @@ -631,6 +631,9 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); } + }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ + assert( pE1!=0 ); + ExprSetProperty(pE1, EP_CanBeNull); } pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); sqlite3SrcItemColumnUsed(pRight, iRightCol); diff --git a/test/join.test b/test/join.test index 789ae0124f..ef2f6335c5 100644 --- a/test/join.test +++ b/test/join.test @@ -1316,20 +1316,30 @@ do_execsql_test join-31.1 { CREATE TABLE t1(c0 INT , c1 INT); INSERT INTO t1(c0, c1) VALUES(NULL,11); CREATE TABLE t2(c0 INT NOT NULL); CREATE TABLE t2n(c0 INT); - CREATE TABLE t3(x INT); INSERT INTO t3(x) VALUES(4); - CREATE TABLE t5(c0 INT, x INT); INSERT INTO t5 VALUES(NULL, 4); + CREATE TABLE t3(x INT); INSERT INTO t3(x) VALUES(3); + CREATE TABLE t4(y INT); INSERT INTO t4(y) VALUES(4); + CREATE TABLE t5(c0 INT, x INT); INSERT INTO t5 VALUES(NULL, 5); } do_execsql_test join-31.2 { SELECT * FROM t2 RIGHT JOIN t3 ON true LEFT JOIN t1 USING(c0); -} {NULL 4 NULL} +} {NULL 3 NULL} do_execsql_test join-31.3 { SELECT * FROM t2 RIGHT JOIN t3 ON true NATURAL LEFT JOIN t1; -} {NULL 4 NULL} +} {NULL 3 NULL} do_execsql_test join-31.4 { SELECT * FROM t2n RIGHT JOIN t3 ON true LEFT JOIN t1 USING(c0); -} {NULL 4 NULL} +} {NULL 3 NULL} do_execsql_test join-31.5 { SELECT * FROM t5 LEFT JOIN t1 USING(c0); -} {NULL 4 NULL} +} {NULL 5 NULL} +do_execsql_test join-31.6 { + SELECT * FROM t3 LEFT JOIN t2 ON true LEFT JOIN t1 USING(c0); +} {3 NULL NULL} +do_execsql_test join-31.7 { + SELECT * FROM t3 LEFT JOIN t2 ON true NATURAL LEFT JOIN t1; +} {3 NULL NULL} +do_execsql_test join-31.8 { + SELECT * FROM t3 LEFT JOIN t2 ON true JOIN t4 ON true NATURAL LEFT JOIN t1; +} {3 NULL 4 NULL} finish_test From b504aab848cb6f2c09cc227d0507db17d9af7dc4 Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 31 May 2025 09:44:00 +0000 Subject: [PATCH 13/35] Add some missing UNUSED_PARAMETER() annotations to squelch downstream build warnings when using -Wextra -pedantic. FossilOrigin-Name: a98a2f49355ec39c56e571c70d377675b1bd99a6d43cf9217b0eb1e081895d8e --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/btree.c | 2 ++ src/dbpage.c | 13 +++++++------ src/select.c | 4 ++++ 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 97b099429a..cb40320603 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Follow-up\sto\sthe\sprevious:\s\sThe\ssame\soptimization\ssuppression\sneeds\sto\nhappen\sif\sthe\sleft-hand\sside\sis\scoming\sfrom\sa\sLEFT\sJOIN. -D 2025-05-30T22:58:09.842 +C Add\ssome\smissing\sUNUSED_PARAMETER()\sannotations\sto\ssquelch\sdownstream\sbuild\swarnings\swhen\susing\s-Wextra\s-pedantic. +D 2025-05-31T09:44:00.684 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -726,14 +726,14 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 782cc29b42b47e7ec6348eb0aaf9ffe60063f498387e7249f458d445af4b53e9 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c 00fcee37947641f48d4b529d96143e74d056b7afa8f26d61292c90ee59c056b2 +F src/btree.c cb028cb29e57b8767cb0973e66659f305dcb8dc1c2402e10ad462a89ec640ef5 F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f F src/callback.c acae8c8dddda41ee85cfdf19b926eefe830f371069f8aadca3aa39adf5b1c859 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 -F src/dbpage.c fcb1aafe00872a8aff9a7aa0ef7ff1b01e5817ec7bbd521f8f3e1e674ac8d609 +F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 F src/expr.c 6f184da1f36576ad1ecc48a03f14774235373c64f88d462c710834930ee6c145 @@ -785,7 +785,7 @@ F src/printf.c 3b91c334f528359145f4dde0dedd945bbb21044d0825ea064934d7222d61662c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c fd56257d2539dc21d68000ca97f6312c99942fed56833234827d42f6443014dd +F src/select.c 5145c03d216cf3cd5b0101b77ce2e8d7e2f1622f07a03d0783a8f80c83ca110f F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8f F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 60adc78a22956429d34ccc4e2c193c5994c11c3b3cff7901d47fad7d92dba935 -R 97620573742ac25256c1feca444af822 -U drh -Z 1fe0e4eaf3e0e7c16ee0e5bb057e90f7 +P cf5b37b3a39013d8ca9de92da2289346caf52b56daff59e19b140cc586a3421f +R bf16fd55e66316305a43e4a57281b369 +U stephan +Z 52f694bf6ce8c40102964ca1cfc5e8c9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b8fffa363c..941391085b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf5b37b3a39013d8ca9de92da2289346caf52b56daff59e19b140cc586a3421f +a98a2f49355ec39c56e571c70d377675b1bd99a6d43cf9217b0eb1e081895d8e diff --git a/src/btree.c b/src/btree.c index 1bd59a1b1f..ed1dde98c8 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2856,6 +2856,7 @@ static int removeFromSharingList(BtShared *pBt){ sqlite3_mutex_leave(pMainMtx); return removed; #else + UNUSED_PARAMETER( pBt ); return 1; #endif } @@ -11317,6 +11318,7 @@ void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ */ int sqlite3BtreeSchemaLocked(Btree *p){ int rc; + UNUSED_PARAMETER(p); /* only used in DEBUG builds */ assert( sqlite3_mutex_held(p->db->mutex) ); sqlite3BtreeEnter(p); rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); diff --git a/src/dbpage.c b/src/dbpage.c index f9fdcc5a37..4e2addad90 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -227,7 +227,7 @@ static int dbpageEof(sqlite3_vtab_cursor *pCursor){ ** idxStr is not used */ static int dbpageFilter( - sqlite3_vtab_cursor *pCursor, + sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -237,10 +237,11 @@ static int dbpageFilter( sqlite3 *db = pTab->db; Btree *pBt; - (void)idxStr; - + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(argc); + /* Default setting is no rows of result */ - pCsr->pgno = 1; + pCsr->pgno = 1; pCsr->mxPgno = 0; if( idxNum & 2 ){ @@ -275,8 +276,8 @@ static int dbpageFilter( } static int dbpageColumn( - sqlite3_vtab_cursor *pCursor, - sqlite3_context *ctx, + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, int i ){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; diff --git a/src/select.c b/src/select.c index 81cb1184ed..a8af934e42 100644 --- a/src/select.c +++ b/src/select.c @@ -2110,6 +2110,10 @@ static void generateColumnTypes( #endif sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); } +#else + UNUSED_PARAMETER(pParse); + UNUSED_PARAMETER(pTabList); + UNUSED_PARAMETER(pEList); #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ } From 10206572b6057c98ce9a7f2c7a9cedfdc0818d4c Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 31 May 2025 11:02:06 +0000 Subject: [PATCH 14/35] tcl extension: UDFs may now 'break' to return an SQL NULL. Add the (eval -asdict) flag to use a dict, instead of an array, for the eval row data. FossilOrigin-Name: 413a626b5c7902c1810142536c36e4ea8ee7c616ea82dfe1114199f9319091f7 --- manifest | 14 ++-- manifest.uuid | 2 +- src/tclsqlite.c | 138 +++++++++++++++++++++++++++------------ test/tclsqlite.test | 153 +++++++++++++++++++++++++++++++------------- 4 files changed, 213 insertions(+), 94 deletions(-) diff --git a/manifest b/manifest index cb40320603..9411b20b10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\smissing\sUNUSED_PARAMETER()\sannotations\sto\ssquelch\sdownstream\sbuild\swarnings\swhen\susing\s-Wextra\s-pedantic. -D 2025-05-31T09:44:00.684 +C tcl\sextension:\sUDFs\smay\snow\s'break'\sto\sreturn\san\sSQL\sNULL.\sAdd\sthe\s(eval\s-asdict)\sflag\sto\suse\sa\sdict,\sinstead\sof\san\sarray,\sfor\sthe\seval\srow\sdata. +D 2025-05-31T11:02:06.099 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -794,7 +794,7 @@ F src/sqliteInt.h bb9137b860b2416b12788f09b32384ceab96b720aae07a6e9afacc545e4361 F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c d0e63ffe7944dd223bf62066d9f982cbee1978811c7fbfd889f4ba9c5baed3d1 +F src/tclsqlite.c 3c604c49e6cf4211960a9ddb9505280fd22cde32175f40884c641c0f5a286036 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 F src/test1.c 9b54135e5f1352f06b1d23d7c183f124c1f33de6ea8997cd801f0f215c43591d F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff @@ -1725,7 +1725,7 @@ F test/tabfunc01.test 8a484fe8b19fc24844f72ca1ceb7c9ae8c9a6bca000a5c6ccab5d89f5c F test/table.test e87294bf1c80bfd7792142b84ab32ea5beb4f3f71e535d7fb263a6b2068377bf F test/tableapi.test e37c33e6be2276e3a96bb54b00eea7f321277115d10e5b30fdb52a112b432750 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test ad0bbd92edabe64cc91d990a0748142fe5ab962d74ac71fa3bfa94d50d2f4c87 +F test/tclsqlite.test 3f697424cfc1cdc9c076ec0cadb0e700f059400a3e3ce134b7d856fc9f880e1c F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cf5b37b3a39013d8ca9de92da2289346caf52b56daff59e19b140cc586a3421f -R bf16fd55e66316305a43e4a57281b369 +P a98a2f49355ec39c56e571c70d377675b1bd99a6d43cf9217b0eb1e081895d8e +R b5e249a32712c6263d2ec9033caa9f81 U stephan -Z 52f694bf6ce8c40102964ca1cfc5e8c9 +Z 24f79bc914343b0b71f5079a7d4e350f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 941391085b..df508c2ee7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a98a2f49355ec39c56e571c70d377675b1bd99a6d43cf9217b0eb1e081895d8e +413a626b5c7902c1810142536c36e4ea8ee7c616ea82dfe1114199f9319091f7 diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 8c40b86922..02a4d84e46 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -49,6 +49,10 @@ # define CONST const #elif !defined(Tcl_Size) typedef int Tcl_Size; +# ifndef Tcl_BounceRefCount +# define Tcl_BounceRefCount(X) Tcl_IncrRefCount(X); Tcl_DecrRefCount(X) + /* https://www.tcl-lang.org/man/tcl9.0/TclLib/Object.html */ +# endif #endif /**** End copy of tclsqlite.h ****/ @@ -1084,7 +1088,9 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ Tcl_DecrRefCount(pCmd); } - if( rc && rc!=TCL_RETURN ){ + if( TCL_BREAK==rc ){ + sqlite3_result_null(context); + }else if( rc && rc!=TCL_RETURN ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); @@ -1102,7 +1108,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ }else if( (c=='b' && pVar->bytes==0 && strcmp(zType,"boolean")==0 ) || (c=='b' && pVar->bytes==0 && strcmp(zType,"booleanString")==0 ) || (c=='w' && strcmp(zType,"wideInt")==0) - || (c=='i' && strcmp(zType,"int")==0) + || (c=='i' && strcmp(zType,"int")==0) ){ eType = SQLITE_INTEGER; }else if( c=='d' && strcmp(zType,"double")==0 ){ @@ -1616,11 +1622,12 @@ struct DbEvalContext { SqlPreparedStmt *pPreStmt; /* Current statement */ int nCol; /* Number of columns returned by pStmt */ int evalFlags; /* Flags used */ - Tcl_Obj *pArray; /* Name of array variable */ + Tcl_Obj *pVarName; /* Name of target array/dict variable */ Tcl_Obj **apColName; /* Array of column names */ }; #define SQLITE_EVAL_WITHOUTNULLS 0x00001 /* Unset array(*) for NULL */ +#define SQLITE_EVAL_ASDICT 0x00002 /* Use dict instead of array */ /* ** Release any cache of column names currently held as part of @@ -1641,20 +1648,20 @@ static void dbReleaseColumnNames(DbEvalContext *p){ /* ** Initialize a DbEvalContext structure. ** -** If pArray is not NULL, then it contains the name of a Tcl array +** If pVarName is not NULL, then it contains the name of a Tcl array ** variable. The "*" member of this array is set to a list containing ** the names of the columns returned by the statement as part of each ** call to dbEvalStep(), in order from left to right. e.g. if the names ** of the returned columns are a, b and c, it does the equivalent of the ** tcl command: ** -** set ${pArray}(*) {a b c} +** set ${pVarName}(*) {a b c} */ static void dbEvalInit( DbEvalContext *p, /* Pointer to structure to initialize */ SqliteDb *pDb, /* Database handle */ Tcl_Obj *pSql, /* Object containing SQL script */ - Tcl_Obj *pArray, /* Name of Tcl array to set (*) element of */ + Tcl_Obj *pVarName, /* Name of Tcl array to set (*) element of */ int evalFlags /* Flags controlling evaluation */ ){ memset(p, 0, sizeof(DbEvalContext)); @@ -1662,9 +1669,9 @@ static void dbEvalInit( p->zSql = Tcl_GetString(pSql); p->pSql = pSql; Tcl_IncrRefCount(pSql); - if( pArray ){ - p->pArray = pArray; - Tcl_IncrRefCount(pArray); + if( pVarName ){ + p->pVarName = pVarName; + Tcl_IncrRefCount(pVarName); } p->evalFlags = evalFlags; addDatabaseRef(p->pDb); @@ -1687,7 +1694,7 @@ static void dbEvalRowInfo( Tcl_Obj **apColName = 0; /* Array of column names */ p->nCol = nCol = sqlite3_column_count(pStmt); - if( nCol>0 && (papColName || p->pArray) ){ + if( nCol>0 && (papColName || p->pVarName) ){ apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol ); for(i=0; iapColName = apColName; } - /* If results are being stored in an array variable, then create - ** the array(*) entry for that array + /* If results are being stored in a variable then create the + ** array(*) or dict(*) entry for that variable. */ - if( p->pArray ){ + if( p->pVarName ){ Tcl_Interp *interp = p->pDb->interp; Tcl_Obj *pColList = Tcl_NewObj(); Tcl_Obj *pStar = Tcl_NewStringObj("*", -1); + Tcl_IncrRefCount(pColList); + Tcl_IncrRefCount(pStar); for(i=0; ipArray, pStar, pColList, 0); + if( 0==(SQLITE_EVAL_ASDICT & p->evalFlags) ){ + Tcl_ObjSetVar2(interp, p->pVarName, pStar, pColList, 0); + }else{ + Tcl_Obj * pDict = Tcl_ObjGetVar2(interp, p->pVarName, NULL, 0); + if( !pDict ){ + pDict = Tcl_NewDictObj(); + }else if( Tcl_IsShared(pDict) ){ + pDict = Tcl_DuplicateObj(pDict); + } + if( Tcl_DictObjPut(interp, pDict, pStar, pColList)==TCL_OK ){ + Tcl_ObjSetVar2(interp, p->pVarName, NULL, pDict, 0); + } + Tcl_BounceRefCount(pDict); + } Tcl_DecrRefCount(pStar); + Tcl_DecrRefCount(pColList); } } @@ -1751,7 +1773,7 @@ static int dbEvalStep(DbEvalContext *p){ if( rcs==SQLITE_ROW ){ return TCL_OK; } - if( p->pArray ){ + if( p->pVarName ){ dbEvalRowInfo(p, 0, 0); } rcs = sqlite3_reset(pStmt); @@ -1802,9 +1824,9 @@ static void dbEvalFinalize(DbEvalContext *p){ dbReleaseStmt(p->pDb, p->pPreStmt, 0); p->pPreStmt = 0; } - if( p->pArray ){ - Tcl_DecrRefCount(p->pArray); - p->pArray = 0; + if( p->pVarName ){ + Tcl_DecrRefCount(p->pVarName); + p->pVarName = 0; } Tcl_DecrRefCount(p->pSql); dbReleaseColumnNames(p); @@ -1879,7 +1901,7 @@ static int DbUseNre(void){ /* ** This function is part of the implementation of the command: ** -** $db eval SQL ?ARRAYNAME? SCRIPT +** $db eval SQL ?TGT-NAME? SCRIPT */ static int SQLITE_TCLAPI DbEvalNextCmd( ClientData data[], /* data[0] is the (DbEvalContext*) */ @@ -1893,8 +1915,8 @@ static int SQLITE_TCLAPI DbEvalNextCmd( ** is a pointer to a Tcl_Obj containing the script to run for each row ** returned by the queries encapsulated in data[0]. */ DbEvalContext *p = (DbEvalContext *)data[0]; - Tcl_Obj *pScript = (Tcl_Obj *)data[1]; - Tcl_Obj *pArray = p->pArray; + Tcl_Obj * const pScript = (Tcl_Obj *)data[1]; + Tcl_Obj * const pVarName = p->pVarName; while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){ int i; @@ -1902,15 +1924,46 @@ static int SQLITE_TCLAPI DbEvalNextCmd( Tcl_Obj **apColName; dbEvalRowInfo(p, &nCol, &apColName); for(i=0; ievalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0 - && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL + && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL ){ - Tcl_UnsetVar2(interp, Tcl_GetString(pArray), - Tcl_GetString(apColName[i]), 0); + /* Remove NULL-containing column from the target container... */ + if( 0==(SQLITE_EVAL_ASDICT & p->evalFlags) ){ + /* Target is an array */ + Tcl_UnsetVar2(interp, Tcl_GetString(pVarName), + Tcl_GetString(apColName[i]), 0); + }else{ + /* Target is a dict */ + Tcl_Obj *pDict = Tcl_ObjGetVar2(interp, pVarName, NULL, 0); + if( pDict ){ + if( Tcl_IsShared(pDict) ){ + pDict = Tcl_DuplicateObj(pDict); + } + if( Tcl_DictObjRemove(interp, pDict, apColName[i])==TCL_OK ){ + Tcl_ObjSetVar2(interp, pVarName, NULL, pDict, 0); + } + Tcl_BounceRefCount(pDict); + } + } + }else if( 0==(SQLITE_EVAL_ASDICT & p->evalFlags) ){ + /* Target is an array: set target(colName) = colValue */ + Tcl_ObjSetVar2(interp, pVarName, apColName[i], + dbEvalColumnValue(p,i), 0); }else{ - Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0); + /* Target is a dict: set target(colName) = colValue */ + Tcl_Obj *pDict = Tcl_ObjGetVar2(interp, pVarName, NULL, 0); + if( !pDict ){ + pDict = Tcl_NewDictObj(); + }else if( Tcl_IsShared(pDict) ){ + pDict = Tcl_DuplicateObj(pDict); + } + if( Tcl_DictObjPut(interp, pDict, apColName[i], + dbEvalColumnValue(p,i))==TCL_OK ){ + Tcl_ObjSetVar2(interp, pVarName, NULL, pDict, 0); + } + Tcl_BounceRefCount(pDict); } } @@ -2019,7 +2072,7 @@ static int SQLITE_TCLAPI DbObjCmd( "timeout", "total_changes", "trace", "trace_v2", "transaction", "unlock_notify", "update_hook", "version", "wal_hook", - 0 + 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, @@ -2853,13 +2906,15 @@ deserialize_error: } /* - ** $db eval ?options? $sql ?array? ?{ ...code... }? + ** $db eval ?options? $sql ?varName? ?{ ...code... }? ** - ** The SQL statement in $sql is evaluated. For each row, the values are - ** placed in elements of the array named "array" and ...code... is executed. - ** If "array" and "code" are omitted, then no callback is every invoked. - ** If "array" is an empty string, then the values are placed in variables - ** that have the same name as the fields extracted by the query. + ** The SQL statement in $sql is evaluated. For each row, the values + ** are placed in elements of the array or dict named $varName and + ** ...code... is executed. If $varName and $code are omitted, then + ** no callback is ever invoked. If $varName is an empty string, + ** then the values are placed in variables that have the same name + ** as the fields extracted by the query, and those variables are + ** accessible during the eval of $code. */ case DB_EVAL: { int evalFlags = 0; @@ -2867,8 +2922,9 @@ deserialize_error: while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){ if( strcmp(zOpt, "-withoutnulls")==0 ){ evalFlags |= SQLITE_EVAL_WITHOUTNULLS; - } - else{ + }else if( strcmp(zOpt, "-asdict")==0 ){ + evalFlags |= SQLITE_EVAL_ASDICT; + }else{ Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0); return TCL_ERROR; } @@ -2876,8 +2932,8 @@ deserialize_error: objv++; } if( objc<3 || objc>5 ){ - Tcl_WrongNumArgs(interp, 2, objv, - "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"); + Tcl_WrongNumArgs(interp, 2, objv, + "?OPTIONS? SQL ?VAR-NAME? ?SCRIPT?"); return TCL_ERROR; } @@ -2903,17 +2959,17 @@ deserialize_error: }else{ ClientData cd2[2]; DbEvalContext *p; - Tcl_Obj *pArray = 0; + Tcl_Obj *pVarName = 0; Tcl_Obj *pScript; if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){ - pArray = objv[3]; + pVarName = objv[3]; } pScript = objv[objc-1]; Tcl_IncrRefCount(pScript); p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext)); - dbEvalInit(p, pDb, objv[2], pArray, evalFlags); + dbEvalInit(p, pDb, objv[2], pVarName, evalFlags); cd2[0] = (void *)p; cd2[1] = (void *)pScript; diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 0758abd822..5f373ea18a 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -9,7 +9,7 @@ # #*********************************************************************** # This file implements regression tests for TCL interface to the -# SQLite library. +# SQLite library. # # Actually, all tests are based on the TCL interface, so the main # interface is pretty well tested. This file contains some addition @@ -121,7 +121,7 @@ ifcapable {complete} { do_test tcl-1.14 { set v [catch {db eval} msg] lappend v $msg -} {1 {wrong # args: should be "db eval ?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?"}} +} {1 {wrong # args: should be "db eval ?OPTIONS? SQL ?VAR-NAME? ?SCRIPT?"}} do_test tcl-1.15 { set v [catch {db function} msg] lappend v $msg @@ -359,6 +359,19 @@ do_test tcl-9.3 { execsql {SELECT typeof(ret_int())} } {integer} +proc breakAsNullUdf args { + if {"1" eq [lindex $args 0]} {return -code break} +} +do_test tcl-9.4 { + db function banu breakAsNullUdf + execsql {SELECT typeof(banu()), typeof(banu(1))} +} {text null} +do_test tcl-9.5 { + db nullvalue banunull + db eval {SELECT banu(), banu(1)} +} {{} banunull} + + # Recursive calls to the same user-defined function # ifcapable tclvar { @@ -465,7 +478,7 @@ do_test tcl-10.13 { db eval {SELECT * FROM t4} } {1 2 5 6 7} -# Now test that [db transaction] commands may be nested with +# Now test that [db transaction] commands may be nested with # the expected results. # do_test tcl-10.14 { @@ -475,7 +488,7 @@ do_test tcl-10.14 { INSERT INTO t4 VALUES('one'); } - catch { + catch { db transaction { db eval { INSERT INTO t4 VALUES('two') } db transaction { @@ -674,11 +687,11 @@ do_test tcl-15.5 { } {0} -# 2017-06-26: The --withoutnulls flag to "db eval". +# 2017-06-26: The -withoutnulls flag to "db eval". # -# In the "db eval --withoutnulls SQL ARRAY" form, NULL results cause the -# corresponding array entry to be unset. The default behavior (without -# the -withoutnulls flags) is for the corresponding array value to get +# In the "db eval -withoutnulls SQL TARGET" form, NULL results cause the +# corresponding target entry to be unset. The default behavior (without +# the -withoutnulls flags) is for the corresponding target value to get # the [db nullvalue] string. # catch {db close} @@ -720,64 +733,64 @@ reset_db proc add {a b} { return [expr $a + $b] } proc ret {a} { return $a } -db function add_i -returntype integer add +db function add_i -returntype integer add db function add_r -ret real add -db function add_t -return text add -db function add_b -returntype blob add -db function add_a -returntype any add +db function add_t -return text add +db function add_b -returntype blob add +db function add_a -returntype any add -db function ret_i -returntype int ret +db function ret_i -returntype int ret db function ret_r -returntype real ret -db function ret_t -returntype text ret -db function ret_b -returntype blob ret -db function ret_a -r any ret +db function ret_t -returntype text ret +db function ret_b -returntype blob ret +db function ret_a -r any ret do_execsql_test 17.0 { SELECT quote( add_i(2, 3) ); - SELECT quote( add_r(2, 3) ); - SELECT quote( add_t(2, 3) ); - SELECT quote( add_b(2, 3) ); - SELECT quote( add_a(2, 3) ); + SELECT quote( add_r(2, 3) ); + SELECT quote( add_t(2, 3) ); + SELECT quote( add_b(2, 3) ); + SELECT quote( add_a(2, 3) ); } {5 5.0 '5' X'35' 5} do_execsql_test 17.1 { SELECT quote( add_i(2.2, 3.3) ); - SELECT quote( add_r(2.2, 3.3) ); - SELECT quote( add_t(2.2, 3.3) ); - SELECT quote( add_b(2.2, 3.3) ); - SELECT quote( add_a(2.2, 3.3) ); + SELECT quote( add_r(2.2, 3.3) ); + SELECT quote( add_t(2.2, 3.3) ); + SELECT quote( add_b(2.2, 3.3) ); + SELECT quote( add_a(2.2, 3.3) ); } {5.5 5.5 '5.5' X'352E35' 5.5} do_execsql_test 17.2 { SELECT quote( ret_i(2.5) ); - SELECT quote( ret_r(2.5) ); - SELECT quote( ret_t(2.5) ); - SELECT quote( ret_b(2.5) ); - SELECT quote( ret_a(2.5) ); + SELECT quote( ret_r(2.5) ); + SELECT quote( ret_t(2.5) ); + SELECT quote( ret_b(2.5) ); + SELECT quote( ret_a(2.5) ); } {2.5 2.5 '2.5' X'322E35' 2.5} do_execsql_test 17.3 { SELECT quote( ret_i('2.5') ); - SELECT quote( ret_r('2.5') ); - SELECT quote( ret_t('2.5') ); - SELECT quote( ret_b('2.5') ); - SELECT quote( ret_a('2.5') ); + SELECT quote( ret_r('2.5') ); + SELECT quote( ret_t('2.5') ); + SELECT quote( ret_b('2.5') ); + SELECT quote( ret_a('2.5') ); } {2.5 2.5 '2.5' X'322E35' '2.5'} do_execsql_test 17.4 { SELECT quote( ret_i('abc') ); - SELECT quote( ret_r('abc') ); - SELECT quote( ret_t('abc') ); - SELECT quote( ret_b('abc') ); - SELECT quote( ret_a('abc') ); + SELECT quote( ret_r('abc') ); + SELECT quote( ret_t('abc') ); + SELECT quote( ret_b('abc') ); + SELECT quote( ret_a('abc') ); } {'abc' 'abc' 'abc' X'616263' 'abc'} do_execsql_test 17.5 { SELECT quote( ret_i(X'616263') ); - SELECT quote( ret_r(X'616263') ); - SELECT quote( ret_t(X'616263') ); - SELECT quote( ret_b(X'616263') ); - SELECT quote( ret_a(X'616263') ); + SELECT quote( ret_r(X'616263') ); + SELECT quote( ret_t(X'616263') ); + SELECT quote( ret_b(X'616263') ); + SELECT quote( ret_a(X'616263') ); } {'abc' 'abc' 'abc' X'616263' X'616263'} do_test 17.6.1 { @@ -848,21 +861,70 @@ do_catchsql_test 19.911 { } {1 {invalid command name "bind_fallback_does_not_exist"}} db bind_fallback {} -#------------------------------------------------------------------------- +# 2025-05-05: the -asdict eval flag +# do_test 20.0 { + execsql {CREATE TABLE tad(a,b)} + execsql {INSERT INTO tad(a,b) VALUES('aa','bb'),('AA','BB')} + db eval -asdict { + SELECT a, b FROM tad WHERE 0 + } D {} + set D +} {* {a b}} + +do_test 20.1 { + unset D + set i 0 + set res {} + set colNames {} + db eval -asdict { + SELECT a, b FROM tad ORDER BY a + } D { + dict set D i [incr i] + lappend res $i [dict get $D a] [dict get $D b] + if {1 == $i} { + set colNames [dict get $D *] + } + } + lappend res $colNames + unset D + set res +} {1 AA BB 2 aa bb {a b}} + +do_test 20.2 { + set res {} + db eval -asdict -withoutnulls { + SELECT n, a, b FROM ( + SELECT 1 as n, 'aa' as a, NULL as b + UNION ALL + SELECT 2 as n, NULL as a, 'bb' as b + ) + ORDER BY n + } D { + dict unset D * + lappend res [dict values $D] + } + unset D + execsql {DROP TABLE tad} + set res +} {{1 aa} {2 bb}} + +#------------------------------------------------------------------------- +do_test 21.0 { db transaction { db close } } {} -do_test 20.1 { +do_test 21.1 { sqlite3 db test.db set rc [catch { db eval {SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3} { db close } } msg] list $rc $msg } {1 {invalid command name "db"}} - + + proc closedb {} { db close @@ -874,7 +936,7 @@ sqlite3 db test.db db func closedb closedb db func func1 func1 -do_test 20.2 { +do_test 21.2 { set rc [catch { db eval { SELECT closedb(),func1() UNION ALL SELECT 20,30 UNION ALL SELECT 30,40 @@ -884,9 +946,10 @@ do_test 20.2 { } {0 {10 1 20 30 30 40}} sqlite3 db :memory: -do_test 21.1 { +do_test 22.1 { catch {db eval {SELECT 1 2 3;}} msg db erroroffset } {9} + finish_test From 1ff4233f903d0fae532a6bda64ccbb7a319e13db Mon Sep 17 00:00:00 2001 From: stephan Date: Sat, 31 May 2025 11:08:06 +0000 Subject: [PATCH 15/35] Move a mis-located makefile comment block. FossilOrigin-Name: 7d884386bec11f47c2c18002dd8c573c9b5cb6f7cdf2307a96cccead05b6abf2 --- ext/wasm/GNUmakefile | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index 6470fd6308..28387872f0 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -598,8 +598,6 @@ emcc.flags += -v endif -# wasmMemory ==> required by our code for use with -sIMPORTED_MEMORY -# Emscripten 4.0.7 (2025-04-15) stops exporting HEAP* by default ######################################################################## # emcc flags for .c/.o. emcc.cflags := @@ -619,6 +617,8 @@ emcc.jsflags += -sNO_POLYFILL emcc.jsflags += -sEXPORTED_FUNCTIONS=@$(EXPORTED_FUNCTIONS.api) emcc.exportedRuntimeMethods := \ -sEXPORTED_RUNTIME_METHODS=wasmMemory,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAP64,HEAPU64 +# wasmMemory ==> required by our code for use with -sIMPORTED_MEMORY +# Emscripten 4.0.7 (2025-04-15) stops exporting HEAP* by default emcc.jsflags += $(emcc.exportedRuntimeMethods) emcc.jsflags += -sUSE_CLOSURE_COMPILER=0 emcc.jsflags += -sIMPORTED_MEMORY diff --git a/manifest b/manifest index 9411b20b10..edb2fc0aed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C tcl\sextension:\sUDFs\smay\snow\s'break'\sto\sreturn\san\sSQL\sNULL.\sAdd\sthe\s(eval\s-asdict)\sflag\sto\suse\sa\sdict,\sinstead\sof\san\sarray,\sfor\sthe\seval\srow\sdata. -D 2025-05-31T11:02:06.099 +C Move\sa\smis-located\smakefile\scomment\sblock. +D 2025-05-31T11:08:06.337 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -621,7 +621,7 @@ F ext/session/sqlite3session.c 6b0877fe1ab832aa4b85eaca72606dfd1630a1363a1be7af1 F ext/session/sqlite3session.h 9bb1a6687b467764b35178dc29bbd2c57ab8cd3acdc8a62f088c34ad17e4fe2b F ext/session/test_session.c 2ddff73ea368d827028c32851b291416e1008845832feb27b751d15e57e13cc3 F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile d6b869cf3d3eaaec8cf56adf925910c3e443f455562bcb4a4cd2d1e43c933d8d +F ext/wasm/GNUmakefile e315b903c33b28ca074367041849de9dd2681c96d1437c11a5e9596abc265012 F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a F ext/wasm/README.md b89605f65661cf35bf034ff6d43e448cc169b8017fc105d498e33b81218b482c F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a98a2f49355ec39c56e571c70d377675b1bd99a6d43cf9217b0eb1e081895d8e -R b5e249a32712c6263d2ec9033caa9f81 +P 413a626b5c7902c1810142536c36e4ea8ee7c616ea82dfe1114199f9319091f7 +R 0a66ec57047a402dd75f80b24d811cb0 U stephan -Z 24f79bc914343b0b71f5079a7d4e350f +Z b135e4a3d41689a53dcec5acda960e8c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index df508c2ee7..789684a762 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -413a626b5c7902c1810142536c36e4ea8ee7c616ea82dfe1114199f9319091f7 +7d884386bec11f47c2c18002dd8c573c9b5cb6f7cdf2307a96cccead05b6abf2 From 420233e37553f0c1539dbffeebd2e7be6de4be75 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 31 May 2025 15:10:41 +0000 Subject: [PATCH 16/35] Fix assert() statements in os_unix.c and os_win.c. Allow walsetlk_recover.test to run in non-SQLITE_ENABLE_SNAPSHOT builds. FossilOrigin-Name: 9f521ecda2b8d2f383cc84e308b3a4adfcf1bd6339eb834c8fa76c8704c861b7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os_unix.c | 12 +++++------- src/os_win.c | 11 +++++------ test/walsetlk_recover.test | 1 - 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 9f161b1800..58cd7b8b71 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sblocking\slocks\sare\senabled,\savoid\susing\sthe\sbusy\shandler\swhen\sblocked\sby\sanother\sprocess\srunning\srecovery. -D 2025-05-30T20:52:18.193 +C Fix\sassert()\sstatements\sin\sos_unix.c\sand\sos_win.c.\sAllow\swalsetlk_recover.test\sto\srun\sin\snon-SQLITE_ENABLE_SNAPSHOT\sbuilds. +D 2025-05-31T15:10:41.660 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -770,8 +770,8 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 8d9b9efbf337b5d59dbb259b7a8ca745f68d4f15495dbe17737b3c325c226363 -F src/os_win.c b39f31fb0b137d67091d21880f0fded6b1c3c8c59b9e24e42844a1c0070437d4 +F src/os_unix.c 04e054ab86d86a7be99ebe5265922687791a40df5afc781d059beb47f4a40acd +F src/os_win.c 6535f8d41674ec9512b1dc516710af5e210db7e51149a500e14bd5b811000601 F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19 F src/pager.c 23c0f17deb892da6b32fef1f465507df7ab5cd01d774288cb43695658a649259 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 @@ -2036,7 +2036,7 @@ F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533 F test/walsetlk.test 9079cd8ef82570b8cf0067f31e049a72bec353fb2d5f0cc88f1736dc42ba9704 F test/walsetlk2.test 9097083633cdf55bf1098b694fb8651d0356d38fef28b869481d18029d7ceaf4 F test/walsetlk3.test 1b82bd92dea7e58f498b4399b0b3d26773dd8ac5c74205ce4a23c207cb8e85fe -F test/walsetlk_recover.test f653e7c85f77ba51828ba64d2d98f42f4afaf26bbd82ac60fbf1c6c8063e370f +F test/walsetlk_recover.test 7c43dbcf550324ee1b37f40f21150bcbb66a028e4be5f10547599a34ffee9123 F test/walsetlk_snapshot.test 6376fc8a76da4571eb35cf4aef06105f716c5e52f991cefec44b9c7015aadf1e F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fe11f85fd3283bb7002f43bd8b796e9e7b67f6d1a92eb676be06b46d1458fc1d -R 23bc39f2089ecb41cbb93275af5fee9c +P a35236757ab57c4c9b34e47c5dbc10d8f1220f8152955f5303cf9c3902ee169b +R eaf3d33697a02bafeb3824ed740b8b2a U dan -Z d039c7225445fc871711c264f1609f48 +Z 2a8dae12be43752fd4cda67357fb4b7f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eed93cc4a0..0991aa57a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a35236757ab57c4c9b34e47c5dbc10d8f1220f8152955f5303cf9c3902ee169b +9f521ecda2b8d2f383cc84e308b3a4adfcf1bd6339eb834c8fa76c8704c861b7 diff --git a/src/os_unix.c b/src/os_unix.c index 5bbd7ceb6e..784bc35176 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5035,22 +5035,20 @@ static int unixShmLock( /* Check that, if this to be a blocking lock, no locks that occur later ** in the following list than the lock being obtained are already held: ** - ** 1. Checkpointer lock (ofst==1). - ** 2. Write lock (ofst==0). - ** 3. Read locks (ofst>=3 && ofst=3 && ofstexclMask|p->sharedMask); assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2 || lockMask==0) /* not RECOVER */ + (ofst!=2 || lockMask==0) && (ofst!=1 || lockMask==0 || lockMask==2) && (ofst!=0 || lockMask<3) && (ofst<3 || lockMask<(1<=3 && ofst=3 && ofstexclMask|p->sharedMask); assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2) /* not RECOVER */ + (ofst!=2 || lockMask==0) && (ofst!=1 || lockMask==0 || lockMask==2) && (ofst!=0 || lockMask<3) && (ofst<3 || lockMask<(1< Date: Sat, 31 May 2025 16:17:14 +0000 Subject: [PATCH 17/35] Relax query flattener constraint (3b) and thereby allow flattening the RHS of a LEFT JOIN even if the RHS contains a virtual table. This was previously disallowed by [9dbae1df75219e2a] as a performance optimization. It turns out that the constraint causes performance issues, and we do not have a record of any performance issue that it solves. FossilOrigin-Name: 1ddaa92057e550ea281d45d9860eafe69399224725548a93dd91c47a34e52152 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 8 ++++---- test/fts3join.test | 5 +---- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index edb2fc0aed..26c77b26aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sa\smis-located\smakefile\scomment\sblock. -D 2025-05-31T11:08:06.337 +C Relax\squery\sflattener\sconstraint\s(3b)\sand\sthereby\sallow\sflattening\sthe\sRHS\sof\na\sLEFT\sJOIN\seven\sif\sthe\sRHS\scontains\sa\svirtual\stable.\s\sThis\swas\spreviously\ndisallowed\sby\s[9dbae1df75219e2a]\sas\sa\sperformance\soptimization.\s\sIt\nturns\sout\sthat\sthe\sconstraint\scauses\sperformance\sissues,\sand\swe\sdo\snot\shave\na\srecord\sof\sany\sperformance\sissue\sthat\sit\ssolves. +D 2025-05-31T16:17:14.990 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 3b91c334f528359145f4dde0dedd945bbb21044d0825ea064934d7222d61662c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 5145c03d216cf3cd5b0101b77ce2e8d7e2f1622f07a03d0783a8f80c83ca110f +F src/select.c d0dfddf0ded00913570263ed6ef46878efd2a7c824233fd3904c81e4d05bc923 F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8f F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -1222,7 +1222,7 @@ F test/fts3fault3.test ccdd2292dd2d4e21e30fc5f4c8e064f79e516087eec5ff57ab6bc4f6a F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 F test/fts3fuzz001.test c78afcd8ad712ea0b8d2ed50851a8aab3bc9dc52c64a536291e07112f519357c F test/fts3integrity.test 0c6fe7353d7b24d78862f4272ee9df4da2f32b3ff30fa3396945cda8119580a8 -F test/fts3join.test 1a4d786539b2b79a41c28ef2ac22cacd92a8ee830249b68a7dee4a020848e3bb +F test/fts3join.test de31d304ba479043a7d33d2f201c514b3e1da809da6797d7a58704d00e8da2e6 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a F test/fts3matchinfo2.test 00144e841704b8debfcdf6097969cd9f2a1cf759e2203cda42583648f2e6bf58 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 413a626b5c7902c1810142536c36e4ea8ee7c616ea82dfe1114199f9319091f7 -R 0a66ec57047a402dd75f80b24d811cb0 -U stephan -Z b135e4a3d41689a53dcec5acda960e8c +P 7d884386bec11f47c2c18002dd8c573c9b5cb6f7cdf2307a96cccead05b6abf2 +R 52b5e04212112150fc1a41026d6d393f +U drh +Z e8f3cf7347e28213896d8a300a9e60bd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 789684a762..87cb14bcb2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d884386bec11f47c2c18002dd8c573c9b5cb6f7cdf2307a96cccead05b6abf2 +1ddaa92057e550ea281d45d9860eafe69399224725548a93dd91c47a34e52152 diff --git a/src/select.c b/src/select.c index a8af934e42..8eaf5e2b65 100644 --- a/src/select.c +++ b/src/select.c @@ -4245,9 +4245,9 @@ static int compoundHasDifferentAffinities(Select *p){ ** from 2015-02-09.) ** ** (3) If the subquery is the right operand of a LEFT JOIN then -** (3a) the subquery may not be a join and -** (3b) the FROM clause of the subquery may not contain a virtual -** table and +** (3a) the subquery may not be a join +** (**) Was (3b): "the FROM clause of the subquery may not contain +** a virtual table" ** (**) Was: "The outer query may not have a GROUP BY." This case ** is now managed correctly ** (3d) the outer query may not be DISTINCT. @@ -4463,7 +4463,7 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ - || IsVirtual(pSubSrc->a[0].pSTab) /* (3b) */ + /**** || IsVirtual(pSubSrc->a[0].pSTab) (3b)-omitted */ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ diff --git a/test/fts3join.test b/test/fts3join.test index cbd08b63f2..9171c817be 100644 --- a/test/fts3join.test +++ b/test/fts3join.test @@ -97,11 +97,8 @@ do_eqp_test 4.2 { WHERE t4.y = ?; } { QUERY PLAN - |--MATERIALIZE rr - | `--SCAN ft4 VIRTUAL TABLE INDEX 3: |--SCAN t4 - |--BLOOM FILTER ON rr (docid=?) - `--SEARCH rr USING AUTOMATIC COVERING INDEX (docid=?) LEFT-JOIN + `--SCAN ft4 VIRTUAL TABLE INDEX 3: LEFT-JOIN } finish_test From 51e3f855b88835139bddf7367b6df4d488fcaee6 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 31 May 2025 18:16:21 +0000 Subject: [PATCH 18/35] Fix an affinity problem caused by a USING or NATURAL JOIN on the LHS of a FULL JOIN. [forum:/forumpost/5028c785b6|Forum post 5028c785b6]. FossilOrigin-Name: 8d393ca07fe09f48d77adb517e2e4baaa58a9251422de62a0504999205d3ea1d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 3 +++ test/joinH.test | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 26c77b26aa..fc2d45f1aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Relax\squery\sflattener\sconstraint\s(3b)\sand\sthereby\sallow\sflattening\sthe\sRHS\sof\na\sLEFT\sJOIN\seven\sif\sthe\sRHS\scontains\sa\svirtual\stable.\s\sThis\swas\spreviously\ndisallowed\sby\s[9dbae1df75219e2a]\sas\sa\sperformance\soptimization.\s\sIt\nturns\sout\sthat\sthe\sconstraint\scauses\sperformance\sissues,\sand\swe\sdo\snot\shave\na\srecord\sof\sany\sperformance\sissue\sthat\sit\ssolves. -D 2025-05-31T16:17:14.990 +C Fix\san\saffinity\sproblem\scaused\sby\sa\sUSING\sor\sNATURAL\sJOIN\son\sthe\sLHS\sof\sa\sFULL\sJOIN.\s[forum:/forumpost/5028c785b6|Forum\spost\s5028c785b6]. +D 2025-05-31T18:16:21.946 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -785,7 +785,7 @@ F src/printf.c 3b91c334f528359145f4dde0dedd945bbb21044d0825ea064934d7222d61662c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c d0dfddf0ded00913570263ed6ef46878efd2a7c824233fd3904c81e4d05bc923 +F src/select.c 9929e56e78f958657bfbb8234916473468243f90af359cc646d97c3ee809c79c F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8f F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 @@ -1376,7 +1376,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2 F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28 F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127 -F test/joinH.test 55f69e64da74d4eca2235237f3acb657aef181e22e45daa228e35bba865e0255 +F test/joinH.test 29a25ea2c6323c6dd1ee7f2da906f24efbd467d60a9531e6704b8e2c88de9b9a F test/journal1.test bc61a4228db11bffca118bd358ba4b868524bf080f3532749de6c539656e20fa F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test e5aeff93a7776cf644dbc48dec277655cff80a1cd24689036abc87869b120ea6 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7d884386bec11f47c2c18002dd8c573c9b5cb6f7cdf2307a96cccead05b6abf2 -R 52b5e04212112150fc1a41026d6d393f -U drh -Z e8f3cf7347e28213896d8a300a9e60bd +P 1ddaa92057e550ea281d45d9860eafe69399224725548a93dd91c47a34e52152 +R 89af89664e25dccfda8f6cb0f81b4128 +U dan +Z bd82500cd206375faf72e64feca43230 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 87cb14bcb2..a49fea986c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ddaa92057e550ea281d45d9860eafe69399224725548a93dd91c47a34e52152 +8d393ca07fe09f48d77adb517e2e4baaa58a9251422de62a0504999205d3ea1d diff --git a/src/select.c b/src/select.c index 8eaf5e2b65..1525a4640a 100644 --- a/src/select.c +++ b/src/select.c @@ -630,6 +630,9 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ if( pFuncArgs ){ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); + if( pE1 ){ + pE1->affExpr = sqlite3ExprAffinity(pFuncArgs->a[0].pExpr); + } } }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ assert( pE1!=0 ); diff --git a/test/joinH.test b/test/joinH.test index 908b93dee5..822ba45b21 100644 --- a/test/joinH.test +++ b/test/joinH.test @@ -341,4 +341,53 @@ do_execsql_test 13.4 { GROUP BY a1.a ORDER BY 1; } {-1480 240 480} +#------------------------------------------------------------------------- +# 2025-05-30 +# https://sqlite.org/forum/forumpost/5028c785b6 +# +reset_db + +do_execsql_test 14.0 { + CREATE TABLE t1(c0 INT); + CREATE TABLE t2(c0 BLOB); + CREATE TABLE t3(c0 BLOB); + CREATE TABLE t4(c4 BLOB); + INSERT INTO t1(c0) VALUES(0); + INSERT INTO t3(c0) VALUES('0'); +} + +do_execsql_test 14.1.1 { + SELECT * FROM t1 NATURAL LEFT JOIN t2 NATURAL JOIN t3; +} {0} + +do_execsql_test 14.1.2 { + SELECT * FROM t1 NATURAL LEFT JOIN t2 NATURAL JOIN t3 FULL JOIN t4 ON true; +} {0 {}} + +do_execsql_test 14.1.3 { + SELECT * FROM (t1 NATURAL LEFT JOIN t2 NATURAL JOIN t3) FULL JOIN t4 ON true; +} {0 {}} + +do_execsql_test 14.1.4 { + SELECT * + FROM (t1 NATURAL LEFT JOIN t2 NATURAL JOIN t3) AS qq FULL JOIN t4 ON true; +} {0 {}} + +do_execsql_test 14.2.1 { + SELECT * FROM t3 NATURAL LEFT JOIN t2 NATURAL JOIN t1; +} {0} + +do_execsql_test 14.2.2 { + SELECT * FROM t3 NATURAL LEFT JOIN t2 NATURAL JOIN t1 FULL JOIN t4 ON true; +} {0 {}} + +do_execsql_test 14.2.3 { + SELECT * FROM (t3 NATURAL LEFT JOIN t2 NATURAL JOIN t1) FULL JOIN t4 ON true; +} {0 {}} + +do_execsql_test 14.2.4 { + SELECT * + FROM (t3 NATURAL LEFT JOIN t2 NATURAL JOIN t1) AS qq FULL JOIN t4 ON true; +} {0 {}} + finish_test From 0d3e5ca28e858335c231cdbc11c01b7b4945a5db Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 31 May 2025 18:26:37 +0000 Subject: [PATCH 19/35] New makefile target "xdevtest" works like "releasetest" except that it omits the "verify-source" dependency so that it can be run with uncommitted changes in the source tree. FossilOrigin-Name: 1afb1ac3e9f0a122f1374799c09b60a0dd5443434d4567d94385096ada91bf12 --- Makefile.msc | 9 ++++++++- main.mk | 6 ++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 6aef671557..644e8e8554 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2674,7 +2674,14 @@ srctree-check: $(TOP)\tool\srctree-check.tcl # Testing for a release # -releasetest: +releasetest: verify-source + $(TCLSH_CMD) $(TOP)\test\testrunner.tcl release + +# xdevtest is like releasetest, except that it skips the +# dependency on verify-source so that xdevtest can be run from +# a modified source tree. +# +xdevtest: $(TCLSH_CMD) $(TOP)\test\testrunner.tcl release diff --git a/main.mk b/main.mk index 88c641b70f..fe874b1f38 100644 --- a/main.mk +++ b/main.mk @@ -1835,6 +1835,12 @@ mdevtest: srctree-check has_tclsh85 sdevtest: has_tclsh85 $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS) +# Like releasetest, except it omits srctree-check and verify-source so +# that it can be used on a modified source tree. +# +xdevtest: has_tclsh85 + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS) + # # Validate that various generated files in the source tree # are up-to-date. diff --git a/manifest b/manifest index fc2d45f1aa..db32e86435 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Fix\san\saffinity\sproblem\scaused\sby\sa\sUSING\sor\sNATURAL\sJOIN\son\sthe\sLHS\sof\sa\sFULL\sJOIN.\s[forum:/forumpost/5028c785b6|Forum\spost\s5028c785b6]. -D 2025-05-31T18:16:21.946 +C New\smakefile\starget\s"xdevtest"\sworks\slike\s"releasetest"\sexcept\sthat\sit\nomits\sthe\s"verify-source"\sdependency\sso\sthat\sit\scan\sbe\srun\swith\suncommitted\nchanges\sin\sthe\ssource\stree. +D 2025-05-31T18:26:37.671 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d F Makefile.in c3e414df4dc8dfb12f1f6baf129fcb6d18cd0ebd3c9109370fb3fceeeef9a37a F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc 0206f28988bb6634c7e8aff05bf6cfa65d6dfe1d2b6bd95160dd99290a83dfc7 +F Makefile.msc aa4f9ae86cf59fe94a3e93bf1a4c241b3ffffe96cf4d823517acf593c277223b F README.md e28077cfbef795e99c9c75ed95aa7257a1166709b562076441a8506ac421b7c1 F VERSION 001dea55eb8304ec9130b6b44a32d3fc349f279d45a7e224fc0730c3cb8e2372 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -709,7 +709,7 @@ F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 F ext/wasm/wasmfs.make 68999f5bd8c489239592d59a420f8c627c99169bbd6fa16a404751f757b9f702 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 517db864e770c486bd1465298c20d91899918d395263266997d477b20ef9eec8 +F main.mk 34290a772ec671de1fa5defd4fa4074aad24b1ea7eaabebba071e30564c6498c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1ddaa92057e550ea281d45d9860eafe69399224725548a93dd91c47a34e52152 -R 89af89664e25dccfda8f6cb0f81b4128 -U dan -Z bd82500cd206375faf72e64feca43230 +P 8d393ca07fe09f48d77adb517e2e4baaa58a9251422de62a0504999205d3ea1d +R 9b94db4e5d892a93cf1670d233c18f80 +U drh +Z 1c2aee3d74e96a6684f9847b4822e599 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a49fea986c..effd39b1f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d393ca07fe09f48d77adb517e2e4baaa58a9251422de62a0504999205d3ea1d +1afb1ac3e9f0a122f1374799c09b60a0dd5443434d4567d94385096ada91bf12 From 977b0f8813d24e64828e92f453b30cc22bbe2810 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 31 May 2025 19:55:07 +0000 Subject: [PATCH 20/35] Update a few test scripts so that they run on windows. FossilOrigin-Name: 14a18f4e3a3f35e636262a253364ab1e8054ed38c0c7fd482633522cbcf5ffc4 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- test/snapshot3.test | 3 +++ test/walsetlk_recover.test | 3 ++- test/walsetlk_snapshot.test | 3 ++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 58cd7b8b71..2ba27879e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sassert()\sstatements\sin\sos_unix.c\sand\sos_win.c.\sAllow\swalsetlk_recover.test\sto\srun\sin\snon-SQLITE_ENABLE_SNAPSHOT\sbuilds. -D 2025-05-31T15:10:41.660 +C Update\sa\sfew\stest\sscripts\sso\sthat\sthey\srun\son\swindows. +D 2025-05-31T19:55:07.528 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -1664,7 +1664,7 @@ F test/skipscan5.test 0672103fd2c8f96bd114133f356192b35ece45c794fe3677e1d9e5e310 F test/skipscan6.test e2b256cf5d538a605beb97dc97ca5e2836dfc24c5e1d9b7a09e13c069a3b8b49 F test/snapshot.test a504f2e7009f512ef66c719f0ea1c55a556bdaf1e1312c80a04d46fc1a3e9632 F test/snapshot2.test 8d6ff5dd9cc503f6e12d408a30409c3f9c653507b24408d9cd7195931c89bc54 -F test/snapshot3.test 41350216abc6c7da37113ad462259c070786e5ad70bdc8709daaed148b1b3a2c +F test/snapshot3.test 2e0328ba019aa981848e10aded4d7dcd6094ec1f9c6290a34ab18415be0c44eb F test/snapshot4.test d4e9347ef2fcabc491fc893506c7bbaf334da3be111d6eb4f3a97cc623b78322 F test/snapshot_fault.test 129234ceb9b26a0e1000e8563a16e790f5c1412354e70749cbd78c3d5d07d60a F test/snapshot_up.test 77dc7853bfb2b4fa249f76e1714cfa1e596826165d9ef22c06ac3a0b7b778d9a @@ -2036,8 +2036,8 @@ F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533 F test/walsetlk.test 9079cd8ef82570b8cf0067f31e049a72bec353fb2d5f0cc88f1736dc42ba9704 F test/walsetlk2.test 9097083633cdf55bf1098b694fb8651d0356d38fef28b869481d18029d7ceaf4 F test/walsetlk3.test 1b82bd92dea7e58f498b4399b0b3d26773dd8ac5c74205ce4a23c207cb8e85fe -F test/walsetlk_recover.test 7c43dbcf550324ee1b37f40f21150bcbb66a028e4be5f10547599a34ffee9123 -F test/walsetlk_snapshot.test 6376fc8a76da4571eb35cf4aef06105f716c5e52f991cefec44b9c7015aadf1e +F test/walsetlk_recover.test fb9f922aeceaece4b156fcea99751ca6dc6a9111d81cd018f891631d9b923bbb +F test/walsetlk_snapshot.test 408e8b9b8b93366e8e3f1f748e755b21fb177c1b56210fe0c68e760ea1fb77f6 F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a35236757ab57c4c9b34e47c5dbc10d8f1220f8152955f5303cf9c3902ee169b -R eaf3d33697a02bafeb3824ed740b8b2a +P 9f521ecda2b8d2f383cc84e308b3a4adfcf1bd6339eb834c8fa76c8704c861b7 +R 56c04d3126b92aeee5cfa0b7b54b5339 U dan -Z 2a8dae12be43752fd4cda67357fb4b7f +Z ced89a3dbbea8e62a4a96a4110c9937a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0991aa57a6..8873e50c22 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f521ecda2b8d2f383cc84e308b3a4adfcf1bd6339eb834c8fa76c8704c861b7 +14a18f4e3a3f35e636262a253364ab1e8054ed38c0c7fd482633522cbcf5ffc4 diff --git a/test/snapshot3.test b/test/snapshot3.test index 470d463a66..6d57b1d0c4 100644 --- a/test/snapshot3.test +++ b/test/snapshot3.test @@ -96,6 +96,9 @@ do_test 1.8 { list [catch { sqlite3_snapshot_open_blob db3 main $snap } msg] $msg } {1 SQLITE_ERROR_SNAPSHOT} +db3 close +db2 close + #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { diff --git a/test/walsetlk_recover.test b/test/walsetlk_recover.test index 0b0977a362..f5b142ec12 100644 --- a/test/walsetlk_recover.test +++ b/test/walsetlk_recover.test @@ -55,7 +55,8 @@ testfixture_nb myvar { } # Give the [testfixture_nb] command time to start -after 1000 +after 1000 {set xyz 1} +vwait xyz testvfs tvfs -fullshm 1 sqlite3 db test.db -vfs tvfs diff --git a/test/walsetlk_snapshot.test b/test/walsetlk_snapshot.test index 35d70cd19a..b0453f7e51 100644 --- a/test/walsetlk_snapshot.test +++ b/test/walsetlk_snapshot.test @@ -62,7 +62,8 @@ testfixture_nb myvar { } # Give the [testfixture_nb] command time to start -after 1000 +after 1000 {set xyz 1} +vwait xyz db timeout 500 set tm [lindex [time { From c0190101d14bca3664689c53b432c4de969905a2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 31 May 2025 20:51:42 +0000 Subject: [PATCH 21/35] Enhance "box" and "column" mode formatting in the CLI to better deal with double-wide characters. FossilOrigin-Name: b0de22ed0abf2ea5d269f191c884d7b2be167a2ed27018c25aaa0ea238cd621a --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/shell.c.in | 13 +++++++++++-- test/dblwidth-a.sql | 20 ++++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 test/dblwidth-a.sql diff --git a/manifest b/manifest index db32e86435..3801f5988e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\smakefile\starget\s"xdevtest"\sworks\slike\s"releasetest"\sexcept\sthat\sit\nomits\sthe\s"verify-source"\sdependency\sso\sthat\sit\scan\sbe\srun\swith\suncommitted\nchanges\sin\sthe\ssource\stree. -D 2025-05-31T18:26:37.671 +C Enhance\s"box"\sand\s"column"\smode\sformatting\sin\sthe\sCLI\sto\sbetter\sdeal\swith\ndouble-wide\scharacters. +D 2025-05-31T20:51:42.476 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -786,7 +786,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 9929e56e78f958657bfbb8234916473468243f90af359cc646d97c3ee809c79c -F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8f +F src/shell.c.in 1da613953db4c8d50e3a4a66fa7d69b4c95edb3628941d732637d3c35ea0dce6 F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e @@ -1084,6 +1084,7 @@ F test/dbfuzz.c fc566102f72c8af84ae8077b4faf7f056c571e6fa7a32e98b66e42b7505f47b6 F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23 +F test/dblwidth-a.sql eb4141518610e52f931a55a984310075e98dc31eee5a28ae806b1e35377be85a F test/dbpage.test 63fab1eb026bada121107e53436fa749bbf83281dc9dea17af422f7a5c0f289f F test/dbpagefault.test ea39de2ca86041a9c6df1135645180a76d0a8da93ac159e2fafe38e39636530b F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 @@ -2207,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8d393ca07fe09f48d77adb517e2e4baaa58a9251422de62a0504999205d3ea1d -R 9b94db4e5d892a93cf1670d233c18f80 +P 1afb1ac3e9f0a122f1374799c09b60a0dd5443434d4567d94385096ada91bf12 +R 241d4fe28f71a66e02a0774aedd929d3 U drh -Z 1c2aee3d74e96a6684f9847b4822e599 +Z 36464e257b6f6b054003c79b6284e296 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index effd39b1f3..cebff17bad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1afb1ac3e9f0a122f1374799c09b60a0dd5443434d4567d94385096ada91bf12 +b0de22ed0abf2ea5d269f191c884d7b2be167a2ed27018c25aaa0ea238cd621a diff --git a/src/shell.c.in b/src/shell.c.in index 8660bd78a2..363685eb0d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -887,12 +887,21 @@ static int strlen30(const char *z){ /* ** Return the length of a string in characters. Multibyte UTF8 characters -** count as a single character. +** count as a single character for single-width characters, or as two +** characters for double-width characters. */ static int strlenChar(const char *z){ int n = 0; while( *z ){ - if( (0xc0&*(z++))!=0x80 ) n++; + if( (0x80&z[0])==0 ){ + n++; + z++; + }else{ + int u = 0; + int len = decodeUtf8((const u8*)z, &u); + z += len; + n += cli_wcwidth(u); + } } return n; } diff --git a/test/dblwidth-a.sql b/test/dblwidth-a.sql new file mode 100644 index 0000000000..38c219698d --- /dev/null +++ b/test/dblwidth-a.sql @@ -0,0 +1,20 @@ +/* +** Run this script using "sqlite3" to confirm that the command-line +** shell properly handles the output of double-width characters. +** +** https://sqlite.org/forum/forumpost/008ac80276 +*/ +.mode box +CREATE TABLE data(word TEXT, description TEXT); +INSERT INTO data VALUES('〈οὐκέτι〉','Greek without dblwidth <...>'); +.print .mode box +SELECT * FROM data; +.mode table +.print .mode table +SELECT * FROM data; +.mode qbox +.print .mode qbox +SELECT * FROM data; +.mode column +.print .mode column +SELECT * FROM data; From f18bf8997bc3843d342118709d431a24a889ec16 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 1 Jun 2025 16:10:25 +0000 Subject: [PATCH 22/35] Fix VACUUM so that it works even when ATTACH_WRITE is disabled. FossilOrigin-Name: 42494f85acb303919d3f1f2202f8b95fbd657652da4b8dc00451c10ea6c496e0 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test1.c | 5 +++++ src/vacuum.c | 3 ++- test/vacuum.test | 21 +++++++++++++++++++++ 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3801f5988e..73550b42d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\s"box"\sand\s"column"\smode\sformatting\sin\sthe\sCLI\sto\sbetter\sdeal\swith\ndouble-wide\scharacters. -D 2025-05-31T20:51:42.476 +C Fix\sVACUUM\sso\sthat\sit\sworks\seven\swhen\sATTACH_WRITE\sis\sdisabled. +D 2025-06-01T16:10:25.448 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -796,7 +796,7 @@ F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 3c604c49e6cf4211960a9ddb9505280fd22cde32175f40884c641c0f5a286036 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 -F src/test1.c 9b54135e5f1352f06b1d23d7c183f124c1f33de6ea8997cd801f0f215c43591d +F src/test1.c 13cc07851f989141b29f7ca3c6c90f6d18f90081ab423c66716c8cb29d277d1f F src/test2.c 62f0830958f9075692c29c6de51b495ae8969e1bef85f239ffcd9ba5fb44a5ff F src/test3.c 432646f581d8af1bb495e58fc98234380250954f5d5535e507fc785eccc3987a F src/test4.c 0ac87fc13cdb334ab3a71823f99b6c32a6bebe5d603cd6a71d84c823d43a25a0 @@ -853,7 +853,7 @@ F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 -F src/vacuum.c d580ceb395c1ae3d59da41cbfea60683ff7dd2b94ddf4d0f5657620159e2eeb7 +F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789 F src/vdbe.c 0feab5781141acca67bd5de84172fff902304274ec5cfe58609f005b8d160050 F src/vdbe.h 31eddcffc1d14c76c2a20fe4e137e1ee43d44f370896fae14a067052801a3625 F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e @@ -1960,7 +1960,7 @@ F test/uri.test 1250724af9beeed2d6c3716f5b990c483200c54f408d3c0ec9543a3c7961f8fc F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/utf16align.test 9fde0bb5d3a821594aa68c6829ab9c5453a084384137ebb9f6153e2d678039da F test/vacuum-into.test 5a489714feecfdabfc7b293be4111564a173dee92c0d6818dd0207f3ade65783 -F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d +F test/vacuum.test f3b2257a4fcd659513c866a5d9e5f70999cc58fd5d74e979290385fa350b79ee F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8af520 F test/vacuum3.test d9d9a04ee58c485b94694fd4f68cffaba49c32234fdefe1ac1a622c5e17d4ce3 F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7c010 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1afb1ac3e9f0a122f1374799c09b60a0dd5443434d4567d94385096ada91bf12 -R 241d4fe28f71a66e02a0774aedd929d3 +P b0de22ed0abf2ea5d269f191c884d7b2be167a2ed27018c25aaa0ea238cd621a +R 66acec589170351980ed2fbfcdde26ad U drh -Z 36464e257b6f6b054003c79b6284e296 +Z 93ec91429727f46ec026565cc279bc29 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cebff17bad..53efaadb52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0de22ed0abf2ea5d269f191c884d7b2be167a2ed27018c25aaa0ea238cd621a +42494f85acb303919d3f1f2202f8b95fbd657652da4b8dc00451c10ea6c496e0 diff --git a/src/test1.c b/src/test1.c index bb2f2d3b9d..1c363ca3b0 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8458,7 +8458,12 @@ static int SQLITE_TCLAPI test_sqlite3_db_config( { "DQS_DML", SQLITE_DBCONFIG_DQS_DML }, { "DQS_DDL", SQLITE_DBCONFIG_DQS_DDL }, { "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, + { "TRUSTED_SCHEMA", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, { "STMT_SCANSTATUS", SQLITE_DBCONFIG_STMT_SCANSTATUS }, + { "REVERSE_SCANORDER", SQLITE_DBCONFIG_REVERSE_SCANORDER }, + { "ATTACH_CREATE", SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE }, + { "ATTACH_WRITE", SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE }, + { "COMMENTS", SQLITE_DBCONFIG_ENABLE_COMMENTS }, }; int i; int v = 0; diff --git a/src/vacuum.c b/src/vacuum.c index 96d77e5bc4..1b48380403 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -195,7 +195,8 @@ SQLITE_NOINLINE int sqlite3RunVacuum( saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; saved_mTrace = db->mTrace; - db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments; + db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments + | SQLITE_AttachCreate | SQLITE_AttachWrite; db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum; db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_Defensive | SQLITE_CountRows); diff --git a/test/vacuum.test b/test/vacuum.test index 57429c29ea..82dd00d09c 100644 --- a/test/vacuum.test +++ b/test/vacuum.test @@ -401,4 +401,25 @@ do_test vacuum-10.1 { } {} do_test vacuum-10.2 { execsql VACUUM } {} +# Verify that VACUUM still works if ATTACH is disabled. +# +do_execsql_test vacuum-11.1 { + PRAGMA page_size=1024; + VACUUM; + PRAGMA page_size; +} {1024} +sqlite3_db_config db ATTACH_CREATE 0 +do_execsql_test vacuum-11.2 { + PRAGMA page_size=2048; + VACUUM; + PRAGMA page_size; +} {2048} +sqlite3_db_config db ATTACH_CREATE 1 +sqlite3_db_config db ATTACH_WRITE 0 +do_execsql_test vacuum-11.3 { + PRAGMA page_size=4096; + VACUUM; + PRAGMA page_size; +} {4096} + finish_test From d4c224b833b7c4d58f1e5748f5a1de2af013fc3d Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 1 Jun 2025 21:38:35 +0000 Subject: [PATCH 23/35] Fix an off-by-one error in the size computation of a vdbe-sorter. [forum:/forumpost/c1cc8b057a|Forum post c1cc8b057a]. Problem introduced by checkin [d4307a0d43f42e96]. FossilOrigin-Name: 8b7a7fcf62e5c2742c243808fa482472954f2b4aae0bc7ae513bc07065c93737 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbesort.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 73550b42d6..27101fa1bd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sVACUUM\sso\sthat\sit\sworks\seven\swhen\sATTACH_WRITE\sis\sdisabled. -D 2025-06-01T16:10:25.448 +C Fix\san\soff-by-one\serror\sin\sthe\ssize\scomputation\sof\sa\svdbe-sorter.\n[forum:/forumpost/c1cc8b057a|Forum\spost\sc1cc8b057a].\nProblem\sintroduced\sby\scheckin\s[d4307a0d43f42e96]. +D 2025-06-01T21:38:35.769 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -861,7 +861,7 @@ F src/vdbeapi.c 28fab30ed0acc981aecfdcaab0a421503609078e29850eb28494816682baf0a7 F src/vdbeaux.c 948c379976885a073b54cc7d8ffda087dc1a1095d1f5bb8df218796f8c933ac3 F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21 -F src/vdbesort.c 49e366d0216c782eba287bf602384e4330d2526a22f1275492d2785ce103c79b +F src/vdbesort.c 706acdc581944cf6381f75c0ccf40f2debf71cdd51c5056592f3b74a1a0c3624 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b0de22ed0abf2ea5d269f191c884d7b2be167a2ed27018c25aaa0ea238cd621a -R 66acec589170351980ed2fbfcdde26ad +P 42494f85acb303919d3f1f2202f8b95fbd657652da4b8dc00451c10ea6c496e0 +R 60ded1de0032e5faec0ccf76dc3b70d5 U drh -Z 93ec91429727f46ec026565cc279bc29 +Z eb3bbd192192ef194bc4af8ae3d8408b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 53efaadb52..5d2f66b41c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42494f85acb303919d3f1f2202f8b95fbd657652da4b8dc00451c10ea6c496e0 +8b7a7fcf62e5c2742c243808fa482472954f2b4aae0bc7ae513bc07065c93737 diff --git a/src/vdbesort.c b/src/vdbesort.c index 9a7e0760c6..6b1b4cff5d 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -969,7 +969,7 @@ int sqlite3VdbeSorterInit( assert( pCsr->eCurType==CURTYPE_SORTER ); assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) < 0x7fffffff ); - szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField+1); + szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField); sz = SZ_VDBESORTER(nWorker+1); pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); From 7590bfd7fc01718a6666e8f927aab839ce136cc2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Jun 2025 09:49:07 +0000 Subject: [PATCH 24/35] Fix stale comments related to KeyInfo. Add new assert()s associated with memory management of KeyInfo. FossilOrigin-Name: abd805bc76f14ede7359b029908179b7ca57e929c5918acae1403ef73ae0bd47 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqliteInt.h | 7 ++++--- src/vdbeaux.c | 20 ++++++++------------ src/vdbesort.c | 8 +++++++- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 27101fa1bd..aa774ea95a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\soff-by-one\serror\sin\sthe\ssize\scomputation\sof\sa\svdbe-sorter.\n[forum:/forumpost/c1cc8b057a|Forum\spost\sc1cc8b057a].\nProblem\sintroduced\sby\scheckin\s[d4307a0d43f42e96]. -D 2025-06-01T21:38:35.769 +C Fix\sstale\scomments\srelated\sto\sKeyInfo.\s\sAdd\snew\sassert()s\sassociated\swith\nmemory\smanagement\sof\sKeyInfo. +D 2025-06-02T09:49:07.082 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -790,7 +790,7 @@ F src/shell.c.in 1da613953db4c8d50e3a4a66fa7d69b4c95edb3628941d732637d3c35ea0dce F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e -F src/sqliteInt.h bb9137b860b2416b12788f09b32384ceab96b720aae07a6e9afacc545e43619a +F src/sqliteInt.h 4c7029a5006cdb7a16a6e7fee703356d621472efc18f85d5bfd019be4bd2be9f F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -858,10 +858,10 @@ F src/vdbe.c 0feab5781141acca67bd5de84172fff902304274ec5cfe58609f005b8d160050 F src/vdbe.h 31eddcffc1d14c76c2a20fe4e137e1ee43d44f370896fae14a067052801a3625 F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e F src/vdbeapi.c 28fab30ed0acc981aecfdcaab0a421503609078e29850eb28494816682baf0a7 -F src/vdbeaux.c 948c379976885a073b54cc7d8ffda087dc1a1095d1f5bb8df218796f8c933ac3 +F src/vdbeaux.c 59c9fab4eae949116d02200baf346dc787437b9bc6a5dc859cc7783fd916decf F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21 -F src/vdbesort.c 706acdc581944cf6381f75c0ccf40f2debf71cdd51c5056592f3b74a1a0c3624 +F src/vdbesort.c 0853cde546251803993c5bc8af8afe13112407156fa3b76ae4bc2f34778ddaae F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 42494f85acb303919d3f1f2202f8b95fbd657652da4b8dc00451c10ea6c496e0 -R 60ded1de0032e5faec0ccf76dc3b70d5 +P 8b7a7fcf62e5c2742c243808fa482472954f2b4aae0bc7ae513bc07065c93737 +R ead7c56c755064ee94c94f51f3c1f639 U drh -Z eb3bbd192192ef194bc4af8ae3d8408b +Z a0e73216c254ff70b1d5987cfd7dc64f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5d2f66b41c..8db97ce6a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b7a7fcf62e5c2742c243808fa482472954f2b4aae0bc7ae513bc07065c93737 +abd805bc76f14ede7359b029908179b7ca57e929c5918acae1403ef73ae0bd47 diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 994a3864c1..230646200b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2644,9 +2644,10 @@ struct FKey { ** argument to sqlite3VdbeKeyCompare and is used to control the ** comparison of the two index keys. ** -** Note that aSortOrder[] and aColl[] have nField+1 slots. There -** are nField slots for the columns of an index then one extra slot -** for the rowid at the end. +** The aSortOrder[] and aColl[] arrays have nAllField slots each. There +** are nKeyField slots for the columns of an index then extra slots +** for the rowid or key at the end. The aSortOrder array is located after +** the aColl[] array. */ struct KeyInfo { u32 nRef; /* Number of references to this KeyInfo object */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a6798e62db..2d63654d04 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4202,24 +4202,17 @@ void sqlite3VdbeSerialGet( return; } /* -** This routine is used to allocate sufficient space for an UnpackedRecord -** structure large enough to be used with sqlite3VdbeRecordUnpack() if -** the first argument is a pointer to KeyInfo structure pKeyInfo. +** Allocate sufficient space for an UnpackedRecord structure large enough +** to hold a decoded index record for pKeyInfo. ** -** The space is either allocated using sqlite3DbMallocRaw() or from within -** the unaligned buffer passed via the second and third arguments (presumably -** stack space). If the former, then *ppFree is set to a pointer that should -** be eventually freed by the caller using sqlite3DbFree(). Or, if the -** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL -** before returning. -** -** If an OOM error occurs, NULL is returned. +** The space is allocated using sqlite3DbMallocRaw(). If an OOM error +** occurs, NULL is returned. */ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( KeyInfo *pKeyInfo /* Description of the record */ ){ UnpackedRecord *p; /* Unpacked record to return */ - int nByte; /* Number of bytes required for *p */ + u64 nByte; /* Number of bytes required for *p */ assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff ); nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); @@ -4250,6 +4243,7 @@ void sqlite3VdbeRecordUnpack( Mem *pMem = p->aMem; p->default_rc = 0; + assert( p->pKeyInfo==pKeyInfo ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); idx = getVarint32(aKey, szHdr); d = szHdr; @@ -4275,6 +4269,8 @@ void sqlite3VdbeRecordUnpack( ** warnings from MSAN. */ sqlite3VdbeMemSetNull(pMem-1); } + testcase( u == pKeyInfo->nKeyField + 1 ); + testcase( u < pKeyInfo->nKeyField + 1 ); assert( u<=pKeyInfo->nKeyField + 1 ); p->nField = u; } diff --git a/src/vdbesort.c b/src/vdbesort.c index 6b1b4cff5d..90ab28cd51 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -969,7 +969,8 @@ int sqlite3VdbeSorterInit( assert( pCsr->eCurType==CURTYPE_SORTER ); assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*) < 0x7fffffff ); - szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nKeyField); + assert( pCsr->pKeyInfo->nKeyField<=pCsr->pKeyInfo->nAllField ); + szKeyInfo = SZ_KEYINFO(pCsr->pKeyInfo->nAllField); sz = SZ_VDBESORTER(nWorker+1); pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); @@ -983,7 +984,12 @@ int sqlite3VdbeSorterInit( pKeyInfo->db = 0; if( nField && nWorker==0 ){ pKeyInfo->nKeyField = nField; + assert( nField<=pCsr->pKeyInfo->nAllField ); } + /* It is OK that pKeyInfo reuses the aSortFlags field from pCsr->pKeyInfo, + ** since the pCsr->pKeyInfo->aSortFlags[] array is invariant and lives + ** longer that pSorter. */ + assert( pKeyInfo->aSortFlags==pCsr->pKeyInfo->aSortFlags ); sqlite3BtreeEnter(pBt); pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); sqlite3BtreeLeave(pBt); From 8658a8df59f00ec8fcfea336a2a6a4b5ef79d2ee Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Jun 2025 13:54:33 +0000 Subject: [PATCH 25/35] Remove an unnecessary parameter from sqlite3VdbeRecordUnpack(). Improved comments and assert()s on KeyInfo. FossilOrigin-Name: 387f4c4d98b8fb83f6ae406e4143dabda7766e8752b7f6ca104655e51330c978 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/btree.c | 2 +- src/sqliteInt.h | 20 +++++++++++++------- src/vdbe.c | 3 ++- src/vdbe.h | 2 +- src/vdbeapi.c | 2 +- src/vdbeaux.c | 8 +++----- src/vdbesort.c | 8 +++++--- 9 files changed, 39 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index aa774ea95a..0d6c30d52e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sstale\scomments\srelated\sto\sKeyInfo.\s\sAdd\snew\sassert()s\sassociated\swith\nmemory\smanagement\sof\sKeyInfo. -D 2025-06-02T09:49:07.082 +C Remove\san\sunnecessary\sparameter\sfrom\ssqlite3VdbeRecordUnpack().\s\sImproved\ncomments\sand\sassert()s\son\sKeyInfo. +D 2025-06-02T13:54:33.921 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -726,7 +726,7 @@ F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 782cc29b42b47e7ec6348eb0aaf9ffe60063f498387e7249f458d445af4b53e9 F src/btmutex.c 30dada73a819a1ef5b7583786370dce1842e12e1ad941e4d05ac29695528daea -F src/btree.c cb028cb29e57b8767cb0973e66659f305dcb8dc1c2402e10ad462a89ec640ef5 +F src/btree.c 117c0d408a7d43939419f67de962ce66272e51ac8e84c38e1681a3e8d9c1fa39 F src/btree.h 18e5e7b2124c23426a283523e5f31a4bff029131b795bb82391f9d2f3136fc50 F src/btreeInt.h 9c0f9ea5c9b5f4dcaea18111d43efe95f2ac276cd86d770dce10fd99ccc93886 F src/build.c 67c1db4c5e89a8519fe9b6dafc287f6bc3627696b5b8536dc5e06db570d8c05f @@ -790,7 +790,7 @@ F src/shell.c.in 1da613953db4c8d50e3a4a66fa7d69b4c95edb3628941d732637d3c35ea0dce F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e -F src/sqliteInt.h 4c7029a5006cdb7a16a6e7fee703356d621472efc18f85d5bfd019be4bd2be9f +F src/sqliteInt.h 75290111d8e37d35ec48a4fbb4e6af5611c9a551dedecceb896734ace9f60018 F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -854,14 +854,14 @@ F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1 F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789 -F src/vdbe.c 0feab5781141acca67bd5de84172fff902304274ec5cfe58609f005b8d160050 -F src/vdbe.h 31eddcffc1d14c76c2a20fe4e137e1ee43d44f370896fae14a067052801a3625 +F src/vdbe.c 714fab7aa7c516edbcf5e4f653ae8f548a3e24c0ed19086d7383bb5851983992 +F src/vdbe.h 93761ed7c6b8bc19524912fd9b9b587d41bf4f1d0ade650a00dadc10518d8958 F src/vdbeInt.h 0bc581a9763be385e3af715e8c0a503ba8422c2b7074922faf4bb0d6ae31b15e -F src/vdbeapi.c 28fab30ed0acc981aecfdcaab0a421503609078e29850eb28494816682baf0a7 -F src/vdbeaux.c 59c9fab4eae949116d02200baf346dc787437b9bc6a5dc859cc7783fd916decf +F src/vdbeapi.c 613a6f29efacd6ed83e886b6e52db0fe52ba80a596b0a137608db1948bad90a9 +F src/vdbeaux.c fd2c6b19a8892c31a2adc719f156f313560f9cc490cdbd04ff08fdae5d7aedb7 F src/vdbeblob.c b1b4032cac46b41e44b957c4d00aee9851f862dfd85ecb68116ba49884b03dfd F src/vdbemem.c e67d9c6484d868c879d20c70d00bf4a9058082f1d4058607ca15d50eb3aebc21 -F src/vdbesort.c 0853cde546251803993c5bc8af8afe13112407156fa3b76ae4bc2f34778ddaae +F src/vdbesort.c cb6f472e83ca12c46aa7de0ac0a9d11458b357986f2617a1c90dfb19a542ecbe F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859 @@ -2208,8 +2208,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8b7a7fcf62e5c2742c243808fa482472954f2b4aae0bc7ae513bc07065c93737 -R ead7c56c755064ee94c94f51f3c1f639 +P abd805bc76f14ede7359b029908179b7ca57e929c5918acae1403ef73ae0bd47 +R 1ff98af5488a25305a0af19b1605424c U drh -Z a0e73216c254ff70b1d5987cfd7dc64f +Z 9034a9d4e20050745e3d6b897bc0cd56 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8db97ce6a2..0ffbeedec5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abd805bc76f14ede7359b029908179b7ca57e929c5918acae1403ef73ae0bd47 +387f4c4d98b8fb83f6ae406e4143dabda7766e8752b7f6ca104655e51330c978 diff --git a/src/btree.c b/src/btree.c index ed1dde98c8..c85491c7d0 100644 --- a/src/btree.c +++ b/src/btree.c @@ -872,7 +872,7 @@ static int btreeMoveto( assert( nKey==(i64)(int)nKey ); pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; - sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); + sqlite3VdbeRecordUnpack((int)nKey, pKey, pIdxKey); if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ rc = SQLITE_CORRUPT_BKPT; }else{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 230646200b..951cd3d34d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2648,6 +2648,11 @@ struct FKey { ** are nKeyField slots for the columns of an index then extra slots ** for the rowid or key at the end. The aSortOrder array is located after ** the aColl[] array. +** +** If SQLITE_ENABLE_PREUPDATE_HOOK is defined, then aSortFlags might be NULL +** to indicate that this object is for use by a preupdate hook. When aSortFlags +** is NULL, then nAllField is uninitialized and no space is allocated for +** aColl[], so those fields may not be used. */ struct KeyInfo { u32 nRef; /* Number of references to this KeyInfo object */ @@ -2659,7 +2664,9 @@ struct KeyInfo { CollSeq *aColl[FLEXARRAY]; /* Collating sequence for each term of the key */ }; -/* The size (in bytes) of a KeyInfo object with up to N fields */ +/* The size (in bytes) of a KeyInfo object with up to N fields. This includes +** the main body of the KeyInfo object and the aColl[] array of N elements, +** but does not count the memory used to hold aSortFlags[]. */ #define SZ_KEYINFO(N) (offsetof(KeyInfo,aColl) + (N)*sizeof(CollSeq*)) /* The size of a bare KeyInfo with no aColl[] entries */ @@ -2687,9 +2694,8 @@ struct KeyInfo { ** ** An instance of this object serves as a "key" for doing a search on ** an index b+tree. The goal of the search is to find the entry that -** is closed to the key described by this object. This object might hold -** just a prefix of the key. The number of fields is given by -** pKeyInfo->nField. +** is closest to the key described by this object. This object might hold +** just a prefix of the key. The number of fields is given by nField. ** ** The r1 and r2 fields are the values to return if this key is less than ** or greater than a key in the btree, respectively. These are normally @@ -2699,7 +2705,7 @@ struct KeyInfo { ** The key comparison functions actually return default_rc when they find ** an equals comparison. default_rc can be -1, 0, or +1. If there are ** multiple entries in the b-tree with the same key (when only looking -** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to +** at the first nField elements) then default_rc can be set to -1 to ** cause the search to find the last match, or +1 to cause the search to ** find the first match. ** @@ -2711,8 +2717,8 @@ struct KeyInfo { ** b-tree. */ struct UnpackedRecord { - KeyInfo *pKeyInfo; /* Collation and sort-order information */ - Mem *aMem; /* Values */ + KeyInfo *pKeyInfo; /* Comparison info for the index that is unpacked */ + Mem *aMem; /* Values for columns of the index */ union { char *z; /* Cache of aMem[0].z for vdbeRecordCompareString() */ i64 i; /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */ diff --git a/src/vdbe.c b/src/vdbe.c index 29b6f9a653..b23bd38d2b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2476,6 +2476,7 @@ case OP_Compare: { pKeyInfo = pOp->p4.pKeyInfo; assert( n>0 ); assert( pKeyInfo!=0 ); + assert( pKeyInfo->aSortFlags!=0 ); p1 = pOp->p1; p2 = pOp->p2; #ifdef SQLITE_DEBUG @@ -5349,7 +5350,7 @@ case OP_Found: { /* jump, in3, ncycle */ if( rc ) goto no_mem; pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); if( pIdxKey==0 ) goto no_mem; - sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); + sqlite3VdbeRecordUnpack(r.aMem->n, r.aMem->z, pIdxKey); pIdxKey->default_rc = 0; rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); sqlite3DbFreeNN(db, pIdxKey); diff --git a/src/vdbe.h b/src/vdbe.h index dc98e270e3..a7aedfbb0e 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -301,7 +301,7 @@ void sqlite3VdbeSetVarmask(Vdbe*, int); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3BlobCompare(const Mem*, const Mem*); -void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); +void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index ed95494628..f5260e7e69 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -2163,7 +2163,7 @@ static UnpackedRecord *vdbeUnpackRecord( pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( pRet ){ memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); + sqlite3VdbeRecordUnpack(nKey, pKey, pRet); } return pRet; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2d63654d04..8a900aeffe 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4218,7 +4218,6 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; - assert( pKeyInfo->aSortFlags!=0 ); p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nKeyField + 1; return p; @@ -4230,7 +4229,6 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( ** contents of the decoded record. */ void sqlite3VdbeRecordUnpack( - KeyInfo *pKeyInfo, /* Information about the record format */ int nKey, /* Size of the binary record */ const void *pKey, /* The binary record */ UnpackedRecord *p /* Populate this structure before returning. */ @@ -4241,9 +4239,9 @@ void sqlite3VdbeRecordUnpack( u16 u; /* Unsigned loop counter */ u32 szHdr; Mem *pMem = p->aMem; + KeyInfo *pKeyInfo = p->pKeyInfo; p->default_rc = 0; - assert( p->pKeyInfo==pKeyInfo ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); idx = getVarint32(aKey, szHdr); d = szHdr; @@ -5130,6 +5128,7 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ ** The easiest way to enforce this limit is to consider only records with ** 13 fields or less. If the first field is an integer, the maximum legal ** header size is (12*5 + 1 + 1) bytes. */ + assert( p->pKeyInfo->aSortFlags!=0 ); if( p->pKeyInfo->nAllField<=13 ){ int flags = p->aMem[0].flags; if( p->pKeyInfo->aSortFlags[0] ){ @@ -5488,7 +5487,6 @@ void sqlite3VdbePreUpdateHook( i64 iKey2; PreUpdate preupdate; const char *zTbl = pTab->zName; - static const u8 fakeSortOrder = 0; #ifdef SQLITE_DEBUG int nRealCol; if( pTab->tabFlags & TF_WithoutRowid ){ @@ -5527,7 +5525,7 @@ void sqlite3VdbePreUpdateHook( preupdate.pKeyinfo->db = db; preupdate.pKeyinfo->enc = ENC(db); preupdate.pKeyinfo->nKeyField = pTab->nCol; - preupdate.pKeyinfo->aSortFlags = (u8*)&fakeSortOrder; + preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */ preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.pTab = pTab; diff --git a/src/vdbesort.c b/src/vdbesort.c index 90ab28cd51..39661eb4c4 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -766,7 +766,7 @@ static int vdbeSorterCompareTail( ){ UnpackedRecord *r2 = pTask->pUnpacked; if( *pbKey2Cached==0 ){ - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); *pbKey2Cached = 1; } return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); @@ -793,7 +793,7 @@ static int vdbeSorterCompare( ){ UnpackedRecord *r2 = pTask->pUnpacked; if( !*pbKey2Cached ){ - sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + sqlite3VdbeRecordUnpack(nKey2, pKey2, r2); *pbKey2Cached = 1; } return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); @@ -833,6 +833,7 @@ static int vdbeSorterCompareText( ); } }else{ + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ res = res * -1; @@ -896,6 +897,7 @@ static int vdbeSorterCompareInt( } } + assert( pTask->pSorter->pKeyInfo->aSortFlags!=0 ); if( res==0 ){ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){ res = vdbeSorterCompareTail( @@ -2769,7 +2771,7 @@ int sqlite3VdbeSorterCompare( assert( r2->nField==nKeyCol ); pKey = vdbeSorterRowkey(pSorter, &nKey); - sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); + sqlite3VdbeRecordUnpack(nKey, pKey, r2); for(i=0; iaMem[i].flags & MEM_Null ){ *pRes = -1; From a3fcd7c79e827f98ac01fb83ee91848096fbb11c Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 2 Jun 2025 15:10:41 +0000 Subject: [PATCH 26/35] TEA: remove the stale man page and references to the MSC makefiles from the README.txt. Based on discussion at [forum:87e6660191a472c5 | forum post 87e6660191a472c5]. A couple of weeks ago we internally discussed pulling in the MSC makefiles from the 3.49 tree but they are stale and possibly unused, so opted against it for the time being. FossilOrigin-Name: c9888a409565e6c8891a3dafa56962df364fb729a61df2701dc0bb282e36fb75 --- autoconf/tea/README.txt | 18 ++++-------------- autoconf/tea/doc/sqlite3.n | 15 --------------- manifest | 15 +++++++-------- manifest.uuid | 2 +- 4 files changed, 12 insertions(+), 38 deletions(-) delete mode 100644 autoconf/tea/doc/sqlite3.n diff --git a/autoconf/tea/README.txt b/autoconf/tea/README.txt index 28f23a88dd..67edce2955 100644 --- a/autoconf/tea/README.txt +++ b/autoconf/tea/README.txt @@ -77,23 +77,13 @@ example will install the extension in the /opt/tcl directory. $ cd sqlite-*-tea $ ./configure --prefix=/opt/tcl - $ make + $ make test $ make install WINDOWS BUILD ============= -The recommended method to build extensions under windows is to use the -Msys + Mingw build process. This provides a Unix-style build while -generating native Windows binaries. Using the Msys + Mingw build tools -means that you can use the same configure script as per the Unix build -to create a Makefile. See the tcl/win/README file for the URL of -the Msys + Mingw download. +On Windows this build is known to work on Cygwin and some Msys2 +environments. We do not currently support Microsoft makefiles for +native Windows builds. -If you have VC++ then you may wish to use the files in the win -subdirectory and build the extension using just VC++. These files have -been designed to be as generic as possible but will require some -additional maintenance by the project developer to synchronise with -the TEA configure.in and Makefile.in files. Instructions for using the -VC++ makefile are written in the first part of the Makefile.vc -file. diff --git a/autoconf/tea/doc/sqlite3.n b/autoconf/tea/doc/sqlite3.n deleted file mode 100644 index 3514046342..0000000000 --- a/autoconf/tea/doc/sqlite3.n +++ /dev/null @@ -1,15 +0,0 @@ -.TH sqlite3 n 4.1 "Tcl-Extensions" -.HS sqlite3 tcl -.BS -.SH NAME -sqlite3 \- an interface to the SQLite3 database engine -.SH SYNOPSIS -\fBsqlite3\fI command_name ?filename?\fR -.br -.SH DESCRIPTION -SQLite3 is a self-contains, zero-configuration, transactional SQL database -engine. This extension provides an easy to use interface for accessing -SQLite database files from Tcl. -.PP -For full documentation see \fIhttps://sqlite.org/\fR and -in particular \fIhttps://sqlite.org/tclsqlite.html\fR. diff --git a/manifest b/manifest index 0d6c30d52e..647e5bc995 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sparameter\sfrom\ssqlite3VdbeRecordUnpack().\s\sImproved\ncomments\sand\sassert()s\son\sKeyInfo. -D 2025-06-02T13:54:33.921 +C TEA:\sremove\sthe\sstale\sman\spage\sand\sreferences\sto\sthe\sMSC\smakefiles\sfrom\sthe\sREADME.txt.\sBased\son\sdiscussion\sat\s[forum:87e6660191a472c5\s|\sforum\spost\s87e6660191a472c5].\s\sA\scouple\sof\sweeks\sago\swe\sinternally\sdiscussed\spulling\sin\sthe\sMSC\smakefiles\sfrom\sthe\s3.49\stree\sbut\sthey\sare\sstale\sand\spossibly\sunused,\sso\sopted\sagainst\sit\sfor\sthe\stime\sbeing. +D 2025-06-02T15:10:41.277 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -23,11 +23,10 @@ F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d6484909 F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807 F autoconf/auto.def 3d994f3a9cc9b712dbce92a5708570ddcf3b988141b6eb738f2ed16127a9f0ac F autoconf/tea/Makefile.in bf6b43eafcd18766d81a8f0085cfc9cb051d8abae9031a8e7c3f5f1246e8f166 -F autoconf/tea/README.txt 656d4686c509d375f5988ff3deda94f65fe6cd8358cd55d1f1dcc7b6e2ff73aa +F autoconf/tea/README.txt ed653d28131f356f87084928ddcf80d4935b3cd84cdb9406f534f045fc0558f7 F autoconf/tea/_teaish.tester.tcl.in 8253b44be88e2e3f21de95a65d3a90c2be8e70b7bdd08a5b80e337ba7402f8f1 F autoconf/tea/auto.def ce95b9450e2fa4ba5dc857e208fe10f4e6f2d737796ac3278aee6079db417529 F autoconf/tea/configure d0b12b984edca6030d1976375b80157ac78b5b90a5b4f0dcee39357f63f4a80b x -F autoconf/tea/doc/sqlite3.n 9a97f4f717ceab73004ea412af7960625c1cb24b5c25e4ae4c8b5d8fa4300f4e F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in e07da6b94561f4aa382bab65b1ccceb04701b97bf59d007c1d1f20a222b22d07 F autoconf/tea/teaish.tcl a2224762a039ed30c45cc1ce4b2fde5667fb0aa2569bb56590f5cb5d45d7410b @@ -2208,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P abd805bc76f14ede7359b029908179b7ca57e929c5918acae1403ef73ae0bd47 -R 1ff98af5488a25305a0af19b1605424c -U drh -Z 9034a9d4e20050745e3d6b897bc0cd56 +P 387f4c4d98b8fb83f6ae406e4143dabda7766e8752b7f6ca104655e51330c978 +R eacb84e1e8fce545c882cbf546adff80 +U stephan +Z 32e930eb9547362a4891574b0cb43d68 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0ffbeedec5..8ed5303148 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -387f4c4d98b8fb83f6ae406e4143dabda7766e8752b7f6ca104655e51330c978 +c9888a409565e6c8891a3dafa56962df364fb729a61df2701dc0bb282e36fb75 From d84bbac8be02e81c32a52765c02dd17996ac3841 Mon Sep 17 00:00:00 2001 From: stephan Date: Mon, 2 Jun 2025 15:17:59 +0000 Subject: [PATCH 27/35] Slight modernization of the TEA README.txt. FossilOrigin-Name: bf7be67e3fb7b75fc281997f7bf9aa69eaf4da6bdf2fefe359b12d25ec95f512 --- autoconf/tea/README.txt | 43 +++++++++++++++++++++++------------------ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/autoconf/tea/README.txt b/autoconf/tea/README.txt index 67edce2955..122b08d32d 100644 --- a/autoconf/tea/README.txt +++ b/autoconf/tea/README.txt @@ -41,24 +41,32 @@ step-by-step instructions at the links below for more information: https://sqlite.org/src/doc/trunk/doc/compile-for-unix.md https://sqlite.org/src/doc/trunk/doc/compile-for-windows.md -The whole point of the amalgamation-autoconf tarball (in which this -README.txt file is embedded) is to provide a means of compiling -SQLite that does not require first installing TCL and/or "tclsh". -The canonical Makefile in the SQLite source tree provides more -capabilities (such as the the ability to run test cases to ensure -that the build worked) and is better maintained. The only -downside of the canonical Makefile is that it requires a TCL -installation. But if you are wanting to build the TCL extension for -SQLite, then presumably you already have a TCL installation. So why -not just use the more-capable and better-maintained canoncal Makefile? +And info about the extension's Tcl interface can be found at: -This TEA builder is derived from code found at + https://sqlite.org/tclsqlite.html + +The whole point of the amalgamation-autoconf tarball (in which this +README.txt file is embedded) is to provide a means of compiling SQLite +that does not require first installing TCL and/or "tclsh". The +canonical Makefile in the SQLite source tree provides more +capabilities (such as the the ability to run test cases to ensure that +the build worked) and is better maintained. The only downside of the +canonical Makefile is that it requires a TCL installation. But if you +are wanting to build the TCL extension for SQLite, then presumably you +already have a TCL installation. So why not just use the more-capable +and better-maintained canoncal Makefile? + +As of version 3.50.0, this build process uses "teaish": + + https://fossil.wanderinghorse.net/r/teaish + +which is conceptually derived from the pre-3.50 toolchain, TEA: http://core.tcl-lang.org/tclconfig http://core.tcl-lang.org/sampleextension -The SQLite developers do not understand how it works. It seems to -work for us. It might also work for you. But we cannot promise that. +It to works for us. It might also work for you. But we cannot +promise that. If you want to use this TEA builder and it works for you, that's fine. But if you have trouble, the first thing you should do is go back @@ -70,13 +78,11 @@ to using the canonical Makefile in the SQLite source tree. UNIX BUILD ========== -Building under most UNIX systems is easy, just run the configure script -and then run make. For more information about the build process, see -the tcl/unix/README file in the Tcl src dist. The following minimal -example will install the extension in the /opt/tcl directory. +Building under most UNIX systems is easy, just run the configure +script and then run make. For example: $ cd sqlite-*-tea - $ ./configure --prefix=/opt/tcl + $ ./configure --with-tcl=/path/to/tcl/install/root $ make test $ make install @@ -86,4 +92,3 @@ WINDOWS BUILD On Windows this build is known to work on Cygwin and some Msys2 environments. We do not currently support Microsoft makefiles for native Windows builds. - diff --git a/manifest b/manifest index 647e5bc995..4e0a3e927d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C TEA:\sremove\sthe\sstale\sman\spage\sand\sreferences\sto\sthe\sMSC\smakefiles\sfrom\sthe\sREADME.txt.\sBased\son\sdiscussion\sat\s[forum:87e6660191a472c5\s|\sforum\spost\s87e6660191a472c5].\s\sA\scouple\sof\sweeks\sago\swe\sinternally\sdiscussed\spulling\sin\sthe\sMSC\smakefiles\sfrom\sthe\s3.49\stree\sbut\sthey\sare\sstale\sand\spossibly\sunused,\sso\sopted\sagainst\sit\sfor\sthe\stime\sbeing. -D 2025-06-02T15:10:41.277 +C Slight\smodernization\sof\sthe\sTEA\sREADME.txt. +D 2025-06-02T15:17:59.511 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -23,7 +23,7 @@ F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d6484909 F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807 F autoconf/auto.def 3d994f3a9cc9b712dbce92a5708570ddcf3b988141b6eb738f2ed16127a9f0ac F autoconf/tea/Makefile.in bf6b43eafcd18766d81a8f0085cfc9cb051d8abae9031a8e7c3f5f1246e8f166 -F autoconf/tea/README.txt ed653d28131f356f87084928ddcf80d4935b3cd84cdb9406f534f045fc0558f7 +F autoconf/tea/README.txt 23475876343498ef2b514cc7510e8f1559a17e8e03fbc7a41c1c8a3b89e7b7e3 F autoconf/tea/_teaish.tester.tcl.in 8253b44be88e2e3f21de95a65d3a90c2be8e70b7bdd08a5b80e337ba7402f8f1 F autoconf/tea/auto.def ce95b9450e2fa4ba5dc857e208fe10f4e6f2d737796ac3278aee6079db417529 F autoconf/tea/configure d0b12b984edca6030d1976375b80157ac78b5b90a5b4f0dcee39357f63f4a80b x @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 387f4c4d98b8fb83f6ae406e4143dabda7766e8752b7f6ca104655e51330c978 -R eacb84e1e8fce545c882cbf546adff80 +P c9888a409565e6c8891a3dafa56962df364fb729a61df2701dc0bb282e36fb75 +R 18aff812c0e458ce4faf4f0cc718bfc5 U stephan -Z 32e930eb9547362a4891574b0cb43d68 +Z c396247e93c4ccc4319211c213bf549c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8ed5303148..5045dbdf69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9888a409565e6c8891a3dafa56962df364fb729a61df2701dc0bb282e36fb75 +bf7be67e3fb7b75fc281997f7bf9aa69eaf4da6bdf2fefe359b12d25ec95f512 From cfee69fbe46608fd662008c5d48e963eb8b7121b Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 2 Jun 2025 18:09:46 +0000 Subject: [PATCH 28/35] Updates to new test cases to run with SQLITE_ENABLE_SETLK_TIMEOUT=2 builds. FossilOrigin-Name: c6d3e3542fdf6a3428d3a2ec20c699c169ed53341dc782d81f7fe5944f769748 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/walsetlk_recover.test | 18 +++++++++++++----- test/walsetlk_snapshot.test | 23 ++++++++++++++++++++++- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index eb9fbb3209..a3a003af32 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\sinto\sthis\sbranch. -D 2025-06-02T17:44:10.848 +C Updates\sto\snew\stest\scases\sto\srun\swith\sSQLITE_ENABLE_SETLK_TIMEOUT=2\sbuilds. +D 2025-06-02T18:09:46.489 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -2036,8 +2036,8 @@ F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533 F test/walsetlk.test 9079cd8ef82570b8cf0067f31e049a72bec353fb2d5f0cc88f1736dc42ba9704 F test/walsetlk2.test 9097083633cdf55bf1098b694fb8651d0356d38fef28b869481d18029d7ceaf4 F test/walsetlk3.test 1b82bd92dea7e58f498b4399b0b3d26773dd8ac5c74205ce4a23c207cb8e85fe -F test/walsetlk_recover.test fb9f922aeceaece4b156fcea99751ca6dc6a9111d81cd018f891631d9b923bbb -F test/walsetlk_snapshot.test 408e8b9b8b93366e8e3f1f748e755b21fb177c1b56210fe0c68e760ea1fb77f6 +F test/walsetlk_recover.test e09ae048a9e6c78af6907f16246bc0233f44c259bd14c98117e1728506d9cdc6 +F test/walsetlk_snapshot.test 0edadd7712d4c3a15e056741beb05651f158da363f975aa199b0310acf664ac8 F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 14a18f4e3a3f35e636262a253364ab1e8054ed38c0c7fd482633522cbcf5ffc4 bf7be67e3fb7b75fc281997f7bf9aa69eaf4da6bdf2fefe359b12d25ec95f512 -R 9d4b9998d3f8edcfb9815d7e9467875d +P 7d27451804e525190f8e67da75aaeb3bf2de677021f7566c6681398e60a88c72 +R 734e170a1ca2f4592eaf31a41ca11e3c U dan -Z c11641e9268877729cb4210049f5ff6d +Z e910bbd4a496935af0bc3162a47411df # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 70843368f7..0f403444be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d27451804e525190f8e67da75aaeb3bf2de677021f7566c6681398e60a88c72 +c6d3e3542fdf6a3428d3a2ec20c699c169ed53341dc782d81f7fe5944f769748 diff --git a/test/walsetlk_recover.test b/test/walsetlk_recover.test index f5b142ec12..080ea638cd 100644 --- a/test/walsetlk_recover.test +++ b/test/walsetlk_recover.test @@ -18,7 +18,7 @@ source $testdir/lock_common.tcl set testprefix walsetlk_recover ifcapable !wal {finish_test ; return } -ifcapable !setlk_timeout {finish_test ; return } +# ifcapable !setlk_timeout {finish_test ; return } do_execsql_test 1.0 { PRAGMA journal_mode = wal; @@ -69,7 +69,7 @@ proc sleep_callback {args} { } sqlite3 db test.db -vfs tvfs -sqlite3_setlk_timeout db 500 +db timeout 500 set tm [lindex [time { catch { db eval {SELECT * FROM t1} @@ -88,9 +88,17 @@ do_execsql_test 1.4 { db close tvfs delete -do_test 1.5 { - set ::sleep_count -} 0 +# All SQLite builds should pass the tests above. SQLITE_ENABLE_SETLK_TIMEOUT=1 +# builds do so without calling the VFS xSleep method. +if {$::sqlite_options(setlk_timeout)==1} { + do_test 1.5.1 { + set ::sleep_count + } 0 +} else { + do_test 1.5.2 { + expr $::sleep_count>0 + } 1 +} finish_test diff --git a/test/walsetlk_snapshot.test b/test/walsetlk_snapshot.test index b0453f7e51..a1e97c5d3d 100644 --- a/test/walsetlk_snapshot.test +++ b/test/walsetlk_snapshot.test @@ -18,9 +18,18 @@ source $testdir/lock_common.tcl set testprefix walsetlk_snapshot ifcapable !wal {finish_test ; return } -ifcapable !setlk_timeout {finish_test ; return } ifcapable !snapshot {finish_test; return} +db close +testvfs tvfs -fullshm 1 +sqlite3 db test.db -vfs tvfs +tvfs script sleep_callback +tvfs filter xSleep +set ::sleep_count 0 +proc sleep_callback {args} { + incr ::sleep_count +} + do_execsql_test 1.0 { PRAGMA journal_mode = wal; CREATE TABLE t1(a, b); @@ -84,5 +93,17 @@ sqlite3_snapshot_free $::snap vwait myvar +# All SQLite builds should pass the tests above. SQLITE_ENABLE_SETLK_TIMEOUT=1 +# builds do so without calling the VFS xSleep method. +if {$::sqlite_options(setlk_timeout)==1} { + do_test 1.5.1 { + set ::sleep_count + } 0 +} else { + do_test 1.5.2 { + expr $::sleep_count>0 + } 1 +} + finish_test From 342ef63e638e167ef16e8fff5bc109e2aa3de344 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Jun 2025 18:34:17 +0000 Subject: [PATCH 29/35] Improve the accuracy of affinity and collating sequence analysis for NATURAL JOINs to the left of RIGHT JOINs where source tables are views or subqueries. Initial problem report in [forum:/forumpost/829306db47|forum post 829306db47]. FossilOrigin-Name: f184d1d236e47962658a4639d9533f67a525b74cfe0f06c93e9b85fdcd02a15f --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 8 ++++++-- src/select.c | 2 +- src/sqliteInt.h | 1 + test/joinH.test | 21 +++++++++++++++++++++ 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4e0a3e927d..2f6ccd2006 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slight\smodernization\sof\sthe\sTEA\sREADME.txt. -D 2025-06-02T15:17:59.511 +C Improve\sthe\saccuracy\sof\saffinity\sand\scollating\ssequence\sanalysis\sfor\nNATURAL\sJOINs\sto\sthe\sleft\sof\sRIGHT\sJOINs\swhere\ssource\stables\sare\sviews\nor\ssubqueries.\s\sInitial\sproblem\sreport\sin\n[forum:/forumpost/829306db47|forum\spost\s829306db47]. +D 2025-06-02T18:34:17.422 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -735,7 +735,7 @@ F src/date.c 9db4d604e699a73e10b8e85a44db074a1f04c0591a77e2abfd77703f50dce1e9 F src/dbpage.c b3e218f8ed74fcbb7fa805df8ca669a3718d397617b3d8a8aac3307dc315c4d6 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42 -F src/expr.c 6f184da1f36576ad1ecc48a03f14774235373c64f88d462c710834930ee6c145 +F src/expr.c f16fa5cbd849991462edf1d31bb7def5b970bb9611afcb4ea21c77e88e52a220 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 928ed2517e8732113d2b9821aa37af639688d752f4ea9ac6e0e393d713eeb76f F src/func.c 7686ea382b20e8bfe2ab9de76150c99ee7b6e83523561f3c7787e0f68cb435c2 @@ -784,12 +784,12 @@ F src/printf.c 3b91c334f528359145f4dde0dedd945bbb21044d0825ea064934d7222d61662c F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 9929e56e78f958657bfbb8234916473468243f90af359cc646d97c3ee809c79c +F src/select.c 882d739e0d5e6c7a8b46a3cca3ada37fe1a56301f1360d6b141312c666bbe482 F src/shell.c.in 1da613953db4c8d50e3a4a66fa7d69b4c95edb3628941d732637d3c35ea0dce6 F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e -F src/sqliteInt.h 75290111d8e37d35ec48a4fbb4e6af5611c9a551dedecceb896734ace9f60018 +F src/sqliteInt.h 0eeb2d363e7994aba3b482d3a9c88248b4d1fdad39cb65ff48621b2ae494a763 F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1376,7 +1376,7 @@ F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f2 F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28 F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127 -F test/joinH.test 29a25ea2c6323c6dd1ee7f2da906f24efbd467d60a9531e6704b8e2c88de9b9a +F test/joinH.test fd76024ff104baec16417db5cafc0894ad4e0863e70803e63c1bba0322706339 F test/journal1.test bc61a4228db11bffca118bd358ba4b868524bf080f3532749de6c539656e20fa F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test e5aeff93a7776cf644dbc48dec277655cff80a1cd24689036abc87869b120ea6 @@ -2207,8 +2207,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c9888a409565e6c8891a3dafa56962df364fb729a61df2701dc0bb282e36fb75 -R 18aff812c0e458ce4faf4f0cc718bfc5 -U stephan -Z c396247e93c4ccc4319211c213bf549c +P bf7be67e3fb7b75fc281997f7bf9aa69eaf4da6bdf2fefe359b12d25ec95f512 +R 1f718a77d399990842b8b713bc67dc26 +U drh +Z a6d9c9cd6e3fa998e21f0f81450c5cf2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5045dbdf69..af5d180aaa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf7be67e3fb7b75fc281997f7bf9aa69eaf4da6bdf2fefe359b12d25ec95f512 +f184d1d236e47962658a4639d9533f67a525b74cfe0f06c93e9b85fdcd02a15f diff --git a/src/expr.c b/src/expr.c index 12c94362f7..606a4cd7eb 100644 --- a/src/expr.c +++ b/src/expr.c @@ -73,7 +73,9 @@ char sqlite3ExprAffinity(const Expr *pExpr){ pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr ); } - if( op==TK_VECTOR ){ + if( op==TK_VECTOR + || (op==TK_FUNCTION && pExpr->affExpr==SQLITE_AFF_DEFER) + ){ assert( ExprUseXList(pExpr) ); return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); } @@ -266,7 +268,9 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ p = p->pLeft; continue; } - if( op==TK_VECTOR ){ + if( op==TK_VECTOR + || (op==TK_FUNCTION && p->affExpr==SQLITE_AFF_DEFER) + ){ assert( ExprUseXList(p) ); p = p->x.pList->a[0].pExpr; continue; diff --git a/src/select.c b/src/select.c index 1525a4640a..6c0e7c92d4 100644 --- a/src/select.c +++ b/src/select.c @@ -631,7 +631,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); if( pE1 ){ - pE1->affExpr = sqlite3ExprAffinity(pFuncArgs->a[0].pExpr); + pE1->affExpr = SQLITE_AFF_DEFER; } } }else if( (pSrc->a[i+1].fg.jointype & JT_LEFT)!=0 && pParse->nErr==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 951cd3d34d..c65d159d1b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2329,6 +2329,7 @@ struct CollSeq { #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ #define SQLITE_AFF_FLEXNUM 0x46 /* 'F' */ +#define SQLITE_AFF_DEFER 0x58 /* 'X' - defer computation until later */ #define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) diff --git a/test/joinH.test b/test/joinH.test index 822ba45b21..3392009680 100644 --- a/test/joinH.test +++ b/test/joinH.test @@ -390,4 +390,25 @@ do_execsql_test 14.2.4 { FROM (t3 NATURAL LEFT JOIN t2 NATURAL JOIN t1) AS qq FULL JOIN t4 ON true; } {0 {}} +# 2025-06-01 +# +reset_db +do_execsql_test 15.1 { + CREATE TABLE t0(c0); + CREATE TABLE t1(c0); + CREATE TABLE t2(c0); + INSERT INTO t0 VALUES ('1.0'); + INSERT INTO t2(c0) VALUES (9); + SELECT t0.c0,t2.c0 FROM (SELECT CAST(t0.c0 as REAL) AS c0 FROM t0) as subquery NATURAL LEFT JOIN t1 NATURAL JOIN t0 RIGHT JOIN t2 ON 1; +} {1.0 9} +do_execsql_test 15.2 { + CREATE TABLE x1(x COLLATE nocase); + CREATE TABLE x2(x); + CREATE TABLE x3(x); + CREATE TABLE t4(y); + INSERT INTO x1 VALUES('ABC'); + INSERT INTO x3 VALUES('abc'); + SELECT lower(x), quote(y) FROM x1 LEFT JOIN x2 USING (x) JOIN x3 USING (x) FULL JOIN t4; +} {abc NULL} + finish_test From 69ce758efa51906c9dad175e78893e160acc04f4 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 2 Jun 2025 18:37:32 +0000 Subject: [PATCH 30/35] Fix os_win.c so that SQLITE_ENABLE_SETLK_TIMEOUT=2 builds work on windows. FossilOrigin-Name: 8efb95e0d4670b9c5dbd8cf34512334f47951a8dff8fdadc8645f75076acd91f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os_win.c | 4 ++++ test/walsetlk_recover.test | 2 +- test/walsetlk_snapshot.test | 2 +- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index a3a003af32..96ed7e1f99 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\snew\stest\scases\sto\srun\swith\sSQLITE_ENABLE_SETLK_TIMEOUT=2\sbuilds. -D 2025-06-02T18:09:46.489 +C Fix\sos_win.c\sso\sthat\sSQLITE_ENABLE_SETLK_TIMEOUT=2\sbuilds\swork\son\swindows. +D 2025-06-02T18:37:32.126 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -770,7 +770,7 @@ F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 F src/os_unix.c 04e054ab86d86a7be99ebe5265922687791a40df5afc781d059beb47f4a40acd -F src/os_win.c 6535f8d41674ec9512b1dc516710af5e210db7e51149a500e14bd5b811000601 +F src/os_win.c b8d3cfdf2f40e2f9715b7d8df64f3c0c7ee18743a2dd0c4fc70c1d57fa1aadc7 F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19 F src/pager.c 23c0f17deb892da6b32fef1f465507df7ab5cd01d774288cb43695658a649259 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 @@ -2036,8 +2036,8 @@ F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533 F test/walsetlk.test 9079cd8ef82570b8cf0067f31e049a72bec353fb2d5f0cc88f1736dc42ba9704 F test/walsetlk2.test 9097083633cdf55bf1098b694fb8651d0356d38fef28b869481d18029d7ceaf4 F test/walsetlk3.test 1b82bd92dea7e58f498b4399b0b3d26773dd8ac5c74205ce4a23c207cb8e85fe -F test/walsetlk_recover.test e09ae048a9e6c78af6907f16246bc0233f44c259bd14c98117e1728506d9cdc6 -F test/walsetlk_snapshot.test 0edadd7712d4c3a15e056741beb05651f158da363f975aa199b0310acf664ac8 +F test/walsetlk_recover.test adccbffc59e365063a4efd2da6b661ae2fcf15d775b6719fe46acd87face08ff +F test/walsetlk_snapshot.test 86d5588380f9927d8fcbbd75133b0a34fddf959378d6823c6f164a390123f70a F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7d27451804e525190f8e67da75aaeb3bf2de677021f7566c6681398e60a88c72 -R 734e170a1ca2f4592eaf31a41ca11e3c +P c6d3e3542fdf6a3428d3a2ec20c699c169ed53341dc782d81f7fe5944f769748 +R 12703d8bfffd8f861886bb5cc39d7c30 U dan -Z e910bbd4a496935af0bc3162a47411df +Z 45c47e26e2dabffe2552459e6f2df0ee # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0f403444be..2655359b9b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6d3e3542fdf6a3428d3a2ec20c699c169ed53341dc782d81f7fe5944f769748 +8efb95e0d4670b9c5dbd8cf34512334f47951a8dff8fdadc8645f75076acd91f diff --git a/src/os_win.c b/src/os_win.c index c39b49e5e9..c7c923e774 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2722,7 +2722,11 @@ static int winHandleLockTimeout( if( res==WAIT_OBJECT_0 ){ ret = TRUE; }else if( res==WAIT_TIMEOUT ){ +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 rc = SQLITE_BUSY_TIMEOUT; +#else + rc = SQLITE_BUSY; +#endif }else{ /* Some other error has occurred */ rc = SQLITE_IOERR_LOCK; diff --git a/test/walsetlk_recover.test b/test/walsetlk_recover.test index 080ea638cd..1daece7470 100644 --- a/test/walsetlk_recover.test +++ b/test/walsetlk_recover.test @@ -77,7 +77,7 @@ set tm [lindex [time { }] 0] do_test 1.2 { set ::msg } {database is locked} -do_test 1.3.($::tm) { expr $::tm>400000 && $::tm<1000000 } 1 +do_test 1.3.($::tm) { expr $::tm>400000 && $::tm<2000000 } 1 vwait myvar diff --git a/test/walsetlk_snapshot.test b/test/walsetlk_snapshot.test index a1e97c5d3d..e05ad69cce 100644 --- a/test/walsetlk_snapshot.test +++ b/test/walsetlk_snapshot.test @@ -83,7 +83,7 @@ set tm [lindex [time { }] 0] do_test 1.2 { set ::msg } {SQLITE_BUSY} -do_test 1.3.($::tm) { expr $::tm<1000000 } 1 +do_test 1.3.($::tm) { expr $::tm<2000000 } 1 do_execsql_test 1.4 { SELECT * FROM t1 From 333b07b18d1f4fb0d89b5380cba85acf5b7d2531 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Jun 2025 18:58:42 +0000 Subject: [PATCH 31/35] Increase the version number to 3.51.0 FossilOrigin-Name: ed69d4432712603bea2161e0ca0c99e59480fb000e1cbf1aa1401d924544e351 --- VERSION | 2 +- manifest | 15 +++++++-------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/VERSION b/VERSION index ca25ff637a..84ba969c48 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.50.0 +3.51.0 diff --git a/manifest b/manifest index 742e098a5e..a662abfe73 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sensure\sSQLITE_ENABLE_SETLK_TIMEOUT\sbuilds\suse\sa\sblocking\slock\sand\sdo\snot\scall\sxSleep()\swhen\s(a)\sopening\sa\ssnapshot\stransaction,\sand\s(b)\swhen\sblocked\sby\sanother\sprocess\srunning\srecovery. -D 2025-06-02T18:48:36.921 +C Increase\sthe\sversion\snumber\sto\s3.51.0 +D 2025-06-02T18:58:42.711 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -8,7 +8,7 @@ F Makefile.in c3e414df4dc8dfb12f1f6baf129fcb6d18cd0ebd3c9109370fb3fceeeef9a37a F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc aa4f9ae86cf59fe94a3e93bf1a4c241b3ffffe96cf4d823517acf593c277223b F README.md e28077cfbef795e99c9c75ed95aa7257a1166709b562076441a8506ac421b7c1 -F VERSION 001dea55eb8304ec9130b6b44a32d3fc349f279d45a7e224fc0730c3cb8e2372 +F VERSION 16eddb43056a79c1977427ab7a05f3457c373fa159dcdced8754eb89ce7e06b8 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d87031 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -2209,9 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f184d1d236e47962658a4639d9533f67a525b74cfe0f06c93e9b85fdcd02a15f 8efb95e0d4670b9c5dbd8cf34512334f47951a8dff8fdadc8645f75076acd91f -R 87f8c350d69796fb64023493aed9406c -T +closed 8efb95e0d4670b9c5dbd8cf34512334f47951a8dff8fdadc8645f75076acd91f -U dan -Z 2e11cb3824d33d1f7410effb2728f2aa +P 7f9c0cdd0630a41db359b188b226a1ad6a3bae1663c27169acfe25edc7fb171b +R 4efb6bc44e0a81b61f5530f71db37e62 +U drh +Z c89f71bacec5bb21cafac9f77551c3dc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 673bfd6f14..98165b5002 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f9c0cdd0630a41db359b188b226a1ad6a3bae1663c27169acfe25edc7fb171b +ed69d4432712603bea2161e0ca0c99e59480fb000e1cbf1aa1401d924544e351 From 2bd9f69d40dd240c4122c6d02f1ff447e7b5c098 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 Jun 2025 23:34:42 +0000 Subject: [PATCH 32/35] Fix JSONB edit so that when it is trying to reduce the size of an element it understands 0xf0 (8-byte) sizes. FossilOrigin-Name: 5b3de6e8ab6b228bf6c0e0c31b50ca29d8b7852b460eaaca6c6ecf5a3c083cab --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/json.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a662abfe73..8afdb6df4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.51.0 -D 2025-06-02T18:58:42.711 +C Fix\sJSONB\sedit\sso\sthat\swhen\sit\sis\strying\sto\sreduce\sthe\ssize\sof\san\selement\nit\sunderstands\s0xf0\s(8-byte)\ssizes. +D 2025-06-02T23:34:42.519 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -745,7 +745,7 @@ F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c d05934dfab2c5c0c480fc6fd2038f11215661de08ea6ff38d2563216bd555c1b -F src/json.c d34969ecb9555f33fc0b2227628189a9a4e20dda5df5d173db9918a014aa7ad1 +F src/json.c cb87977b1ee25ee7d27505d65a9261b687395bf895342c8ba566b7c01aee2047 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c d7edd8e671237539d795d30daaf888908a2c82e99bade4c78f3be021e8b7d655 F src/main.c 07f78d917ffcdf327982840cfd8e855fd000527a2ea5ace372ce4febcbd0bf97 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7f9c0cdd0630a41db359b188b226a1ad6a3bae1663c27169acfe25edc7fb171b -R 4efb6bc44e0a81b61f5530f71db37e62 +P ed69d4432712603bea2161e0ca0c99e59480fb000e1cbf1aa1401d924544e351 +R 745c36561be7de68cb06b54ba333e439 U drh -Z c89f71bacec5bb21cafac9f77551c3dc +Z 6eb7eaab7de1ec41a609797433fd777e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 98165b5002..73c441d7d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ed69d4432712603bea2161e0ca0c99e59480fb000e1cbf1aa1401d924544e351 +5b3de6e8ab6b228bf6c0e0c31b50ca29d8b7852b460eaaca6c6ecf5a3c083cab diff --git a/src/json.c b/src/json.c index 4ae17a5a4b..3078be34ba 100644 --- a/src/json.c +++ b/src/json.c @@ -1285,8 +1285,10 @@ static int jsonBlobChangePayloadSize( nExtra = 1; }else if( szType==13 ){ nExtra = 2; - }else{ + }else if( szType==14 ){ nExtra = 4; + }else{ + nExtra = 8; } if( szPayload<=11 ){ nNeeded = 0; From 140748f949aa52e1cc09eaa9d8e4fb685c426154 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 3 Jun 2025 10:18:54 +0000 Subject: [PATCH 33/35] Fix harmless compiler warning introduced by the setlk-snapshot-fix merge. FossilOrigin-Name: c1f20f89d9eb3e1dd1018c0e0efe5d3043a592f078e235ad04b960334c7186c2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8afdb6df4f..5569d56774 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sJSONB\sedit\sso\sthat\swhen\sit\sis\strying\sto\sreduce\sthe\ssize\sof\san\selement\nit\sunderstands\s0xf0\s(8-byte)\ssizes. -D 2025-06-02T23:34:42.519 +C Fix\sharmless\scompiler\swarning\sintroduced\sby\sthe\ssetlk-snapshot-fix\smerge. +D 2025-06-03T10:18:54.950 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -865,7 +865,7 @@ F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf8 F src/vdbevtab.c fc46b9cbd759dc013f0b3724549cc0d71379183c667df3a5988f7e2f1bd485f3 F src/vtab.c 828221bdbeaaa6d62126ee6d07fd4ec0d09dcaea846f87ad01944d8b7e548859 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 78da33510b8cb1b096fb5ae9954be910998d2477ddb623e56f5df84e56b5814d +F src/wal.c b0f848cfba8dd057f77073493cdd542f9125b4cf87941f53e9d0db21604155c8 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 F src/where.c 45a3b496248a0b36d91ce34da3278d54f8fa20e9d3fbd36d45a42051d1118137 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ed69d4432712603bea2161e0ca0c99e59480fb000e1cbf1aa1401d924544e351 -R 745c36561be7de68cb06b54ba333e439 +P 5b3de6e8ab6b228bf6c0e0c31b50ca29d8b7852b460eaaca6c6ecf5a3c083cab +R 84ba82d7ea7bde162a62e665c4790bc6 U drh -Z 6eb7eaab7de1ec41a609797433fd777e +Z b23b72ad23ffb60025f9c361dddc5b4d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 73c441d7d1..6361ae4e50 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b3de6e8ab6b228bf6c0e0c31b50ca29d8b7852b460eaaca6c6ecf5a3c083cab +c1f20f89d9eb3e1dd1018c0e0efe5d3043a592f078e235ad04b960334c7186c2 diff --git a/src/wal.c b/src/wal.c index fc176988bd..1fd5b201cb 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3076,7 +3076,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ ** WAL_RETRY this routine will be called again and will probably be ** right on the second iteration. */ - walEnableBlocking(pWal); + (void)walEnableBlocking(pWal); if( pWal->apWiData[0]==0 ){ /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. ** We assume this is a transient condition, so return WAL_RETRY. The From df724c893add695f0786bca0f203c33174e093ac Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 3 Jun 2025 10:28:47 +0000 Subject: [PATCH 34/35] Fix an off-by-one error in sqlite3_rsync, reported in [forum:/forumpost/b6d78f60fc|forum post b6d78f60fc]. FossilOrigin-Name: 27d9e8e79b921c4a86916556f3bf56b94684a7e3d40166c0fdaaf750d4011de0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/sqlite3_rsync.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5569d56774..e2ece112be 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sintroduced\sby\sthe\ssetlk-snapshot-fix\smerge. -D 2025-06-03T10:18:54.950 +C Fix\san\soff-by-one\serror\sin\ssqlite3_rsync,\sreported\sin\n[forum:/forumpost/b6d78f60fc|forum\spost\sb6d78f60fc]. +D 2025-06-03T10:28:47.757 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -2191,7 +2191,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 4969fd642dad0ea483e4e104163021d92baf98f6a8eac981fe48525f9b873430 F tool/sqldiff.c 134be7866be19f8beb32043d5aea5657f01aaeae2df8d33d758ff722c78666b9 F tool/sqlite3_analyzer.c.in 14f02cb5ec3c264cd6107d1f1dad77092b1cf440fc196c30b69ae87b56a1a43b -F tool/sqlite3_rsync.c e8659970e839d71d2ef04b96d48ad65f1d4298a41636affaf93c32ed71f3f879 +F tool/sqlite3_rsync.c 4e152221a51ed2974f08100d86500c2cda549472e48e09699a8011bfb956d00c F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c 6c655d9a8d6b30f3648fc78a79bf3838ed68f8543869d380c43ea9f17b3b8501 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 5b3de6e8ab6b228bf6c0e0c31b50ca29d8b7852b460eaaca6c6ecf5a3c083cab -R 84ba82d7ea7bde162a62e665c4790bc6 +P c1f20f89d9eb3e1dd1018c0e0efe5d3043a592f078e235ad04b960334c7186c2 +R 5368c7993d91b172776e037221fcf8b9 U drh -Z b23b72ad23ffb60025f9c361dddc5b4d +Z 4a32614f4e43a012c04f76325fcd66fb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6361ae4e50..029062c3d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1f20f89d9eb3e1dd1018c0e0efe5d3043a592f078e235ad04b960334c7186c2 +27d9e8e79b921c4a86916556f3bf56b94684a7e3d40166c0fdaaf750d4011de0 diff --git a/tool/sqlite3_rsync.c b/tool/sqlite3_rsync.c index 46ff2e50e3..84ebf15c58 100644 --- a/tool/sqlite3_rsync.c +++ b/tool/sqlite3_rsync.c @@ -1538,7 +1538,7 @@ static void originSide(SQLiteRsync *p){ sqlite3_finalize(pInsHash); pCkHash = 0; pInsHash = 0; - if( mxHashnPage ){ + if( mxHash<=p->nPage ){ runSql(p, "WITH RECURSIVE c(n) AS" " (VALUES(%d) UNION ALL SELECT n+1 FROM c WHERE n<%d)" " INSERT INTO badHash SELECT n, 1 FROM c", From 1d151e6d256ec01d92c8cf3e6c25dd19f222055a Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 3 Jun 2025 10:49:51 +0000 Subject: [PATCH 35/35] Enhance sqlite3_rsync so that it works even if the replica database is initially malformed. FossilOrigin-Name: ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/sqlite3_rsync.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e2ece112be..a74d89470c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\soff-by-one\serror\sin\ssqlite3_rsync,\sreported\sin\n[forum:/forumpost/b6d78f60fc|forum\spost\sb6d78f60fc]. -D 2025-06-03T10:28:47.757 +C Enhance\ssqlite3_rsync\sso\sthat\sit\sworks\seven\sif\sthe\sreplica\sdatabase\sis\ninitially\smalformed. +D 2025-06-03T10:49:51.412 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -2191,7 +2191,7 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d F tool/split-sqlite3c.tcl 4969fd642dad0ea483e4e104163021d92baf98f6a8eac981fe48525f9b873430 F tool/sqldiff.c 134be7866be19f8beb32043d5aea5657f01aaeae2df8d33d758ff722c78666b9 F tool/sqlite3_analyzer.c.in 14f02cb5ec3c264cd6107d1f1dad77092b1cf440fc196c30b69ae87b56a1a43b -F tool/sqlite3_rsync.c 4e152221a51ed2974f08100d86500c2cda549472e48e09699a8011bfb956d00c +F tool/sqlite3_rsync.c c1e1a737ebb458a4ccbbaa21e5eaa878448fef1aaa71b879b9a685785e28987f F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 F tool/src-verify.c 6c655d9a8d6b30f3648fc78a79bf3838ed68f8543869d380c43ea9f17b3b8501 @@ -2209,8 +2209,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c1f20f89d9eb3e1dd1018c0e0efe5d3043a592f078e235ad04b960334c7186c2 -R 5368c7993d91b172776e037221fcf8b9 +P 27d9e8e79b921c4a86916556f3bf56b94684a7e3d40166c0fdaaf750d4011de0 +R 9cc60dad3acf43f97f93eee6529b25c7 U drh -Z 4a32614f4e43a012c04f76325fcd66fb +Z b6b73666051465f0df1cb185ca3428e3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 029062c3d8..4b4b23196c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -27d9e8e79b921c4a86916556f3bf56b94684a7e3d40166c0fdaaf750d4011de0 +ea1754f7d8a770477a1b19b606b27724fdc0b733e51fef32c1ef834f972c3cc5 diff --git a/tool/sqlite3_rsync.c b/tool/sqlite3_rsync.c index 84ebf15c58..03a74f3655 100644 --- a/tool/sqlite3_rsync.c +++ b/tool/sqlite3_rsync.c @@ -1797,6 +1797,7 @@ static void replicaSide(SQLiteRsync *p){ closeDb(p); break; } + sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0); runSql(p, "ATTACH %Q AS 'replica'", p->zReplica); if( p->wrongEncoding ){ p->wrongEncoding = 0;