diff --git a/Makefile.linux-gcc b/Makefile.linux-gcc index ad5d4dd093..fe7349ad46 100644 --- a/Makefile.linux-gcc +++ b/Makefile.linux-gcc @@ -22,12 +22,6 @@ TOP = ../sqlite BCC = gcc -g -O0 #BCC = /opt/ancic/bin/c89 -0 -#### If the target operating system supports the "usleep()" system -# call, then define the HAVE_USLEEP macro for all C modules. -# -#USLEEP = -USLEEP = -DHAVE_USLEEP=1 - #### If you want the SQLite library to be safe for use within a # multi-threaded program, then define the following macro # appropriately: diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index e46840c2e8..9d80e79e56 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4752,7 +4752,7 @@ static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ nEntry += pLvl->aSeg[iSeg].nEntry; nTomb += pLvl->aSeg[iSeg].nEntryTombstone; } - assert( nEntry>0 || pLvl->nSeg==0 ); + assert_nc( nEntry>0 || pLvl->nSeg==0 ); if( nEntry>0 ){ int nPercent = (nTomb * 100) / nEntry; if( nPercent>=pConfig->nDeleteMerge && nPercent>nBest ){ @@ -8092,15 +8092,16 @@ static int fts5structCloseMethod(sqlite3_vtab_cursor *cur){ */ static int fts5structNextMethod(sqlite3_vtab_cursor *cur){ Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; + Fts5Structure *p = pCsr->pStruct; assert( pCsr->pStruct ); pCsr->iSeg++; pCsr->iRowid++; - while( pCsr->iSeg>=pCsr->pStruct->aLevel[pCsr->iLevel].nSeg ){ + while( pCsr->iLevelnLevel && pCsr->iSeg>=p->aLevel[pCsr->iLevel].nSeg ){ pCsr->iLevel++; pCsr->iSeg = 0; } - if( pCsr->iLevel>=pCsr->pStruct->nLevel ){ + if( pCsr->iLevel>=p->nLevel ){ fts5StructureRelease(pCsr->pStruct); pCsr->pStruct = 0; } diff --git a/ext/wasm/api/extern-post-js.c-pp.js b/ext/wasm/api/extern-post-js.c-pp.js index 00cb3fab90..63e55051c6 100644 --- a/ext/wasm/api/extern-post-js.c-pp.js +++ b/ext/wasm/api/extern-post-js.c-pp.js @@ -62,6 +62,7 @@ const toExportForESM = globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",globalThis.location); return originalInit(...args).then((EmscriptenModule)=>{ +//#if wasmfs if('undefined'!==typeof WorkerGlobalScope && EmscriptenModule['ENVIRONMENT_IS_PTHREAD']){ /** Workaround for wasmfs-generated worker, which calls this @@ -72,6 +73,7 @@ const toExportForESM = //console.warn("sqlite3InitModule() returning E-module.",EmscriptenModule); return EmscriptenModule; } +//#endif //console.warn("sqlite3InitModule() returning sqlite3 object."); const s = EmscriptenModule.sqlite3; s.scriptInfo = initModuleState; diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 0179091c02..3b29041c37 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1645,7 +1645,8 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( do not. */ tgt.push(capi.sqlite3_value_to_js( - wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)) + wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)), + throwIfCannotConvert )); } return tgt; diff --git a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js index ee8d1a5d68..3ba889c393 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js @@ -865,6 +865,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ //! Documented elsewhere in this file. importDb(name, bytes){ + if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes); const n = bytes.byteLength; if(n<512 || n%512!=0){ toss("Byte array size is invalid for an SQLite db."); @@ -1074,16 +1075,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Returns an array of the names of the files currently allocated to slots. This list is the same length as getFileCount(). - - void importDb(name, byteArray) + - void importDb(name, bytes) Imports the contents of an SQLite database, provided as a byte - array, under the given name, overwriting any existing - content. Throws if the pool has no available file slots, on I/O - error, or if the input does not appear to be a database. In the - latter case, only a cursory examination is made. Note that this - routine is _only_ for importing database files, not arbitrary files, - the reason being that this VFS will automatically clean up any - non-database files so importing them is pointless. + array or ArrayBuffer, under the given name, overwriting any + existing content. Throws if the pool has no available file slots, + on I/O error, or if the input does not appear to be a + database. In the latter case, only a cursory examination is made. + Note that this routine is _only_ for importing database files, + not arbitrary files, the reason being that this VFS will + automatically clean up any non-database files so importing them + is pointless. - [async] number reduceCapacity(n) diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index cbe6ab3518..57141d7e2b 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -18,7 +18,7 @@ endif ifeq (,$(SHELL_SRC)) $(error Could not parse SHELL_SRC from $(dir.top)/Makefile.) endif -$(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl +$(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl $(sqlite3.c) $(MAKE) -C $(dir.top) shell.c # /shell.c ######################################################################## @@ -61,9 +61,9 @@ $(fiddle.SOAP.js): $(SOAP.js) $(eval $(call call-make-pre-post,fiddle-module,vanilla)) $(fiddle-module.js): $(MAKEFILE) $(MAKEFILE.fiddle) \ $(EXPORTED_FUNCTIONS.fiddle) \ - $(fiddle.cses) $(pre-post-fiddle-module.deps.vanilla) $(fiddle.SOAP.js) + $(fiddle.cses) $(pre-post-fiddle-module-vanilla.deps) $(fiddle.SOAP.js) $(emcc.bin) -o $@ $(fiddle.emcc-flags) \ - $(pre-post-fiddle-module.flags.vanilla) \ + $(pre-post-fiddle-module-vanilla.flags) \ $(fiddle.cses) $(maybe-wasm-strip) $(fiddle-module.wasm) gzip < $@ > $@.gz diff --git a/ext/wasm/fiddle/fiddle-worker.js b/ext/wasm/fiddle/fiddle-worker.js index e239cbf51e..67f61008fb 100644 --- a/ext/wasm/fiddle/fiddle-worker.js +++ b/ext/wasm/fiddle/fiddle-worker.js @@ -221,7 +221,7 @@ f._(); } }; - + self.onmessage = function f(ev){ ev = ev.data; if(!f.cache){ @@ -371,12 +371,14 @@ sqlite3InitModule(fiddleModule).then((_sqlite3)=>{ sqlite3 = _sqlite3; console.warn("Installing sqlite3 module globally (in Worker)", - "for use in the dev console."); - self.sqlite3 = sqlite3; + "for use in the dev console.", sqlite3); + globalThis.sqlite3 = sqlite3; const dbVfs = sqlite3.wasm.xWrap('fiddle_db_vfs', "*", ['string']); fiddleModule.fsUnlink = (fn)=>{ return sqlite3.wasm.sqlite3_wasm_vfs_unlink(dbVfs(0), fn); }; wMsg('fiddle-ready'); - })/*then()*/; + }).catch(e=>{ + console.error("Fiddle worker init failed:",e); + }); })(); diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index db4b50f4b6..c1b16d5e81 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -353,7 +353,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; const sahPoolConfig = { name: 'opfs-sahpool-tester1', clearOnInit: true, - initialCapacity: 3 + initialCapacity: 6 }; //////////////////////////////////////////////////////////////////////// // End of infrastructure setup. Now define the tests... @@ -3076,7 +3076,24 @@ globalThis.sqlite3InitModule = sqlite3InitModule; T.assert(1 === fileNames.length) .assert(dbName === fileNames[0]) .assert(1 === u1.getFileCount()) - .assert(true === u1.unlink(dbName)) + + if(1){ // test exportFile() and importDb() + const dbytes = u1.exportFile(dbName); + T.assert(dbytes.length >= 4096); + const dbName2 = '/exported.db'; + u1.importDb(dbName2, dbytes); + T.assert( 2 == u1.getFileCount() ); + let db2 = new u1.OpfsSAHPoolDb(dbName2); + T.assert(db2 instanceof sqlite3.oo1.DB) + .assert(3 === db2.selectValue('select count(*) from t')); + db2.close(); + T.assert(true === u1.unlink(dbName2)) + .assert(false === u1.unlink(dbName2)) + .assert(1 === u1.getFileCount()) + .assert(1 === u1.getFileNames().length); + } + + T.assert(true === u1.unlink(dbName)) .assert(false === u1.unlink(dbName)) .assert(0 === u1.getFileCount()) .assert(0 === u1.getFileNames().length); @@ -3089,6 +3106,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; log("Installed second SAH instance as",conf2.name); T.assert(0 === POther.getFileCount()) .assert(true === await POther.removeVfs()); + if(0){ /* Enable this block to inspect vfs's contents via the dev console or OPFS Explorer browser extension. The diff --git a/manifest b/manifest index fb3b812441..b5e978aaf9 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sbedrock\sbranch. -D 2023-07-28T18:52:09.247 +D 2023-08-03T23:26:39.123 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 0423d5a97be582884ffdb228216790f5bb10678bed50f359cce6f0745107bf32 -F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 +F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 F Makefile.msc 97f9b14ef0418943c315db08f4961932f2fc839603c13ab646079840b0d83329 F README.md c1c4218efcc4071a6e26db2b517fdbc1035696a29b370edd655faddbef02b224 F VERSION c6366dc72582d3144ce87b013cc35fe48d62f6d07d5be0c9716ea33c862144aa @@ -94,7 +94,7 @@ F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b7292 F ext/fts5/fts5_config.c 054359543566cbff1ba65a188330660a5457299513ac71c53b3a07d934c7b081 F ext/fts5/fts5_expr.c 2473c13542f463cae4b938c498d6193c90d38ea1a2a4f9849c0479736e50d24d F ext/fts5/fts5_hash.c 65e7707bc8774706574346d18c20218facf87de3599b995963c3e6d6809f203d -F ext/fts5/fts5_index.c a4e35cd126c19df66887801db15ccae7290b51129add3d4cdd31e2d9ea240398 +F ext/fts5/fts5_index.c 93b4cd116b76b6adf224cd3d213f1e06cfe10ae0eb21d6372b1c53b8f0c382a3 F ext/fts5/fts5_main.c 08a60103dd5bc1b58c5f83f92ec40e2c1d369c8525a943545379e43d18c973a6 F ext/fts5/fts5_storage.c 3c9b41fce41b6410f2e8f82eb035c6a29b2560483f773e6dc98cf3cb2e4ddbb5 F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae @@ -502,7 +502,7 @@ F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api c5eaceabb9e759aaae7d3101a4a3e542f9 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 5eb44fa02e9c693a1884a3692428647894b0380b24bca120866b7a24c8786134 -F ext/wasm/api/extern-post-js.c-pp.js e7257ea56d4077d0773d7537fcb8eade59aad0c118dab92497c27939edca41cb +F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 @@ -510,12 +510,12 @@ F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057af F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e F ext/wasm/api/sqlite3-api-glue.js cc6b0bb093bdb6279d4af259200b7b9e150e3796a8a3a4cd09a4928c43d25e56 F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8 -F ext/wasm/api/sqlite3-api-prologue.js cbd7d6ba185f3a844a8b0020e954b49bbc2ca78b305d117bec2ceca21431795a +F ext/wasm/api/sqlite3-api-prologue.js 76258e160bf6a89cc75a7d3c05646a054c8cab7219cd1e10bc20cacaad022131 F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379 F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25 -F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 44740935f6eeab3a0c6dc9f0ca93aebb6339f8d8365f03ea6d7808c134dbfe46 +F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 54cee22aacadb9dfaea438d72ac0882249d028c37903208d48c52871290ceff7 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e7a690e0e78ff4d563f2eca468f91db69f001ff4b79c6d2304cbb6f62dca437d F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f10c3ecd9df06f6320073c2ce230a7ed7c56034d8b88c1e57095f2a97faf423a @@ -538,9 +538,9 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2 F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef F ext/wasm/dist.make 3a851858aad72e246a5d9c5aaf6b6a144305f1bf898ac1846760ea7bab95c9a3 F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make dbe36b90b8907ae28ecb9c0e9fd8389dbdaecf117ea4fb2ea33864bdfa498a94 +F ext/wasm/fiddle.make fa2ba6e90457ba2a71cb745f200d409caf773076df75ae5b177cc225d7627a11 F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f -F ext/wasm/fiddle/fiddle-worker.js 163d6139a93fab4bcb72064923df050d4e7c0ff0d8aa061ce8776a6e75da8a10 +F ext/wasm/fiddle/fiddle-worker.js e0153f9af6500805c6f09c0b3cfdb7d857e9d6863dbee9d50d1628fccf5f4b4d F ext/wasm/fiddle/fiddle.html 550c5aafce40bd218de9bf26192749f69f9b10bc379423ecd2e162bcef885c08 F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715 F ext/wasm/index-dist.html 22379774f0ad4edcaaa8cf9c674c82e794cc557719a8addabed74eb8069d412e @@ -562,7 +562,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js b9a493a764f2113f6a8205d4e5573a25731d6f965338005460920389ac0693e0 +F ext/wasm/tester1.c-pp.js b88dcad5424a652e8204c44a71bbc3deb22a4922c97ba792aedbabb7a6827b91 F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 @@ -592,7 +592,7 @@ F src/bitvec.c 501daeef838fa82a9fb53540d72f29e3d9172c8867f1e19f94f681e2e20b966e F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 F src/btree.c 728b0fa125e113553489389ffb6992ce2e0bda0431a1e9f2f8baac952bd07e01 F src/btree.h d906e4d53f483c83d471d99479fa73fcdf20696305d578876f46ee283f3507cb -F src/btreeInt.h c99c2c6b29c1d36f2a6cc67dcf220b080c8817cb2812e6d5ca27e158a14e1e68 +F src/btreeInt.h 9c6d726acb6357b12683908530073836d9eb515bdeda3e32ee998edc3542a750 F src/build.c d1f3d6478799b6eef9bb39214fc5495c8ee940fe2e70bf0b65ad8b6984bf0db9 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -600,7 +600,7 @@ F src/ctime.c f439c21d439aaf4706950a2597474f1a796b557a0750666308202c0f601ef0fd F src/date.c f73f203b3877cef866c60ab402aec2bf89597219b60635cf50cbe3c5e4533e94 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef -F src/delete.c cd5f5cd06ed0b6a882ec1a8c2a0d73b3cecb28479ad19e9931c4706c5e2182be +F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 F src/expr.c ef4a81822da6f767696bd7f4b9983328af061158958138540142285a5b1181b7 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36 @@ -611,10 +611,10 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276 -F src/json.c 60b6b0815ddaf546396e3c7328065a114b581721dc1fa20697a52610fb2259aa +F src/json.c d2b7f613a1792043f8e758fdcfe9469f9b81f522999b508f436517752a5d7071 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465 -F src/main.c 429a1a25752edd6afa97de4b8ac10b98f557bbd93f01e39fcd2fa2204a8f54bb +F src/main.c e56843b488ead74369eeffc64cd5b9d3a7ffbf8621bb0cd695272d9b9ce53afa F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 @@ -635,7 +635,7 @@ 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 c2c3b93b716194a2115b282c37f828438e071e6f2fc4e38c5d6f24d5ba822e7a +F src/os_unix.c c8003dfe6502315cf930160b6cf1b93f82211bed5ab9226509faa6324030c8ea F src/os_win.c 7038223a1cda0a47e2ab4db47f63bf1833fe53ba0542f0f283a062ea13894103 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 71f3c8b45890d35156518ffeb71e422274557793cbedff80585b4e292feed234 @@ -651,17 +651,17 @@ F src/printf.c e3ba080e2f409f9bfcc8d34724e6fc160e9c718dc92d0548f6b71b8b6f860ce2 F src/random.c 9bd018738ec450bf35d28050b4b33fa9a6eebf3aaefb1a1cff42dc14a7725673 F src/resolve.c 37953a5f36c60bea413c3c04efcd433b6177009f508ef2ace0494728912fe2e9 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c 0b7c7b89576c39a5e6c166a12d1f377fd58bd26da16db0a580bbfa74d7b9e140 +F src/select.c 0945ea9f5bb57efda1156b69c3d1f2d41f7fe0ad1cd5f79142fd145791e6f4fd F src/shell.c.in 694aaf751f00610381533d4a31c83d142cfc83ef91ef65e2aa6912ace7c39b40 -F src/sqlite.h.in cadea2f657e69e715e4a2e501cd0139c2a613e00ad771957b4bd9cc5a8a628ff +F src/sqlite.h.in bc5d3d1776a3681ab552590c60589e0e93cbdfb66c7ed1615d649a180a62805f F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 -F src/sqliteInt.h 3f9fcac18b13d70e3098d2a3e630e8e5a72f528b30cc66a6c5fe50dbbf26d2fe +F src/sqliteInt.h c6d007de03ed2f9e74cbf31b6ecea0fd7fdd2cf5aa68ca4a0f5ea1df46b09c17 F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd -F src/test1.c 60804113ea9fdbd2dff1c711f4c7d7f41eaac3f3bf1dabfdbc997ac1b14d4f38 +F src/test1.c 91addc5c30c1389d257380b6e42ae0681d32d24553b9938d798a47ff96fa75ca F src/test2.c 827446e259a3b7ab949da1542953edda7b5117982576d3e6f1c24a0dd20a5cef F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664 @@ -716,18 +716,18 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 0fb405f9adf3f757c26bfc1ae6d58ac5dccbb918917ba9e5ef0e6673a06563d3 F src/treeview.c 1d52fbc4e97161e65858d36e3424ea6e3fc045dd8a679c82b4b9593dc30de3bd F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0 -F src/update.c 94a803cf0e45208d12952250500c4210f9ca1b6401fc822033009484f2d39331 +F src/update.c 9a3fc67079371bf9c21b38926f87d812cb0888df6ec0cc00f17117ba44f23519 F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c c2aa170f2eb429235b1dddce8952770787ffa5124dc89d405bfbe8ebad8e7ebd +F src/util.c b3532a95ad56db67b3acd3955e688e4cb80ebec6fd1f459a8eb51cceedd6de69 F src/vacuum.c b1dd6d73869229b6e08bac910ac011dc9da42e3120ec2b7241accc5a752bd419 -F src/vdbe.c 017239fcce6f09ce356353ceb7cd2ef142a537433055dd35a231480ba73295c7 +F src/vdbe.c 6db2c0f04ffff4e26524b18e3f3c8f50a39aae2fee16cbfb4cd5a420ddecfe48 F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0 -F src/vdbeInt.h cd829ff67fc18aff2476fe3209262ba8671cb43d51cb6913de4a670e37d2fbe3 -F src/vdbeapi.c 0cba9fe6e860e46bfb5e45a76a8c2c6ccd5ebc8f954319e4288e7793c2eca88c +F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c +F src/vdbeapi.c f37822f215740ede2a8fcae99bc13f2cc3a72dd0e1d22b81b9298c5ca67dbc38 F src/vdbeaux.c e4ff54897dca508b3c3726973a1cb08f09d81cbe13c0c36012d9c2572402327c F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce -F src/vdbemem.c adb5877dc54330865e45e0fba50f6455c1d9d8b83434c59f0e3d2d2a0b9f0e58 +F src/vdbemem.c 317b9f48708139db6239ade40c7980b4bc8233168383690d588dad6d8437f722 F src/vdbesort.c 0d40dca073c94e158ead752ef4225f4fee22dee84145e8c00ca2309afb489015 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c 57fa8f56478e5b5cb558cb425e7878515e0a105c54f96f1d1bbf4b9433529254 @@ -736,7 +736,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 6e1705125b58635ce9ed534f4d26942e4a5e8b5a33219c88f436a9e4691026d4 F src/wal.h dd2cd9880f308a1bda0a72f36a29c3d4388d47db45f321ebe936a378ac845e32 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 -F src/where.c 477fcc5e561ef169e6002499602af6b805156c2aae6b2f5c2c93ef8c1cd64768 +F src/where.c b8917792f1e0dbfa28fb29e6cd3d560060d69667be0ba4c491cbc772363264f5 F src/whereInt.h c7d19902863beadec1d04e66aca39c0bcd60b74f05f0eaa7422c7005dfc5d51a F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1 F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00 @@ -930,7 +930,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test 9d8cbf6214e492abe9e822e759b9751ae336cec0a6fe3ff3b37bfbd8ff9c22ca F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test b42978028afc5eefc8b51d8d7cd6a9344ba7362d7ed4511ee2070f56e06d5a1c +F test/corruptL.test 504d90502d9993440226edc355d2275524b89064ea3df5ee5c27f7028ec59d07 F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/corruptN.test 57985a0737f5e008283a91c24630cd3c7003d3c7b62824edaa21258e46da9455 F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576 @@ -1159,7 +1159,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db b8725a5f5cf7a3b7241a9038e57ca7e7cc8c3f4d86b44bd770617bda245ab2b0 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db f6c2f2af4deaaae0ddb3310d509c2659990794aa653dc501b80a0534c3493f80 +F test/fuzzdata8.db 40c85daae47da64387c3dab7bbd99c21e425c0bfdb4b149cb685b1ab474a2cb4 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc @@ -1792,7 +1792,7 @@ F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test 0edaf3411d300693bca595897c5201421c6c5ec787990a1dfe2f7f60ae93f1e2 -F test/update.test 90772ede84cfc779fc3d31884a84ec4c74deb501eeb09a1c6c91c03d8e94c0d8 +F test/update.test 85d3f46d0863033370bd881b1097f5694369a8730e53c5f85d96f32b7b310b47 F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3 F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041 F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1 @@ -1906,7 +1906,7 @@ F test/where3.test 5b4ffc0ac2ea0fe92f02b1244b7531522fe4d7bccf6fa8741d54e82c10e67 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b -F test/where7.test 1c1bf436bf31b913d4764a2b62ac6e98b9681e5c7ae2b562605592a56b7e946b +F test/where7.test 15041c7a5838f3bac98f3fb933709674a0b59367664e88fafaf105ff7416eb07 F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f F test/where9.test 2db942671a002621eff4f713e347bb25243295f79d8990297cd160bebcfde3f7 F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20 @@ -1980,7 +1980,7 @@ F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e04534bbf F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x -F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 +F tool/build-shell.sh f193b5e3eb4afcb4abbf96bf1475be6cfb74763ee2e50c82bc7ca105e8a136c5 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/custom.txt 6cdf298f43e1db4bb91406d14777669b8fb1df790837823fa6754c4308decc27 @@ -2063,7 +2063,7 @@ F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl 1dcb7632e57cf57105248029e6e162fddaf6c0fccb3bb9e6215603752c5a2d4a F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 -F tool/warnings.sh ab651bb82586c43ff8b560beceac959735bf917b44c5e0f67ba3426e474f29f8 +F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85 F vsixtest/App.xaml.cpp 41158ee43269820136fa3bba00c0bd91b26cc38b650ee392aec2a8d823e54318 @@ -2086,8 +2086,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a6f344399472e211941dffa6586a83fc1740c60e807e85387080a88c9c54658d c1fa1cb5e0c420614481636f3ce2dd9ad2142274bb7b37d39e5c26228317f992 -R ca3ad5620f1225e6ce92f51709515fd0 +P 1d6ded3234bbfa3226ef718eec8d0ce06ae2844628866cb6197383c9bf06267c 6fa71e11197111ab52d1983b35190899a5881dcb9ed822488c92bc839c72cb55 +R b9c55641cb16099f76bc77535273a425 U drh -Z 026c14fcd8a2733b517841db43bd86ef +Z 640d187b55e31c3095d500eb8d395e77 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d83b2d819b..2272f288bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d6ded3234bbfa3226ef718eec8d0ce06ae2844628866cb6197383c9bf06267c \ No newline at end of file +877ffece0531054f24410c9e4c0b89599a9506689cc97233d33c18b9a15e6308 \ No newline at end of file diff --git a/src/btreeInt.h b/src/btreeInt.h index 6c19d09899..6973f86861 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -180,7 +180,7 @@ ** 0x81 0x00 becomes 0x00000080 ** 0x82 0x00 becomes 0x00000100 ** 0x80 0x7f becomes 0x0000007f -** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 +** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678 ** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 ** ** Variable length integers are used for rowids and to hold the number of diff --git a/src/delete.c b/src/delete.c index 641d1ae589..2baff5b3d4 100644 --- a/src/delete.c +++ b/src/delete.c @@ -525,7 +525,8 @@ void sqlite3DeleteFrom( if( pWInfo==0 ) goto delete_from_cleanup; eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); - assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); + assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF + || OptimizationDisabled(db, SQLITE_OnePass) ); if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); diff --git a/src/json.c b/src/json.c index cc39264c05..1e4b94e7aa 100644 --- a/src/json.c +++ b/src/json.c @@ -30,25 +30,51 @@ ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) +/* +** Characters that are special to JSON. Control charaters, +** '"' and '\\'. +*/ +static const char jsonIsOk[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + + #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) # define VVA(X) #else @@ -357,11 +383,16 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ p->zBuf[p->nUsed++] = '"'; for(i=0; izBuf[p->nUsed++] = c; + }else if( c=='"' || c=='\\' ){ json_simple_escape: if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; - }else if( c<=0x1f ){ + p->zBuf[p->nUsed++] = c; + }else if( c=='\'' ){ + p->zBuf[p->nUsed++] = c; + }else{ static const char aSpecial[] = { 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -372,6 +403,7 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ assert( aSpecial['\n']=='n' ); assert( aSpecial['\r']=='r' ); assert( aSpecial['\t']=='t' ); + assert( c>=0 && czBuf[p->nUsed++] = 'u'; p->zBuf[p->nUsed++] = '0'; p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = '0' + (c>>4); - c = "0123456789abcdef"[c&0xf]; + p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; + p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; } - p->zBuf[p->nUsed++] = c; } p->zBuf[p->nUsed++] = '"'; assert( p->nUsednAlloc ); @@ -1070,7 +1101,9 @@ static int jsonParseAddNode( if( pParse->nNode>=pParse->nAlloc ){ return jsonParseAddNodeExpand(pParse, eType, n, zContent); } + assert( pParse->aNode!=0 ); p = &pParse->aNode[pParse->nNode]; + assert( p!=0 ); p->eType = (u8)(eType & 0xff); p->jnFlags = (u8)(eType >> 8); VVA( p->eU = zContent ? 1 : 0 ); @@ -1090,6 +1123,8 @@ static void jsonParseAddNodeArray( JsonNode *aNode, /* Array of nodes to add */ u32 nNode /* Number of elements in aNew */ ){ + assert( aNode!=0 ); + assert( nNode>=1 ); if( pParse->nNode + nNode > pParse->nAlloc ){ u32 nNew = pParse->nNode + nNode; JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); @@ -1465,26 +1500,7 @@ json_parse_restart: parse_string: cDelim = z[i]; for(j=i+1; 1; j++){ - static const char aOk[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - }; - if( aOk[(unsigned char)z[j]] ) continue; + if( jsonIsOk[(unsigned char)z[j]] ) continue; c = z[j]; if( c==cDelim ){ break; @@ -2672,10 +2688,11 @@ static void jsonPatchFunc( UNUSED_PARAMETER(argc); pX = jsonParseCached(ctx, argv[0], ctx, 1); if( pX==0 ) return; + assert( pX->hasMod==0 ); + pX->hasMod = 1; pY = jsonParseCached(ctx, argv[1], ctx, 1); if( pY==0 ) return; pX->useMod = 1; - pX->hasMod = 1; pY->useMod = 1; pResult = jsonMergePatch(pX, 0, pY->aNode); assert( pResult!=0 || pX->oom ); diff --git a/src/main.c b/src/main.c index 8345923219..7630ed0fc2 100644 --- a/src/main.c +++ b/src/main.c @@ -1665,9 +1665,9 @@ static int sqliteDefaultBusyCallback( void *ptr, /* Database connection */ int count /* Number of times table has been busy */ ){ -#if SQLITE_OS_WIN || HAVE_USLEEP +#if SQLITE_OS_WIN || !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP /* This case is for systems that have support for sleeping for fractions of - ** a second. Examples: All windows systems, unix systems with usleep() */ + ** a second. Examples: All windows systems, unix systems with nanosleep() */ static const u8 delays[] = { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; static const u8 totals[] = @@ -4160,10 +4160,12 @@ int sqlite3_test_control(int op, ...){ sqlite3ShowSrcList(0); sqlite3ShowWith(0); sqlite3ShowUpsert(0); +#ifndef SQLITE_OMIT_TRIGGER sqlite3ShowTriggerStep(0); sqlite3ShowTriggerStepList(0); sqlite3ShowTrigger(0); sqlite3ShowTriggerList(0); +#endif #ifndef SQLITE_OMIT_WINDOWFUNC sqlite3ShowWindow(0); sqlite3ShowWinFunc(0); @@ -4470,6 +4472,7 @@ int sqlite3_test_control(int op, ...){ break; } +#if !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); ** ** X<0 Make no changes to the bUseLongDouble. Just report value. @@ -4484,6 +4487,7 @@ int sqlite3_test_control(int op, ...){ rc = sqlite3Config.bUseLongDouble!=0; break; } +#endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) diff --git a/src/os_unix.c b/src/os_unix.c index 16be92635d..73be4c97ea 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -6901,12 +6901,17 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ ** than the argument. */ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ -#if OS_VXWORKS || _POSIX_C_SOURCE >= 199309L +#if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 struct timespec sp; - sp.tv_sec = microseconds / 1000000; sp.tv_nsec = (microseconds % 1000000) * 1000; + + /* Almost all modern unix systems support nanosleep(). But if you are + ** compiling for one of the rare exceptions, you can use + ** -DHAVE_NANOSLEEP=0 (perhaps in conjuction with -DHAVE_USLEEP if + ** usleep() is available) in order to bypass the use of nanosleep() */ nanosleep(&sp, NULL); + UNUSED_PARAMETER(NotUsed); return microseconds; #elif defined(HAVE_USLEEP) && HAVE_USLEEP diff --git a/src/select.c b/src/select.c index ce688663da..5dce50e543 100644 --- a/src/select.c +++ b/src/select.c @@ -4292,7 +4292,8 @@ static int compoundHasDifferentAffinities(Select *p){ ** (27b) the subquery is a compound query and the RIGHT JOIN occurs ** in any arm of the compound query. (See also (17g).) ** -** (28) The subquery is not a MATERIALIZED CTE. +** (28) The subquery is not a MATERIALIZED CTE. (This is handled +** in the caller before ever reaching this routine.) ** ** ** In this routine, the "p" parameter is a pointer to the outer query. @@ -4402,9 +4403,9 @@ static int flattenSubquery( if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ return 0; /* Restriction (27a) */ } - if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ - return 0; /* (28) */ - } + + /* Condition (28) is blocked by the caller */ + assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes ); /* Restriction (17): If the sub-query is a compound SELECT, then it must ** use only the UNION ALL operator. And none of the simple select queries @@ -7285,6 +7286,14 @@ int sqlite3Select( goto select_end; } + /* Do not attempt the usual optimizations (flattening and ORDER BY + ** elimination) on a MATERIALIZED common table expression because + ** a MATERIALIZED common table expression is an optimization fence. + */ + if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){ + continue; + } + /* Do not try to flatten an aggregate subquery. ** ** Flattening an aggregate subquery is only possible if the outer query @@ -7314,6 +7323,8 @@ int sqlite3Select( ** (a) The outer query has a different ORDER BY clause ** (b) The subquery is part of a join ** See forum post 062d576715d277c8 + ** + ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. */ if( pSub->pOrderBy!=0 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d6f7f4178d..819f775d6b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4426,10 +4426,10 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); ** METHOD: sqlite3_stmt ** ** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN -** setting for prepared statement S. If E is zero, then S becomes +** setting for [prepared statement] S. If E is zero, then S becomes ** a normal prepared statement. If E is 1, then S behaves as if -** its SQL text began with "EXPLAIN". If E is 2, then S behaves as if -** its SQL text began with "EXPLAIN QUERY PLAN". +** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if +** its SQL text began with "[EXPLAIN QUERY PLAN]". ** ** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared. ** SQLite tries to avoid a reprepare, but a reprepare might be necessary @@ -4437,8 +4437,8 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); ** ** Because of the potential need to reprepare, a call to ** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be -** reprepared because it was created using sqlite3_prepare() instead of -** the newer sqlite_prepare_v2() or sqlite3_prepare_v3() interfaces and +** reprepared because it was created using [sqlite3_prepare()] instead of +** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and ** hence has no saved SQL text with which to reprepare. ** ** Changing the explain setting for a prepared statement does not change diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c80322ad08..5eb036044b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1899,6 +1899,7 @@ struct sqlite3 { #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ +#define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -3815,7 +3816,7 @@ struct Parse { int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ Returning *pReturning; /* The RETURNING clause */ } u1; - u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ + LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK diff --git a/src/test1.c b/src/test1.c index 453a6b3631..237c61b39e 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8060,6 +8060,7 @@ static int SQLITE_TCLAPI optimization_control( { "push-down", SQLITE_PushDown }, { "balanced-merge", SQLITE_BalancedMerge }, { "propagate-const", SQLITE_PropagateConst }, + { "one-pass", SQLITE_OnePass }, }; if( objc!=4 ){ diff --git a/src/update.c b/src/update.c index 7d0afa69bf..c2d8f0fffb 100644 --- a/src/update.c +++ b/src/update.c @@ -752,7 +752,7 @@ void sqlite3Update( && !hasFK && !chngKey && !bReplace - && (sNC.ncFlags & NC_Subquery)==0 + && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery)) ){ flags |= WHERE_ONEPASS_MULTIROW; } diff --git a/src/util.c b/src/util.c index 1200aef0e3..25fd6ff597 100644 --- a/src/util.c +++ b/src/util.c @@ -591,7 +591,12 @@ do_atof_calc: while( e<=-10 ){ e+=10; r *= 1.0e-10L; } while( e<=-1 ){ e+=1; r *= 1.0e-01L; } } - *pResult = r; + assert( r>=0.0 ); + if( r>+1.7976931348623157081452742373e+308L ){ + *pResult = +INFINITY; + }else{ + *pResult = (double)r; + } }else{ double rr[2]; u64 s2; diff --git a/src/vdbe.c b/src/vdbe.c index 4c43cc95b5..68d6604052 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -708,6 +708,8 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( int iCol, /* The column to read */ int t, /* The serial-type code for the column value */ i64 iOffset, /* Offset to the start of the content value */ + u32 cacheStatus, /* Current Vdbe.cacheCtr value */ + u32 colCacheCtr, /* Current value of the column cache counter */ Mem *pDest /* Store the value into this register. */ ){ int rc; @@ -716,12 +718,16 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( int len = sqlite3VdbeSerialTypeLen(t); assert( pC->eCurType==CURTYPE_BTREE ); if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG; - if( len > 4000 ){ + if( len > 4000 && pC->pKeyInfo==0 ){ /* Cache large column values that are on overflow pages using ** an RCStr (reference counted string) so that if they are reloaded, ** that do not have to be copied a second time. The overhead of ** creating and managing the cache is such that this is only ** profitable for larger TEXT and BLOB values. + ** + ** Only do this on table-btrees so that writes to index-btrees do not + ** need to clear the cache. This buys performance in the common case + ** in exchange for generality. */ VdbeTxtBlbCache *pCache; char *pBuf; @@ -733,6 +739,8 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( pCache = pC->pCache; if( pCache->pCValue==0 || pCache->iCol!=iCol + || pCache->cacheStatus!=cacheStatus + || pCache->colCacheCtr!=colCacheCtr || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor) ){ if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue); @@ -744,6 +752,8 @@ static SQLITE_NOINLINE int vdbeColumnFromOverflow( pBuf[len+1] = 0; pBuf[len+2] = 0; pCache->iCol = iCol; + pCache->cacheStatus = cacheStatus; + pCache->colCacheCtr = colCacheCtr; pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor); }else{ pBuf = pCache->pCValue; @@ -814,6 +824,7 @@ int sqlite3VdbeExec( Mem *pIn2 = 0; /* 2nd input operand */ Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ + u32 colCacheCtr = 0; /* Column cache counter */ #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) u64 *pnCycle = 0; int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; @@ -3145,7 +3156,7 @@ op_column_restart: || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG)) ) ) - || (len = sqlite3VdbeSerialTypeLen(t))==0 + || sqlite3VdbeSerialTypeLen(t)==0 ){ /* Content is irrelevant for ** 1. the typeof() function, @@ -3162,7 +3173,8 @@ op_column_restart: */ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ - rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], pDest); + rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], + p->cacheCtr, colCacheCtr, pDest); if( rc ){ if( rc==SQLITE_NOMEM ) goto no_mem; if( rc==SQLITE_TOOBIG ) goto too_big; @@ -5736,6 +5748,7 @@ case OP_Insert: { ); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; + colCacheCtr++; /* Invoke the update-hook if required. */ if( rc ) goto abort_due_to_error; @@ -5896,6 +5909,7 @@ case OP_Delete: { rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; + colCacheCtr++; pC->seekResult = 0; if( rc ) goto abort_due_to_error; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index f424559929..2a23c3f285 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -159,6 +159,8 @@ struct VdbeTxtBlbCache { char *pCValue; /* A RCStr buffer to hold the value */ i64 iOffset; /* File offset of the row being cached */ int iCol; /* Column for which the cache is valid */ + u32 cacheStatus; /* Vdbe.cacheCtr value */ + u32 colCacheCtr; /* Column cache counter */ }; /* diff --git a/src/vdbeapi.c b/src/vdbeapi.c index cb631413c4..cc58e7a877 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1863,19 +1863,23 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ Vdbe *v = (Vdbe*)pStmt; int rc; - if( v->eVdbeState!=VDBE_READY_STATE ) return SQLITE_BUSY; - if( v->explain==eMode ) return SQLITE_OK; - if( v->zSql==0 || eMode<0 || eMode>2 ) return SQLITE_ERROR; sqlite3_mutex_enter(v->db->mutex); - if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ + if( v->explain==eMode ){ + rc = SQLITE_OK; + }else if( eMode<0 || eMode>2 ){ + rc = SQLITE_ERROR; + }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ + rc = SQLITE_ERROR; + }else if( v->eVdbeState!=VDBE_READY_STATE ){ + rc = SQLITE_BUSY; + }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ /* No reprepare necessary */ v->explain = eMode; rc = SQLITE_OK; }else{ - int haveEqpOps = v->explain==2 || v->haveEqpOps; v->explain = eMode; rc = sqlite3Reprepare(v); - v->haveEqpOps = haveEqpOps!=0; + v->haveEqpOps = eMode==2; } if( v->explain ){ v->nResColumn = 12 - 4*v->explain; diff --git a/src/vdbemem.c b/src/vdbemem.c index 07fb8feee8..e25efc9771 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -322,7 +322,10 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ ** this routine is a no-op. */ void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ - if( (pMem->flags & (MEM_Str|MEM_Term))!=MEM_Str ) return; + if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){ + /* pMem must be a string, and it cannot be an ephemeral or static string */ + return; + } if( pMem->enc!=SQLITE_UTF8 ) return; if( NEVER(pMem->z==0) ) return; if( pMem->flags & MEM_Dyn ){ @@ -338,7 +341,7 @@ void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ pMem->flags |= MEM_Term; return; } - }else if( pMem->szMalloc>0 && pMem->szMalloc >= pMem->n+1 ){ + }else if( pMem->szMalloc >= pMem->n+1 ){ pMem->z[pMem->n] = 0; pMem->flags |= MEM_Term; return; diff --git a/src/where.c b/src/where.c index 35b9056ffe..213df42230 100644 --- a/src/where.c +++ b/src/where.c @@ -2535,7 +2535,7 @@ static WhereLoop **whereLoopFindLesser( /* If pTemplate is always better than p, then cause p to be overwritten ** with pTemplate. pTemplate is better than p if: - ** (1) pTemplate has no more dependences than p, and + ** (1) pTemplate has no more dependencies than p, and ** (2) pTemplate has an equal or lower cost than p. */ if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ @@ -5003,7 +5003,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** For joins of 3 or more tables, track the 10 best paths */ mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); assert( nLoop<=pWInfo->pTabList->nSrc ); - WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst)); + WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", + nRowEst, pParse->nQueryLoop)); /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this ** case the purpose of this call is to estimate the number of rows returned @@ -5757,6 +5758,28 @@ static SQLITE_NOINLINE void whereAddIndexedExpr( } } +/* +** Set the reverse-scan order mask to one for all tables in the query +** with the exception of MATERIALIZED common table expressions that have +** their own internal ORDER BY clauses. +** +** This implements the PRAGMA reverse_unordered_selects=ON setting. +** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER). +*/ +static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ + int ii; + for(ii=0; iipTabList->nSrc; ii++){ + SrcItem *pItem = &pWInfo->pTabList->a[ii]; + if( !pItem->fg.isCte + || pItem->u2.pCteUse->eM10d!=M10d_Yes + || NEVER(pItem->pSelect==0) + || pItem->pSelect->pOrderBy==0 + ){ + pWInfo->revMask |= MASKBIT(ii); + } + } +} + /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains @@ -6121,8 +6144,9 @@ WhereInfo *sqlite3WhereBegin( if( db->mallocFailed ) goto whereBeginError; } } + assert( pWInfo->pTabList!=0 ); if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ - pWInfo->revMask = ALLBITS; + whereReverseScanOrder(pWInfo); } if( pParse->nErr ){ goto whereBeginError; @@ -6222,6 +6246,7 @@ WhereInfo *sqlite3WhereBegin( 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) && !IsVirtual(pTabList->a[0].pTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) + && OptimizationEnabled(db, SQLITE_OnePass) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ diff --git a/test/corruptL.test b/test/corruptL.test index 65d9821b35..cf38764415 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -1269,6 +1269,7 @@ do_test 15.0 { }]} {} extra_schema_checks 0 +optimization_control db one-pass off do_catchsql_test 15.1 { PRAGMA cell_size_check = 0; UPDATE c1 SET c= NOT EXISTS(SELECT 1 FROM c1 ORDER BY (SELECT 1 FROM c1 ORDER BY a)) +10 WHERE d BETWEEN 4 AND 7; diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index a4969047aa..6b434f6bbf 100644 Binary files a/test/fuzzdata8.db and b/test/fuzzdata8.db differ diff --git a/test/update.test b/test/update.test index 47b6029bee..bf7666662a 100644 --- a/test/update.test +++ b/test/update.test @@ -764,5 +764,27 @@ do_execsql_test update-21.4 { SELECT * FROM t1 ORDER BY vkey, c5; ROLLBACK; } {6 -54 100 NULL} +# Follow-up on 2023-07-31 (forum post https://sqlite.org/forum/forumpost/8ab195fd44e75ed0): +# Only disable one-pass if the subquery is in the WHERE clause. The SET expressions +# do not count. +do_execsql_test update-21.11 { + DROP TABLE t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); + CREATE TABLE t2(d INT); +} +do_eqp_test update-21.12 { + WITH t3(x,y) AS (SELECT d, row_number()OVER() FROM t2) + UPDATE t1 SET b=(SELECT y FROM t3 WHERE t1.a=t3.x); +} { + QUERY PLAN + |--SCAN t1 + `--CORRELATED SCALAR SUBQUERY xxxxxx + |--CO-ROUTINE t3 + | |--CO-ROUTINE (subquery-xxxxxx) + | | `--SCAN t2 + | `--SCAN (subquery-xxxxxx) + |--BLOOM FILTER ON t3 (x=?) + `--SEARCH t3 USING AUTOMATIC COVERING INDEX (x=?) +} finish_test diff --git a/test/where7.test b/test/where7.test index f76e8aba8b..681684b809 100644 --- a/test/where7.test +++ b/test/where7.test @@ -47,18 +47,33 @@ do_test where7-1.1 { SELECT * FROM t1; } } {1 2 3 4 2 3 4 5 3 4 6 8 4 5 10 15 5 10 100 1000} -do_execsql_test where7-1.1.1 { - CREATE TABLE t(a); - CREATE INDEX ta ON t(a); - INSERT INTO t(a) VALUES(1),(2); - SELECT * FROM t ORDER BY a; - SELECT * FROM t WHERE a<2 OR a<3 ORDER BY a; - PRAGMA count_changes=ON; - DELETE FROM t WHERE a<2 OR a<3; - SELECT * FROM t; - PRAGMA count_changes=OFF; - DROP TABLE t; -} {1 2 1 2 2} +if {[permutation] != "no_optimization"} { + do_execsql_test where7-1.1.1 { + CREATE TABLE t(a); + CREATE INDEX ta ON t(a); + INSERT INTO t(a) VALUES(1),(2); + SELECT * FROM t ORDER BY a; + SELECT * FROM t WHERE a<2 OR a<3 ORDER BY a; + PRAGMA count_changes=ON; + DELETE FROM t WHERE a<2 OR a<3; + SELECT * FROM t; + PRAGMA count_changes=OFF; + DROP TABLE t; + } {1 2 1 2 2} +} else { + do_execsql_test where7-1.1.1-noopt { + CREATE TABLE t(a); + CREATE INDEX ta ON t(a); + INSERT INTO t(a) VALUES(1),(2); + SELECT * FROM t ORDER BY a; + SELECT * FROM t WHERE a<2 OR a<3 ORDER BY a; + PRAGMA count_changes=ON; + DELETE FROM t WHERE a<2 OR a<3; + SELECT * FROM t; + PRAGMA count_changes=OFF; + DROP TABLE t; + } {1 2 1 2 3} +} do_test where7-1.2 { count_steps { SELECT a FROM t1 WHERE b=3 OR c=6 ORDER BY a diff --git a/tool/build-shell.sh b/tool/build-shell.sh index 6a48299d73..a57f753039 100644 --- a/tool/build-shell.sh +++ b/tool/build-shell.sh @@ -16,7 +16,6 @@ gcc -o sqlite3 -g -Os -I. \ -DSQLITE_ENABLE_FTS4 \ -DSQLITE_ENABLE_RTREE \ -DHAVE_READLINE \ - -DHAVE_USLEEP=1 \ ../sqlite/src/shell.c \ ../sqlite/src/test_vfstrace.c \ sqlite3.c -ldl -lreadline -lncurses diff --git a/tool/warnings.sh b/tool/warnings.sh index 60d2b42100..2b962d15ed 100644 --- a/tool/warnings.sh +++ b/tool/warnings.sh @@ -32,7 +32,6 @@ if test x`uname` = 'xLinux'; then echo '********** Android configuration ******************************' echo '********** ' Options: $WARNING_ANDROID_OPTS gcc -c \ - -DHAVE_USLEEP=1 \ -DSQLITE_HAVE_ISNAN \ -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \ -DSQLITE_THREADSAFE=2 \