From 554a19dbeef3c45d5f52c540a79920403c54170a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 12 Aug 2019 18:26:46 +0000 Subject: [PATCH 01/15] Make sure the btree cursor overflow cache is cleared when overwriting a cell in sqlite3BtreeInsert(). Ticket [3cf9bb227e9a5d32] FossilOrigin-Name: 7dae7b969ed314605a3a2da2cfdce4d81152740f5d3bfbc2a6e311b13ee325a7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 ++ test/insert.test | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 89ec0e6944..138066f7d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sthe\s".testctrl\sprng_seed"\scommand\sin\sthe\sCLI,\sif\sthe\sargument\sis\s"random"\nthen\sselect\sa\srandom\sinteger\sseed\sand\sprint\sthe\sseed\svalue\son\sstdout. -D 2019-08-12T16:25:11.731 +C Make\ssure\sthe\sbtree\scursor\soverflow\scache\sis\scleared\swhen\soverwriting\na\scell\sin\ssqlite3BtreeInsert().\s\sTicket\s[3cf9bb227e9a5d32] +D 2019-08-12T18:26:46.324 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -464,7 +464,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 781e4594098dca97db672e52ed17c7f063b5b65db144c0c1bf1e9818e7be1ad4 +F src/btree.c 6061323b98cc794a1e3ad6907f683f1ad2b8c48d7c7d486072b21f18efe73761 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556 @@ -1056,7 +1056,7 @@ F test/indexexpr1.test 0f293369ed6f56764cfc3db05685d45469d9e685ba87e3698527049ba F test/indexexpr2.test d319e7d1b1043403f39a20c892d512e02b5549c6004806b977030f2430c60208 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 -F test/insert.test 9773604f8e1a2595f51488a5643c359d8a11dc55a11cb185910d93387d378458 +F test/insert.test 72004f6a900a25bd3f1ce9a72e73d02749644666a8ce6d6d2dba061137e5aa63 F test/insert2.test 4d14b8f1b810a41995f6286b64a6943215d52208 F test/insert3.test 1b7db95a03ad9c5013fdf7d6722b6cd66ee55e30 F test/insert4.test 7802ada6ba8738661b9f6c0e26858d3375b40cc7180289fd350644cd7a08fec9 @@ -1836,7 +1836,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 48d9b48ab4ace234eb1a055cf33cb533a1c3aa82d0a6e086d96226bd9474ceca -R 5a141faa1c39cc955778f126f1aabd0f +P 636ca4472c9f41eb3989f28854d4968867837399a2092f389d1b814d98cccbae +R 35de1073023e10ac023f683a008bdac4 U drh -Z 779c2cf81842090ecdd5432af318ddb5 +Z 4e3a468c24aea8e9967dfc838bb1156b diff --git a/manifest.uuid b/manifest.uuid index 74af8f947f..187033b4b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -636ca4472c9f41eb3989f28854d4968867837399a2092f389d1b814d98cccbae \ No newline at end of file +7dae7b969ed314605a3a2da2cfdce4d81152740f5d3bfbc2a6e311b13ee325a7 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 30cd0d128c..932ce04359 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8716,6 +8716,8 @@ int sqlite3BtreeInsert( memcpy(newCell, oldCell, 4); } rc = clearCell(pPage, oldCell, &info); + testcase( pCur->curFlags & BTCF_ValidOvfl ); + invalidateOverflowCache(pCur); if( info.nSize==szNew && info.nLocal==info.nPayload && (!ISAUTOVACUUM || szNewminLocal) ){ diff --git a/test/insert.test b/test/insert.test index 01c7016d84..397a0e6ff9 100644 --- a/test/insert.test +++ b/test/insert.test @@ -460,4 +460,20 @@ do_execsql_test insert-14.1 { integrity_check insert-99.0 +# 2019-08-12. +# +do_execsql_test insert-15.1 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT); + CREATE INDEX i1 ON t1(b); + CREATE TABLE t2(a, b); + INSERT INTO t2 VALUES(4, randomblob(31000)); + INSERT INTO t2 VALUES(4, randomblob(32000)); + INSERT INTO t2 VALUES(4, randomblob(33000)); + REPLACE INTO t1 SELECT a, b FROM t2; + SELECT a, length(b) FROM t1; +} {4 33000} + + finish_test From b8a8d523cbfa1371e35a4e5d1fc4727128e74ead Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Aug 2019 15:11:25 +0000 Subject: [PATCH 02/15] Fix a problem with RBU function sqlite3rbu_bp_progress() when used during an RBU vacuum. FossilOrigin-Name: 8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe --- ext/rbu/rbuprogress.test | 32 ++++++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 9 +++++---- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/ext/rbu/rbuprogress.test b/ext/rbu/rbuprogress.test index db479e32e5..bf37b4e505 100644 --- a/ext/rbu/rbuprogress.test +++ b/ext/rbu/rbuprogress.test @@ -414,5 +414,37 @@ foreach {bReopen} { 0 1 } { } } +#------------------------------------------------------------------------- +# Test that sqlite3_bp_progress() works with an RBU vacuum if there +# is an rbu_count table in the db being vacuumed. +# +reset_db +do_execsql_test 6.0 { + CREATE TABLE t1(a, b, c); + CREATE INDEX i1 ON t1(a); + CREATE INDEX i2 ON t1(b); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO t1 SELECT i, i, i FROM s; + CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; + INSERT INTO rbu_count VALUES('t1', (SELECT count(*) FROM t1)); + INSERT INTO rbu_count VALUES('rbu_count', 2); +} + +forcedelete state.db +do_test 6.1 { + set maxA 0 + set maxB 0 + sqlite3rbu_vacuum rbu test.db state.db + while {[rbu step]=="SQLITE_OK"} { + foreach {a b} [rbu bp_progress] { + if {$a > $maxA} { set maxA $a } + if {$b > $maxB} { set maxB $b } + } + } + list [rbu close] $maxA $maxB +} {SQLITE_DONE 10000 10000} + finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 7409618499..5c2ae95453 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -944,8 +944,8 @@ static void rbuTargetNameFunc( zIn = (const char*)sqlite3_value_text(argv[0]); if( zIn ){ if( rbuIsVacuum(p) ){ - assert( argc==2 ); - if( 0==sqlite3_value_int(argv[1]) ){ + assert( argc==2 || argc==1 ); + if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); } }else{ @@ -3860,10 +3860,11 @@ static void rbuIndexCntFunc( sqlite3_stmt *pStmt = 0; char *zErrmsg = 0; int rc; + sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); - rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, + rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, sqlite3_mprintf("SELECT count(*) FROM sqlite_master " "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) ); @@ -3878,7 +3879,7 @@ static void rbuIndexCntFunc( if( rc==SQLITE_OK ){ sqlite3_result_int(pCtx, nIndex); }else{ - sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1); + sqlite3_result_error(pCtx, sqlite3_errmsg(db), -1); } } diff --git a/manifest b/manifest index 138066f7d7..349b4244e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sbtree\scursor\soverflow\scache\sis\scleared\swhen\soverwriting\na\scell\sin\ssqlite3BtreeInsert().\s\sTicket\s[3cf9bb227e9a5d32] -D 2019-08-12T18:26:46.324 +C Fix\sa\sproblem\swith\sRBU\sfunction\ssqlite3rbu_bp_progress()\swhen\sused\sduring\san\sRBU\svacuum. +D 2019-08-13T15:11:25.734 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -354,7 +354,7 @@ F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d F ext/rbu/rbumisc.test 329986cf5dd51890c4eb906c2f960ebb773a79a64bed90f506b7c417825b37eb F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9 F ext/rbu/rbupartial.test f25df014b8dbe3c5345851fba6e66f79ab237f57dc201b2d5f0dbae658ae5a4c -F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9 +F ext/rbu/rbuprogress.test 857cf1f8166c83ef977edb9ef4fc42d80f71fbd798652b46ae2f3a7031870f8d F ext/rbu/rburesume.test dbdc4ca504e9c76375a69e5f0d91205db967dcc509a5166ca80231f8fda49eb1 F ext/rbu/rbusave.test f4190a1a86fccf84f723af5c93813365ae33feda35845ba107b59683d1cdd926 F ext/rbu/rbusplit.test b37e7b40b38760881dc9c854bd40b4744c6b6cd74990754eca3bda0f407051e8 @@ -363,7 +363,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 -F ext/rbu/sqlite3rbu.c 4261ba8d5dc1c4aa1c9cf4c8c60f8ba4df3780d1516720771d2bbc292892e11b +F ext/rbu/sqlite3rbu.c f3a3e09f575157052813be667d6ab3b54f47fb02e6e1c9f767ad7bb8f1fb90b3 F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -1836,7 +1836,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 636ca4472c9f41eb3989f28854d4968867837399a2092f389d1b814d98cccbae -R 35de1073023e10ac023f683a008bdac4 -U drh -Z 4e3a468c24aea8e9967dfc838bb1156b +P 7dae7b969ed314605a3a2da2cfdce4d81152740f5d3bfbc2a6e311b13ee325a7 +R 860238736fdd0447f200637ad8b8114e +U dan +Z 5966eddfdd5804ca0c3aea69442d9a4f diff --git a/manifest.uuid b/manifest.uuid index 187033b4b5..da1d8fd8e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7dae7b969ed314605a3a2da2cfdce4d81152740f5d3bfbc2a6e311b13ee325a7 \ No newline at end of file +8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe \ No newline at end of file From 3c1970fceeecef6da620c37cdd0755f31af646a7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Aug 2019 17:27:43 +0000 Subject: [PATCH 03/15] Update some corruption test cases to take [724f4df9c] into account. FossilOrigin-Name: 927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 --- ext/rtree/rtreefuzz001.test | 2 ++ manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts3corrupt4.test | 13 ++++++++++++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ext/rtree/rtreefuzz001.test b/ext/rtree/rtreefuzz001.test index f4a91264c7..db9df205af 100644 --- a/ext/rtree/rtreefuzz001.test +++ b/ext/rtree/rtreefuzz001.test @@ -465,6 +465,7 @@ do_test rtreefuzz001-100 { | end c1b.db }] catchsql { + PRAGMA writable_schema = 1; SELECT rtreecheck('t1'); } } {1 {SQL logic error}} @@ -1040,6 +1041,7 @@ do_test rtreefuzz001-500 { | 2880: ff ff ff 06 00 00 00 0c 00 00 00 01 00 00 00 0b ................ | 2896: 00 00 00 00 00 00 00 02 40 00 00 00 00 00 00 00 ........@....... | end crash-2e81f5dce5cbd4.db}] + execsql { PRAGMA writable_schema = 1;} catchsql {UPDATE t1 SET ex= ex ISNULL} } {1 {database disk image is malformed}} diff --git a/manifest b/manifest index 349b4244e6..6acb6a9831 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sRBU\sfunction\ssqlite3rbu_bp_progress()\swhen\sused\sduring\san\sRBU\svacuum. -D 2019-08-13T15:11:25.734 +C Update\ssome\scorruption\stest\scases\sto\stake\s[724f4df9c]\sinto\saccount. +D 2019-08-13T17:27:43.409 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -401,7 +401,7 @@ F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b5879 F ext/rtree/rtreecheck.test d67d5b3e9e45bfa8cd90734e8e9302144ac415b8e9176c6f02d4f92892ee8a35 F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d -F ext/rtree/rtreefuzz001.test f9fecd174fc6475174d876f78f77b538122c1db296a96dca4615918953a892be +F ext/rtree/rtreefuzz001.test eef1ed593bb15886cd5d5367a2f2492f81e315848896cdf7afb6e21454978827 F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff @@ -935,7 +935,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test 9c21ef823a72b0b4a09428d78e63a44c961c19b0821682f4e99cdfe147ac105b +F test/fts3corrupt4.test d5389e14950e57333bfc972f262c90b5ba0e864a958df9e437e3aacd3a5570a7 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338 F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f @@ -1836,7 +1836,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 7dae7b969ed314605a3a2da2cfdce4d81152740f5d3bfbc2a6e311b13ee325a7 -R 860238736fdd0447f200637ad8b8114e +P 8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe +R 7c1844eb7914622ca55e2a5e5ecac9a6 U dan -Z 5966eddfdd5804ca0c3aea69442d9a4f +Z 44af29e1f24cdb5aeb5d48277738f602 diff --git a/manifest.uuid b/manifest.uuid index da1d8fd8e3..dcd9c2344a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe \ No newline at end of file +927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 \ No newline at end of file diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index fdcfa969f2..d693702bf5 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -2147,6 +2147,7 @@ do_test 14.0 { }]} {} do_execsql_test 14.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; } @@ -3049,6 +3050,7 @@ do_test 19.0 { }]} {} do_catchsql_test 19.1 { + PRAGMA writable_schema = 1; SELECT rowid,a,c,snippet(t1,85101090932165,-1,10) FROM t1 WHERE a MATCH 'rtree'; } {1 {database disk image is malformed}} @@ -3250,6 +3252,7 @@ do_test 20.0 { }]} {} do_execsql_test 20.1 { + PRAGMA writable_schema = 1; BEGIN; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; @@ -3472,8 +3475,8 @@ do_test 21.0 { | end crash-18cc014e42e828.db }]} {} -breakpoint do_catchsql_test 21.1 { + PRAGMA writable_schema = 1; SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'R*'; } {1 {database disk image is malformed}} @@ -3694,6 +3697,7 @@ do_test 22.0 { }]} {} do_catchsql_test 22.1 { + PRAGMA writable_schema = 1; SELECT snippet(t1,'', '', '--',-1,01)==0 FROM t1 WHERE a MATCH 'rtree OR json1rtree OR json1'; } {0 {0 0 0 0 0 0 0}} @@ -3913,6 +3917,7 @@ do_test 23.0 { }]} {} do_catchsql_test 23.1 { + PRAGMA writable_schema = 1; SELECT 'FyzLy'FROM t1 WHERE t1 MATCH 'j'; } {1 {database disk image is malformed}} @@ -4131,6 +4136,7 @@ do_test 24.0 { }]} {} do_catchsql_test 24.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT '4hE'+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} @@ -4374,6 +4380,7 @@ do_test 25.0 { }]} {} do_catchsql_test 25.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE x<599237) INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ; } {0 {}} @@ -4608,6 +4615,7 @@ do_test 26.0 { }]} {} do_execsql_test 26.1 { + PRAGMA writable_schema = 1; SELECT count(*) FROM ( SELECT t1, (t1) FROM t1 WHERE b MATCH 'x' ) @@ -4826,6 +4834,7 @@ do_test 27.0 { }]} {} do_catchsql_test 27.2 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x GLOB 2.16770 FROM x) INSERT INTO t1(a) SELECT randomblob(3000) FROM t2 ; } {0 {}} @@ -5058,6 +5067,7 @@ do_test 28.0 { }]} {} do_catchsql_test 28.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} @@ -5312,6 +5322,7 @@ do_test 29.0 { }]} {} do_catchsql_test 29.1 { + PRAGMA writable_schema = 1; INSERT INTO t1(a) SELECT X'819192E578DE3F'; UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*'; INSERT INTO t1(b) VALUES(x'78'); From 7c2321fdf38986cbf72e656aad204c2b10f5067d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Aug 2019 17:56:56 +0000 Subject: [PATCH 04/15] Update test cases so that they work with ICU enabled. FossilOrigin-Name: 408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 --- manifest | 14 ++++++------ manifest.uuid | 2 +- test/vtab1.test | 40 +++++++++++++++++---------------- test/vtabH.test | 60 +++++++++++++++++++++++++------------------------ 4 files changed, 60 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index 6acb6a9831..494df1beb8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\ssome\scorruption\stest\scases\sto\stake\s[724f4df9c]\sinto\saccount. -D 2019-08-13T17:27:43.409 +C Update\stest\scases\sso\sthat\sthey\swork\swith\sICU\senabled. +D 2019-08-13T17:56:56.995 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1611,7 +1611,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test c1e64ff5a860fdbb7b52add0996af2ee1af563ddf2e86b964d15d04d81a001be -F test/vtab1.test fa6baded08fdadd6f416a9c54956c049ae327b9bdd05d25bf8163f65e65e849c +F test/vtab1.test efb4c4a45146193d6d55fb85f7162febd6423f29c72ede09bb96383f49e3abc1 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 @@ -1626,7 +1626,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b45f F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test e65540eed0f7434cdf0b160374570b51f3e3179548f0fa5e99b1d33f8dcdf9a0 +F test/vtabH.test 2efb5a24b0bb50796b21eca23032cfb77abfa4b0c03938e38ce5897abac404ca F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783 @@ -1836,7 +1836,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 8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe -R 7c1844eb7914622ca55e2a5e5ecac9a6 +P 927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 +R c967e09641613ccf8efee454c9ec6fe8 U dan -Z 44af29e1f24cdb5aeb5d48277738f602 +Z 9b0309a4ce7be165e70467c33152a3d5 diff --git a/manifest.uuid b/manifest.uuid index dcd9c2344a..8829389704 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 \ No newline at end of file +408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 \ No newline at end of file diff --git a/test/vtab1.test b/test/vtab1.test index fd7c1fd41d..0a45c4e2d9 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1311,25 +1311,27 @@ do_execsql_test 18.1.0 { CREATE VIRTUAL TABLE e6 USING echo(t6); } -foreach {tn sql res filter} { - 1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James} - - 1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9} - - 1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8J%} - - 1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8j%} - - 1.5 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%} -} { - set echo_module {} - do_execsql_test 18.$tn.1 $sql $res - do_test 18.$tn.2 { lrange $::echo_module 2 end } $filter +ifcapable !icu { + foreach {tn sql res filter} { + 1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James} + + 1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9} + + 1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8J%} + + 1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8j%} + + 1.5 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%} + } { + set echo_module {} + do_execsql_test 18.$tn.1 $sql $res + do_test 18.$tn.2 { lrange $::echo_module 2 end } $filter + } } do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON } diff --git a/test/vtabH.test b/test/vtabH.test index 78b156cb63..f1a0466554 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -30,36 +30,38 @@ do_execsql_test 1.0 { CREATE VIRTUAL TABLE e6 USING echo(t6); } -foreach {tn sql expect} { - 1 "SELECT * FROM e6 WHERE b LIKE '8abc'" { - xBestIndex - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} - xFilter - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} - 8ABC 8abd 8abc +ifcapable !icu { + foreach {tn sql expect} { + 1 "SELECT * FROM e6 WHERE b LIKE '8abc'" { + xBestIndex + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} + xFilter + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} + 8ABC 8abd 8abc + } + + 2 "SELECT * FROM e6 WHERE b GLOB '8abc'" { + xBestIndex + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} + xFilter + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} + 8abc 8abd 8abc + } + 3 "SELECT * FROM e6 WHERE b LIKE '8e/'" { + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} + xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/ + } + 4 "SELECT * FROM e6 WHERE b GLOB '8e/'" { + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} + xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/ + } + } { + do_test 1.$tn { + set echo_module {} + execsql $sql + set ::echo_module + } [list {*}$expect] } - - 2 "SELECT * FROM e6 WHERE b GLOB '8abc'" { - xBestIndex - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} - xFilter - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} - 8abc 8abd 8abc - } - 3 "SELECT * FROM e6 WHERE b LIKE '8e/'" { - xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} - xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/ - } - 4 "SELECT * FROM e6 WHERE b GLOB '8e/'" { - xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} - xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/ - } -} { - do_test 1.$tn { - set echo_module {} - execsql $sql - set ::echo_module - } [list {*}$expect] } From 87ae34ba1ab96e0e6811c0c49324d562bbb9e6a0 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 13 Aug 2019 20:34:35 +0000 Subject: [PATCH 05/15] Add some static to the 'regexp' extension. FossilOrigin-Name: a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa --- ext/misc/regexp.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index bd82aa5d10..3359109ab3 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -610,7 +610,7 @@ static const char *re_subcompile_string(ReCompiled *p){ ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ -void re_free(ReCompiled *pRe){ +static void re_free(ReCompiled *pRe){ if( pRe ){ sqlite3_free(pRe->aOp); sqlite3_free(pRe->aArg); @@ -624,7 +624,7 @@ void re_free(ReCompiled *pRe){ ** compiled regular expression in *ppRe. Return NULL on success or an ** error message if something goes wrong. */ -const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ +static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ ReCompiled *pRe; const char *zErr; int i, j; diff --git a/manifest b/manifest index 494df1beb8..4183e3a60b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\stest\scases\sso\sthat\sthey\swork\swith\sICU\senabled. -D 2019-08-13T17:56:56.995 +C Add\ssome\sstatic\sto\sthe\s'regexp'\sextension. +D 2019-08-13T20:34:35.045 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -302,7 +302,7 @@ F ext/misc/nextchar.c 279f80fe8ef5ba413242e2704e246503ac601f005eefb180d19e6c9203 F ext/misc/normalize.c b4290464f542bae7a97b43f15bd197949b833ffd668b7c313631bd5d4610212c F ext/misc/percentile.c 148dd07286b16e50f232bb638a47850085ad37d51f270429905bd865e595d1ca F ext/misc/prefixes.c 7be86d17525cfae6ed462fc3c519efc44488ac329890f77491c8f82871f57e17 -F ext/misc/regexp.c 79345bf03496155a640ee0300d3307296761cebb5e115b4e342cc2fb5861ec10 +F ext/misc/regexp.c 653b6ab5e89bcb5d45f9ebe0747d7f8f3f5706cac963fcbc9a3ddbe5fdc1efa2 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77 F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad @@ -1836,7 +1836,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 927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 -R c967e09641613ccf8efee454c9ec6fe8 -U dan -Z 9b0309a4ce7be165e70467c33152a3d5 +P 408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 +R e1eff49797b82e19658f2ee082875e36 +U mistachkin +Z ca11739ed6199651720067a09b5d23b0 diff --git a/manifest.uuid b/manifest.uuid index 8829389704..4123f2650e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 \ No newline at end of file +a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa \ No newline at end of file From 908e7c43a7386594926bdfce4029884cd20ea012 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Aug 2019 15:17:21 +0000 Subject: [PATCH 06/15] Always check for reads past the end of the file on the in-memory journal driver. This used to be an assert(). FossilOrigin-Name: 4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/memjournal.c | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 4183e3a60b..d3d9df741e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\sstatic\sto\sthe\s'regexp'\sextension. -D 2019-08-13T20:34:35.045 +C Always\scheck\sfor\sreads\spast\sthe\send\sof\sthe\sfile\son\sthe\sin-memory\sjournal\ndriver.\s\sThis\sused\sto\sbe\san\sassert(). +D 2019-08-14T15:17:21.194 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db -F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661 +F src/memjournal.c 7561c01c90958f3ba9bc6cb2d857123d932bdfa5539ea34427a0957b2e35154d F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 @@ -1836,7 +1836,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 408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 -R e1eff49797b82e19658f2ee082875e36 -U mistachkin -Z ca11739ed6199651720067a09b5d23b0 +P a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa +R ed8fa0e6bed90bb78f3894955acd52ae +U drh +Z 721554492d795644318a412d01d91bde diff --git a/manifest.uuid b/manifest.uuid index 4123f2650e..9d7ba8cea8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa \ No newline at end of file +4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c index 3b0e7a6728..0a14e847a2 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -96,14 +96,9 @@ static int memjrnlRead( int iChunkOffset; FileChunk *pChunk; -#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ - || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) if( (iAmt+iOfst)>p->endpoint.iOffset ){ return SQLITE_IOERR_SHORT_READ; } -#endif - - assert( (iAmt+iOfst)<=p->endpoint.iOffset ); assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ sqlite3_int64 iOff = 0; From b9fc45534dec6b6a5e8047285d8d8527ac963bdb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 00:04:44 +0000 Subject: [PATCH 07/15] Early detection out-of-bounds page numbers on the direct-overflow-read optimization gives consistent error messages regardless of whether or not the optimization is enabled. FossilOrigin-Name: b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d3d9df741e..5c813276b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\scheck\sfor\sreads\spast\sthe\send\sof\sthe\sfile\son\sthe\sin-memory\sjournal\ndriver.\s\sThis\sused\sto\sbe\san\sassert(). -D 2019-08-14T15:17:21.194 +C Early\sdetection\sout-of-bounds\spage\snumbers\son\sthe\sdirect-overflow-read\noptimization\sgives\sconsistent\serror\smessages\sregardless\sof\swhether\sor\snot\nthe\soptimization\sis\senabled. +D 2019-08-15T00:04:44.923 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -464,7 +464,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 6061323b98cc794a1e3ad6907f683f1ad2b8c48d7c7d486072b21f18efe73761 +F src/btree.c a6b6f4730862a4c3b92c903ecebac309626788ac8a977394198d69cd613fbf2b F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556 @@ -1836,7 +1836,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 a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa -R ed8fa0e6bed90bb78f3894955acd52ae +P 4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef +R cbbc98ec5ac255f891702508ca882f04 U drh -Z 721554492d795644318a412d01d91bde +Z 5ba220c2acba929340df86e7b8719d9b diff --git a/manifest.uuid b/manifest.uuid index 9d7ba8cea8..a6c01e5fd0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef \ No newline at end of file +b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 932ce04359..dd441aef50 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4879,6 +4879,7 @@ static int accessPayload( assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); + if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else From 27e80a3b68010d7ece74ed4a6836ab9f0b2fb9ac Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 13:17:49 +0000 Subject: [PATCH 08/15] Ensure that the cell overwrite optimization does not overwrite the header of the b-tree page. FossilOrigin-Name: 4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 6 ++++-- test/fuzzdata8.db | Bin 1288192 -> 1311744 bytes 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5c813276b7..64901db7c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Early\sdetection\sout-of-bounds\spage\snumbers\son\sthe\sdirect-overflow-read\noptimization\sgives\sconsistent\serror\smessages\sregardless\sof\swhether\sor\snot\nthe\soptimization\sis\senabled. -D 2019-08-15T00:04:44.923 +C Ensure\sthat\sthe\scell\soverwrite\soptimization\sdoes\snot\soverwrite\sthe\sheader\nof\sthe\sb-tree\spage. +D 2019-08-15T13:17:49.826 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -464,7 +464,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c a6b6f4730862a4c3b92c903ecebac309626788ac8a977394198d69cd613fbf2b +F src/btree.c 5cf994516c1b74928b9d15971573a8bc8595e1afec129184099976da603402de F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556 @@ -1011,7 +1011,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db e7a86fd83dda151d160445d542e32e5c6019c541b3a74c2a525b6ac640639711 -F test/fuzzdata8.db 2f1375f053b772a48e0820fd3684eac0e109bc37d5612b72b0bb4bcebc1f0133 +F test/fuzzdata8.db dc52be9b732f5bc1cdc0db0ff5b8e69b87bc8989b13a94eb8acaef63897a007c F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1836,7 +1836,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 4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef -R cbbc98ec5ac255f891702508ca882f04 +P b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 +R 99504bb8346f69a0c987562da440ce64 U drh -Z 5ba220c2acba929340df86e7b8719d9b +Z c6c5cb19819200b45c3cd69274447def diff --git a/manifest.uuid b/manifest.uuid index a6c01e5fd0..ae239c6fc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 \ No newline at end of file +4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index dd441aef50..6e6a9b2797 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7675,7 +7675,7 @@ static int balance_nonroot( */ memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ - if( limitaiOvfl[0] ){ + if( NEVER(limitaiOvfl[0]) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } @@ -8476,7 +8476,9 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ Pgno ovflPgno; /* Next overflow page to write */ u32 ovflPageSize; /* Size to write on overflow page */ - if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){ + if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd + || pCur->info.pPayload < pPage->aData + pPage->cellOffset + ){ return SQLITE_CORRUPT_BKPT; } /* Overwrite the local portion first */ diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 353f39ba70cedd99c078d243654615c4ea9f1d46..5abaf46cb98d6bcbf04076d2ff6971ad0521efa7 100644 GIT binary patch delta 31498 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 delta 23251 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 Date: Thu, 15 Aug 2019 13:46:39 +0000 Subject: [PATCH 09/15] Avoid downgrading SQLITE_CORRUPT errors detected by the schema parser into SQLITE_NOMEM or SQLITE_ERROR errors. FossilOrigin-Name: b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/prepare.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 64901db7c3..394b53716c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\scell\soverwrite\soptimization\sdoes\snot\soverwrite\sthe\sheader\nof\sthe\sb-tree\spage. -D 2019-08-15T13:17:49.826 +C Avoid\sdowngrading\sSQLITE_CORRUPT\serrors\sdetected\sby\sthe\sschema\sparser\sinto\nSQLITE_NOMEM\sor\sSQLITE_ERROR\serrors. +D 2019-08-15T13:46:39.741 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -518,7 +518,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848 F src/pragma.c a42d4c6040893a59b69a0c987e5ed0402730c444ee451fde9bbe6203e7f73b1d F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13 -F src/prepare.c 1dcd92a57f63f7ba02ece7997c0cd36647f6ea05c05726f02d7709b18bd368ac +F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c d49679d55d3cf529bbdff8734c4ac02cedfb2fc785545b89815ddb79680b9198 @@ -1836,7 +1836,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 b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 -R 99504bb8346f69a0c987562da440ce64 +P 4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 +R 8d34b75339aca80871316bc3b34ad384 U drh -Z c6c5cb19819200b45c3cd69274447def +Z 6594db806a9430ef05667df996896231 diff --git a/manifest.uuid b/manifest.uuid index ae239c6fc7..191b74e093 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 \ No newline at end of file +b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index c6d7fba703..70c162658a 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -115,7 +115,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ - pData->rc = rc; + if( rc > pData->rc ) pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ From a3fcc000cb7bd5b12816512834e6484c68658576 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 15 Aug 2019 13:53:22 +0000 Subject: [PATCH 10/15] Ensure that SQLite does not attempt to process incompatible window functions in a single scan. Fix for [256741a1]. FossilOrigin-Name: 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/expr.c | 7 +------ src/resolve.c | 11 +---------- src/sqliteInt.h | 1 + src/window.c | 21 +++++++++++++++++++++ test/window9.test | 23 +++++++++++++++++++++++ 7 files changed, 59 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 394b53716c..ade3aa6fda 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sdowngrading\sSQLITE_CORRUPT\serrors\sdetected\sby\sthe\sschema\sparser\sinto\nSQLITE_NOMEM\sor\sSQLITE_ERROR\serrors. -D 2019-08-15T13:46:39.741 +C Ensure\sthat\sSQLite\sdoes\snot\sattempt\sto\sprocess\sincompatible\swindow\sfunctions\sin\sa\ssingle\sscan.\sFix\sfor\s[256741a1]. +D 2019-08-15T13:53:22.869 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 85239130e25f54279b1dfb3641984a335ce5a38709af29f9b62b555ed1459d07 +F src/expr.c 1b4f5a53a5f48ba3f718413586e0f9715cf90c684fba9038186a62728e2ebe72 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -521,14 +521,14 @@ F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13 F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c d49679d55d3cf529bbdff8734c4ac02cedfb2fc785545b89815ddb79680b9198 +F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117 F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 0598c87a995d63b09bcc408552bf38205cd902b577e74b7c3237bde71093c28b +F src/sqliteInt.h 4875fb443102c9d92ed1cb23b7fb6e2d97714591f02725d595576ef316596b94 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -613,7 +613,7 @@ F src/where.c 90cb93dc8eb9383e72f661b2074551d47ff21e5379f7167f7e078bed436989e9 F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc -F src/window.c 98b2571c66246bddadf42e76da45ed970fe7518a4c9c1ccc8cdace0711bfabba +F src/window.c 07e1c15081a735750218185c6b17053c87ecb764d06ab2c0a1ce568a2b4688e5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1712,7 +1712,7 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761 F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f F test/window8.tcl 9e9a82ae9eea90a4a83481d641a812b974980c38f9247f3b89a6e3c8bed45518 F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91d43f -F test/window9.test 1fd3ff49119c28006e8f55e48e8425bf4d5bf560195c4df470ef147641004f56 +F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test 403693d7d951c5473f052f7ecddb61ed15ac9d212f238b8904ea270ba90f83e5 @@ -1836,7 +1836,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 4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 -R 8d34b75339aca80871316bc3b34ad384 -U drh -Z 6594db806a9430ef05667df996896231 +P b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a +R b2cc9a11d7f17926cd103784a544e4bc +U dan +Z a8ef7cc1d7134e3e2d9b097acd8c412a diff --git a/manifest.uuid b/manifest.uuid index 191b74e093..2c85f9837b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a \ No newline at end of file +4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e00b319ed2..8f02ae569a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1325,12 +1325,7 @@ static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ assert( pWin ); assert( IsWindowFunc(pExpr) ); assert( pWin->ppThis==0 ); - if( pSelect->pWin ){ - pSelect->pWin->ppThis = &pWin->pNextWin; - } - pWin->pNextWin = pSelect->pWin; - pWin->ppThis = &pSelect->pWin; - pSelect->pWin = pWin; + sqlite3WindowLink(pSelect, pWin); } return WRC_Continue; } diff --git a/src/resolve.c b/src/resolve.c index d88abc4a4b..31600382fb 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -908,16 +908,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExprList(pWalker, pWin->pPartition); sqlite3WalkExprList(pWalker, pWin->pOrderBy); sqlite3WalkExpr(pWalker, pWin->pFilter); - if( 0==pSel->pWin - || 0==sqlite3WindowCompare(pParse, pSel->pWin, pWin, 0) - ){ - pWin->pNextWin = pSel->pWin; - if( pSel->pWin ){ - pSel->pWin->ppThis = &pWin->pNextWin; - } - pSel->pWin = pWin; - pWin->ppThis = &pSel->pWin; - } + sqlite3WindowLink(pSel, pWin); pNC->ncFlags |= NC_HasWin; }else #endif /* SQLITE_OMIT_WINDOWFUNC */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1104b771f3..d6746aadca 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3609,6 +3609,7 @@ void sqlite3WindowUnlinkFromSelect(Window*); void sqlite3WindowListDelete(sqlite3 *db, Window *p); Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); void sqlite3WindowAttach(Parse*, Expr*, Window*); +void sqlite3WindowLink(Select *pSel, Window *pWin); int sqlite3WindowCompare(Parse*, Window*, Window*, int); void sqlite3WindowCodeInit(Parse*, Window*); void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); diff --git a/src/window.c b/src/window.c index ebcb576bb5..e2f0b62276 100644 --- a/src/window.c +++ b/src/window.c @@ -1229,6 +1229,25 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ } } +/* +** Possibly link window pWin into the list at pSel->pWin (window functions +** to be processed as part of SELECT statement pSel). The window is linked +** in if either (a) there are no other windows already linked to this +** SELECT, or (b) the windows already linked use a compatible window frame. +*/ +void sqlite3WindowLink(Select *pSel, Window *pWin){ + if( 0==pSel->pWin + || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) + ){ + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; + } +} + /* ** Return 0 if the two window objects are identical, or non-zero otherwise. ** Identical window objects can be processed in a single scan. @@ -1416,6 +1435,8 @@ static void windowAggStep( int nArg = windowArgCount(pWin); int i; + assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); + for(i=0; izName!=nth_valueName ){ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); diff --git a/test/window9.test b/test/window9.test index cf4d83ae8e..d79e5f3d00 100644 --- a/test/window9.test +++ b/test/window9.test @@ -171,6 +171,29 @@ foreach {tn sql} { } {~/ORDER/} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t0(c0); + INSERT INTO t0(c0) VALUES (0); +} + +do_execsql_test 6.1 { + SELECT * FROM t0 WHERE + EXISTS ( + SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 + ) >=1 AND + EXISTS ( + SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 + ) <=1; +} {0} + +do_execsql_test 6.2 { + SELECT * FROM t0 WHERE EXISTS ( + SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 + ) + BETWEEN 1 AND 1; +} {0} finish_test From 725dd72400872da94dcfb6af48128905b93d57fe Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 14:35:45 +0000 Subject: [PATCH 11/15] Ensure that the optional "sz=N" parameter that can be manually added to the end of an sqlite_stat1 entry does not have an N value that is too small. Ticket [e4598ecbdd18bd82] FossilOrigin-Name: 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/analyze.c | 4 +++- src/where.c | 1 + test/analyzeC.test | 14 ++++++++++++++ 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ade3aa6fda..7d4def8408 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sSQLite\sdoes\snot\sattempt\sto\sprocess\sincompatible\swindow\sfunctions\sin\sa\ssingle\sscan.\sFix\sfor\s[256741a1]. -D 2019-08-15T13:53:22.869 +C Ensure\sthat\sthe\soptional\s"sz=N"\sparameter\sthat\scan\sbe\smanually\sadded\sto\sthe\nend\sof\san\ssqlite_stat1\sentry\sdoes\snot\shave\san\sN\svalue\sthat\sis\stoo\ssmall.\nTicket\s[e4598ecbdd18bd82] +D 2019-08-15T14:35:45.987 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -458,7 +458,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190 -F src/analyze.c 0278dbf6dbc0be90dc5391cb020772b461d789af17c390f857a34308c7ac9858 +F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2 F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 90cb93dc8eb9383e72f661b2074551d47ff21e5379f7167f7e078bed436989e9 +F src/where.c 2fac51d2420f05ab6f644f1813d4f73f6214304836fd9b22345738d943faad9b F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc @@ -643,7 +643,7 @@ F test/analyze6.test 6c3f7df2996cb6872f355a6ac1eb6d5de00a5a9288214bad7ef25c97d9c F test/analyze7.test 6ef0b12369f61ddeadc7d8a705c40e6b52cb29f63de3a4c56581b510b46b5783 F test/analyze8.test 36ce54947710bd44e4f9484e1ad07e725ef01a9d7078b417c1bc884356febe4d F test/analyze9.test 9fbf0e0101eef4f5dc149769aa14e10b76ee06e7c28598264b32173cd1999a54 -F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 +F test/analyzeC.test 489fe2ea3be3f17548e8dd895f1b41c9669b52de1b0861f5bffe6eec46eac710 F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb @@ -1836,7 +1836,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 b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a -R b2cc9a11d7f17926cd103784a544e4bc -U dan -Z a8ef7cc1d7134e3e2d9b097acd8c412a +P 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a +R e211e009e748f2e64e3d39bc31b03be2 +U drh +Z bec392cb43d1df3c3b62ac4b05f24424 diff --git a/manifest.uuid b/manifest.uuid index 2c85f9837b..7672348cd3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a \ No newline at end of file +98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 31fb6f5b51..1904b9be02 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1450,7 +1450,9 @@ static void decodeIntArray( if( sqlite3_strglob("unordered*", z)==0 ){ pIndex->bUnordered = 1; }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ - pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); + int sz = sqlite3Atoi(z+3); + if( sz<2 ) sz = 2; + pIndex->szIdxRow = sqlite3LogEst(sz); }else if( sqlite3_strglob("noskipscan*", z)==0 ){ pIndex->noSkipScan = 1; } diff --git a/src/where.c b/src/where.c index 65c92863a5..a37a810a2b 100644 --- a/src/where.c +++ b/src/where.c @@ -2670,6 +2670,7 @@ static int whereLoopAddBtreeIndex( ** it to pNew->rRun, which is currently set to the cost of the index ** seek only. Then, if this is a non-covering index, add the cost of ** visiting the rows in the main table. */ + assert( pSrc->pTab->szTabRow>0 ); rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ diff --git a/test/analyzeC.test b/test/analyzeC.test index 02faa9c7e9..2a0a897810 100644 --- a/test/analyzeC.test +++ b/test/analyzeC.test @@ -132,6 +132,20 @@ do_execsql_test 4.3 { SELECT count(a) FROM t1; } {/.*INDEX t1ca.*/} +# 2019-08-15. +# Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901 +# The sz=N parameter in the sqlite_stat1 table needs to have a value of +# 2 or more to avoid a division by zero in the query planner. +# +do_execsql_test 4.4 { + DROP TABLE IF EXISTS t44; + CREATE TABLE t44(a PRIMARY KEY); + INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0'); + ANALYZE sqlite_master; + SELECT 0 FROM t44 WHERE a IN(1,2,3); +} {} + + # The sz=NNN parameter works even if there is other extraneous text # in the sqlite_stat1.stat column. From 42d2fce7f5b5e5776f3e881b4685deae2e0266ff Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 20:04:09 +0000 Subject: [PATCH 12/15] Provide the SQLITE_DIRECTONLY flag for app-defined functions that prohibits the use of those functions within triggers or views. FossilOrigin-Name: fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1 --- manifest | 31 ++++++++++++---------- manifest.uuid | 2 +- src/attach.c | 1 + src/main.c | 4 ++- src/resolve.c | 9 +++++++ src/sqlite.h.in | 13 +++++++++- src/sqliteInt.h | 63 ++++++++++++++++++++++++--------------------- src/tclsqlite.c | 14 ++++++++-- src/treeview.c | 6 ++--- test/func.test | 40 +++++++++++++++++++++++++++- test/tclsqlite.test | 2 +- 11 files changed, 131 insertions(+), 54 deletions(-) diff --git a/manifest b/manifest index 7d4def8408..9b54e4ca09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\soptional\s"sz=N"\sparameter\sthat\scan\sbe\smanually\sadded\sto\sthe\nend\sof\san\ssqlite_stat1\sentry\sdoes\snot\shave\san\sN\svalue\sthat\sis\stoo\ssmall.\nTicket\s[e4598ecbdd18bd82] -D 2019-08-15T14:35:45.987 +C Provide\sthe\sSQLITE_DIRECTONLY\sflag\sfor\sapp-defined\sfunctions\sthat\sprohibits\nthe\suse\sof\sthose\sfunctions\swithin\striggers\sor\sviews. +D 2019-08-15T20:04:09.316 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -459,7 +459,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190 F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2 -F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c +F src/attach.c a6f108eb7922fad920e8aba0cda56fb56d89d136d519be5177cd3bd3559f2566 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -487,7 +487,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c -F src/main.c 3add6433e077635dac5579edaf7b3942e3ff3dda5588c49c0edd7abea2096482 +F src/main.c ff418603f9435914e8bd2febd1d5dbfcbf2ece3a4e853481a81a50fc27b321ab F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -521,18 +521,18 @@ F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13 F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa +F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117 F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e -F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906 +F src/sqlite.h.in dfbb64c0b8e4b3de2958d8372208437509acdc523aed8ae90a164f3a5d9a5739 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 4875fb443102c9d92ed1cb23b7fb6e2d97714591f02725d595576ef316596b94 +F src/sqliteInt.h 12e8af40a561a3006b6996938c88cce1e24efe690955e193824571d20c3ef352 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424 +F src/tclsqlite.c a65eb317f8b83f7ae546f88db56600f9a39550688d70501b8eb0cc3a4b4960c9 F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -588,7 +588,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e -F src/treeview.c 06e65db6ffa14dd583f90403192190dfe3855c0e3acfcbac0e82109a46e2b16c +F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e F src/trigger.c 2305271878e95addc1c01361e5e8e342e87cba5efefdd7d3032687e5d67e05d1 F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 @@ -990,7 +990,7 @@ F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3c F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429 F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test e4313baba80bf933e58eb89a7c617bec0f0c348c862b096ec4387f36e05ad0a6 +F test/func.test 0889128141b99b38aa9ce78445acfc4c1f9fbe9aa4f51d4c6aff88ae43cf125b F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6 F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f @@ -1388,7 +1388,7 @@ F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test 5a06962d8f18edf4703931f6b7dacd83678d02fa5c8ced9a7958c007ad58626a +F test/tclsqlite.test 6c7368554f15ea6df3852173c0f1d6353f824afb1896f6fc17fb21b057c0685a F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1836,7 +1836,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a -R e211e009e748f2e64e3d39bc31b03be2 +P 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 +R ad310bbebd66791c892628fc8eec172c +T *branch * directonly +T *sym-directonly * +T -sym-trunk * U drh -Z bec392cb43d1df3c3b62ac4b05f24424 +Z 950f463a47bf34120eda446765855ee2 diff --git a/manifest.uuid b/manifest.uuid index 7672348cd3..bd2dbbdbb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 \ No newline at end of file +fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 55e0eb5363..61f169ed76 100644 --- a/src/attach.c +++ b/src/attach.c @@ -560,6 +560,7 @@ int sqlite3FixExpr( Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ + ExprSetProperty(pExpr, EP_Indirect); if( pExpr->op==TK_VARIABLE ){ if( pFix->pParse->db->init.busy ){ pExpr->op = TK_NULL; diff --git a/src/main.c b/src/main.c index 06a55eca02..969bd570c4 100644 --- a/src/main.c +++ b/src/main.c @@ -1720,7 +1720,8 @@ int sqlite3CreateFunc( } assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); - extraFlags = enc & SQLITE_DETERMINISTIC; + assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); + extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); #ifndef SQLITE_OMIT_UTF16 @@ -1783,6 +1784,7 @@ int sqlite3CreateFunc( p->u.pDestructor = pDestructor; p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; testcase( p->funcFlags & SQLITE_DETERMINISTIC ); + testcase( p->funcFlags & SQLITE_DIRECTONLY ); p->xSFunc = xSFunc ? xSFunc : xStep; p->xFinalize = xFinal; p->xValue = xValue; diff --git a/src/resolve.c b/src/resolve.c index 31600382fb..ab22664095 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -823,6 +823,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** SQL is being compiled using sqlite3NestedParse() */ no_such_func = 1; pDef = 0; + }else + if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + && ExprHasProperty(pExpr, EP_Indirect) + && !IN_RENAME_OBJECT + ){ + /* Functions tagged with SQLITE_DIRECTONLY may not be used + ** inside of triggers and views */ + sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", + pDef->zName); } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d68cef2490..d50f44e6cc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4848,6 +4848,9 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** function that is not deterministic. The SQLite query planner is able to ** perform additional optimizations on deterministic functions, so use ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. +** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] +** flag, which if present prevents the function from being invoked from +** within VIEWs or TRIGGERs. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ @@ -4965,8 +4968,16 @@ int sqlite3_create_window_function( ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. +** +** The SQLITE_DETERMINISTIC flag means that the new function will always +** maps the same inputs into the same output. The abs() function is +** deterministic, for example, but randomblob() is not. +** +** The SQLITE_DIRECTONLY flag means that the function may only be invoked +** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. */ -#define SQLITE_DETERMINISTIC 0x800 +#define SQLITE_DETERMINISTIC 0x000000800 +#define SQLITE_DIRECTONLY 0x000080000 /* ** CAPI3REF: Deprecated Functions diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d6746aadca..47b4e749da 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1663,6 +1663,7 @@ struct FuncDestructor { ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API +** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ @@ -1683,6 +1684,7 @@ struct FuncDestructor { #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ +#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -2494,36 +2496,37 @@ struct Expr { ** EP_Agg == NC_HasAgg == SF_HasAgg ** EP_Win == NC_HasWin */ -#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ -#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */ -#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ -#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ -#define EP_Agg 0x000010 /* Contains one or more aggregate functions */ -#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ -#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ -#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ -#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ -#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ -#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ -#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ -#define EP_Skip 0x001000 /* Operator does not contribute to affinity */ -#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ -#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ -#define EP_Win 0x008000 /* Contains window functions */ -#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ -#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ -#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ -#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ -#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ -#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ -#define EP_Alias 0x400000 /* Is an alias for a result set column */ -#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ -#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ -#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ -#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ -#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ -#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ -#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ +#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ +#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */ +#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ +#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ +#define EP_Agg 0x000010 /* Contains one or more aggregate functions */ +#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ +#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ +#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ +#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ +#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ +#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ +#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ +#define EP_Skip 0x001000 /* Operator does not contribute to affinity */ +#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ +#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ +#define EP_Win 0x008000 /* Contains window functions */ +#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ +#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ +#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ +#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ +#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ +#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ +#define EP_Alias 0x400000 /* Is an alias for a result set column */ +#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ +#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ +#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ +#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ +#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ +#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ +#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ +#define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */ /* ** The EP_Propagate mask is a set of properties that automatically propagate diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a78d5676c7..511a9c8a66 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2741,10 +2741,16 @@ deserialize_error: } /* - ** $db function NAME [-argcount N] [-deterministic] SCRIPT + ** $db function NAME [OPTIONS] SCRIPT ** ** Create a new SQL function called NAME. Whenever that function is ** called, invoke SCRIPT to evaluate the function. + ** + ** Options: + ** --argcount N Function has exactly N arguments + ** --deterministic The function is pure + ** --directonly Prohibit use inside triggers and views + ** --returntype TYPE Specify the return type of the function */ case DB_FUNCTION: { int flags = SQLITE_UTF8; @@ -2777,6 +2783,9 @@ deserialize_error: if( n>1 && strncmp(z, "-deterministic",n)==0 ){ flags |= SQLITE_DETERMINISTIC; }else + if( n>1 && strncmp(z, "-directonly",n)==0 ){ + flags |= SQLITE_DIRECTONLY; + }else if( n>1 && strncmp(z, "-returntype", n)==0 ){ const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); @@ -2792,7 +2801,8 @@ deserialize_error: eType++; }else{ Tcl_AppendResult(interp, "bad option \"", z, - "\": must be -argcount, -deterministic or -returntype", (char*)0 + "\": must be -argcount, -deterministic, -directonly," + " or -returntype", (char*)0 ); return TCL_ERROR; } diff --git a/src/treeview.c b/src/treeview.c index 753f214899..6dfdccd7ee 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -557,10 +557,10 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ #endif } if( pExpr->op==TK_AGG_FUNCTION ){ - sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q", - pExpr->op2, pExpr->u.zToken); + sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s", + pExpr->op2, pExpr->u.zToken, zFlgs); }else{ - sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken); + sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); diff --git a/test/func.test b/test/func.test index 579bad8e44..7315af322a 100644 --- a/test/func.test +++ b/test/func.test @@ -1419,7 +1419,45 @@ do_execsql_test func-32.150 { SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y; } {8} - +# 2019-08-15 +# Direct-only functions. +# +proc testdirectonly {x} {return [expr {$x*2}]} +do_test func-33.1 { + db func testdirectonly -directonly testdirectonly + db eval {SELECT testdirectonly(15)} +} {30} +do_catchsql_test func-33.2 { + CREATE VIEW v33(y) AS SELECT testdirectonly(15); + SELECT * FROM v33; +} {1 {testdirectonly() prohibited in triggers and views}} +do_execsql_test func-33.3 { + SELECT * FROM (SELECT testdirectonly(15)) AS v33; +} {30} +do_execsql_test func-33.4 { + WITH c(x) AS (SELECT testdirectonly(15)) + SELECT * FROM c; +} {30} +do_catchsql_test func-33.5 { + WITH c(x) AS (SELECT * FROM v33) + SELECT * FROM c; +} {1 {testdirectonly() prohibited in triggers and views}} +do_execsql_test func-33.10 { + CREATE TABLE t33a(a,b); + CREATE TABLE t33b(x,y); + CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN + INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b); + END; +} {} +do_catchsql_test func-33.11 { + INSERT INTO t33a VALUES(1,2); +} {1 {testdirectonly() prohibited in triggers and views}} +do_execsql_test func-33.20 { + ALTER TABLE t33a RENAME COLUMN a TO aaa; + SELECT sql FROM sqlite_master WHERE name='r1'; +} {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN + INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b); + END}} finish_test diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 319737426f..ec0312254c 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -789,7 +789,7 @@ do_test 17.6.2 { do_test 17.6.3 { list [catch { db function xyz -n object ret } msg] $msg -} {1 {bad option "-n": must be -argcount, -deterministic or -returntype}} +} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, or -returntype}} # 2019-02-28: The "bind_fallback" command. # From 11d88e68abdf23f131dca81ad8d3517a5cf8449b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 21:27:20 +0000 Subject: [PATCH 13/15] Add the SQLITE_DBCONFIG_ENABLE_VIEW option, together with a "db config" command in the TCL interface that can access that option as well as all the other sqlite3_db_config() boolean options. FossilOrigin-Name: 61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 --- manifest | 26 +++++----- manifest.uuid | 2 +- src/main.c | 2 + src/select.c | 4 ++ src/shell.c.in | 1 + src/sqlite.h.in | 14 +++++- src/sqliteInt.h | 13 ++--- src/tclsqlite.c | 114 +++++++++++++++++++++++++++++++++++--------- test/tclsqlite.test | 2 +- test/view.test | 12 +++++ 10 files changed, 146 insertions(+), 44 deletions(-) diff --git a/manifest b/manifest index 7d4def8408..de79942910 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\soptional\s"sz=N"\sparameter\sthat\scan\sbe\smanually\sadded\sto\sthe\nend\sof\san\ssqlite_stat1\sentry\sdoes\snot\shave\san\sN\svalue\sthat\sis\stoo\ssmall.\nTicket\s[e4598ecbdd18bd82] -D 2019-08-15T14:35:45.987 +C Add\sthe\sSQLITE_DBCONFIG_ENABLE_VIEW\soption,\stogether\swith\sa\s"db\sconfig"\ncommand\sin\sthe\sTCL\sinterface\sthat\scan\saccess\sthat\soption\sas\swell\sas\sall\sthe\nother\ssqlite3_db_config()\sboolean\soptions. +D 2019-08-15T21:27:20.669 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c -F src/main.c 3add6433e077635dac5579edaf7b3942e3ff3dda5588c49c0edd7abea2096482 +F src/main.c 9465ba2bfc021f5c2ec1f58fc97c55b123d277ad0993c49a2f333df9da483f8f F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -523,16 +523,16 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117 -F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e -F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906 +F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 +F src/shell.c.in b748cfb4277fe1952609d688b181b152dd5920425a83dab1baddbfdcb722346c +F src/sqlite.h.in fe09e2452f68148dcd2724fa1aefe0939802b4fab89355fb194aa40126ac4b51 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 4875fb443102c9d92ed1cb23b7fb6e2d97714591f02725d595576ef316596b94 +F src/sqliteInt.h d8e878fa1cb949ee8943f51965cbb917acdb4cc1238af8481eb839d11bf34d0a F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424 +F src/tclsqlite.c 172792eb66e9a8985e8a246e689318cadbda50e10c13f0e51eea32215c6c9161 F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -1388,7 +1388,7 @@ F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test 5a06962d8f18edf4703931f6b7dacd83678d02fa5c8ced9a7958c007ad58626a +F test/tclsqlite.test f7bacdbe12bc208e0fe81b5cf5d712331d52f724917a6b4810c4cd686202843e F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1610,7 +1610,7 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 -F test/view.test c1e64ff5a860fdbb7b52add0996af2ee1af563ddf2e86b964d15d04d81a001be +F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5 F test/vtab1.test efb4c4a45146193d6d55fb85f7162febd6423f29c72ede09bb96383f49e3abc1 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e @@ -1836,7 +1836,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 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a -R e211e009e748f2e64e3d39bc31b03be2 +P 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 +R 039c157cf6533868154794e96c549de4 U drh -Z bec392cb43d1df3c3b62ac4b05f24424 +Z 9ba4f898522b0ea8e4f41f060393ee57 diff --git a/manifest.uuid b/manifest.uuid index 7672348cd3..6e0115e877 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 \ No newline at end of file +61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 06a55eca02..ecc7e5c518 100644 --- a/src/main.c +++ b/src/main.c @@ -836,6 +836,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ } aFlagOp[] = { { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, + { SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView }, { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, @@ -3075,6 +3076,7 @@ static int openDatabase( db->nMaxSorterMmap = 0x7FFFFFFF; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger + | SQLITE_EnableView | SQLITE_CacheSpill /* The SQLITE_DQS compile-time option determines the default settings diff --git a/src/select.c b/src/select.c index ca1256d160..bd8fee87ed 100644 --- a/src/select.c +++ b/src/select.c @@ -4906,6 +4906,10 @@ static int selectExpander(Walker *pWalker, Select *p){ u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); + if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ + sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", + pTab->zName); + } pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; diff --git a/src/shell.c.in b/src/shell.c.in index 19280e318d..0ffd9aece7 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7135,6 +7135,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } aDbConfig[] = { { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, + { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d68cef2490..4b1d4723bb 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2093,6 +2093,17 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. ** +** [[SQLITE_DBCONFIG_ENABLE_VIEW]] +**
SQLITE_DBCONFIG_ENABLE_VIEW
+**
^This option is used to enable or disable [CREATE VIEW | views]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable views, +** positive to enable views or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether views are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the view setting is not reported back.
+** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
**
^This option is used to enable or disable the @@ -2265,7 +2276,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */ #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d6746aadca..52c982159b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1537,16 +1537,17 @@ struct sqlite3 { #define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ #define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/ #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/ +#define SQLITE_EnableView 0x80000000 /* Enable the use of views */ /* Flags used only if debugging */ #define HI(X) ((u64)(X)<<32) #ifdef SQLITE_DEBUG -#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */ -#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */ -#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */ -#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */ -#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */ -#define SQLITE_ParserTrace HI(0x0020) /* PRAGMA parser_trace=ON */ +#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ +#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ +#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */ +#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */ +#define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */ #endif /* diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a78d5676c7..d296af8f9f 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1917,33 +1917,33 @@ static int SQLITE_TCLAPI DbObjCmd( "authorizer", "backup", "bind_fallback", "busy", "cache", "changes", "close", "collate", "collation_needed", - "commit_hook", "complete", "copy", - "deserialize", "enable_load_extension", "errorcode", - "eval", "exists", "function", - "incrblob", "interrupt", "last_insert_rowid", - "nullvalue", "onecolumn", "preupdate", - "profile", "progress", "rekey", - "restore", "rollback_hook", "serialize", - "status", "timeout", "total_changes", - "trace", "trace_v2", "transaction", - "unlock_notify", "update_hook", "version", - "wal_hook", 0 + "commit_hook", "complete", "config", + "copy", "deserialize", "enable_load_extension", + "errorcode", "eval", "exists", + "function", "incrblob", "interrupt", + "last_insert_rowid", "nullvalue", "onecolumn", + "preupdate", "profile", "progress", + "rekey", "restore", "rollback_hook", + "serialize", "status", "timeout", + "total_changes", "trace", "trace_v2", + "transaction", "unlock_notify", "update_hook", + "version", "wal_hook", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, - DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY, - DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE, - DB_EVAL, DB_EXISTS, DB_FUNCTION, - DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, - DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE, - DB_PROFILE, DB_PROGRESS, DB_REKEY, - DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE, - DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, - DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, - DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, - DB_WAL_HOOK + DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG, + DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION, + DB_ERRORCODE, DB_EVAL, DB_EXISTS, + DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, + DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, + DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, + DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, + DB_SERIALIZE, DB_STATUS, DB_TIMEOUT, + DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2, + DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, + DB_VERSION, DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2331,6 +2331,76 @@ static int SQLITE_TCLAPI DbObjCmd( break; } + /* $db config ?OPTION? ?BOOLEAN? + ** + ** Configure the database connection using the sqlite3_db_config() + ** interface. + */ + case DB_CONFIG: { + static const struct DbConfigChoices { + const char *zName; + int op; + } aDbConfig[] = { + { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, + { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, + { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, + { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, + { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, + { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, + { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, + { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, + { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, + { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, + { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, + { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, + { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, + }; + Tcl_Obj *pResult; + int ii; + if( objc>4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?"); + return TCL_ERROR; + } + if( objc==2 ){ + /* With no arguments, list all configuration options and with the + ** current value */ + pResult = Tcl_NewListObj(0,0); + for(ii=0; iidb, aDbConfig[ii].op, -1, &v); + if( rc!=SQLITE_OK ) continue; + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewStringObj(aDbConfig[ii].zName,-1)); + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewIntObj(v)); + } + }else{ + const char *zOpt = Tcl_GetString(objv[2]); + int rc; + int onoff = -1; + int v = 0; + if( zOpt[0]=='-' ) zOpt++; + for(ii=0; ii=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){ + Tcl_AppendResult(interp, "unknown config option: \"", zOpt, + "\"", (void*)0); + return TCL_ERROR; + } + if( objc==4 ){ + if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){ + return TCL_ERROR; + } + } + rc = sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); + pResult = Tcl_NewIntObj(v); + } + Tcl_SetObjResult(interp, pResult); + break; + } + /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? ** ** Copy data into table from filename, optionally using SEPARATOR diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 319737426f..02f8dd9db8 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -42,7 +42,7 @@ do_test tcl-1.1.1 { do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg -} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} +} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg diff --git a/test/view.test b/test/view.test index 490dc65a68..b3f50dc008 100644 --- a/test/view.test +++ b/test/view.test @@ -38,6 +38,18 @@ do_test view-1.1 { SELECT * FROM v1 ORDER BY a; } } {1 2 4 5 7 8} +do_test view-1.1.100 { + db config enable_view off + catchsql { + SELECT * FROM v1 ORDER BY a; + } +} {1 {access to view "v1" prohibited}} +do_test view-1.1.110 { + db config enable_view on + catchsql { + SELECT * FROM v1 ORDER BY a; + } +} {0 {1 2 4 5 7 8}} do_test view-1.2 { catchsql { ROLLBACK; From 4043cfef7590c5a8b90cfbee44b45f6ca8bbf176 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 23:11:42 +0000 Subject: [PATCH 14/15] Fix harmless compiler warnings in the TCL interface. FossilOrigin-Name: f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index de79942910..d1c778bab0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_DBCONFIG_ENABLE_VIEW\soption,\stogether\swith\sa\s"db\sconfig"\ncommand\sin\sthe\sTCL\sinterface\sthat\scan\saccess\sthat\soption\sas\swell\sas\sall\sthe\nother\ssqlite3_db_config()\sboolean\soptions. -D 2019-08-15T21:27:20.669 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sTCL\sinterface. +D 2019-08-15T23:11:42.012 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -532,7 +532,7 @@ F src/sqliteInt.h d8e878fa1cb949ee8943f51965cbb917acdb4cc1238af8481eb839d11bf34d F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c 172792eb66e9a8985e8a246e689318cadbda50e10c13f0e51eea32215c6c9161 +F src/tclsqlite.c 2170b327318f888aa3ed861a6ef3e88c6906839f584ab2b01552c8b19db6f9e5 F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -1836,7 +1836,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 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 -R 039c157cf6533868154794e96c549de4 +P 61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 +R ad07753edbdb65bae98d204ed9a7c2cb U drh -Z 9ba4f898522b0ea8e4f41f060393ee57 +Z f83b80ce99769ab61a563e51215a8c91 diff --git a/manifest.uuid b/manifest.uuid index 6e0115e877..5e9e71cf03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 \ No newline at end of file +f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index d296af8f9f..8b32bf82de 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2368,8 +2368,7 @@ static int SQLITE_TCLAPI DbObjCmd( pResult = Tcl_NewListObj(0,0); for(ii=0; iidb, aDbConfig[ii].op, -1, &v); - if( rc!=SQLITE_OK ) continue; + sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v); Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(aDbConfig[ii].zName,-1)); Tcl_ListObjAppendElement(interp, pResult, @@ -2377,7 +2376,6 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ const char *zOpt = Tcl_GetString(objv[2]); - int rc; int onoff = -1; int v = 0; if( zOpt[0]=='-' ) zOpt++; @@ -2394,7 +2392,7 @@ static int SQLITE_TCLAPI DbObjCmd( return TCL_ERROR; } } - rc = sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); + sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); pResult = Tcl_NewIntObj(v); } Tcl_SetObjResult(interp, pResult); From cc5979dbd384049c1efef847e5cc22082191024b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Aug 2019 22:58:29 +0000 Subject: [PATCH 15/15] Add the ability to unregister a virtual table module by invoking sqlite3_create_module() with a NULL sqlite3_module pointer. FossilOrigin-Name: 31e34fa3390196cdc3178bf120224b08df5ec58fa2c77079ede6e9461a430dad --- manifest | 24 ++++++++++---------- manifest.uuid | 2 +- src/main.c | 5 +---- src/shell.c.in | 18 +++++++++++++++ src/sqlite.h.in | 4 ++++ src/sqliteInt.h | 3 +++ src/vtab.c | 55 ++++++++++++++++++++++++++++++++++------------ test/intarray.test | 8 +++---- test/vtab1.test | 4 ++-- 9 files changed, 86 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index d1c778bab0..5feb38ed1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sTCL\sinterface. -D 2019-08-15T23:11:42.012 +C Add\sthe\sability\sto\sunregister\sa\svirtual\stable\smodule\sby\sinvoking\nsqlite3_create_module()\swith\sa\sNULL\ssqlite3_module\spointer. +D 2019-08-16T22:58:29.636 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c -F src/main.c 9465ba2bfc021f5c2ec1f58fc97c55b123d277ad0993c49a2f333df9da483f8f +F src/main.c 1ffcd1890908444567471e72246f22595a8f63cfa84fa8f5ee7fc80c0d2a1863 F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -524,11 +524,11 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 -F src/shell.c.in b748cfb4277fe1952609d688b181b152dd5920425a83dab1baddbfdcb722346c -F src/sqlite.h.in fe09e2452f68148dcd2724fa1aefe0939802b4fab89355fb194aa40126ac4b51 +F src/shell.c.in d2465e7747a014bd48a75c1bcf648e8e6cb46832dcc6e1293c5f285bc5542e8b +F src/sqlite.h.in fe836f566b3517201077f4ff69ec7379b626b311ccc6e24ad5ca11c262775ca7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h d8e878fa1cb949ee8943f51965cbb917acdb4cc1238af8481eb839d11bf34d0a +F src/sqliteInt.h a89fe72e4a00652fdad88911e73ad376a351a477ec86a822f602863f01a495d3 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -604,7 +604,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75 F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 +F src/vtab.c 4d833811e3784409627919899e1fd75ee08f0e5db6d9924eac9a0bfe0cb762dc F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1064,7 +1064,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74 F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a -F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c53fb7 +F test/intarray.test bb976b0b3df0ebb6a2eddfb61768280440e672beba5460ed49679ea984ccf440 F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 @@ -1611,7 +1611,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5 -F test/vtab1.test efb4c4a45146193d6d55fb85f7162febd6423f29c72ede09bb96383f49e3abc1 +F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 @@ -1836,7 +1836,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 61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 -R ad07753edbdb65bae98d204ed9a7c2cb +P f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f +R cde2fc12434d097e80f94e2e70c1f8fb U drh -Z f83b80ce99769ab61a563e51215a8c91 +Z bcecf677f5410a7291761a23528080f1 diff --git a/manifest.uuid b/manifest.uuid index 5e9e71cf03..b8c13348fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f \ No newline at end of file +31e34fa3390196cdc3178bf120224b08df5ec58fa2c77079ede6e9461a430dad \ No newline at end of file diff --git a/src/main.c b/src/main.c index ecc7e5c518..79a17e5a5c 100644 --- a/src/main.c +++ b/src/main.c @@ -1236,11 +1236,8 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ Module *pMod = (Module *)sqliteHashData(i); - if( pMod->xDestroy ){ - pMod->xDestroy(pMod->pAux); - } sqlite3VtabEponymousTableClear(db, pMod); - sqlite3DbFree(db, pMod); + sqlite3VtabModuleUnref(db, pMod); } sqlite3HashClear(&db->aModule); #endif diff --git a/src/shell.c.in b/src/shell.c.in index 0ffd9aece7..494a3d7e21 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3649,6 +3649,9 @@ static const char *(azHelp[]) = { " --row Trace each row (SQLITE_TRACE_ROW)", " --close Trace connection close (SQLITE_TRACE_CLOSE)", #endif /* SQLITE_OMIT_TRACE */ +#ifdef SQLITE_DEBUG + ".unmodule NAME ... Unregister virtual table modules", +#endif ".vfsinfo ?AUX? Information about the top-level VFS", ".vfslist List all available VFSes", ".vfsname ?AUX? Print the name of the VFS stack", @@ -9401,6 +9404,21 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif /* !defined(SQLITE_OMIT_TRACE) */ +#ifdef SQLITE_DEBUG + if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){ + int ii; + if( nArg<2 ){ + raw_printf(stderr, "Usage: .unmodule NAME ...\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + for(ii=1; iidb, azArg[ii], 0, 0); + } + }else +#endif + #if SQLITE_USER_AUTHENTICATION if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ if( nArg<2 ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4b1d4723bb..e0d02b2722 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6624,6 +6624,10 @@ struct sqlite3_index_info { ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. +** +** ^If the third parameter (the pointer to the sqlite3_module object) is +** NULL then no new module is create and any existing modules with the +** same name are dropped. */ int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 52c982159b..07e241a1c4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1797,6 +1797,7 @@ struct Savepoint { struct Module { const sqlite3_module *pModule; /* Callback pointers */ const char *zName; /* Name passed to create_module() */ + int nRefModule; /* Number of pointers to this object */ void *pAux; /* pAux passed to create_module() */ void (*xDestroy)(void *); /* Module destructor function */ Table *pEpoTab; /* Eponymous table for this module */ @@ -4438,6 +4439,7 @@ void sqlite3AutoLoadExtensions(sqlite3*); # define sqlite3VtabInSync(db) 0 # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) +# define sqlite3VtabModuleUnref(D,X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) @@ -4449,6 +4451,7 @@ void sqlite3AutoLoadExtensions(sqlite3*); int sqlite3VtabCommit(sqlite3 *db); void sqlite3VtabLock(VTable *); void sqlite3VtabUnlock(VTable *); + void sqlite3VtabModuleUnref(sqlite3*,Module*); void sqlite3VtabUnlockList(sqlite3*); int sqlite3VtabSavepoint(sqlite3 *, int, int); void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); diff --git a/src/vtab.c b/src/vtab.c index 41e26ef62f..a711a7be5f 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -32,6 +32,9 @@ struct VtabCtx { ** Construct and install a Module object for a virtual table. When this ** routine is called, it is guaranteed that all appropriate locks are held ** and the module is not already part of the connection. +** +** If there already exists a module with zName, replace it with the new one. +** If pModule==0, then delete the module zName if it exists. */ Module *sqlite3VtabCreateModule( sqlite3 *db, /* Database in which module is registered */ @@ -41,25 +44,35 @@ Module *sqlite3VtabCreateModule( void (*xDestroy)(void *) /* Module destructor function */ ){ Module *pMod; - int nName = sqlite3Strlen30(zName); - pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); - if( pMod==0 ){ - sqlite3OomFault(db); + Module *pDel; + char *zCopy; + if( pModule==0 ){ + zCopy = (char*)zName; + pMod = 0; }else{ - Module *pDel; - char *zCopy = (char *)(&pMod[1]); + int nName = sqlite3Strlen30(zName); + pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); + if( pMod==0 ){ + sqlite3OomFault(db); + return 0; + } + zCopy = (char *)(&pMod[1]); memcpy(zCopy, zName, nName+1); pMod->zName = zCopy; pMod->pModule = pModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; pMod->pEpoTab = 0; - pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); - assert( pDel==0 || pDel==pMod ); - if( pDel ){ + pMod->nRefModule = 1; + } + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + if( pDel ){ + if( pDel==pMod ){ sqlite3OomFault(db); sqlite3DbFree(db, pDel); pMod = 0; + }else{ + sqlite3VtabModuleUnref(db, pDel); } } return pMod; @@ -80,11 +93,7 @@ static int createModule( int rc = SQLITE_OK; sqlite3_mutex_enter(db->mutex); - if( sqlite3HashFind(&db->aModule, zName) ){ - rc = SQLITE_MISUSE_BKPT; - }else{ - (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); - } + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); sqlite3_mutex_leave(db->mutex); @@ -123,6 +132,22 @@ int sqlite3_create_module_v2( return createModule(db, zName, pModule, pAux, xDestroy); } +/* +** Decrement the reference count on a Module object. Destroy the +** module when the reference count reaches zero. +*/ +void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){ + assert( pMod->nRefModule>0 ); + pMod->nRefModule--; + if( pMod->nRefModule==0 ){ + if( pMod->xDestroy ){ + pMod->xDestroy(pMod->pAux); + } + assert( pMod->pEpoTab==0 ); + sqlite3DbFree(db, pMod); + } +} + /* ** Lock the virtual table so that it cannot be disconnected. ** Locks nest. Every lock should have a corresponding unlock. @@ -162,6 +187,7 @@ void sqlite3VtabUnlock(VTable *pVTab){ pVTab->nRef--; if( pVTab->nRef==0 ){ sqlite3_vtab *p = pVTab->pVtab; + sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); if( p ){ p->pModule->xDisconnect(p); } @@ -566,6 +592,7 @@ static int vtabCallConstructor( ** the sqlite3_vtab object if successful. */ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); pVTable->pVtab->pModule = pMod->pModule; + pMod->nRefModule++; pVTable->nRef = 1; if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; diff --git a/test/intarray.test b/test/intarray.test index 049f117cc2..2250027c5d 100644 --- a/test/intarray.test +++ b/test/intarray.test @@ -47,12 +47,12 @@ do_test intarray-1.1 { } } {table ia1 table ia2 table ia3 table ia4} -# Verify the inability to DROP and recreate an intarray virtual table. +# Verify the ability to DROP and recreate an intarray virtual table. do_test intarray-1.1b { db eval {DROP TABLE ia1} - set rc [catch {sqlite3_intarray_create db ia1} msg] - lappend rc $msg -} {1 SQLITE_MISUSE} + set rc [catch {sqlite3_intarray_create db ia1} ia1] + lappend rc $ia1 +} {/0 [0-9A-Z]+/} do_test intarray-1.2 { db eval { diff --git a/test/vtab1.test b/test/vtab1.test index 0a45c4e2d9..e8891a632c 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1352,7 +1352,7 @@ foreach {tn sql res filter} { do_execsql_test 18.2.x { PRAGMA case_sensitive_like = OFF } #------------------------------------------------------------------------- -# Test that an existing module may not be overridden. +# Test that it is ok to override and existing module. # do_test 19.1 { sqlite3 db2 test.db @@ -1360,7 +1360,7 @@ do_test 19.1 { } SQLITE_OK do_test 19.2 { register_echo_module [sqlite3_connection_pointer db2] -} SQLITE_MISUSE +} SQLITE_OK do_test 19.3 { db2 close } {}