diff --git a/ext/expert/expert1.test b/ext/expert/expert1.test index a0a18f6374..3e5d604d52 100644 --- a/ext/expert/expert1.test +++ b/ext/expert/expert1.test @@ -37,6 +37,9 @@ proc squish {txt} { proc do_setup_rec_test {tn setup sql res} { reset_db + if {[info exists ::set_main_db_name]} { + dbconfig_maindbname_icecube db + } db eval $setup uplevel [list do_rec_test $tn $sql $res] } @@ -76,6 +79,10 @@ foreach {tn setup} { } } 3 { + if {[info commands sqlite3_expert_new]==""} { continue } + set ::set_main_db_name 1 + } + 4 { if {![file executable $CLI]} { continue } proc do_rec_test {tn sql res} { @@ -336,7 +343,7 @@ proc do_candidates_test {tn sql res} { reset_db -do_execsql_test 4.0 { +do_execsql_test 5.0 { CREATE TABLE t1(a, b); CREATE TABLE t2(c, d); @@ -346,7 +353,7 @@ do_execsql_test 4.0 { WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100) INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s; } -do_candidates_test 4.1 { +do_candidates_test 5.1 { SELECT * FROM t1,t2 WHERE (b=? OR a=?) AND (c=? OR d=?) } { CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20 @@ -355,14 +362,14 @@ do_candidates_test 4.1 { CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5 } -do_candidates_test 4.2 { +do_candidates_test 5.2 { SELECT * FROM t1,t2 WHERE a=? AND b=? AND c=? AND d=? } { CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 17 CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5 } -do_execsql_test 4.3 { +do_execsql_test 5.3 { CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50 CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20 CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 16 diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 253be1174d..f5114eca42 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -4953,6 +4953,12 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ ** Exit early in this case. */ if( nSeg<=0 ) break; + assert( nMod<=0x7FFFFFFF ); + if( iAbsLevel<0 || iAbsLevel>(nMod<<32) ){ + rc = FTS_CORRUPT_VTAB; + break; + } + /* Open a cursor to iterate through the contents of the oldest nSeg ** indexes of absolute level iAbsLevel. If this cursor is opened using ** the 'hint' parameters, it is possible that there are less than nSeg diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 7fbe32a7eb..92d7c5438e 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -143,7 +143,7 @@ static int icuLikeCompare( ** 3. uPattern is an unescaped escape character, or ** 4. uPattern is to be handled as an ordinary character */ - if( !prevEscape && uPattern==MATCH_ALL ){ + if( uPattern==MATCH_ALL && !prevEscape && uPattern!=(uint32_t)uEsc ){ /* Case 1. */ uint8_t c; @@ -169,12 +169,12 @@ static int icuLikeCompare( } return 0; - }else if( !prevEscape && uPattern==MATCH_ONE ){ + }else if( uPattern==MATCH_ONE && !prevEscape && uPattern!=(uint32_t)uEsc ){ /* Case 2. */ if( *zString==0 ) return 0; SQLITE_ICU_SKIP_UTF8(zString); - }else if( !prevEscape && uPattern==(uint32_t)uEsc){ + }else if( uPattern==(uint32_t)uEsc && !prevEscape ){ /* Case 3. */ prevEscape = 1; diff --git a/manifest b/manifest index 0ae75e6bd2..d4b41459ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\sfor\swhen\sSQLITE_ENABLE_STAT4\sis\sdefined. -D 2020-03-18T15:58:13.804 +C Merge\srecent\senhancements\sfrom\strunk. +D 2020-03-31T18:41:21.038 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -48,7 +48,7 @@ F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74 F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 -F ext/expert/expert1.test e2afc53a27610e8251e44c7f961806607a5490ff204b3db342740d558e052662 +F ext/expert/expert1.test 2e10ff875c31c9e6fc5e324767624181273859771fe34c5daeeadf3f2974a4f7 F ext/expert/sqlite3expert.c 3da865f2286433588260f41e796422c611bceaca3a0bbf9139a619cf7d062c19 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 @@ -100,7 +100,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c ddf34315b6c3dce79a28d966981cc76919b18f645d82c6132133a7c65b8ed283 +F ext/fts3/fts3_write.c eb5c0184762a310003762db4ebd5ddcce097d9bb08804279ba33a42907f847a6 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -231,7 +231,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138 -F ext/icu/icu.c 7adfe8a72dd4f54b47684dc9b88523399c6ef119d733b73e17371445f7428dd1 +F ext/icu/icu.c 91c021c7e3e8bbba286960810fa303295c622e323567b2e6def4ce58e4466e60 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9 F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013 @@ -467,26 +467,26 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de F src/analyze.c 3d90f56656f5c6e7f835659b46ccf517c156df5222be86b4ff279eb476e8e373 -F src/attach.c fa5addce233a2bb2dfdefeee3b37000e154c47214d3269cab1bb331416e330db +F src/attach.c ff2daea0fe62080192e3f262670e4f61f5a86c1e7bea9cec34e960fe79852aa1 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c f2e0c75c8321bb4279dcfa6daaf4ac9e15c73ad887f24f7d28f4f2d5f78c02a7 +F src/btree.c 25e062b1600cc339d274f3d254335bc5bee7c6b387eb3d9efa10b2032f708e8a F src/btree.h 7c0a1c67a378254a6e3cfe29a9d6d2f09fdf58e8f69944076b6dbf517a810887 F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175 -F src/build.c 406645db37154920075d90a4ea3c47f33d5f5b6e0769010a54ea8247ee433c1a +F src/build.c 3d22f21c4701f62c1a191c6b6d17552fb1b593fe9a97c0613cca05ab104a9a51 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 060c9bc1c8a848a942326c6e73fff449e54e8e98487f555e49e7b897639db270 -F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712 +F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a -F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da +F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d -F src/expr.c ed718ee2206166c9c2fc4fe89eadb1f369318aeb8645e06033566b387970fb9a +F src/expr.c 226293a02bd8376db5981a52a2163a5022c52d69878cb64a5821529743f51162 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41 -F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4 +F src/func.c f3dcdc0e95509864767c1f0991b19360f969e44177f4e058fd51da9a6154f47e F src/global.c 79a988b56b06ce2d08ebefe1d35da9aa25b3851faa47ea5233361c4827185a64 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -495,8 +495,8 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 8e4211d04eb460c0694d486c6ba1c068d468c6f653c3f237869a802ad82854de F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32 -F src/main.c b11eec03807a038b4075d310936dc33ce597078ab78c35dacdf5f05446ed53de -F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 +F src/main.c 2e076b6dc1f8ab69c7fc604e8af88ab138a64c0616826361e254cee55bcba4e8 +F src/malloc.c cabfef0d725e04c8abfe0231a556ed8b78bf329dcc3fddbf903f6cdcd53cf4e6 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -515,12 +515,12 @@ F src/os.c 669cc3839cc35d20f81faf0be1ab6d4581cea35e9d8f3a9d48a98d6571f7c285 F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0 +F src/os_unix.c 06593ba4bdfae42b30a897b3b4e59abb88a11d50dd0cad39003da955d822b8d1 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c a71ffd145f55e28cbdc1bdabb5e6bef063da428a6c0de3c3a36e9a0c41d4c8c0 F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3 -F src/parse.y 8575183809cf30f8c9d1fbea65ca34d1de78b659792bc7c42681e01fc596b520 +F src/parse.y c8eff38606f443d5ba245263fa7abc05e4116d95656e050c4b78e9bfbf931add F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a @@ -529,14 +529,14 @@ F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5 F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf +F src/resolve.c 903a70c48d0f72fdd657b225d499cf99ec01d575cf3fbc8196b43562045319ac F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 04a4138c646b0ecf2ca89142ce5756d2bebed30da15d47e86a69ac59ebbcaafa -F src/shell.c.in f76590931c0cbbfef347f44f81ade6b335f80c46bc6e59b8b6114383a8df30e0 -F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 +F src/select.c ef8626664c381e89b2710884336a36fdf73a5bb5ebcaa746aa817795be9baa05 +F src/shell.c.in 7bb9005bf876c4e1210257a63fa49b556f4eddf59f94b6eb310fcb5096bec0e9 +F src/sqlite.h.in cc7d0949ac32bb68ed97acdb3e7ae91cd413a24d32d6ff049ef8308d620a4367 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee -F src/sqliteInt.h 5f74c1c52b152259ee07f241821620f11736e4f590936cfaf1cbbff9a2f563d3 +F src/sqliteInt.h b0165686885990e29622f56b2f95b93c12c6f84be4cf1ee60797d80a0dcd7f15 F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -595,28 +595,28 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d -F src/treeview.c f78cd9cd79a889e70cd98bd6edd4a464c421452da833e65e987d97d8c41f71fe -F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc +F src/tokenize.c eee7bae3ec0bc4abee951554bf46a8ba567c0f7752ac90c820ed8afff4c612dc +F src/treeview.c 82c6391a3ba76215d4185fd4719a56ec4caf186a40c8a7b6e6ba4ae4467c2742 +F src/trigger.c 4ada1037cc99777f647a882cdacbd1a4deb6567b69daf02946286401b88cdc04 F src/update.c 3eb778c42155d944377a4ee5e440b04520f07094804ed6ce63d2528f619614d9 F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7 F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9 -F src/vdbe.c 45896ffb6241d1b001a73a84a480af25036de89bab4a74ed1814d9020384d420 +F src/vdbe.c f55fe7dbffae72e1cd5861e9ea3b55d50b70d863eebce3aebf11e1271ceae796 F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9 -F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 -F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 -F src/vdbeaux.c 1ca2d4b3f913ecc4759becfab72952f25493390d674714586ab356c9f06ac279 +F src/vdbeInt.h 0b728ee662862a38b1912af741e2ac64f524de3c77aa86cf4306c42bdcd9de59 +F src/vdbeapi.c d176ee7251d5344de7bb2a0d2dd0fe536834e5843d9bc2389e0f5cdcd5374141 +F src/vdbeaux.c 8349559e72bf0cfa2258b1159b004ec4d1717a054d2e1829c8cc897c32da8752 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc +F src/wal.c ea8dad28bb0e2b85ac1ab7618968687ff5fd522af8a1a38d6960ec176ebc8ee6 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a -F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d +F src/walker.c 7c429c694abd12413a5c17aec9f47cfe9eba6807e6b0a32df883e8e3a14835ed F src/where.c 9546c82056e8cdb27291f98cf1adca5d271240b399bb97b32f77fc2bea6146c9 F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d @@ -666,7 +666,7 @@ F test/atof1.test 1ccfc96a6888566597b83d882c81b3c04258dc39317e8c1cec89ba481eaa2f F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061 F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da F test/atrc.c ec92d56d8fbed9eb3e11aaf1ab98cf7dd59e69dae31f128013f1d97e54e7dfed -F test/attach.test 21bce8681f780a8d631a5ec7ecd0d849bfe84611257b038ae4ffeccc609d8a4e +F test/attach.test d42862c72fef3d54367d962d41dcfb5363442a4a1bd898c22ae950cea1aa0dd3 F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce F test/attach3.test c59d92791070c59272e00183b7353eeb94915976 F test/attach4.test aa05b1d8218b24eba5a7cccf4f224f514ba57ba705c9267f09d2bb63fed0eea1 @@ -828,10 +828,10 @@ F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145 F test/e_blobwrite.test f87ff598b67af5b3ec002a8d83e804dc8d23808e88cf0080c176612fc9ffce14 F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 -F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76d0df33b0a7 +F test/e_createtable.test ea27082d6f84df61e1d9e383f3fd79220418856a4a8afc41af75d458b8e7ac33 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 -F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5 +F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7 F test/e_expr.test 328d2d7c84f8e53e942a13eac771b337bcdfcf4c3569324001868b5639f3c857 F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 @@ -966,7 +966,7 @@ F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11e F test/fts3join.test 949b4f5ae3ae9cc2423cb865d711e32476bdb205ab2be923fdf48246e4a44166 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a -F test/fts3misc.test c47d2c1ea1351c51c32c688545b02c8180a3f22156d1aedc206a8c09b9d95905 +F test/fts3misc.test 236f37a57d97fa1b7e0a4303aab7e02da87a9818c106e513ae88af76f25ace4a F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2 @@ -1016,7 +1016,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c cdd94f1710957b8b907019b25c6cf4f7b63815a08b19021e8b215bc2419bb7f9 +F test/fuzzcheck.c 1ead09510c7bb3475675e499feb721790544e57e00168d687124d9d94ea843ac F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1036,7 +1036,7 @@ F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 F test/hook.test 1604b3b2f5931430087540404555c1b6be3618600b81558657c66b533ed70b13 F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 -F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a +F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1 F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test ae4ba0fe3232fdd84ef1090a68c5cd6ccd93f1f8774d5c967dd0c1b301492eed @@ -1113,9 +1113,9 @@ F test/kvtest.c 94da54bb66aae7a54e47cf7e4ea4acecc0f217560f79ad3abfcc0361d6d557ba F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 -F test/like.test 3d702d79bf871fa32985b1ce334294c587e3948d3ab972001e811a58577e8b3c +F test/like.test 47b81d5de2ff19d996d49a65d50ec9754246aacbe0e950b48d186d9d8171eaf0 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test 4f940ad275c006319950054a7a65661f476772171b82b6fdf795e4dda36f246f +F test/like3.test 03d1bdf848483b78d2cfd1db283d75c4ec2e37c8b8eccc006813f3978d78fbbd F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04 @@ -1173,7 +1173,7 @@ F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db F test/misc5.test c4aeaa0fa28faa08f2485309c38db4719e6cd1364215d5687a5b96d340a3fa58 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test 4f21954012e4eb0a923c54a311f38c81bf6798ccdd7b51584db46d4007f63daa -F test/misc8.test 8fb0f31d7a8aed484d759773ab8ad12ec746a477f4a67394a4af0e677494c3ca +F test/misc8.test 8782708f4c8a459591c3e8fe1215bd2048bffb4024b3df249e9b9ed407dc61ed F test/misuse.test 9e7f78402005e833af71dcab32d048003869eca5abcaccc985d4f8dc1d86bcc7 F test/mjournal.test 28a08d5cb5fb5b5702a46e19176e45e964e0800d1f894677169e79f34030e152 F test/mmap1.test fb04e0c10492455007624ade884ca0c8852ff3e4e11d95408f9709ca2ef7f626 @@ -1232,7 +1232,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 8587800fe1a0eb01456a3f4500b821e54e3347e78acf11dbf05f4990530f6cee +F test/permutations.test c83339862d72b6272f957905205f874e6eefdbad2823380452c4f0128fd3d906 F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54 F test/pragma.test 59becdfd720b80d463ab750f69f7118fde10dfd556aa5d554f3bf6b7e5ea7533 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f @@ -1333,7 +1333,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 43e12c7d4ff65f041803ad24a93fd3818deb2cb83e721810f27d0fde61d64a13 +F test/shell1.test 1796b7f76d09ffd2b2dc0ff5ad89428e9892f237d4f4e33ef2278f064a2d94a4 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494 F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce @@ -1415,7 +1415,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl abba168acd7f01dbfa3ffdbf402d151eb97e8a824d9208e845ab34c194441483 +F test/tester.tcl fd9d134a7cc4e31b307ad028a195f51cdcf556fc620d74b680515562f0137f25 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a773fd4698d474fda5e57bc77ed66a79cf74efee2706f43f6def6f450bfd1fc0 -R 6430bd4bd4bb467e3eec7a041f966c13 +P 8f0a8c2aa45f7cf7339094d83893aeb046b010b5b97bb4dae99ac07a8ebf2fa6 a49f8ec552bede7da731e0571ccf49de1a30e7be3a5673150436c8b411ba6ffc +R f330422722a52c77c50a3e7d8a9da878 U drh -Z 544d5db127f99a945af7a33bac1ef578 +Z 2ae26fc9e4b49bbb8102a35ce551a2aa diff --git a/manifest.uuid b/manifest.uuid index a8f4744c32..c079a7d71d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f0a8c2aa45f7cf7339094d83893aeb046b010b5b97bb4dae99ac07a8ebf2fa6 \ No newline at end of file +c705ce266ad25af71791035590875f0ea9f2c72826b3eda17f065d2bf091de92 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index e7d31e3b9e..628a8bc83b 100644 --- a/src/attach.c +++ b/src/attach.c @@ -45,6 +45,17 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr) return rc; } +/* +** Return true if zName points to a name that may be used to refer to +** database iDb attached to handle db. +*/ +int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){ + return ( + sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0 + || (iDb==0 && sqlite3StrICmp("main", zName)==0) + ); +} + /* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: @@ -117,9 +128,8 @@ static void attachFunc( goto attach_error; } for(i=0; inDb; i++){ - char *z = db->aDb[i].zDbSName; - assert( z && zName ); - if( sqlite3StrICmp(z, zName)==0 ){ + assert( zName ); + if( sqlite3DbIsNamed(db, i, zName) ){ zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); goto attach_error; } @@ -272,7 +282,7 @@ static void detachFunc( for(i=0; inDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 ) continue; - if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; + if( sqlite3DbIsNamed(db, i, zName) ) break; } if( i>=db->nDb ){ @@ -463,20 +473,21 @@ int sqlite3FixSrcList( SrcList *pList /* The Source list to check and modify */ ){ int i; - const char *zDb; struct SrcList_item *pItem; + sqlite3 *db = pFix->pParse->db; + int iDb = sqlite3FindDbName(db, pFix->zDb); if( NEVER(pList==0) ) return 0; - zDb = pFix->zDb; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ if( pFix->bTemp==0 ){ - if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ + if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", pFix->zType, pFix->pName, pItem->zDatabase); return 1; } - sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); + sqlite3DbFree(db, pItem->zDatabase); pItem->zDatabase = 0; pItem->pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; diff --git a/src/btree.c b/src/btree.c index c2103819cc..71472a6e55 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9529,7 +9529,7 @@ int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){ /* Unless an error occurs, the following loop runs one iteration for each ** page in the B-Tree structure (not including overflow pages). */ - while( rc==SQLITE_OK && !db->u1.isInterrupted ){ + while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){ int iIdx; /* Index of child node in parent */ MemPage *pPage; /* Current page of the b-tree */ @@ -9654,7 +9654,7 @@ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ checkAppendMsg(pCheck, "2nd reference to page %d", iPage); return 1; } - if( pCheck->db->u1.isInterrupted ) return 1; + if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1; setPageReferenced(pCheck, iPage); return 0; } diff --git a/src/build.c b/src/build.c index 73e4cea7cc..dcd035e99d 100644 --- a/src/build.c +++ b/src/build.c @@ -315,7 +315,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ while(1){ for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ + if( zDatabase==0 || sqlite3DbIsNamed(db, j, zDatabase) ){ assert( sqlite3SchemaMutexHeld(db, j, 0) ); p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); if( p ) return p; @@ -437,7 +437,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ Schema *pSchema = db->aDb[j].pSchema; assert( pSchema ); - if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue; + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; assert( sqlite3SchemaMutexHeld(db, j, 0) ); p = sqlite3HashFind(&pSchema->idxHash, zName); if( p ) break; diff --git a/src/date.c b/src/date.c index 6a8defc668..fff062fb5a 100644 --- a/src/date.c +++ b/src/date.c @@ -621,12 +621,12 @@ static const struct { double rLimit; /* Maximum NNN value for this transform */ double rXform; /* Constant used for this transform */ } aXformType[] = { - { 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) }, - { 0, 6, "minute", 7737817680.0, 86400000.0/(24.0*60.0) }, - { 0, 4, "hour", 128963628.0, 86400000.0/24.0 }, - { 0, 3, "day", 5373485.0, 86400000.0 }, - { 1, 5, "month", 176546.0, 30.0*86400000.0 }, - { 2, 4, "year", 14713.0, 365.0*86400000.0 }, + { 0, 6, "second", 464269060800.0, 1000.0 }, + { 0, 6, "minute", 7737817680.0, 60000.0 }, + { 0, 4, "hour", 128963628.0, 3600000.0 }, + { 0, 3, "day", 5373485.0, 86400000.0 }, + { 1, 5, "month", 176546.0, 2592000000.0 }, + { 2, 4, "year", 14713.0, 31536000000.0 }, }; /* diff --git a/src/dbstat.c b/src/dbstat.c index 2fea48ce8c..bddde79ced 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -238,6 +238,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ i = 0; if( iSchema>=0 ){ pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i; + pIdxInfo->aConstraintUsage[iSchema].omit = 1; pIdxInfo->idxNum |= 0x01; } if( iName>=0 ){ @@ -452,7 +453,9 @@ static int statDecodePage(Btree *pBt, StatPage *p){ if( nPayload>(u32)nLocal ){ int j; int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); - if( iOff+nLocal>nUsable ) goto statPageIsCorrupt; + if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){ + goto statPageIsCorrupt; + } pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); pCell->nOvfl = nOvfl; pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl); diff --git a/src/expr.c b/src/expr.c index 8587f5ec78..e588897370 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2941,6 +2941,8 @@ void sqlite3CodeRhsOfIN( affinity = sqlite3ExprAffinity(pLeft); if( affinity<=SQLITE_AFF_NONE ){ affinity = SQLITE_AFF_BLOB; + }else if( affinity==SQLITE_AFF_REAL ){ + affinity = SQLITE_AFF_NUMERIC; } if( pKeyInfo ){ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); @@ -3250,21 +3252,13 @@ static void sqlite3ExprCodeIN( int r2, regToFree; int regCkNull = 0; int ii; - int bLhsReal; /* True if the LHS of the IN has REAL affinity */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( destIfNull!=destIfFalse ){ regCkNull = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); } - bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL; for(ii=0; iinExpr; ii++){ - if( bLhsReal ){ - r2 = regToFree = sqlite3GetTempReg(pParse); - sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2); - sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC); - }else{ - r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); - } + r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); } diff --git a/src/func.c b/src/func.c index 966a0075e4..167b6afd7d 100644 --- a/src/func.c +++ b/src/func.c @@ -853,6 +853,7 @@ static void likeFunc( int nPat; sqlite3 *db = sqlite3_context_db_handle(context); struct compareInfo *pInfo = sqlite3_user_data(context); + struct compareInfo backupInfo; #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( sqlite3_value_type(argv[0])==SQLITE_BLOB @@ -888,6 +889,12 @@ static void likeFunc( return; } escape = sqlite3Utf8Read(&zEsc); + if( escape==pInfo->matchAll || escape==pInfo->matchOne ){ + memcpy(&backupInfo, pInfo, sizeof(backupInfo)); + pInfo = &backupInfo; + if( escape==pInfo->matchAll ) pInfo->matchAll = 0; + if( escape==pInfo->matchOne ) pInfo->matchOne = 0; + } }else{ escape = pInfo->matchSet; } @@ -1870,16 +1877,6 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ return 0; } - if( nExpr<3 ){ - aWc[3] = 0; - }else{ - Expr *pEscape = pExpr->x.pList->a[2].pExpr; - char *zEscape; - if( pEscape->op!=TK_STRING ) return 0; - zEscape = pEscape->u.zToken; - if( zEscape[0]==0 || zEscape[1]!=0 ) return 0; - aWc[3] = zEscape[0]; - } /* The memcpy() statement assumes that the wildcard characters are ** the first three statements in the compareInfo structure. The @@ -1889,6 +1886,20 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll ); assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne ); assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet ); + + if( nExpr<3 ){ + aWc[3] = 0; + }else{ + Expr *pEscape = pExpr->x.pList->a[2].pExpr; + char *zEscape; + if( pEscape->op!=TK_STRING ) return 0; + zEscape = pEscape->u.zToken; + if( zEscape[0]==0 || zEscape[1]!=0 ) return 0; + if( zEscape[0]==aWc[0] ) return 0; + if( zEscape[0]==aWc[1] ) return 0; + aWc[3] = zEscape[0]; + } + *pIsNocase = (pDef->funcFlags & SQLITE_FUNC_CASE)==0; return 1; } diff --git a/src/main.c b/src/main.c index 98e030fad1..d693621b1e 100644 --- a/src/main.c +++ b/src/main.c @@ -1569,9 +1569,21 @@ static int sqliteDefaultBusyCallback( #ifdef SQLITE_ENABLE_SETLK_TIMEOUT if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){ if( count ){ - tmout = 0; - sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout); - return 0; + /* If this is the second or later invocation of the busy-handler, + ** but tmout==0, then code in wal.c must have disabled the blocking + ** lock before the SQLITE_BUSY error was hit. In this case, no delay + ** occurred while waiting for the lock, so fall through to the xSleep() + ** code below to delay a while before retrying the lock. + ** + ** Alternatively, if tmout!=0, then SQLite has already waited + ** sqlite3.busyTimeout ms for a lock. In this case, return 0 to + ** indicate that the lock should not be retried and the SQLITE_BUSY + ** error returned to the application. */ + if( tmout ){ + tmout = 0; + sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout); + return 0; + } }else{ return 1; } @@ -1721,7 +1733,7 @@ void sqlite3_interrupt(sqlite3 *db){ return; } #endif - db->u1.isInterrupted = 1; + AtomicStore(&db->u1.isInterrupted, 1); } @@ -2343,7 +2355,7 @@ int sqlite3_wal_checkpoint_v2( /* If there are no active statements, clear the interrupt flag at this ** point. */ if( db->nVdbeActive==0 ){ - db->u1.isInterrupted = 0; + AtomicStore(&db->u1.isInterrupted, 0); } sqlite3_mutex_leave(db->mutex); diff --git a/src/malloc.c b/src/malloc.c index 9dd400a3ba..a19d8bdfb3 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -760,7 +760,7 @@ void sqlite3OomFault(sqlite3 *db){ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ db->mallocFailed = 1; if( db->nVdbeExec>0 ){ - db->u1.isInterrupted = 1; + AtomicStore(&db->u1.isInterrupted, 1); } DisableLookaside; if( db->pParse ){ @@ -779,7 +779,7 @@ void sqlite3OomFault(sqlite3 *db){ void sqlite3OomClear(sqlite3 *db){ if( db->mallocFailed && db->nVdbeExec==0 ){ db->mallocFailed = 0; - db->u1.isInterrupted = 0; + AtomicStore(&db->u1.isInterrupted, 0); assert( db->lookaside.bDisable>0 ); EnableLookaside; } diff --git a/src/os_unix.c b/src/os_unix.c index cf1c579fd0..a4dd2f906c 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3995,7 +3995,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT case SQLITE_FCNTL_LOCK_TIMEOUT: { + int iOld = pFile->iBusyTimeout; pFile->iBusyTimeout = *(int*)pArg; + *(int*)pArg = iOld; return SQLITE_OK; } #endif @@ -4817,6 +4819,24 @@ static int unixShmLock( assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 ); assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 ); + /* Check that, if this to be a blocking lock, that locks have been + ** obtained in the following order. + ** + ** 1. Checkpointer lock (ofst==1). + ** 2. Recover lock (ofst==2). + ** 3. Read locks (ofst>=3 && ofstiBusyTimeout==0 + || (flags & SQLITE_SHM_UNLOCK) || ofst==0 + || ((p->exclMask|p->sharedMask)&~((1<1 || mask==(1<pShmMutex); diff --git a/src/parse.y b/src/parse.y index c321daf195..09731eb99c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1194,10 +1194,11 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { */ sqlite3ExprUnmapAndDelete(pParse, A); A = sqlite3Expr(pParse->db, TK_INTEGER, N ? "1" : "0"); - }else if( 0 && Y->nExpr==1 && sqlite3ExprIsConstant(Y->a[0].pExpr) ){ + }else if( Y->nExpr==1 && sqlite3ExprIsConstant(Y->a[0].pExpr) ){ Expr *pRHS = Y->a[0].pExpr; Y->a[0].pExpr = 0; sqlite3ExprListDelete(pParse->db, Y); + pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); A = sqlite3PExpr(pParse, TK_EQ, A, pRHS); if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0); }else{ diff --git a/src/resolve.c b/src/resolve.c index 05ef0c06eb..e90e8a7686 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -175,6 +175,31 @@ static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){ } } +/* +** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN. +** return the appropriate colUsed mask. +*/ +Bitmask sqlite3ExprColUsed(Expr *pExpr){ + int n; + Table *pExTab; + + n = pExpr->iColumn; + pExTab = pExpr->y.pTab; + assert( pExTab!=0 ); + if( (pExTab->tabFlags & TF_HasGenerated)!=0 + && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 + ){ + testcase( pExTab->nCol==BMS-1 ); + testcase( pExTab->nCol==BMS ); + return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1; + }else{ + testcase( n==BMS-1 ); + testcase( n==BMS ); + if( n>=BMS ) n = BMS-1; + return ((Bitmask)1)<nDb && sqlite3StrICmp("main", zDb)==0 ){ + /* This branch is taken when the main database has been renamed + ** using SQLITE_DBCONFIG_MAINDBNAME. */ + pSchema = db->aDb[0].pSchema; + zDb = db->aDb[0].zDbSName; + } } } @@ -571,22 +602,7 @@ static int lookupName( ** of the table. */ if( pExpr->iColumn>=0 && pMatch!=0 ){ - int n = pExpr->iColumn; - Table *pExTab = pExpr->y.pTab; - assert( pExTab!=0 ); - assert( pMatch->iCursor==pExpr->iTable ); - if( (pExTab->tabFlags & TF_HasGenerated)!=0 - && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 - ){ - testcase( pExTab->nCol==BMS-1 ); - testcase( pExTab->nCol==BMS ); - pMatch->colUsed = pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1; - }else{ - testcase( n==BMS-1 ); - testcase( n==BMS ); - if( n>=BMS ) n = BMS-1; - pMatch->colUsed |= ((Bitmask)1)<colUsed |= sqlite3ExprColUsed(pExpr); } /* Clean up and return diff --git a/src/select.c b/src/select.c index fcd2a35eb3..3f33165edb 100644 --- a/src/select.c +++ b/src/select.c @@ -3580,6 +3580,38 @@ static void substSelect( } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** pSelect is a SELECT statement and pSrcItem is one item in the FROM +** clause of that SELECT. +** +** This routine scans the entire SELECT statement and recomputes the +** pSrcItem->colUsed mask. +*/ +static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ + struct SrcList_item *pItem; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; + pItem = pWalker->u.pSrcItem; + if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue; + if( pExpr->iColumn<0 ) return WRC_Continue; + pItem->colUsed |= sqlite3ExprColUsed(pExpr); + return WRC_Continue; +} +static void recomputeColumnsUsed( + Select *pSelect, /* The complete SELECT statement */ + struct SrcList_item *pSrcItem /* Which FROM clause item to recompute */ +){ + Walker w; + if( NEVER(pSrcItem->pTab==0) ) return; + memset(&w, 0, sizeof(w)); + w.xExprCallback = recomputeColumnsUsedExpr; + w.xSelectCallback = sqlite3SelectWalkNoop; + w.u.pSrcItem = pSrcItem; + pSrcItem->colUsed = 0; + sqlite3WalkSelect(&w, pSelect); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** This routine attempts to flatten subqueries as a performance optimization. @@ -4118,6 +4150,12 @@ static int flattenSubquery( pParent->pLimit = pSub->pLimit; pSub->pLimit = 0; } + + /* Recompute the SrcList_item.colUsed masks for the flattened + ** tables. */ + for(i=0; ia[i+iFrom]); + } } /* Finially, delete what is left of the subquery and return diff --git a/src/shell.c.in b/src/shell.c.in index 728a4d051d..54b779dcb1 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2358,8 +2358,7 @@ static void set_table_name(ShellState *p, const char *zName){ */ static int run_table_dump_query( ShellState *p, /* Query context */ - const char *zSelect, /* SELECT statement to extract content */ - const char *zFirstRow /* Print before first row, if not NULL */ + const char *zSelect /* SELECT statement to extract content */ ){ sqlite3_stmt *pSelect; int rc; @@ -2376,10 +2375,6 @@ static int run_table_dump_query( rc = sqlite3_step(pSelect); nResult = sqlite3_column_count(pSelect); while( rc==SQLITE_ROW ){ - if( zFirstRow ){ - utf8_printf(p->out, "%s", zFirstRow); - zFirstRow = 0; - } z = (const char*)sqlite3_column_text(pSelect, 0); utf8_printf(p->out, "%s", z); for(i=1; ishowHeader; int savedShellFlags = p->shellFlgs; @@ -7306,12 +7303,10 @@ static int do_meta_command(char *zLine, ShellState *p){ goto meta_command_exit; } }else if( zLike ){ - raw_printf(stderr, "Usage: .dump ?--preserve-rowids? " - "?--newlines? ?LIKE-PATTERN?\n"); - rc = 1; - goto meta_command_exit; + zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'", + zLike, azArg[i]); }else{ - zLike = azArg[i]; + zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]); } } @@ -7329,35 +7324,25 @@ static int do_meta_command(char *zLine, ShellState *p){ ** corrupt. */ sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); p->nErr = 0; - if( zLike==0 ){ - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" - ); - run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE name=='sqlite_sequence'" - ); - run_table_dump_query(p, - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 - ); - }else{ - char *zSql; - zSql = sqlite3_mprintf( - "SELECT name, type, sql FROM sqlite_master " - "WHERE tbl_name LIKE %Q AND type=='table'" - " AND sql NOT NULL", zLike); - run_schema_dump_query(p,zSql); - sqlite3_free(zSql); - zSql = sqlite3_mprintf( - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL" - " AND type IN ('index','trigger','view')" - " AND tbl_name LIKE %Q", zLike); - run_table_dump_query(p, zSql, 0); - sqlite3_free(zSql); - } + if( zLike==0 ) zLike = sqlite3_mprintf("true"); + zSql = sqlite3_mprintf( + "SELECT name, type, sql FROM sqlite_master " + "WHERE (%s) AND type=='table'" + " AND sql NOT NULL" + " ORDER BY tbl_name='sqlite_sequence', rowid", + zLike + ); + run_schema_dump_query(p,zSql); + sqlite3_free(zSql); + zSql = sqlite3_mprintf( + "SELECT sql FROM sqlite_master " + "WHERE (%s) AND sql NOT NULL" + " AND type IN ('index','trigger','view')", + zLike + ); + run_table_dump_query(p, zSql); + sqlite3_free(zSql); + sqlite3_free(zLike); if( p->writableSchema ){ raw_printf(p->out, "PRAGMA writable_schema=OFF;\n"); p->writableSchema = 0; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7b2049ae0a..86c3223801 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1087,10 +1087,12 @@ struct sqlite3_io_methods { ** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. ** **
  • [[SQLITE_FCNTL_LOCK_TIMEOUT]] -** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain -** a file lock using the xLock or xShmLock methods of the VFS to wait -** for up to M milliseconds before failing, where M is the single -** unsigned integer parameter. +** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS +** to block for up to M milliseconds before failing when attempting to +** obtain a file lock using the xLock or xShmLock methods of the VFS. +** The parameter is a pointer to a 32-bit signed integer that contains +** the value that M is to be set to. Before returning, the 32-bit signed +** integer is overwritten with the previous value of M. ** **
  • [[SQLITE_FCNTL_DATA_VERSION]] ** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7a00b576a0..d08c7ce1e7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -186,6 +186,21 @@ #pragma warn -spa /* Suspicious pointer arithmetic */ #endif +/* +** WAL mode depends on atomic aligned 32-bit loads and stores in a few +** places. The following macros try to make this explicit. +*/ +#ifndef __has_feature +# define __has_feature(x) 0 /* compatibility with non-clang compilers */ +#endif +#if GCC_VERSION>=4007000 || __has_feature(c_atomic) +# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) +# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) +#else +# define AtomicLoad(PTR) (*(PTR)) +# define AtomicStore(PTR,VAL) (*(PTR) = (VAL)) +#endif + /* ** Include standard header files as necessary */ @@ -3695,6 +3710,7 @@ struct Walker { struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ + struct SrcList_item *pSrcItem; /* A single FROM clause item */ } u; }; @@ -4394,6 +4410,7 @@ void sqlite3DeferForeignKey(Parse*, int); # define sqlite3AuthContextPush(a,b,c) # define sqlite3AuthContextPop(a) ((void)(a)) #endif +int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName); void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); void sqlite3Detach(Parse*, Expr*); void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); @@ -4549,6 +4566,7 @@ int sqlite3MatchEName( const char*, const char* ); +Bitmask sqlite3ExprColUsed(Expr*); int sqlite3ResolveExprNames(NameContext*, Expr*); int sqlite3ResolveExprListNames(NameContext*, ExprList*); void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); diff --git a/src/tokenize.c b/src/tokenize.c index 48f92218d3..8467c0ffe0 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -568,7 +568,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( zSql!=0 ); mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; if( db->nVdbeActive==0 ){ - db->u1.isInterrupted = 0; + AtomicStore(&db->u1.isInterrupted, 0); } pParse->rc = SQLITE_OK; pParse->zTail = zSql; @@ -613,7 +613,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); #endif /* SQLITE_OMIT_WINDOWFUNC */ - if( db->u1.isInterrupted ){ + if( AtomicLoad(&db->u1.isInterrupted) ){ pParse->rc = SQLITE_INTERRUPT; break; } diff --git a/src/treeview.c b/src/treeview.c index 2d9da55077..45c0d748b1 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -138,8 +138,8 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3_str_appendf(&x, " %s", pItem->zName); } if( pItem->pTab ){ - sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p", - pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab); + sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", + pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); } if( pItem->zAlias ){ sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); diff --git a/src/trigger.c b/src/trigger.c index 458aa2996c..646d6942d3 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -580,7 +580,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue; + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; assert( sqlite3SchemaMutexHeld(db, j, 0) ); pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); if( pTrigger ) break; diff --git a/src/vdbe.c b/src/vdbe.c index 4eac7be647..69055d9161 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -707,7 +707,7 @@ int sqlite3VdbeExec( assert( p->explain==0 ); p->pResultSet = 0; db->busyHandler.nBusy = 0; - if( db->u1.isInterrupted ) goto abort_due_to_interrupt; + if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; sqlite3VdbeIOTraceSql(p); #ifdef SQLITE_DEBUG sqlite3BeginBenignMalloc(); @@ -891,7 +891,7 @@ jump_to_p2_and_check_for_interrupt: ** checks on every opcode. This helps sqlite3_step() to run about 1.5% ** faster according to "valgrind --tool=cachegrind" */ check_for_interrupt: - if( db->u1.isInterrupted ) goto abort_due_to_interrupt; + if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number ** of VDBE ops have been executed (either since this invocation of @@ -8005,7 +8005,7 @@ no_mem: ** flag. */ abort_due_to_interrupt: - assert( db->u1.isInterrupted ); + assert( AtomicLoad(&db->u1.isInterrupted) ); rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; p->rc = rc; sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 8102831624..a256ed5bd1 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -418,9 +418,9 @@ struct Vdbe { u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ + u8 doingRerun; /* True if rerunning after an auto-reprepare */ bft expired:2; /* 1: recompile VM immediately 2: when convenient */ bft explain:2; /* True if EXPLAIN present on SQL command */ - bft doingRerun:1; /* True if rerunning after an auto-reprepare */ bft changeCntOn:1; /* True to update the change-counter */ bft runOnlyOnce:1; /* Automatically expire on reset */ bft usesStmtJournal:1; /* True if uses a statement journal */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 074d458815..4337a33a54 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -663,7 +663,7 @@ static int sqlite3Step(Vdbe *p){ ** from interrupting a statement that has not yet started. */ if( db->nVdbeActive==0 ){ - db->u1.isInterrupted = 0; + AtomicStore(&db->u1.isInterrupted, 0); } assert( db->nVdbeWrite>0 || db->autoCommit==0 diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 4ef1c72fe1..cfddc0f614 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -424,7 +424,7 @@ void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ #endif /* -** Add a new OP_ opcode. +** Add a new OP_Explain opcode. ** ** If the bPush flag is true, then make this opcode the parent for ** subsequent Explains until sqlite3VdbeExplainPop() is called. @@ -2093,7 +2093,7 @@ int sqlite3VdbeList( } if( rc==SQLITE_OK ){ - if( db->u1.isInterrupted ){ + if( AtomicLoad(&db->u1.isInterrupted) ){ p->rc = SQLITE_INTERRUPT; rc = SQLITE_ERROR; sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); @@ -2375,6 +2375,7 @@ void sqlite3VdbeMakeReady( }; int iFirst, mx, i; if( nMem<10 ) nMem = 10; + p->explain = pParse->explain; if( pParse->explain==2 ){ sqlite3VdbeSetNumCols(p, 4); iFirst = 8; @@ -2425,7 +2426,6 @@ void sqlite3VdbeMakeReady( p->pVList = pParse->pVList; pParse->pVList = 0; - p->explain = pParse->explain; if( db->mallocFailed ){ p->nVar = 0; p->nCursor = 0; diff --git a/src/wal.c b/src/wal.c index 034a1624ea..3e4f4acfde 100644 --- a/src/wal.c +++ b/src/wal.c @@ -258,18 +258,6 @@ int sqlite3WalTrace = 0; # define WALTRACE(X) #endif -/* -** WAL mode depends on atomic aligned 32-bit loads and stores in a few -** places. The following macros try to make this explicit. -*/ -#if GCC_VESRION>=5004000 -# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) -# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) -#else -# define AtomicLoad(PTR) (*(PTR)) -# define AtomicStore(PTR,VAL) (*(PTR) = (VAL)) -#endif - /* ** The maximum (and only) versions of the wal and wal-index formats ** that may be interpreted by this version of SQLite. @@ -1140,6 +1128,11 @@ static int walIndexRecover(Wal *pWal){ u32 aFrameCksum[2] = {0, 0}; int iLock; /* Lock offset to lock for checkpoint */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int tmout = 0; + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout); +#endif + /* Obtain an exclusive lock on all byte in the locking range not already ** locked by the caller. The caller is guaranteed to have locked the ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte. @@ -1886,7 +1879,7 @@ static int walCheckpoint( while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ i64 iOffset; assert( walFramePgno(pWal, iFrame)==iDbpage ); - if( db->u1.isInterrupted ){ + if( AtomicLoad(&db->u1.isInterrupted) ){ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; break; } @@ -2599,7 +2592,8 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ for(i=1; iaReadMark+i,mxFrame); + AtomicStore(pInfo->aReadMark+i,mxFrame); + mxReadMark = mxFrame; mxI = i; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); break; @@ -2758,6 +2752,9 @@ int sqlite3WalSnapshotRecover(Wal *pWal){ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ int rc; /* Return code */ int cnt = 0; /* Number of TryBeginRead attempts */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int tmout = 0; +#endif #ifdef SQLITE_ENABLE_SNAPSHOT int bChanged = 0; @@ -2767,6 +2764,12 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ } #endif +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* Disable blocking locks. They are not useful when trying to open a + ** read-transaction, and blocking may cause deadlock anyway. */ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout); +#endif + do{ rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); }while( rc==WAL_RETRY ); @@ -2775,6 +2778,16 @@ int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ testcase( rc==SQLITE_PROTOCOL ); testcase( rc==SQLITE_OK ); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* If they were disabled earlier and the read-transaction has been + ** successfully opened, re-enable blocking locks. This is because the + ** connection may attempt to upgrade to a write-transaction, which does + ** benefit from using blocking locks. */ + if( rc==SQLITE_OK ){ + sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout); + } +#endif + #ifdef SQLITE_ENABLE_SNAPSHOT if( rc==SQLITE_OK ){ if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){ diff --git a/src/walker.c b/src/walker.c index 5733210c47..48d7ddbf3d 100644 --- a/src/walker.c +++ b/src/walker.c @@ -156,15 +156,16 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ struct SrcList_item *pItem; pSrc = p->pSrc; - assert( pSrc!=0 ); - for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ - return WRC_Abort; - } - if( pItem->fg.isTabFunc - && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) - ){ - return WRC_Abort; + if( pSrc ){ + for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ + if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ + return WRC_Abort; + } + if( pItem->fg.isTabFunc + && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) + ){ + return WRC_Abort; + } } } return WRC_Continue; diff --git a/test/attach.test b/test/attach.test index 5ddab1abac..1e1d426a41 100644 --- a/test/attach.test +++ b/test/attach.test @@ -148,10 +148,8 @@ do_test attach-1.14 { ATTACH 'test.db' as db9; } } {1 {database db9 is already in use}} -do_test attach-1.15 { - catchsql { - ATTACH 'test.db' as main; - } +do_catchsql_test attach-1.15 { + ATTACH 'test.db' as main; } {1 {database main is already in use}} ifcapable tempdb { do_test attach-1.16 { @@ -160,10 +158,8 @@ ifcapable tempdb { } } {1 {database temp is already in use}} } -do_test attach-1.17 { - catchsql { - ATTACH 'test.db' as MAIN; - } +do_catchsql_test attach-1.17 { + ATTACH 'test.db' as MAIN; } {1 {database MAIN is already in use}} do_test attach-1.18 { catchsql { @@ -231,6 +227,7 @@ do_test attach-1.26 { } } {1 {cannot detach database main}} + ifcapable tempdb { do_test attach-1.27 { catchsql { diff --git a/test/e_createtable.test b/test/e_createtable.test index 7f6cf48ce9..c9742eaee3 100644 --- a/test/e_createtable.test +++ b/test/e_createtable.test @@ -395,17 +395,19 @@ do_createtable_tests 1.2.2 { 4 {CREATE TABLE auxb.xyz(z)} {} } drop_all_tables -do_createtable_tests 1.3 -tclquery { - unset -nocomplain X - array set X [table_list] - list $X(main) $X(temp) $X(auxa) $X(auxb) -} { - 1 "CREATE TABLE main.abc(a, b, c)" {abc {} {} {}} - 2 "CREATE TABLE main.t1(a, b, c)" {{abc t1} {} {} {}} - 3 "CREATE TABLE temp.tmp(a, b, c)" {{abc t1} tmp {} {}} - 4 "CREATE TABLE auxb.tbl(x, y)" {{abc t1} tmp {} tbl} - 5 "CREATE TABLE auxb.t1(k, v)" {{abc t1} tmp {} {t1 tbl}} - 6 "CREATE TABLE auxa.next(c, d)" {{abc t1} tmp next {t1 tbl}} +if {[permutation]!="maindbname"} { + do_createtable_tests 1.3 -tclquery { + unset -nocomplain X + array set X [table_list] + list $X(main) $X(temp) $X(auxa) $X(auxb) + } { + 1 "CREATE TABLE main.abc(a, b, c)" {abc {} {} {}} + 2 "CREATE TABLE main.t1(a, b, c)" {{abc t1} {} {} {}} + 3 "CREATE TABLE temp.tmp(a, b, c)" {{abc t1} tmp {} {}} + 4 "CREATE TABLE auxb.tbl(x, y)" {{abc t1} tmp {} tbl} + 5 "CREATE TABLE auxb.t1(k, v)" {{abc t1} tmp {} {t1 tbl}} + 6 "CREATE TABLE auxa.next(c, d)" {{abc t1} tmp next {t1 tbl}} + } } # EVIDENCE-OF: R-18895-27365 If the "TEMP" or "TEMPORARY" keyword occurs @@ -413,13 +415,15 @@ do_createtable_tests 1.3 -tclquery { # temp database. # drop_all_tables -do_createtable_tests 1.4 -tclquery { - unset -nocomplain X - array set X [table_list] - list $X(main) $X(temp) $X(auxa) $X(auxb) -} { - 1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}} - 2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}} +if {[permutation]!="maindbname"} { + do_createtable_tests 1.4 -tclquery { + unset -nocomplain X + array set X [table_list] + list $X(main) $X(temp) $X(auxa) $X(auxb) + } { + 1 "CREATE TEMP TABLE t1(a, b)" {{} t1 {} {}} + 2 "CREATE TEMPORARY TABLE t2(a, b)" {{} {t1 t2} {} {}} + } } # EVIDENCE-OF: R-23976-43329 It is an error to specify both a @@ -436,30 +440,34 @@ do_createtable_tests 1.5.1 -error { 4 "CREATE TEMPORARY TABLE main.xxx(x)" {} } drop_all_tables -do_createtable_tests 1.5.2 -tclquery { - unset -nocomplain X - array set X [table_list] - list $X(main) $X(temp) $X(auxa) $X(auxb) -} { - 1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}} - 2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}} - 3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}} - 4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}} +if {[permutation]!="maindbname"} { + do_createtable_tests 1.5.2 -tclquery { + unset -nocomplain X + array set X [table_list] + list $X(main) $X(temp) $X(auxa) $X(auxb) + } { + 1 "CREATE TEMP TABLE temp.t1(a, b)" {{} t1 {} {}} + 2 "CREATE TEMPORARY TABLE temp.t2(a, b)" {{} {t1 t2} {} {}} + 3 "CREATE TEMP TABLE TEMP.t3(a, b)" {{} {t1 t2 t3} {} {}} + 4 "CREATE TEMPORARY TABLE TEMP.xxx(x)" {{} {t1 t2 t3 xxx} {} {}} + } } # EVIDENCE-OF: R-31997-24564 If no schema name is specified and the TEMP # keyword is not present then the table is created in the main database. # drop_all_tables -do_createtable_tests 1.6 -tclquery { - unset -nocomplain X - array set X [table_list] - list $X(main) $X(temp) $X(auxa) $X(auxb) -} { - 1 "CREATE TABLE t1(a, b)" {t1 {} {} {}} - 2 "CREATE TABLE t2(a, b)" {{t1 t2} {} {} {}} - 3 "CREATE TABLE t3(a, b)" {{t1 t2 t3} {} {} {}} - 4 "CREATE TABLE xxx(x)" {{t1 t2 t3 xxx} {} {} {}} +if {[permutation]!="maindbname"} { + do_createtable_tests 1.6 -tclquery { + unset -nocomplain X + array set X [table_list] + list $X(main) $X(temp) $X(auxa) $X(auxb) + } { + 1 "CREATE TABLE t1(a, b)" {t1 {} {} {}} + 2 "CREATE TABLE t2(a, b)" {{t1 t2} {} {} {}} + 3 "CREATE TABLE t3(a, b)" {{t1 t2 t3} {} {} {}} + 4 "CREATE TABLE xxx(x)" {{t1 t2 t3 xxx} {} {} {}} + } } drop_all_tables diff --git a/test/e_dropview.test b/test/e_dropview.test index 04c4ad8c4b..00f59ddc4f 100644 --- a/test/e_dropview.test +++ b/test/e_dropview.test @@ -126,37 +126,37 @@ do_execsql_test 3.1.0 { SELECT * FROM temp.v1 } {{a temp} {b temp}} do_execsql_test 3.1.1 { DROP VIEW temp.v1 } {} do_catchsql_test 3.1.2 { SELECT * FROM temp.v1 } {1 {no such table: temp.v1}} do_test 3.1.3 { list_all_views } {main.v1 main.v2 aux.v1 aux.v2 aux.v3} -do_test 3.1.4 { list_all_data } $databasedata +do_test 3.1.4 { string compare [list_all_data] $databasedata } 0 do_execsql_test 3.2.0 { SELECT * FROM v1 } {{a main} {b main}} do_execsql_test 3.2.1 { DROP VIEW v1 } {} do_catchsql_test 3.2.2 { SELECT * FROM main.v1 } {1 {no such table: main.v1}} do_test 3.2.3 { list_all_views } {main.v2 aux.v1 aux.v2 aux.v3} -do_test 3.2.4 { list_all_data } $databasedata +do_test 3.2.4 { string compare [list_all_data] $databasedata } 0 do_execsql_test 3.3.0 { SELECT * FROM v2 } {{a main} {b main}} do_execsql_test 3.3.1 { DROP VIEW v2 } {} do_catchsql_test 3.3.2 { SELECT * FROM main.v2 } {1 {no such table: main.v2}} do_test 3.3.3 { list_all_views } {aux.v1 aux.v2 aux.v3} -do_test 3.3.4 { list_all_data } $databasedata +do_test 3.3.4 { string compare [list_all_data] $databasedata } 0 do_execsql_test 3.4.0 { SELECT * FROM v1 } {{a aux} {b aux}} do_execsql_test 3.4.1 { DROP VIEW v1 } {} do_catchsql_test 3.4.2 { SELECT * FROM v1 } {1 {no such table: v1}} do_test 3.4.3 { list_all_views } {aux.v2 aux.v3} -do_test 3.4.4 { list_all_data } $databasedata +do_test 3.4.4 { string compare [list_all_data] $databasedata } 0 -do_execsql_test 3.4.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}} -do_execsql_test 3.4.1 { DROP VIEW aux.v2 } {} -do_catchsql_test 3.4.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}} -do_test 3.4.3 { list_all_views } {aux.v3} -do_test 3.4.4 { list_all_data } $databasedata +do_execsql_test 3.5.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}} +do_execsql_test 3.5.1 { DROP VIEW aux.v2 } {} +do_catchsql_test 3.5.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}} +do_test 3.5.3 { list_all_views } {aux.v3} +do_test 3.5.4 { string compare [list_all_data] $databasedata } 0 -do_execsql_test 3.5.0 { SELECT * FROM v3 } {{a aux} {b aux}} -do_execsql_test 3.5.1 { DROP VIEW v3 } {} -do_catchsql_test 3.5.2 { SELECT * FROM v3 } {1 {no such table: v3}} -do_test 3.5.3 { list_all_views } {} -do_test 3.5.4 { list_all_data } $databasedata +do_execsql_test 3.6.0 { SELECT * FROM v3 } {{a aux} {b aux}} +do_execsql_test 3.6.1 { DROP VIEW v3 } {} +do_catchsql_test 3.6.2 { SELECT * FROM v3 } {1 {no such table: v3}} +do_test 3.6.3 { list_all_views } {} +do_test 3.6.4 { string compare [list_all_data] $databasedata } 0 # EVIDENCE-OF: R-25558-37487 If the specified view cannot be found and # the IF EXISTS clause is not present, it is an error. @@ -179,11 +179,11 @@ do_dropview_tests 5 -repair { dropview_reopen_db } -tclquery { list_all_views - expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"} + #expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"} } { - 1 "DROP VIEW IF EXISTS xx" 1 - 2 "DROP VIEW IF EXISTS main.xx" 1 - 3 "DROP VIEW IF EXISTS temp.v2" 1 + 1 "DROP VIEW IF EXISTS xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3" + 2 "DROP VIEW IF EXISTS main.xx" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3" + 3 "DROP VIEW IF EXISTS temp.v2" "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3" } diff --git a/test/fts3misc.test b/test/fts3misc.test index 92b93d033d..9becba9af7 100644 --- a/test/fts3misc.test +++ b/test/fts3misc.test @@ -303,4 +303,16 @@ do_execsql_test 9.2 { -4764623217061966105 8324454597464624651 } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 10.0 { + CREATE VIRTUAL TABLE f USING fts3(a,b); + CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB); + INSERT INTO f_stat VALUES (1,x'3b3b3b3b3b3b3b28ffffffffffffffffff1807f9073481f1d43bc93b3b3b3b3b3b3b3b3b3b18073b3b3b3b3b3b3b9b003b'); +} {} + +do_catchsql_test 10.1 { + INSERT INTO f(f) VALUES ('merge=69,59'); +} {1 {database disk image is malformed}} + finish_test diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 3785024368..992b225d36 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -94,11 +94,9 @@ # include #endif -#ifdef SQLITE_OSS_FUZZ -# include -# if !defined(_MSC_VER) -# include -# endif +#include +#if !defined(_MSC_VER) +# include #endif #if defined(_MSC_VER) diff --git a/test/icu.test b/test/icu.test index 4c4e6d14ec..644cbb1f08 100644 --- a/test/icu.test +++ b/test/icu.test @@ -146,4 +146,22 @@ ifcapable icu { } } +# 2020-03-19 +# The ESCAPE clause on LIKE takes precedence over wildcards +# +do_execsql_test idu-6.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT); + INSERT INTO t1 VALUES + (1,'abcde'), + (2,'abc_'), + (3,'abc__'), + (4,'abc%'), + (5,'abc%%'); + SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%'; +} {4} +do_execsql_test icu-6.1 { + SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_'; +} {2} + finish_test diff --git a/test/like.test b/test/like.test index 0fc80254ba..c29ebb2676 100644 --- a/test/like.test +++ b/test/like.test @@ -1113,4 +1113,22 @@ do_execsql_test 16.2 { SELECT * FROM t1 WHERE a LIKE ' 1-'; } {{ 1-}} +# 2020-03-19 +# The ESCAPE clause on LIKE takes precedence over wildcards +# +do_execsql_test 17.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(id INTEGER PRIMARY KEY, x TEXT); + INSERT INTO t1 VALUES + (1,'abcde'), + (2,'abc_'), + (3,'abc__'), + (4,'abc%'), + (5,'abc%%'); + SELECT id FROM t1 WHERE x LIKE 'abc%%' ESCAPE '%'; +} {4} +do_execsql_test 17.1 { + SELECT id FROM t1 WHERE x LIKE 'abc__' ESCAPE '_'; +} {2} + finish_test diff --git a/test/like3.test b/test/like3.test index 07053155ef..3bfe30c318 100644 --- a/test/like3.test +++ b/test/like3.test @@ -237,7 +237,7 @@ do_eqp_test like3-6.110 { `--SEARCH TABLE t1 USING PRIMARY KEY (path>? AND path? AND path? AND path? AND path? AND path? AND path