diff --git a/doc/lemon.html b/doc/lemon.html index 324b3f3319..16aea8784b 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -322,7 +322,7 @@ These are the steps: diff --git a/ext/fts5/test/fts5misc.test b/ext/fts5/test/fts5misc.test index fb609e2c86..da3f652697 100644 --- a/ext/fts5/test/fts5misc.test +++ b/ext/fts5/test/fts5misc.test @@ -329,7 +329,7 @@ do_execsql_test 12.3 { reset_db sqlite3_db_config db DEFENSIVE 1 -do_execsql_test 13.0 { +do_execsql_test 13.1.0 { CREATE TABLE a (id INTEGER PRIMARY KEY, name TEXT); CREATE VIRTUAL TABLE b USING fts5(name); CREATE TRIGGER a_trigger AFTER INSERT ON a BEGIN @@ -337,18 +337,44 @@ do_execsql_test 13.0 { END; } -do_test 13.1 { +do_test 13.1.1 { set ::STMT [ sqlite3_prepare db "INSERT INTO a VALUES (1, 'foo') RETURNING id;" -1 dummy ] sqlite3_step $::STMT } {SQLITE_ROW} -do_test 13.2 { +do_test 13.1.2 { sqlite3_finalize $::STMT } {SQLITE_OK} -do_test 13.3 { +do_test 13.1.3 { + sqlite3_errmsg db +} {not an error} + +reset_db +sqlite3_db_config db DEFENSIVE 1 +do_execsql_test 13.2.0 { + BEGIN; + CREATE TABLE a (id INTEGER PRIMARY KEY, name TEXT); + CREATE VIRTUAL TABLE b USING fts5(name); + CREATE TRIGGER a_trigger AFTER INSERT ON a BEGIN + INSERT INTO b (name) VALUES ('foo'); + END; +} + +do_test 13.2.1 { + set ::STMT [ + sqlite3_prepare db "INSERT INTO a VALUES (1, 'foo') RETURNING id;" -1 dummy + ] + sqlite3_step $::STMT +} {SQLITE_ROW} + +do_test 13.2.2 { + sqlite3_finalize $::STMT +} {SQLITE_OK} + +do_test 13.2.3 { sqlite3_errmsg db } {not an error} diff --git a/ext/misc/basexx.c b/ext/misc/basexx.c index c1808aa70f..0dcde54356 100644 --- a/ext/misc/basexx.c +++ b/ext/misc/basexx.c @@ -69,9 +69,12 @@ __declspec(dllexport) #endif int sqlite3_basexx_init(sqlite3 *db, char **pzErr, const sqlite3_api_routines *pApi){ + int rc1; + int rc2; + init_api_ptr(pApi); - int rc1 = BASE64_INIT(db); - int rc2 = BASE85_INIT(db); + rc1 = BASE64_INIT(db); + rc2 = BASE85_INIT(db); if( rc1==SQLITE_OK && rc2==SQLITE_OK ){ BASE64_EXPOSE(db, pzErr); diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index 5da80dd924..a50008ca35 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -595,7 +595,7 @@ static const char *re_subcompile_string(ReCompiled *p){ break; } case '[': { - int iFirst = p->nState; + unsigned int iFirst = p->nState; if( rePeek(p)=='^' ){ re_append(p, RE_OP_CC_EXC, 0); p->sIn.i++; @@ -619,7 +619,7 @@ static const char *re_subcompile_string(ReCompiled *p){ if( rePeek(p)==']' ){ p->sIn.i++; break; } } if( c==0 ) return "unclosed '['"; - p->aArg[iFirst] = p->nState - iFirst; + if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst; break; } case '\\': { diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index f65ef83864..15b05cede1 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -3156,11 +3156,18 @@ static int rbuLockDatabase(sqlite3 *db){ sqlite3_file *fd = 0; sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd); - if( fd==0 ){ + if( fd ){ + sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); + rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); + if( rc==SQLITE_OK ){ + rc = fd->pMethods->xUnlock(fd, SQLITE_LOCK_NONE); + } + sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd); + }else{ sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); } - if( fd->pMethods ){ + if( rc==SQLITE_OK && fd->pMethods ){ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); if( rc==SQLITE_OK ){ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE); diff --git a/ext/recover/recover1.test b/ext/recover/recover1.test index 26894eaca2..070dd03d69 100644 --- a/ext/recover/recover1.test +++ b/ext/recover/recover1.test @@ -329,5 +329,38 @@ do_test 17.2 { list [catch { $R finish } msg] $msg } {0 {}} +#------------------------------------------------------------------------- +foreach enc {utf8 utf16 utf16le utf16be} { + reset_db + do_execsql_test 18.$enc.1 { + PRAGMA auto_vacuum = 0; + PRAGMA encoding='utf16'; + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); + INSERT INTO t1 VALUES('abc', 'def'); + PRAGMA writable_schema = 1; + DELETE FROM sqlite_schema WHERE name='t1'; + } + + proc my_sql_hook {sql} { + if {[string match "INSERT INTO lostandfound*" $sql]} { + lappend ::script $sql + } + return 0 + } + do_test 18.$enc.2 { + set ::script [list] + set R [sqlite3_recover_init_sql db main my_sql_hook] + $R config lostandfound lostandfound + $R run + $R finish + set ::script + } {{INSERT INTO lostandfound VALUES(2, 2, 2, 1, 'abc', 'def')}} +} + + + + + finish_test diff --git a/manifest b/manifest index 730a2c4371..0182592b6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\swal2\schanges\sinto\sthis\sbranch. -D 2023-05-04T14:41:10.021 +C Merge\sthe\slatest\s3.42.0\sbeta\schanges\sinto\sthe\sbedrock\sbranch. +D 2023-05-13T15:10:42.409 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -39,7 +39,7 @@ F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/begin_concurrent.md 4bee2c3990d1eb800f1ce3726a911292a8e4b889300b2ffd4b08d357370db299 F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f -F doc/lemon.html efc0cd2345d66905505d98f862e1c571512def0ceb5b016cb658fd4918eb76a3 +F doc/lemon.html d2862dbef72496e87f7996f37e814b146848190a742c12161d13fd15346051b0 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -172,7 +172,7 @@ F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc27826807405 F ext/fts5/test/fts5matchinfo.test 10c9a6f7fe61fb132299c4183c012770b10c4d5c2f2edb6df0b6607f683d737a F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 -F ext/fts5/test/fts5misc.test c02f3e78aa7e62891b5f711c498a877f03252f10a6974e23bc722533233f2603 +F ext/fts5/test/fts5misc.test 416ec0ffbc79320a0760ec32d6684866e3ccd3fbce09f9bcd62d9aee4c666b43 F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581 F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd @@ -277,7 +277,7 @@ F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a2 F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824 F ext/misc/base64.c a71b131e50300c654a66c469a25b62874481f3d1cb3beb56aca9a68edd812e0d F ext/misc/base85.c 073054111988db593ef5fdb87ab8c459df1ea0c3aaaddf0f5bfa3d72b7e6280a -F ext/misc/basexx.c 5e859e1820620aa8080fb9145eb47089de426ae808f6abb01a8e12921c3a8e67 +F ext/misc/basexx.c 89ad6b76558efbceb627afd5e2ef1d84b2e96d9aaf9b7ecb20e3d00b51be6fcf F ext/misc/bgckpt.c 49ae19aa03e6da393db5d17da256374d4c4d36889fdd89d6e4bc93aca2b752e6 F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9 @@ -307,7 +307,7 @@ F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea57645 F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196 F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009 F ext/misc/randomjson.c 7dd13664155319d47b9facc0d8dbf45e13062966a47168e54e3f26d48240d7ea -F ext/misc/regexp.c f50ab59bfa8934b7ed98de069d2c74c187f2ef523fb09e85f8840f6459a90942 +F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab84070963624047db F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 @@ -375,11 +375,11 @@ F ext/rbu/rbuvacuum.test 542561741ff2b262e3694bc6012b44694ee62c545845319a06f3237 F ext/rbu/rbuvacuum2.test ae097d04feb041446a74fac94b24bffeb3fdd60e32b848c5611e507ab702b81b F ext/rbu/rbuvacuum3.test 3ce42695fdf21aaa3499e857d7d4253bc499ad759bcd6c9362042c13cd37d8de F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69eefaebb205 -F ext/rbu/sqlite3rbu.c 71a7f0dea3a846ff7c2499dc34a2528f5ddcbe23e2c54dc3cd1fa4d933377c6d +F ext/rbu/sqlite3rbu.c d4ddf8f0e93772556e452a6c2814063cf47efb760a0834391a9d0cd9859fa4b9 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304 F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055 F ext/recover/dbdata.c 31d580785cf14eb3c20ed6fbb421a10a66569858f837928e6b326088c38d4c72 -F ext/recover/recover1.test 36a4fd33134809439e677c0e7045b1d31a0ae4f70f464830bce158e2fb1e82f8 +F ext/recover/recover1.test c484d01502239f11b61f23c1cee9f5dd19fa17617f8974e42e74d64639c524cf F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3 F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e @@ -582,28 +582,28 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 F src/bitvec.c 3907fcbe8a0c8c2db58d97087d15cdabbf2842adb9125df9ab9ff87d3db16775 F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca -F src/btree.c 827ca2c3508bfb97cffdb64c46015b9d454298431397cf01dd565b6a34ac4a9d +F src/btree.c b665847a53bc556d663a70231fdaa600f5eb4d7d29684690fd4f63b1262621b3 F src/btree.h 77a092acf63526827e74e88d0480123212d079593a841ff1fe85507adf256ef6 -F src/btreeInt.h 6b0e8a3bcd995cb0019729c0d3138b7aea19e6cc26d78f8d55e7597e70e8c6cf -F src/build.c 58d1e9f2272c35068d99df45e63ac049ce13ee5933013f253b8bf1f909d04312 -F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a +F src/btreeInt.h 757425aeff908b819f2f086eadcc44ca847a672617ced5161c56c60c6b39c226 +F src/build.c 52784bddd510438361a3ab1141db6aaf0aad76096e2e06208e3c23d21b279ba2 +F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c f439c21d439aaf4706950a2597474f1a796b557a0750666308202c0f601ef0fd -F src/date.c f21815ca7172ce073db3163ac54c8d9f2841077165c1a6123b4d1c376a0c7ec7 +F src/date.c aca9e0c08b400b21238b609aea7c09585396cd770985cf8f475560f69222dad3 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef F src/delete.c a9c6d3f51c0a31e9b831e0a0580a98d702904b42d216fee530940e40dec34873 -F src/expr.c 871cfd80c516ee39d90414b2d3da2b5bc9c9e21fe87b7eb787ea7ae4b6461758 +F src/expr.c b239be118a24f1520b44efb850cd1754854606bccb1a5f9dceeb0ff48f6bad79 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 03c134cc8bffe54835f742ddea0b72ebfc8f6b32773d175c71b8afeea6cb5c83 -F src/func.c 48acd78a3a583f42d9b5c2172f90f4de570045b37c930a2d8284e67f08c63664 +F src/func.c 3537d30d5ad9095373a3a105980812ffc8a106c43691328b7a0dc8de2988ddda F src/global.c bd0892ade7289f6e20bff44c07d06371f2ff9b53cea359e7854b9b72f65adc30 F src/hash.c c6af5f96a7a76d000f07c5402c48c318c2566beecdee9e78b9d9f60ce7119565 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h b638809e083b601b618df877b2e89cb87c2a47a01f4def10be4c4ebb54664ac7 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c a8de1db43335fc4946370a7a7e47d89975ad678ddb15078a150e993ba2fb37d4 -F src/json.c 7297dbd1d623850578c21bb8a99b87e745d09e14fd36ebc965ace67c86f902b4 +F src/json.c 39b1c7527f3111923e65f168a87b03b591f12a41400a63d05c119794bee36620 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c be5af440f3192c58681b5d43167dbca3ccbfce394d89faa22378a14264781136 F src/main.c 711be7ef7cc818de5f89887bad67e8196fcad8af9bd27a4ac354447e2b5a4833 @@ -630,7 +630,7 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210 F src/os_unix.c a585801080e5d36365a409221813534216f503b58f1f7a4398f225c4ae0bc424 F src/os_win.c 2b2411279f7b24f927591561303fc5871845732df42641cbf695c23640b16975 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c c0de0168428e951e5e2f7ee6b63a5dced0b71f74e5dabcdde82bd3e3e270e93e +F src/pager.c 9dd0da3b43166ceb465fce53a0826b0f6c3ea6ea9e294f7ce22a97d2f6d1f8e8 F src/pager.h 3ddab454e313da7c93f92fea35c842ad17ae9f4e96254871ddb0171b2bfb859a F src/parse.y 03d4d7a079481e6fab9f9256971fa87c716af20d46fffba2ecea21583e6f05db F src/pcache.c 8ee13acccfd9accbf0af94910b7323dd7f7d55300d92ddafcf40e34fcc8e21be @@ -639,16 +639,16 @@ F src/pcache1.c f3d06b0c1bd400cf657095757d427b149f6c1788e9447b2ce019988a5344ede8 F src/pragma.c 450aab7bd07c7570355f3b34df830869c86882f33b7acca842fbdf45146c0c8a F src/pragma.h 1f421360eed1a7721e8c521463df8519a7c8d0d5893ebd9dbfe0dba8de996f8c F src/prepare.c 6350675966bd0e7ac3a464af9dbfe26db6f0d4237f4e1f1acdb17b12ad371e6e -F src/printf.c 7eac1a9896a80697e03e08963e210830532ae2ff610e16c193e95af007ca5623 +F src/printf.c b9320cdbeca0b336c3f139fd36dd121e4167dd62b35fbe9ccaa9bab44c0af38d F src/random.c 9bd018738ec450bf35d28050b4b33fa9a6eebf3aaefb1a1cff42dc14a7725673 F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 79a6e11500d373b538aef918295d66a27f43481368557e06a07666b3b1c22017 -F src/shell.c.in 39ea3d9c17c65c42c6c415222d89a32ae683b245c8af7b4bfc544d9246055d16 -F src/sqlite.h.in e0cb5c60fb0654c2e772f61c920dc9d43ae26c9d4f22f038ce09600b8a527a16 +F src/select.c 7d7981de8abdd3c114e8bdbc3f25c4a3fa7b8a308b158d06893c229888e8d71c +F src/shell.c.in 1e18312f58d365042036fc9d19dcef416074f783702b168f07814332c2268ee0 +F src/sqlite.h.in 9394cdda0ef0179054a870ceb0e8d1b25f347ab75a728297452d41b3ac3e983a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 -F src/sqliteInt.h 4dfafdb2314a331174b5754a77cdbe1d028268215786468e858d6821c8990415 +F src/sqliteInt.h daf4e9f9d868fc1d0a1dd2f347a4ff7073f2c76a2d92911f1fff29f1cc22fcad F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -713,22 +713,22 @@ F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c d4bcb560471cd94e6e17d448311f8d5bf81a7e5276295a53501058ef1b95dd1a F src/vacuum.c f6e47729554e0d2c576bb710c415d5bc414935be0d7a70f38d1f58ffa7a6d8c0 -F src/vdbe.c fe7fa949ffd17f52c4b518751fc4fd49cecc3e64c84dedf77a2e4a30333eafea +F src/vdbe.c fb5e47fce79990f8bebcc3c75f79538c88a90446065866ce42298f93a2d4708d F src/vdbe.h 637ae853b7d42ae3951034cc63ab7c8af837861f79504cdb5399552fcd89a884 F src/vdbeInt.h a4147a4ddf613cb1bcb555ace9e9e74a9c099d65facd88155f191b1fb4d74cfb F src/vdbeapi.c b4982cde547054c4f7341198db3c3008a48e1eb028f757601bf5bf2fc026cbcf F src/vdbeaux.c f6d04ddce4450244ef4e845deb74462edd01f731bc57b737ae2d5a13d34a6092 -F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd +F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce F src/vdbemem.c 1cac4028c0dabbf1f3259f107440e2780e05ac9fe419e9709e6eb4e166ba714b F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac -F src/vtab.c 4a1b231b5938de0282fbb605eb068ca673a1b6a383130f54d1bcbbac951988ad +F src/vtab.c 4758a96d36c9a120848386ae603b1ab32a4876e0a1faf81bfcfb524455e583dc F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b6c4ad0a5689dbba6f339cff30b8fb029b092db81544821cf05f670368eb5ff8 F src/wal.h 7a733af13b966ecb81872ce397e862116b3575ea53245b90b139a2873ee87825 F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c f69d94f34e1c523cd9b66041e4afe015cad29888617f3c09a2a5bc36018917d0 +F src/where.c cec6a06508239c09e3637b52a12484fc9a84dc4302d45b4a311cce2ea6e4fd47 F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c F src/wherecode.c b300db0bcd84ad6c2642bf3f509f92fad7b7d697b9856b64dd66d692d184d054 F src/whereexpr.c 22cf19b0ececeaf838daed1039c5231a8778784eba5ad67b991442a23473fd3f @@ -945,7 +945,7 @@ F test/ctime.test 340f362f41f92972bbd71f44e10569a5cc694062b692231bd08aa6fe6c1c47 F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 -F test/date.test 118e04db8c8b4efeb885542b4918c7b869a34c460a6bebbfe927dfd75706b80d +F test/date.test 1d44557f668298b10d3335b22ab8feb133267b67ec4d85538908fe4dfebd2611 F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1 F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5 F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 @@ -1250,7 +1250,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test aea7a4f55b2d9eb8ef3434ea78f55b15bd688ab6136a11105c9c52f77424f199 +F test/join.test f7abfef3faeaf2800308872e33a57e5b6e4a2b44fb8c6b90c6068412e71a6cf4 F test/join2.test 8561fe82ce434ac96de91544072e578dc2cadddf2d9bc9cd802f866a9b92502e F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -1276,13 +1276,13 @@ F test/json/README.md 506af1f54574b524106acb50d1a341ab5ddfa6d83fe25095007892b07e F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f F test/json/json-q1.txt 335a7c8ab291d354f33b7decc9559e99a2823d4142291c4be7aa339a631f3c2d F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x -F test/json101.test ff8024cbb8092e723237648cea9bdbd51f31476b5015a4df3a5ecc8a5efda837 +F test/json101.test 94126d4291d4a00e45f6988ce885c410de69243490e46e70e9946cb6e6f9ea02 F test/json102.test 13dc9e7b7f359ecb861e02f9bd7019f7342a63d1c354273b0a8f3904050560a8 F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1 F test/json105.test 11670a4387f4308ae0318cadcbd6a918ea7edcd19fbafde020720a073952675d F test/json501.test f71710f60fa45b19dc336fbaac9e8362f70f80cf81badefdb845ed3f7c7c2ccc -F test/json502.test 66d150cc098674b8bf4354526a8dd411b926f43ca892306bcb3b6d3f93fef7be +F test/json502.test 98c38e3c4573841028a1381dfb81d4c3f9b105d39668167da10d055e503f6d0b F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 @@ -1401,7 +1401,7 @@ F test/ossfuzz.c 9636dad2092a05a32110df0ca06713038dd0c43dd89a77dabe4b8b0d7109671 F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test ffd885cdc98b986c9f746496508c0c4810ed0eaade3575ddf53c222e85880552 -F test/pager2.test 57ce815e31a7509fcdf7c5474577fd2e9cfee1281d45601e0f7a3bd5534d70a4 +F test/pager2.test c0ede15952b607f9a38f653acdfa73c19e657958e9104aab1a71950ea7b71831 F test/pager3.test 4e9a83d6ca0838d7c602c9eb93d1357562d9059c1e02ffb138a8271020838370 F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e F test/pagerfault.test 63c5da625562c66345ab4528790327ca63db2f6f9cbae2aba8cb7c51de3d1628 @@ -1422,11 +1422,11 @@ F test/pragma4.test ca5e4dfc46adfe490f75d73734f70349d95a199e6510973899e502eef2c8 F test/pragma5.test 7b33fc43e2e41abf17f35fb73f71b49671a380ea92a6c94b6ce530a25f8d9102 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9 -F test/printf.test 931381fede4f901d5f76275959339502f7d3312492c8df129972487951ff9fd1 +F test/printf.test 512152dca7f2f578f045a5a732e7bee08e4f47a8a212f83ce46791b518eba70f F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224cce60 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc -F test/pushdown.test c183fa51f93bb3a604eee9141133e36b5fbef0aac3b0447e464d977a84d6d00a +F test/pushdown.test 043e69055d841f5c4be0ff264b2a9de32d2342c3d71b20a786b0e6656603c66a F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quickcheck.test f86b25b33455af0189b4d3fe7bd6e553115e80b2d7ec9bbe9a6b37fce0881bfe @@ -1614,6 +1614,7 @@ F test/thread004.test f51dfc3936184aaf73ee85f315224baad272a87f F test/thread005.test 50d10b5684399676174bd96c94ad4250b1a2c8b6 F test/thread1.test df115faa10a4ba1d456e9d4d9ec165016903eae4 F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 +F test/thread3.test 5f53b6a8e7391d8653116fd0bee4f9774efee4410e039990821de39c6b4375a9 F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 @@ -1908,7 +1909,7 @@ F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test cd6e7cff618eaaa5910ce57c3657aa50110397f86213886a2400afb9bfec7b7b F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03 -F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 +F test/walpersist.test 8d78a1ec91299163451417b451a2bac3481f8eb9f455b1ca507a6625c927ca6e F test/walprotocol.test 1b3f922125e341703f6e946d77fdc564d38fb3e07a9385cfdc6c99cac1ecf878 F test/walprotocol2.test 7e4bedd5ee83607e2928ac438bf7332a396b980d3e02aa0746509ce11ad1f13c F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20 @@ -2044,7 +2045,7 @@ F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08 -F tool/omittest.tcl 3bc9609aceea871e1ca6ed6749df9ce79b89369d22b492f6ce6078f40647cc3f +F tool/omittest.tcl e99c9fecc3f7a8ca2fa75d8ec8bdbb5acce33dc69f0c280aae53064693387f65 F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/replace.tcl 937c931ad560688e85bdd6258bdc754371bb1e2732e1fb28ef441e44c9228fce @@ -2065,7 +2066,7 @@ F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd -F tool/split-sqlite3c.tcl 6b02bb5444cabc477c0d6eb3ecedcc827063e9ac41954831e90c72c481aa9d30 +F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 F tool/sqldiff.c 4f967c199c5f93eec64978e3a625d6c07fb1162212b1d48f65740d9eb4607eee F tool/sqlite3_analyzer.c.in f88615bf33098945e0a42f17733f472083d150b58bdaaa5555a7129d0a51621c F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 @@ -2104,8 +2105,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 a95a4bce8892eba3ab6e76a49975a52efeedebfd9af22bb31af30301b1d92328 49777032f29517d23c8c7483536f8ba828e7000dc303415da6881cc458620be2 -R 30d81d321a4c80a366fe52a9c425623c -U dan -Z 3610e2d3aeed2452f8a2e1ddcf7df823 +P b2e0800b24f8c676e189d63abd77ca45a972de9722ece5de6efe2db6ede75cbd 3bbfbdcd9b0e03b1ed50f41b1714ada5d241b8030f73ced8d0da8fff28a268e0 +R cde7e859e02244b9a4d583fbda09c452 +U drh +Z 5467b7cb54267f126eb88c1ac6f78d83 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f2a27ab0b4..7112c7ee8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2e0800b24f8c676e189d63abd77ca45a972de9722ece5de6efe2db6ede75cbd \ No newline at end of file +d55ba8bb85b1796d534d2db196db63312624630738712054553bd01f2ab30df9 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4fa4ed3206..30b3ffb657 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8164,7 +8164,7 @@ static int editPage( nCell -= nTail; } - pData = &aData[get2byteNotZero(&aData[hdr+5])]; + pData = &aData[get2byte(&aData[hdr+5])]; if( pDatapPg->aDataEnd) ) goto editpage_fail; diff --git a/src/btreeInt.h b/src/btreeInt.h index 1c057aeeec..e48d69b3db 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -563,7 +563,7 @@ struct BtCursor { #define BTCF_WriteFlag 0x01 /* True if a write cursor */ #define BTCF_ValidNKey 0x02 /* True if info.nKey is valid */ #define BTCF_ValidOvfl 0x04 /* True if aOverflow is valid */ -#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */ +#define BTCF_AtLast 0x08 /* Cursor is pointing to the last entry */ #define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */ #define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */ #define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */ diff --git a/src/build.c b/src/build.c index 16559da90b..6cc3381777 100644 --- a/src/build.c +++ b/src/build.c @@ -848,7 +848,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ if( IsOrdinaryTable(pTable) ){ sqlite3FkDelete(db, pTable); } -#ifndef SQLITE_OMIT_VIRTUAL_TABLE +#ifndef SQLITE_OMIT_VIRTUALTABLE else if( IsVirtual(pTable) ){ sqlite3VtabClear(db, pTable); } diff --git a/src/callback.c b/src/callback.c index 6cbe8e5847..c36d51a4ec 100644 --- a/src/callback.c +++ b/src/callback.c @@ -185,6 +185,7 @@ void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){ ** strings is BINARY. */ db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0); + sqlite3ExpirePreparedStatements(db, 1); } /* diff --git a/src/date.c b/src/date.c index 7cc6fa684e..9b7957bbf0 100644 --- a/src/date.c +++ b/src/date.c @@ -77,6 +77,7 @@ struct DateTime { char validTZ; /* True (1) if tz is valid */ char tzSet; /* Timezone was set explicitly */ char isError; /* An overflow has occurred */ + char useSubsec; /* Display subsecond precision */ }; @@ -391,6 +392,11 @@ static int parseDateOrTime( }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ setRawDateNumber(p, r); return 0; + }else if( (sqlite3StrICmp(zDate,"subsec")==0 + || sqlite3StrICmp(zDate,"subsecond")==0) + && sqlite3NotPureFunc(context) ){ + p->useSubsec = 1; + return setDateTimeToCurrent(context, p); } return 1; } @@ -805,8 +811,22 @@ static int parseModifier( ** ** Move the date backwards to the beginning of the current day, ** or month or year. + ** + ** subsecond + ** subsec + ** + ** Show subsecond precision in the output of datetime() and + ** unixepoch() and strftime('%s'). */ - if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break; + if( sqlite3_strnicmp(z, "start of ", 9)!=0 ){ + if( sqlite3_stricmp(z, "subsec")==0 + || sqlite3_stricmp(z, "subsecond")==0 + ){ + p->useSubsec = 1; + rc = 0; + } + break; + } if( !p->validJD && !p->validYMD && !p->validHMS ) break; z += 9; computeYMD(p); @@ -1004,7 +1024,11 @@ static void unixepochFunc( DateTime x; if( isDate(context, argc, argv, &x)==0 ){ computeJD(&x); - sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); + if( x.useSubsec ){ + sqlite3_result_double(context, (x.iJD - 21086676*(i64)10000000)/1000.0); + }else{ + sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); + } } } @@ -1020,8 +1044,8 @@ static void datetimeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - int Y, s; - char zBuf[24]; + int Y, s, n; + char zBuf[32]; computeYMD_HMS(&x); Y = x.Y; if( Y<0 ) Y = -Y; @@ -1042,15 +1066,28 @@ static void datetimeFunc( zBuf[15] = '0' + (x.m/10)%10; zBuf[16] = '0' + (x.m)%10; zBuf[17] = ':'; - s = (int)x.s; - zBuf[18] = '0' + (s/10)%10; - zBuf[19] = '0' + (s)%10; - zBuf[20] = 0; + if( x.useSubsec ){ + s = (int)1000.0*x.s; + zBuf[18] = '0' + (s/10000)%10; + zBuf[19] = '0' + (s/1000)%10; + zBuf[20] = '.'; + zBuf[21] = '0' + (s/100)%10; + zBuf[22] = '0' + (s/10)%10; + zBuf[23] = '0' + (s)%10; + zBuf[24] = 0; + n = 24; + }else{ + s = (int)x.s; + zBuf[18] = '0' + (s/10)%10; + zBuf[19] = '0' + (s)%10; + zBuf[20] = 0; + n = 20; + } if( x.Y<0 ){ zBuf[0] = '-'; - sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT); + sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); }else{ - sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT); + sqlite3_result_text(context, &zBuf[1], n-1, SQLITE_TRANSIENT); } } } @@ -1067,7 +1104,7 @@ static void timeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - int s; + int s, n; char zBuf[16]; computeHMS(&x); zBuf[0] = '0' + (x.h/10)%10; @@ -1076,11 +1113,24 @@ static void timeFunc( zBuf[3] = '0' + (x.m/10)%10; zBuf[4] = '0' + (x.m)%10; zBuf[5] = ':'; - s = (int)x.s; - zBuf[6] = '0' + (s/10)%10; - zBuf[7] = '0' + (s)%10; - zBuf[8] = 0; - sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT); + if( x.useSubsec ){ + s = (int)1000.0*x.s; + zBuf[6] = '0' + (s/10000)%10; + zBuf[7] = '0' + (s/1000)%10; + zBuf[8] = '.'; + zBuf[9] = '0' + (s/100)%10; + zBuf[10] = '0' + (s/10)%10; + zBuf[11] = '0' + (s)%10; + zBuf[12] = 0; + n = 12; + }else{ + s = (int)x.s; + zBuf[6] = '0' + (s/10)%10; + zBuf[7] = '0' + (s)%10; + zBuf[8] = 0; + n = 8; + } + sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT); } } @@ -1211,8 +1261,13 @@ static void strftimeFunc( break; } case 's': { - i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); - sqlite3_str_appendf(&sRes,"%lld",iS); + if( x.useSubsec ){ + sqlite3_str_appendf(&sRes,"%.3f", + (x.iJD - 21086676*(i64)10000000)/1000.0); + }else{ + i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); + sqlite3_str_appendf(&sRes,"%lld",iS); + } break; } case 'S': { diff --git a/src/expr.c b/src/expr.c index 9ffc3baded..52fc791c6f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2378,12 +2378,16 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ } /* -** Check pExpr to see if it is an invariant constraint on data source pSrc. +** Check pExpr to see if it is an constraint on the single data source pSrc. +** In other words, check to see if pExpr constrains pSrc but does not depend +** on any other tables or data sources anywhere else in the query. Return +** true (non-zero) if pExpr is a constraint on pSrc only. +** ** This is an optimization. False negatives will perhaps cause slower ** queries, but false positives will yield incorrect answers. So when in ** doubt, return 0. ** -** To be an invariant constraint, the following must be true: +** To be an single-source constraint, the following must be true: ** ** (1) pExpr cannot refer to any table other than pSrc->iCursor. ** @@ -2400,7 +2404,7 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ ** operand of a RIGHT JOIN, then pExpr must be from the WHERE ** clause, not an ON clause. */ -int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ +int sqlite3ExprIsSingleTableConstraint(Expr *pExpr, const SrcItem *pSrc){ if( pSrc->fg.jointype & JT_LTORJ ){ return 0; /* rule (3) */ } @@ -3843,7 +3847,7 @@ void sqlite3ExprCodeGeneratedColumn( int nErr = pParse->nErr; assert( v!=0 ); assert( pParse->iSelfTab!=0 ); - if( pParse->iSelfTab>0 ){ + if( pParse->iSelfTab>0 ){ iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); }else{ iAddr = 0; diff --git a/src/func.c b/src/func.c index 20ad938272..5f28e6ac6b 100644 --- a/src/func.c +++ b/src/func.c @@ -1520,7 +1520,7 @@ static void trimFunc( /* ** The "unknown" function is automatically substituted in place of ** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN -** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used. +** when the SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION compile-time option is used. ** When the "sqlite3" command-line shell is built using this functionality, ** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries ** involving application-defined functions to be examined in a generic diff --git a/src/json.c b/src/json.c index ada8a91c58..8735634c84 100644 --- a/src/json.c +++ b/src/json.c @@ -144,10 +144,10 @@ struct JsonParse { ** Maximum nesting depth of JSON for this implementation. ** ** This limit is needed to avoid a stack overflow in the recursive -** descent parser. A depth of 2000 is far deeper than any sane JSON -** should go. +** descent parser. A depth of 1000 is far deeper than any sane JSON +** should go. Historical note: This limit was 2000 prior to version 3.42.0 */ -#define JSON_MAX_DEPTH 2000 +#define JSON_MAX_DEPTH 1000 /************************************************************************** ** Utility routines for dealing with JsonString objects @@ -1085,6 +1085,7 @@ json_parse_restart: return -1; } for(j=i+1;;j++){ + u32 nNode = pParse->nNode; x = jsonParseValue(pParse, j); if( x<=0 ){ if( x==(-2) ){ @@ -1111,7 +1112,7 @@ json_parse_restart: } } if( pParse->oom ) return -1; - pNode = &pParse->aNode[pParse->nNode-1]; + pNode = &pParse->aNode[nNode]; if( pNode->eType!=JSON_STRING ){ pParse->iErr = j; return -1; diff --git a/src/pager.c b/src/pager.c index 8baca35ee9..6681793d0b 100644 --- a/src/pager.c +++ b/src/pager.c @@ -7635,13 +7635,15 @@ int sqlite3PagerWalSupported(Pager *pPager){ */ static int pagerExclusiveLock(Pager *pPager){ int rc; /* Return code */ + u8 eOrigLock; /* Original lock */ - assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); + assert( pPager->eLock>=SHARED_LOCK ); + eOrigLock = pPager->eLock; rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ /* If the attempt to grab the exclusive lock failed, release the ** pending lock that may have been obtained instead. */ - pagerUnlockDb(pPager, SHARED_LOCK); + pagerUnlockDb(pPager, eOrigLock); } return rc; diff --git a/src/printf.c b/src/printf.c index 65e539befd..3e1782d466 100644 --- a/src/printf.c +++ b/src/printf.c @@ -649,6 +649,7 @@ void sqlite3_str_vappendf( { i64 szBufNeeded; /* Size of a temporary buffer needed */ szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15; + if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3; if( szBufNeeded > etBUFSIZE ){ bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded); if( bufpt==0 ) return; @@ -666,10 +667,12 @@ void sqlite3_str_vappendf( }else if( msd>0 ){ for(; e2>=0; e2--){ *(bufpt++) = et_getdigit_int(&longvalue,&msd); + if( cThousand && (e2%3)==0 && e2>1 ) *(bufpt++) = ','; } }else{ for(; e2>=0; e2--){ *(bufpt++) = et_getdigit(&realvalue,&nsd); + if( cThousand && (e2%3)==0 && e2>1 ) *(bufpt++) = ','; } } /* The decimal point */ diff --git a/src/select.c b/src/select.c index 52055d5c18..8c4d1173ec 100644 --- a/src/select.c +++ b/src/select.c @@ -717,7 +717,7 @@ static void pushOntoSorter( ** (2) All output columns are included in the sort record. In that ** case regData==regOrigData. ** (3) Some output columns are omitted from the sort record due to - ** the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the + ** the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the ** SQLITE_ECEL_OMITREF optimization, or due to the ** SortCtx.pDeferredRowLoad optimiation. In any of these cases ** regOrigData is 0 to prevent this routine from trying to copy @@ -5107,6 +5107,23 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** or EXCEPT, then all of the result set columns for all arms of ** the compound must use the BINARY collating sequence. ** +** (9) All three of the following are true: +** +** (9a) The WHERE clause expression originates in the ON or USING clause +** of a join (either an INNER or an OUTER join), and +** +** (9b) The subquery is to the right of the ON/USING clause +** +** (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING +** clause and the subquery. +** +** Without this restriction, the push-down optimization might move +** the ON/USING filter expression from the left side of a RIGHT JOIN +** over to the right side, which leads to incorrect answers. +** +** (10) The inner query is not the right-hand table of a RIGHT JOIN. +** +** (11) The subquery is not a VALUES clause ** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. @@ -5115,13 +5132,20 @@ static int pushDownWhereTerms( Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ - SrcItem *pSrc /* The subquery term of the outer FROM clause */ + SrcList *pSrcList, /* The complete from clause of the outer query */ + int iSrc /* Which FROM clause term to try to push into */ ){ Expr *pNew; + SrcItem *pSrc; /* The subquery FROM term into which WHERE is pushed */ int nChng = 0; + pSrc = &pSrcList->a[iSrc]; if( pWhere==0 ) return 0; - if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; - if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0; + if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ){ + return 0; /* restrictions (2) and (11) */ + } + if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ){ + return 0; /* restrictions (10) */ + } if( pSubq->pPrior ){ Select *pSel; @@ -5176,11 +5200,29 @@ static int pushDownWhereTerms( return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrcList, iSrc); pWhere = pWhere->pLeft; } -#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ + if( ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) /* (9a) */ + && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0 /* Fast pre-test of (9c) */ + ){ + int jj; + for(jj=0; jjw.iJoin==pSrcList->a[jj].iCursor ){ + /* If we reach this point, both (9a) and (9b) are satisfied. + ** The following loop checks (9c): + */ + for(jj++; jja[jj].fg.jointype & JT_RIGHT)!=0 ){ + return 0; /* restriction (9) */ + } + } + } + } + } + +#if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */ if( isLeftJoin && (ExprHasProperty(pWhere,EP_OuterON)==0 || pWhere->w.iJoin!=iCursor) @@ -5194,7 +5236,7 @@ static int pushDownWhereTerms( } #endif - if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){ + if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrc) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -7192,7 +7234,7 @@ int sqlite3Select( pTabList->a[0].fg.jointype & JT_LTORJ); } - /* No futher action if this term of the FROM clause is no a subquery */ + /* No futher action if this term of the FROM clause is not a subquery */ if( pSub==0 ) continue; /* Catch mismatch in the declared columns of a view and the number of @@ -7389,7 +7431,7 @@ int sqlite3Select( if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) - && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i) ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x4000 ){ diff --git a/src/shell.c.in b/src/shell.c.in index bf804aca9f..ccaed896d9 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -605,6 +605,10 @@ static struct ConsoleState { DWORD consoleMode; /* Console mode upon shell start */ } conState = { 0, 0, 0, 0, INVALID_HANDLE_VALUE, 0 }; +#ifndef _O_U16TEXT /* For build environments lacking this constant: */ +# define _O_U16TEXT 0x20000 +#endif + /* ** Prepare console, (if known to be a WIN32 console), for UTF-8 ** input (from either typing or suitable paste operations) and for @@ -1772,6 +1776,7 @@ static void editFunc( }else{ /* If the file did not originally contain \r\n then convert any new ** \r\n back into \n */ + p[sz] = 0; for(i=j=0; idb==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n", zDbFilename, sqlite3_errmsg(p->db)); - if( openFlags & OPEN_DB_KEEPALIVE ){ - sqlite3_open(":memory:", &p->db); - return; + if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){ + exit(1); + } + sqlite3_close(p->db); + sqlite3_open(":memory:", &p->db); + if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ + utf8_printf(stderr, + "Also: unable to open substitute in-memory database.\n" + ); + exit(1); + }else{ + utf8_printf(stderr, + "Notice: using substitute in-memory database instead of \"%s\"\n", + zDbFilename); } - exit(1); } sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0); @@ -6130,7 +6145,7 @@ static void tryToCloneSchema( zName = sqlite3_column_text(pQuery, 0); zSql = sqlite3_column_text(pQuery, 1); if( zName==0 || zSql==0 ) continue; - if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ) continue; + if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue; printf("%s... ", zName); fflush(stdout); sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); if( zErrMsg ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 03f1e57c8f..3278642fb4 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2142,28 +2142,28 @@ struct sqlite3_mem_methods { ** compile-time option is not set, then the default maximum is 1073741824. ** */ -#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ -#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ -#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ -#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ -#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ -#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ -#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ -#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ -/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ -#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ -#define SQLITE_CONFIG_PCACHE 14 /* no-op */ -#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ -#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ -#define SQLITE_CONFIG_URI 17 /* int */ -#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ -#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ +#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ +#define SQLITE_CONFIG_SERIALIZED 3 /* nil */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ +#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ +#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ +#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ +#define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ +#define SQLITE_CONFIG_PCACHE 14 /* no-op */ +#define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ +#define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ +#define SQLITE_CONFIG_URI 17 /* int */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ -#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ -#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a9ab4d5463..007b79ee4e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4927,7 +4927,7 @@ int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*, u8); int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); int sqlite3ExprIsTableConstant(Expr*,int); -int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*); +int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcItem*); #ifdef SQLITE_ENABLE_CURSOR_HINTS int sqlite3ExprContainsSubquery(Expr*); #endif diff --git a/src/vdbe.c b/src/vdbe.c index 2793e2996e..7b043638f3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2399,7 +2399,7 @@ case OP_Compare: { /* Opcode: Jump P1 P2 P3 * * ** ** Jump to the instruction at address P1, P2, or P3 depending on whether -** in the most recent OP_Compare instruction the P1 vector was less than +** in the most recent OP_Compare instruction the P1 vector was less than, ** equal to, or greater than the P2 vector, respectively. ** ** This opcode must immediately follow an OP_Compare opcode. diff --git a/src/vdbeblob.c b/src/vdbeblob.c index a18ee05b52..32987da137 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -342,7 +342,7 @@ blob_open_out: if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); sqlite3DbFree(db, pBlob); } - sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); sqlite3DbFree(db, zErr); sqlite3ParseObjectReset(&sParse); rc = sqlite3ApiExit(db, rc); @@ -501,7 +501,7 @@ int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ ((Vdbe*)p->pStmt)->rc = SQLITE_OK; rc = blobSeekToRow(p, iRow, &zErr); if( rc!=SQLITE_OK ){ - sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr); sqlite3DbFree(db, zErr); } assert( rc!=SQLITE_SCHEMA ); diff --git a/src/vtab.c b/src/vtab.c index 3477d67ce3..ad629bb031 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -1102,7 +1102,10 @@ int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ break; } if( xMethod && pVTab->iSavepoint>iSavepoint ){ + u64 savedFlags = (db->flags & SQLITE_Defensive); + db->flags &= ~(u64)SQLITE_Defensive; rc = xMethod(pVTab->pVtab, iSavepoint); + db->flags |= savedFlags; } sqlite3VtabUnlock(pVTab); } diff --git a/src/where.c b/src/where.c index f517150e12..cb41f0f3a3 100644 --- a/src/where.c +++ b/src/where.c @@ -922,7 +922,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** WHERE clause (or the ON clause of a LEFT join) that constrain which ** rows of the target table (pSrc) that can be used. */ if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsTableConstraint(pExpr, pSrc) + && sqlite3ExprIsSingleTableConstraint(pExpr, pSrc) ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); @@ -1183,7 +1183,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( for(pTerm=pWInfo->sWC.a; pTermpExpr; if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsTableConstraint(pExpr, pItem) + && sqlite3ExprIsSingleTableConstraint(pExpr, pItem) ){ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); } @@ -5522,6 +5522,13 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ ** at most a single row. ** 4) The table must not be referenced by any part of the query apart ** from its own USING or ON clause. +** 5) The table must not have an inner-join ON or USING clause if there is +** a RIGHT JOIN anywhere in the query. Otherwise the ON/USING clause +** might move from the right side to the left side of the RIGHT JOIN. +** Note: Due to (2), this condition can only arise if the table is +** the right-most table of a subquery that was flattened into the +** main query and that subquery was the right-hand operand of an +** inner join that held an ON or USING clause. ** ** For example, given: ** @@ -5547,6 +5554,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( ){ int i; Bitmask tabUsed; + int hasRightJoin; /* Preconditions checked by the caller */ assert( pWInfo->nLevel>=2 ); @@ -5561,6 +5569,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( if( pWInfo->pOrderBy ){ tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); } + hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0; for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; SrcItem *pItem; @@ -5583,6 +5592,12 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( break; } } + if( hasRightJoin + && ExprHasProperty(pTerm->pExpr, EP_InnerON) + && pTerm->pExpr->w.iJoin==pItem->iCursor + ){ + break; /* restriction (5) */ + } } if( pTerm drop loop %c not used\n", pLoop->cId)); diff --git a/test/date.test b/test/date.test index 62233ad8f6..3e93181896 100644 --- a/test/date.test +++ b/test/date.test @@ -544,4 +544,10 @@ datetest 17.7 {datetime(38,'start of year')} {-4712-01-01 00:00:00} # datetest 18.1 {strftime('%f',1.234,'unixepoch','localtime')} {01.234} +# 2023-04 The 'subsecond' (or 'subsec') modifier alters resolutions +# to at least milliseconds. Added for release 3.42.0 . +datetest 18.2 {unixepoch('1970-01-01T00:00:00.1', 'subsec')} {0.1} +datetest 18.3 {unixepoch('1970-01-01T00:00:00.2', 'subsecond')} {0.2} +datetest 18.4 {julianday('-4713-11-24 13:40:48.864', 'subsec')} {0.07001} +datetest 18.5 {typeof(unixepoch('now', 'subsecond'))} {real} finish_test diff --git a/test/join.test b/test/join.test index 44bfb3bef2..aa526aeb29 100644 --- a/test/join.test +++ b/test/join.test @@ -1263,4 +1263,30 @@ do_execsql_test join-29.3 { SELECT * FROM t1 JOIN v2 ON false FULL OUTER JOIN t0 ON true; } {NULL NULL 1} +# 2023-05-11 https://sqlite.org/forum/forumpost/49f2c7f690 +# Verify that omit-noop-join optimization does not apply if the table +# to be omitted has an inner-join constraint and there is a RIGHT JOIN +# anywhere in the query. +# +reset_db +db null NULL +do_execsql_test join-30.1 { + CREATE TABLE t0(z INT); INSERT INTO t0 VALUES(1),(2); + CREATE TABLE t1(a INT); INSERT INTO t1 VALUES(1); + CREATE TABLE t2(b INT); INSERT INTO t2 VALUES(2); + CREATE TABLE t3(c INT, d INT); INSERT INTO t3 VALUES(3,4); + CREATE TABLE t4(e INT); INSERT INTO t4 VALUES(5); + CREATE VIEW v5(x,y) AS SELECT c, d FROM t3 LEFT JOIN t4 ON false; +} +do_execsql_test join-30.2 { + SELECT DISTINCT a, b + FROM t1 RIGHT JOIN t2 ON a=b LEFT JOIN v5 ON false + WHERE x <= y; +} {} +do_execsql_test join-30.3 { + SELECT DISTINCT a, b + FROM t0 JOIN t1 ON z=a RIGHT JOIN t2 ON a=b LEFT JOIN v5 ON false + WHERE x <= y; +} {} + finish_test diff --git a/test/json101.test b/test/json101.test index e17c8cd6a2..543e4c71e7 100644 --- a/test/json101.test +++ b/test/json101.test @@ -721,20 +721,20 @@ do_execsql_test json-10.95 { # do_execsql_test json-11.0 { /* Shallow enough to be parsed */ - SELECT json_valid(printf('%.2000c0%.2000c','[',']')); + SELECT json_valid(printf('%.1000c0%.1000c','[',']')); } {1} do_execsql_test json-11.1 { /* Too deep by one */ - SELECT json_valid(printf('%.2001c0%.2001c','[',']')); + SELECT json_valid(printf('%.1001c0%.1001c','[',']')); } {0} do_execsql_test json-11.2 { /* Shallow enough to be parsed { */ - SELECT json_valid(replace(printf('%.2000c0%.2000c','[','}'),'[','{"a":')); + SELECT json_valid(replace(printf('%.1000c0%.1000c','[','}'),'[','{"a":')); /* } */ } {1} do_execsql_test json-11.3 { /* Too deep by one { */ - SELECT json_valid(replace(printf('%.2001c0%.2001c','[','}'),'[','{"a":')); + SELECT json_valid(replace(printf('%.1001c0%.1001c','[','}'),'[','{"a":')); /* } */ } {0} diff --git a/test/json502.test b/test/json502.test index b5e570320d..595bf63318 100644 --- a/test/json502.test +++ b/test/json502.test @@ -16,10 +16,25 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix json502 +ifcapable vtab { + do_execsql_test 1.1 { CREATE TABLE t1(x JSON); INSERT INTO t1(x) VALUES('{a:{b:{c:"hello",},},}'); SELECT fullkey FROM t1, json_tree(x); } {{$} {$.a} {$.a.b} {$.a.b.c}} +} + +do_execsql_test 2.1 { + SELECT json_error_position('{a:null,{"h":[1,[1,2,3]],"j":"abc"}:true}'); +} 9 +do_catchsql_test 2.2 { + SELECT json('{a:null,{"h":[1,[1,2,3]],"j":"abc"}:true}'); +} {1 {malformed JSON}} +do_catchsql_test 2.3 { + SELECT '{a:null,{"h":[1,[1,2,3]],"j":"abc"}:true}'->'$h[#-1]'; +} {1 {malformed JSON}} + + finish_test diff --git a/test/pager2.test b/test/pager2.test index 1d78b30f5a..ef05cc76a2 100644 --- a/test/pager2.test +++ b/test/pager2.test @@ -147,24 +147,25 @@ do_test pager2-2.2 { file size test.db } {3072} -#------------------------------------------------------------------------- -# Test that shared in-memory databases seem to work. -# -db close -do_test pager2-3.1 { - forcedelete test.db - sqlite3_shutdown - sqlite3_config_uri 1 - - sqlite3 db1 {file:test.db?mode=memory&cache=shared} - sqlite3 db2 {file:test.db?mode=memory&cache=shared} - sqlite3 db3 test.db - - db1 eval { CREATE TABLE t1(a, b) } - db2 eval { INSERT INTO t1 VALUES(1, 2) } - list [catch { db3 eval { INSERT INTO t1 VALUES(3, 4) } } msg] $msg -} {1 {no such table: t1}} - -db1 close +ifcapable shared_cache { + #------------------------------------------------------------------------- + # Test that shared in-memory databases seem to work. + # + db close + do_test pager2-3.1 { + forcedelete test.db + sqlite3_shutdown + sqlite3_config_uri 1 + + sqlite3 db1 {file:test.db?mode=memory&cache=shared} + sqlite3 db2 {file:test.db?mode=memory&cache=shared} + sqlite3 db3 test.db + + db1 eval { CREATE TABLE t1(a, b) } + db2 eval { INSERT INTO t1 VALUES(1, 2) } + list [catch { db3 eval { INSERT INTO t1 VALUES(3, 4) } } msg] $msg + } {1 {no such table: t1}} + db1 close +} finish_test diff --git a/test/printf.test b/test/printf.test index e4beb12dd0..6d4ad71d28 100644 --- a/test/printf.test +++ b/test/printf.test @@ -16,7 +16,6 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl - do_test printf-1.1.1 { sqlite3_mprintf_int {abc: %d %x %o :xyz}\ 1 1 1 @@ -3824,4 +3823,14 @@ do_execsql_test printf-17.11 { SELECT format('%.30f',1.0000000000000000076e-50); } 0.000000000000000000000000000000 +#------------------------------------------------------------------------- +# dbsqlfuzz ad651aad4bb2100f3a724129a555d8d773366d46 +# +db close +sqlite3 db test.db +sqlite3_db_config_lookaside db 0 0 0 +do_execsql_test printf-18.1 { + SELECT length( format('%,.249f', -5.0e-300) ); +} {252} + finish_test diff --git a/test/pushdown.test b/test/pushdown.test index b9ee48c4ac..2b5b1cb994 100644 --- a/test/pushdown.test +++ b/test/pushdown.test @@ -184,4 +184,27 @@ do_eqp_test 3.8 { # The query should be converted into: # SELECT (SELECT count(*) FROM t1)+(SELECT count(*) FROM t2) +# 2023-05-09 https://sqlite.org/forum/forumpost/a7d4be7fb6 +# Restriction (9) on the push-down optimization. +# +reset_db +db null - +do_execsql_test 4.1 { + CREATE TABLE t1(a INT); + CREATE TABLE t2(b INT); + CREATE TABLE t3(c INT); + INSERT INTO t3(c) VALUES(3); + CREATE TABLE t4(d INT); + CREATE TABLE t5(e INT); + INSERT INTO t5(e) VALUES(5); + CREATE VIEW v6(f,g) AS SELECT d, e FROM t4 RIGHT JOIN t5 ON true; + SELECT * FROM t1 JOIN t2 ON false RIGHT JOIN t3 ON true CROSS JOIN v6; +} {- - 3 - 5} +do_execsql_test 4.2 { + SELECT * FROM v6 JOIN t5 ON false RIGHT JOIN t3 ON true; +} {- - - 3} +do_execsql_test 4.3 { + SELECT * FROM t1 JOIN t2 ON false JOIN v6 ON true RIGHT JOIN t3 ON true; +} {- - - - 3} + finish_test diff --git a/test/thread3.test b/test/thread3.test new file mode 100644 index 0000000000..25699b7655 --- /dev/null +++ b/test/thread3.test @@ -0,0 +1,78 @@ +# 2023 May 13 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] + +source $testdir/tester.tcl +source $testdir/lock_common.tcl +if {[run_thread_tests]==0} { finish_test ; return } + +set testprefix thread3 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + PRAGMA journal_mode = DELETE; +} {delete} + +proc wait_for_var {varname} { + if {0==[uplevel [list info exists $varname]]} { + uplevel [list vwait $varname] + } + uplevel [list set $varname] +} + +set nAttempt 250 + +do_test 1.1 { + for {set i 0} {$i < $nAttempt} {incr i} { + unset -nocomplain X + unset -nocomplain Y + + sqlthread spawn X { + sqlite3 dbI test.db + dbI timeout 100 + set rc 1 + set nBusy 0 + while {$rc} { + set rc [catch { + dbI eval { INSERT INTO t1 VALUES(203, 'message') RETURNING a; } + } msg] + if {$rc} { incr nBusy } + } + dbI close + set nBusy + } + + sqlthread spawn Y { + sqlite3 dbR test.db + catch { + dbR eval { SELECT count(*) FROM t1 } + } msg + dbR close + set msg + } + + wait_for_var X + wait_for_var Y + incr nTotalBusy $X + } + + execsql { SELECT count(*) FROM t1 } + set {} {} +} {} + +do_execsql_test "1.Total BUSY errors: $nTotalBusy .2" { + SELECT count(*) FROM t1; +} $nAttempt + +finish_test + diff --git a/test/walpersist.test b/test/walpersist.test index 692728dda4..73e6de13d4 100644 --- a/test/walpersist.test +++ b/test/walpersist.test @@ -121,6 +121,22 @@ do_test walpersist-3.4 { sqlite3 db test.db execsql { PRAGMA integrity_check } } {ok} - + +# 2023-05-07 https://sqlite.org/forum/forumpost/8130545bc6 +# +reset_db +do_test 4.1 { + db eval { + PRAGMA journal_mode=WAL; + CREATE TABLE t1(x); + } + file_control_persist_wal db 1 + db eval { + PRAGMA journal_mode=TRUNCATE; + PRAGMA journal_mode=MEMORY; + PRAGMA journal_mode=WAL; + PRAGMA journal_mode=PERSIST; + } +} {truncate memory wal persist} finish_test diff --git a/tool/omittest.tcl b/tool/omittest.tcl index b54f2984d4..8862c685f8 100644 --- a/tool/omittest.tcl +++ b/tool/omittest.tcl @@ -192,9 +192,9 @@ proc main {argv} { SQLITE_OMIT_AUTOMATIC_INDEX \ SQLITE_OMIT_AUTORESET \ SQLITE_OMIT_AUTOVACUUM \ + SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS \ SQLITE_OMIT_BETWEEN_OPTIMIZATION \ SQLITE_OMIT_BLOB_LITERAL \ - SQLITE_OMIT_BTREECOUNT \ SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA \ SQLITE_OMIT_CAST \ SQLITE_OMIT_CHECK \ @@ -225,7 +225,7 @@ proc main {argv} { SQLITE_OMIT_LOOKASIDE \ SQLITE_OMIT_MEMORYDB \ SQLITE_OMIT_OR_OPTIMIZATION \ - SQLITE_OMIT_PAGER_PRAGMAS \ + SQLITE_OMIT_PAGER_PRAGMAS \ SQLITE_OMIT_PARSER_TRACE \ SQLITE_OMIT_POPEN \ SQLITE_OMIT_PRAGMA \ @@ -244,8 +244,9 @@ proc main {argv} { SQLITE_OMIT_TRACE \ SQLITE_OMIT_TRIGGER \ SQLITE_OMIT_TRUNCATE_OPTIMIZATION \ + SQLITE_OMIT_TWOSIZE_LOOKASIDE \ SQLITE_OMIT_UPSERT \ - SQLITE_OMIT_UTF16 \ + SQLITE_OMIT_UTF \ SQLITE_OMIT_VACUUM \ SQLITE_OMIT_VIEW \ SQLITE_OMIT_VIRTUALTABLE \ @@ -258,24 +259,69 @@ proc main {argv} { set ::ENABLE_SYMBOLS [list \ SQLITE_ALLOW_ROWID_IN_VIEW \ SQLITE_DISABLE_DIRSYNC \ + SQLITE_DISABLE_FTS \ + SQLITE_DISABLE_INTRINSIC \ SQLITE_DISABLE_LFS \ + SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS \ + SQLITE_DISABLE_SKIPAHEAD_DISTINCT \ + SQLITE_ENABLE_API_ARMOR \ SQLITE_ENABLE_ATOMIC_WRITE \ + SQLITE_ENABLE_BATCH_ATOMIC_WRITE \ + SQLITE_ENABLE_BYTECODE_VTAB \ + SQLITE_ENABLE_CEROD \ SQLITE_ENABLE_COLUMN_METADATA \ + SQLITE_ENABLE_COLUMN_USED_MASK \ + SQLITE_ENABLE_COMMENTS \ + SQLITE_ENABLE_CORRUPT_PGNO \ + SQLITE_ENABLE_COSTMULT \ + SQLITE_ENABLE_CURSOR_HINTS \ + SQLITE_ENABLE_DBPAGE_VTAB \ + SQLITE_ENABLE_DBSTAT_VTAB \ SQLITE_ENABLE_EXPENSIVE_ASSERT \ - SQLITE_ENABLE_FTS3 \ - SQLITE_ENABLE_FTS3_PARENTHESIS \ - SQLITE_ENABLE_FTS4 \ + SQLITE_ENABLE_EXPLAIN_COMMENTS \ + SQLITE_ENABLE_FTS \ + SQLITE_ENABLE_GEOPOLY \ + SQLITE_ENABLE_HIDDEN_COLUMNS \ + SQLITE_ENABLE_ICU \ + SQLITE_ENABLE_ICU_COLLATIONS \ + SQLITE_ENABLE_INTERNAL_FUNCTIONS \ SQLITE_ENABLE_IOTRACE \ SQLITE_ENABLE_LOAD_EXTENSION \ SQLITE_ENABLE_LOCKING_STYLE \ + SQLITE_ENABLE_MATH_FUNCTIONS \ SQLITE_ENABLE_MEMORY_MANAGEMENT \ - SQLITE_ENABLE_MEMSYS3 \ - SQLITE_ENABLE_MEMSYS5 \ + SQLITE_ENABLE_MEMSYS \ + SQLITE_ENABLE_MODULE_COMMENTS \ + SQLITE_ENABLE_MULTIPLEX \ + SQLITE_ENABLE_MULTITHREADED_CHECKS \ + SQLITE_ENABLE_NORMALIZE \ + SQLITE_ENABLE_NULL_TRIM \ + SQLITE_ENABLE_OFFSET_SQL_FUNC \ SQLITE_ENABLE_OVERSIZE_CELL_CHECK \ + SQLITE_ENABLE_PREUPDATE_HOOK \ + SQLITE_ENABLE_QPSG \ + SQLITE_ENABLE_RBU \ SQLITE_ENABLE_RTREE \ - SQLITE_ENABLE_STAT3 \ + SQLITE_ENABLE_SELECTTRACE \ + SQLITE_ENABLE_SESSION \ + SQLITE_ENABLE_SETLK_TIMEOUT \ + SQLITE_ENABLE_SNAPSHOT \ + SQLITE_ENABLE_SORTER_MMAP\ + SQLITE_ENABLE_SORTER_REFERENCE \ + SQLITE_ENABLE_SORTER_REFERENCES \ + SQLITE_ENABLE_SQLLOG\ + SQLITE_ENABLE_STAT \ + SQLITE_ENABLE_STMT_SCANSTATUS \ + SQLITE_ENABLE_STMTVTAB \ + SQLITE_ENABLE_TREETRACE \ + SQLITE_ENABLE_UNKNOWN_FUNCTION \ + SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION \ SQLITE_ENABLE_UNLOCK_NOTIFY \ SQLITE_ENABLE_UPDATE_DELETE_LIMIT \ + SQLITE_ENABLE_URI_00_ERROR \ + SQLITE_ENABLE_VFSTRACE \ + SQLITE_ENABLE_WHERETRACE \ + SQLITE_ENABLE_ZIPVFS \ ] # Process any command line options. diff --git a/tool/split-sqlite3c.tcl b/tool/split-sqlite3c.tcl index 9751e7de9c..0308431dab 100644 --- a/tool/split-sqlite3c.tcl +++ b/tool/split-sqlite3c.tcl @@ -48,7 +48,14 @@ set filecnt 0 proc write_one_file {content} { global filecnt incr filecnt - set out [open sqlite3-$filecnt.c w] + set label $filecnt + if {$filecnt>9} { + set label [string index ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop \ + [expr {$filecnt-10}]] + } else { + set label $filecnt + } + set out [open sqlite3-$label.c w] fconfigure $out -translation lf puts -nonewline $out $content close $out