From 2a740060870d67738e5c438dac8cd9423871d5e0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Feb 2020 18:28:17 +0000 Subject: [PATCH 001/102] Small size reduction and performance improvement in the sqlite3VdbeMemFromBtree() interface used to pull content out of the b-tree and into an sqlite3_value object. FossilOrigin-Name: ae6dd8d3e921670ee6450453b54245dd71bcfff3fd1bc7fdb7cf4cf9585c3375 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 4 ++-- src/vdbeInt.h | 1 + src/vdbeaux.c | 4 ++-- src/vdbemem.c | 15 ++++++--------- 6 files changed, 22 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 12be146f1b..23030851f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\smore\sdetailed\slog\smessages\sin\sSQLITE_ENABLE_CORRUPT_PGNO\sbuilds\sif\sdatabase\scorruption\sis\sencountered. -D 2020-02-04T20:01:44.357 +C Small\ssize\sreduction\sand\sperformance\simprovement\sin\sthe\nsqlite3VdbeMemFromBtree()\sinterface\sused\sto\spull\scontent\sout\sof\sthe\sb-tree\nand\sinto\san\ssqlite3_value\sobject. +D 2020-02-05T18:28:17.819 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -603,13 +603,13 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c 736ff76753236ffbc8b5b939f5e0607f28aeaa7c780b3a56b419228f0a81c87b F src/util.c d035b09df9cecbc0e8f07c34b815acbf0d43c8adc8d2c540e3dc92eecb27855a F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c b34d430a44ebb9f4ccdaf590de641b8ef126480a64f1544b11146a5d8b672879 +F src/vdbe.c 0fdca82c67c68499d1dc3e310e39b7ee30cd262a535f848f3d0a3fee00b70662 F src/vdbe.h defd693289c7bb8d325f109be9490c77138061211a116827da7244b6015a4934 -F src/vdbeInt.h 30d3e8b991547cdf39025e416a0a737b0416d46747af70ae058f60e2e0466fe7 +F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 -F src/vdbeaux.c 873d96bc4c046a016b3a35c736a45f26a31b59b1480a0cdd79e40f02c9bd001c +F src/vdbeaux.c eaf1df6465f410e69330864bfc152458208f9bb2edd99930432ae342662d2ecd F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 -F src/vdbemem.c 6200af702c87105d5b00d8ac5f5fa2c6d8f796aa974dbe2d15dcd95379ba1fa7 +F src/vdbemem.c ff2a1fd86ea943efb7174bd74bc661815c449be6165e136e8849e1dc59e24353 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515 @@ -1858,7 +1858,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 29a969d6b1709b80d9cb88b60971e4eb021f7f5f8ee9a619be74b833a78a35ef -R 020ae1619dff77b0c976eacd97de532f -U dan -Z c5d72d1ce7fa174b00e7f8ecef1901cb +P 57c36a293e16bb4d9652874124ee1447bef278e08664bc8dd0070a0ee2ef1173 +R 9dccc312e85b3ed88562ba275ed8ce3c +U drh +Z 6739930e1718a08cc04c781aee16b618 diff --git a/manifest.uuid b/manifest.uuid index 85e13c2086..172eab1b25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -57c36a293e16bb4d9652874124ee1447bef278e08664bc8dd0070a0ee2ef1173 \ No newline at end of file +ae6dd8d3e921670ee6450453b54245dd71bcfff3fd1bc7fdb7cf4cf9585c3375 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 015aa30e4a..8e59d89c0e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2713,7 +2713,7 @@ case OP_Column: { /* Make sure zData points to enough of the record to cover the header. */ if( pC->aRow==0 ){ memset(&sMem, 0, sizeof(sMem)); - rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pC->uc.pCursor,aOffset[0],&sMem); if( rc!=SQLITE_OK ) goto abort_due_to_error; zData = (u8*)sMem.z; }else{ @@ -5209,7 +5209,7 @@ case OP_RowData: { goto too_big; } testcase( n==0 ); - rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCrsr, n, pOut); if( rc ) goto abort_due_to_error; if( !pOp->p3 ) Deephemeralize(pOut); UPDATE_MAX_BLOBSIZE(pOut); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 9311591fbc..8102831624 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -532,6 +532,7 @@ int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemNumerify(Mem*); int sqlite3VdbeMemCast(Mem*,u8,u8); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); +int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*); void sqlite3VdbeMemRelease(Mem *p); int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 69b6216c06..52959a43ee 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -4862,7 +4862,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ /* Read in the complete content of the index entry */ sqlite3VdbeMemInit(&m, db, 0); - rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ){ return rc; } @@ -4944,7 +4944,7 @@ int sqlite3VdbeIdxKeyCompare( return SQLITE_CORRUPT_BKPT; } sqlite3VdbeMemInit(&m, db, 0); - rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); if( rc ){ return rc; } diff --git a/src/vdbemem.c b/src/vdbemem.c index ddb6b2c113..27f1c7dce3 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1169,7 +1169,7 @@ int sqlite3VdbeMemSetStr( ** If this routine fails for any reason (malloc returns NULL or unable ** to read from the disk) then the pMem is left in an inconsistent state. */ -static SQLITE_NOINLINE int vdbeMemFromBtreeResize( +int sqlite3VdbeMemFromBtree( BtCursor *pCur, /* Cursor pointing at record to retrieve. */ u32 offset, /* Offset from the start of data to return bytes from. */ u32 amt, /* Number of bytes to return. */ @@ -1192,13 +1192,11 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize( } return rc; } -int sqlite3VdbeMemFromBtree( +int sqlite3VdbeMemFromBtreeZeroOffset( BtCursor *pCur, /* Cursor pointing at record to retrieve. */ - u32 offset, /* Offset from the start of data to return bytes from. */ u32 amt, /* Number of bytes to return. */ Mem *pMem /* OUT: Return data in this Mem structure. */ ){ - char *zData; /* Data from the btree layer */ u32 available = 0; /* Number of bytes available on the local btree page */ int rc = SQLITE_OK; /* Return code */ @@ -1208,15 +1206,14 @@ int sqlite3VdbeMemFromBtree( /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ assert( !sqlite3VdbeMemIsRowSet(pMem) ); - zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); - assert( zData!=0 ); + pMem->z = (char *)sqlite3BtreePayloadFetch(pCur, &available); + assert( pMem->z!=0 ); - if( offset+amt<=available ){ - pMem->z = &zData[offset]; + if( amt<=available ){ pMem->flags = MEM_Blob|MEM_Ephem; pMem->n = (int)amt; }else{ - rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem); + rc = sqlite3VdbeMemFromBtree(pCur, 0, amt, pMem); } return rc; From fcbc673752b34da00b88d235338ddde25e244200 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 6 Feb 2020 10:55:10 +0000 Subject: [PATCH 002/102] Fix some fts3 problems found by usan. FossilOrigin-Name: fb7ccf61bed8d862986eda7096bec3df5947f1d1c88f27e7d9c8acf420f40c50 --- ext/fts3/fts3_tokenize_vtab.c | 2 +- ext/fts3/fts3_write.c | 2 +- manifest | 18 +++++++++--------- manifest.uuid | 2 +- test/fts3corrupt4.test | 13 +++++++++++++ 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/ext/fts3/fts3_tokenize_vtab.c b/ext/fts3/fts3_tokenize_vtab.c index 313a3c0ffb..fe6e242840 100644 --- a/ext/fts3/fts3_tokenize_vtab.c +++ b/ext/fts3/fts3_tokenize_vtab.c @@ -350,7 +350,7 @@ static int fts3tokFilterMethod( if( pCsr->zInput==0 ){ rc = SQLITE_NOMEM; }else{ - memcpy(pCsr->zInput, zByte, nByte); + if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte); pCsr->zInput[nByte] = 0; rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr); if( rc==SQLITE_OK ){ diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 197aebdd49..253be1174d 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -2502,7 +2502,7 @@ static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ if( rc!=SQLITE_OK ) return rc; sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); sqlite3_bind_int64(pStmt, 2, - ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL + (((u64)iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL ); *pbMax = 0; diff --git a/manifest b/manifest index 23030851f0..f36594516f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\simprovement\sin\sthe\nsqlite3VdbeMemFromBtree()\sinterface\sused\sto\spull\scontent\sout\sof\sthe\sb-tree\nand\sinto\san\ssqlite3_value\sobject. -D 2020-02-05T18:28:17.819 +C Fix\ssome\sfts3\sproblems\sfound\sby\susan. +D 2020-02-06T10:55:10.559 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -94,13 +94,13 @@ F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009 F ext/fts3/fts3_snippet.c 052b35ad746349ffb53820379bacdb23ff3ac60d3cc13d986e56d42822ef5a9a F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1 F ext/fts3/fts3_test.c 73b16e229e517c1b1f0fb8e1046182a4e5dbc8dbe6eea8a5d4353fcce7dbbf39 -F ext/fts3/fts3_tokenize_vtab.c 1de9a61acfa2a0445ed989310c31839c57f6b6086dd9d5c97177ae734a17fd8b +F ext/fts3/fts3_tokenize_vtab.c cb792f59212f7799bf2891c7d4579bbf568f124ce8fbb0a9902aa5bd577e8b75 F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 6f9dd5d774003ea81b8b32daa7d0819f9aaf01bf2b5f33498a69aab096094ed3 +F ext/fts3/fts3_write.c ddf34315b6c3dce79a28d966981cc76919b18f645d82c6132133a7c65b8ed283 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -944,7 +944,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f F test/fts3corrupt.test ce7f7b5eaeee5f1804584d061b978d85e64abf2af9adaa7577589fac6f7eae01 F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test e407c7b4f4cd3335080833aff3a8855d520e531b79f84dcc77be4623af2342d4 +F test/fts3corrupt4.test e8ad49403179cbf714b6b669d2e0f9234ae95f4ca258a253b0f29ce28c1b027c F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f @@ -1858,7 +1858,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 57c36a293e16bb4d9652874124ee1447bef278e08664bc8dd0070a0ee2ef1173 -R 9dccc312e85b3ed88562ba275ed8ce3c -U drh -Z 6739930e1718a08cc04c781aee16b618 +P ae6dd8d3e921670ee6450453b54245dd71bcfff3fd1bc7fdb7cf4cf9585c3375 +R 0487967de468b81b8b62d26c2e2b6661 +U dan +Z 5a6dd2cfccba72f8d349f449c1f47679 diff --git a/manifest.uuid b/manifest.uuid index 172eab1b25..5f44c5eff9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae6dd8d3e921670ee6450453b54245dd71bcfff3fd1bc7fdb7cf4cf9585c3375 \ No newline at end of file +fb7ccf61bed8d862986eda7096bec3df5947f1d1c88f27e7d9c8acf420f40c50 \ No newline at end of file diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index 7404ddeb2c..b11d19c7f1 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -5821,4 +5821,17 @@ do_catchsql_test 36.0 { INSERT INTO f(f) VALUES ('merge=53,216'); } {0 {}} +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 36.0 { + CREATE VIRTUAL TABLE f USING fts3(a,b); + CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB); + INSERT INTO f_stat VALUES (1,x'11014101000101c5c5014b010164c5014b010101c50101c5c5010201010101014101000101c5c5014b010101c5014b010101c50101c5c501010100c50101c5c5010101010101e40201010101014101000201010101014101000101010201010101014101000101c5c503b5fefefe3afeffffc5c5c5c50101010101010201010101014101adadadadadadadadadadadad91adadadadadadadad0101c50101c5c501f9ffffffffffffffff0001010102010101010140f5000101c5c5014b010101c50101c5c501010101e6010201010101014101000101c5c5014b010101c50101c5c5010101114b0101c5c50101010a0101020101e60101'); +} + +do_catchsql_test 36.1 { + INSERT INTO f(f) VALUES ('merge=59,59'); +} {1 {database disk image is malformed}} + finish_test From 5bdad79f014b019c8ca16c21385ef6152b53de82 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Feb 2020 13:09:56 +0000 Subject: [PATCH 003/102] Remove dead code from the sqlite3_filename_database() function. FossilOrigin-Name: 1b6185550f2bcfa11513898984f1fc2029e0356e9acdc786c5c4a8006b1da2ba --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/main.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f36594516f..815da23d80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\sfts3\sproblems\sfound\sby\susan. -D 2020-02-06T10:55:10.559 +C Remove\sdead\scode\sfrom\sthe\ssqlite3_filename_database()\sfunction. +D 2020-02-06T13:09:56.663 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 2223cf26a924f9209fdc78c54d22561fc3aabf1ad0148f4f275d4059ca7abc08 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8cd803f1747c03a50b32fe87ebfb5851998d0cdafefe02737daa95e0616b42bb -F src/main.c d7f1fc6891ac97845381b343ce5fa767b10d0768aa307c6a8e0c5675d457c4b6 +F src/main.c 332de0873baf22addd6479df053aeeb6e143e40f8959686487318da432b0624f F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -1858,7 +1858,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 ae6dd8d3e921670ee6450453b54245dd71bcfff3fd1bc7fdb7cf4cf9585c3375 -R 0487967de468b81b8b62d26c2e2b6661 -U dan -Z 5a6dd2cfccba72f8d349f449c1f47679 +P fb7ccf61bed8d862986eda7096bec3df5947f1d1c88f27e7d9c8acf420f40c50 +R 47d7d1ecdb43ed69247a9e06037e9529 +U drh +Z a68a579de8fd2a79231a8dd086eae079 diff --git a/manifest.uuid b/manifest.uuid index 5f44c5eff9..1f130ff739 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb7ccf61bed8d862986eda7096bec3df5947f1d1c88f27e7d9c8acf420f40c50 \ No newline at end of file +1b6185550f2bcfa11513898984f1fc2029e0356e9acdc786c5c4a8006b1da2ba \ No newline at end of file diff --git a/src/main.c b/src/main.c index 179cff4856..1ceaa798a4 100644 --- a/src/main.c +++ b/src/main.c @@ -4348,7 +4348,6 @@ sqlite3_int64 sqlite3_uri_int64( */ const char *sqlite3_filename_database(const char *zFilename){ return databaseName(zFilename); - return sqlite3_uri_parameter(zFilename - 3, "\003"); } const char *sqlite3_filename_journal(const char *zFilename){ zFilename = databaseName(zFilename); From c879c4eac05f6fe5f6dc6c8efd214751a7add863 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Feb 2020 13:57:08 +0000 Subject: [PATCH 004/102] Separate OP_IdxInsert and OP_SorterInsert into completely separate opcodes, helping each one to run a little faster. FossilOrigin-Name: 447d71f0867a11f789eba164ea77470b3ae4953927556304b0861cf690250776 --- manifest | 12 +++++----- manifest.uuid | 2 +- src/vdbe.c | 61 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 44 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 815da23d80..902cdc59bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sdead\scode\sfrom\sthe\ssqlite3_filename_database()\sfunction. -D 2020-02-06T13:09:56.663 +C Separate\sOP_IdxInsert\sand\sOP_SorterInsert\sinto\scompletely\sseparate\sopcodes,\nhelping\seach\sone\sto\srun\sa\slittle\sfaster. +D 2020-02-06T13:57:08.833 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -603,7 +603,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c 736ff76753236ffbc8b5b939f5e0607f28aeaa7c780b3a56b419228f0a81c87b F src/util.c d035b09df9cecbc0e8f07c34b815acbf0d43c8adc8d2c540e3dc92eecb27855a F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 0fdca82c67c68499d1dc3e310e39b7ee30cd262a535f848f3d0a3fee00b70662 +F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8 F src/vdbe.h defd693289c7bb8d325f109be9490c77138061211a116827da7244b6015a4934 F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 @@ -1858,7 +1858,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 fb7ccf61bed8d862986eda7096bec3df5947f1d1c88f27e7d9c8acf420f40c50 -R 47d7d1ecdb43ed69247a9e06037e9529 +P 1b6185550f2bcfa11513898984f1fc2029e0356e9acdc786c5c4a8006b1da2ba +R 6c5034c183af00de058bb8ba30ad870b U drh -Z a68a579de8fd2a79231a8dd086eae079 +Z 5ae5fcb755dbae0b5dc8eff20eb76a38 diff --git a/manifest.uuid b/manifest.uuid index 1f130ff739..56c7043a5e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b6185550f2bcfa11513898984f1fc2029e0356e9acdc786c5c4a8006b1da2ba \ No newline at end of file +447d71f0867a11f789eba164ea77470b3ae4953927556304b0861cf690250776 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 8e59d89c0e..e3a920ffcc 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5587,14 +5587,6 @@ next_tail: ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ -/* Opcode: SorterInsert P1 P2 * * * -** Synopsis: key=r[P2] -** -** Register P2 holds an SQL index key made using the -** MakeRecord instructions. This opcode writes that key -** into the sorter P1. Data for the entry is nil. -*/ -case OP_SorterInsert: /* in2 */ case OP_IdxInsert: { /* in2 */ VdbeCursor *pC; BtreePayload x; @@ -5603,28 +5595,49 @@ case OP_IdxInsert: { /* in2 */ pC = p->apCsr[pOp->p1]; sqlite3VdbeIncrWriteCounter(p, pC); assert( pC!=0 ); - assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); + assert( !isSorter(pC) ); pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert ); + assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc ) goto abort_due_to_error; - if( pOp->opcode==OP_SorterInsert ){ - rc = sqlite3VdbeSorterWrite(pC, pIn2); - }else{ - x.nKey = pIn2->n; - x.pKey = pIn2->z; - x.aMem = aMem + pOp->p3; - x.nMem = (u16)pOp->p4.i; - rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) - ); - assert( pC->deferredMoveto==0 ); - pC->cacheStatus = CACHE_STALE; - } + x.nKey = pIn2->n; + x.pKey = pIn2->z; + x.aMem = aMem + pOp->p3; + x.nMem = (u16)pOp->p4.i; + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) + ); + assert( pC->deferredMoveto==0 ); + pC->cacheStatus = CACHE_STALE; + if( rc) goto abort_due_to_error; + break; +} + +/* Opcode: SorterInsert P1 P2 * * * +** Synopsis: key=r[P2] +** +** Register P2 holds an SQL index key made using the +** MakeRecord instructions. This opcode writes that key +** into the sorter P1. Data for the entry is nil. +*/ +case OP_SorterInsert: { /* in2 */ + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; + sqlite3VdbeIncrWriteCounter(p, pC); + assert( pC!=0 ); + assert( isSorter(pC) ); + pIn2 = &aMem[pOp->p2]; + assert( pIn2->flags & MEM_Blob ); + assert( pC->isTable==0 ); + rc = ExpandBlob(pIn2); + if( rc ) goto abort_due_to_error; + rc = sqlite3VdbeSorterWrite(pC, pIn2); if( rc) goto abort_due_to_error; break; } From 0de19cac43b83ff4fa9840479633636f8bc0af37 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 6 Feb 2020 15:38:43 +0000 Subject: [PATCH 005/102] Unroll the comparison loop inside keywordCode() for to avoid unnecessary comparisions and thus help that routine run faster. FossilOrigin-Name: cec5f920f5c2a963f88329a08a443fc04be2dd6f7f2d840be63c0ab1de898f0a --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/mkkeywordhash.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 902cdc59bf..150ab07c28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Separate\sOP_IdxInsert\sand\sOP_SorterInsert\sinto\scompletely\sseparate\sopcodes,\nhelping\seach\sone\sto\srun\sa\slittle\sfaster. -D 2020-02-06T13:57:08.833 +C Unroll\sthe\scomparison\sloop\sinside\skeywordCode()\sfor\sto\savoid\sunnecessary\ncomparisions\sand\sthus\shelp\sthat\sroutine\srun\sfaster. +D 2020-02-06T15:38:43.416 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1786,7 +1786,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c 27ffc6f6e7e3ecbfc5bca1f1f11a09fc5badf6d67557a5fb2d3b069dbed90617 +F tool/mkkeywordhash.c 11a3f3af8e787d0c5ca459ed66fe80fd09e661876506e7b978ec08c19477bdc2 F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 @@ -1858,7 +1858,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 1b6185550f2bcfa11513898984f1fc2029e0356e9acdc786c5c4a8006b1da2ba -R 6c5034c183af00de058bb8ba30ad870b +P 447d71f0867a11f789eba164ea77470b3ae4953927556304b0861cf690250776 +R ea5228ccf18ab13503d6bdce095d9bcb U drh -Z 5ae5fcb755dbae0b5dc8eff20eb76a38 +Z 1d0c980ba3c95578cb44a456472b3894 diff --git a/manifest.uuid b/manifest.uuid index 56c7043a5e..56a4a65f87 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -447d71f0867a11f789eba164ea77470b3ae4953927556304b0861cf690250776 \ No newline at end of file +cec5f920f5c2a963f88329a08a443fc04be2dd6f7f2d840be63c0ab1de898f0a \ No newline at end of file diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index e4393e8a5a..83ec179ba0 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -652,12 +652,17 @@ int main(int argc, char **argv){ bestSize); printf(" for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){\n"); printf(" if( aKWLen[i]!=n ) continue;\n"); - printf(" j = 0;\n"); printf(" zKW = &zKWText[aKWOffset[i]];\n"); printf("#ifdef SQLITE_ASCII\n"); + printf(" if( (z[0]&~0x20)!=zKW[0] ) continue;\n"); + printf(" if( (z[1]&~0x20)!=zKW[1] ) continue;\n"); + printf(" j = 2;\n"); printf(" while( j Date: Thu, 6 Feb 2020 20:46:08 +0000 Subject: [PATCH 006/102] There is no need to keep track of the number of changed rows or of the last-insert-rowid while running VACUUM. FossilOrigin-Name: a8a7c05b16f6c73ac55c359fbf62cae4a76eb0d105a3c53e9f47cede9fd85916 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 150ab07c28..3cb0eaad8f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Unroll\sthe\scomparison\sloop\sinside\skeywordCode()\sfor\sto\savoid\sunnecessary\ncomparisions\sand\sthus\shelp\sthat\sroutine\srun\sfaster. -D 2020-02-06T15:38:43.416 +C There\sis\sno\sneed\sto\skeep\strack\sof\sthe\snumber\sof\schanged\srows\sor\sof\sthe\nlast-insert-rowid\swhile\srunning\sVACUUM. +D 2020-02-06T20:46:08.792 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 2223cf26a924f9209fdc78c54d22561fc3aabf1ad0148f4f275d4059ca7abc08 +F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8cd803f1747c03a50b32fe87ebfb5851998d0cdafefe02737daa95e0616b42bb F src/main.c 332de0873baf22addd6479df053aeeb6e143e40f8959686487318da432b0624f @@ -1858,7 +1858,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 447d71f0867a11f789eba164ea77470b3ae4953927556304b0861cf690250776 -R ea5228ccf18ab13503d6bdce095d9bcb +P cec5f920f5c2a963f88329a08a443fc04be2dd6f7f2d840be63c0ab1de898f0a +R b51f3dfb362da39a5cd79beb6cd6234e U drh -Z 1d0c980ba3c95578cb44a456472b3894 +Z 17a97c3ab44b587d0093a75b4dccf269 diff --git a/manifest.uuid b/manifest.uuid index 56a4a65f87..58d9ad8533 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cec5f920f5c2a963f88329a08a443fc04be2dd6f7f2d840be63c0ab1de898f0a \ No newline at end of file +a8a7c05b16f6c73ac55c359fbf62cae4a76eb0d105a3c53e9f47cede9fd85916 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 5951a546f9..43d2f11c14 100644 --- a/src/insert.c +++ b/src/insert.c @@ -2791,8 +2791,7 @@ static int xferOptimization( } if( db->mDbFlags & DBFLAG_Vacuum ){ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID| - OPFLAG_APPEND|OPFLAG_USESEEKRESULT; + insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT; }else{ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND; } @@ -2844,8 +2843,7 @@ static int xferOptimization( idxInsFlags = OPFLAG_USESEEKRESULT; sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); } - } - if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ + }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); From b48c0d59faf3bfd3e1fc0c3bed5557816c36cb7e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2020 01:12:53 +0000 Subject: [PATCH 007/102] Simplify the code by removing the unsupported and undocumented SQLITE_HAS_CODEC compile-time option FossilOrigin-Name: 5a877221ce90e7523059353a68650c5fdd28ed032807afc2f10afbfbf864bdfe --- manifest | 52 +++++++-------- manifest.uuid | 2 +- src/attach.c | 36 ---------- src/backup.c | 31 --------- src/btree.c | 6 -- src/btreeInt.h | 3 - src/ctime.c | 3 - src/global.c | 9 +-- src/main.c | 38 ----------- src/pager.c | 155 ++----------------------------------------- src/pager.h | 7 -- src/pragma.c | 50 +------------- src/pragma.h | 133 +++++++++++++------------------------ src/sqlite.h.in | 45 ------------- src/sqliteInt.h | 6 +- src/tclsqlite.c | 32 +-------- src/test1.c | 28 -------- src/test_config.c | 4 -- src/test_thread.c | 16 ----- src/util.c | 4 +- src/vacuum.c | 11 --- src/wal.c | 8 --- tool/mkpragmatab.tcl | 34 +--------- 23 files changed, 85 insertions(+), 628 deletions(-) diff --git a/manifest b/manifest index 3cb0eaad8f..6e923b7e4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C There\sis\sno\sneed\sto\skeep\strack\sof\sthe\snumber\sof\schanged\srows\sor\sof\sthe\nlast-insert-rowid\swhile\srunning\sVACUUM. -D 2020-02-06T20:46:08.792 +C Simplify\sthe\scode\sby\sremoving\sthe\sunsupported\sand\sundocumented\s\nSQLITE_HAS_CODEC\scompile-time\soption +D 2020-02-07T01:12:53.927 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -467,18 +467,18 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c -F src/attach.c df0ead9091042c68964856ecc08dba55d5403ad5f3ca865d9d396d71528c511a +F src/attach.c fee2f4279474edad2df73f38ff17d8b6b250429c6e9b59a708fb48a090f3ad32 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 -F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab +F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c ff1af84ce7ddb2a38dc47c7a331a2d7b4603565e41ae0588c55aa7e3d43a6cd3 +F src/btree.c 7cc1fb4086847a9089d78ebc3e52f5437d4aed20fc7d2da13219cba9fd5a8c8d F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471 -F src/btreeInt.h 6794084fad08c9750b45145743c0e3e5c27c94dee89f26dd8df7073314934fd2 +F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175 F src/build.c 2394d2c853088106dfc1cf485d609f20e6421d7c84892b795824e454f78e50ad F src/callback.c c547d00963ae28100117b4fb1f0f32242109b5804374ee3bfe01138a54da7f76 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 +F src/ctime.c 6a77ec9e0eb87aea929e002c816298907e337094a7b556898ae2d1e6be209f90 F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da @@ -487,7 +487,7 @@ F src/expr.c 6617ca8d4cc808b82348ae0c2844000b665de86aacc60fa0524f1b29b1918921 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847 F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4 -F src/global.c 59601d885a0dbbfbd22ed2d030424a5e7f1b9809a17ca46686058bbc4a55e980 +F src/global.c 79a988b56b06ce2d08ebefe1d35da9aa25b3851faa47ea5233361c4827185a64 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 @@ -495,7 +495,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8cd803f1747c03a50b32fe87ebfb5851998d0cdafefe02737daa95e0616b42bb -F src/main.c 332de0873baf22addd6479df053aeeb6e143e40f8959686487318da432b0624f +F src/main.c 12d42b43c331778f6e3a1ebc57b63470f1951350efbea377e03cac6660e03b57 F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -518,14 +518,14 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c ad7640c04eed946052a3b12856362a773d0a717696707313037186df0e2b59f2 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c c0bca72aa3f7b1cf521a9f350fcf8e5975ebf98da7dbb03492be876b0f053781 -F src/pager.h 71fe1d5016ec54d0cc5d344cd474e563450b438c59f535e8c1ec8a13b1373f14 +F src/pager.c b1e79698f3903e64d7a8ab5f4b3163aa39ed25686289a68de20b6b5734de70e6 +F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3 F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c 0d49d43b22d66397aa026db505457f6683d8a66cd0a4f9db2e6776156bda716c -F src/pragma.h 9f86a3a3a0099e651189521c8ad03768df598974e7bbdc21c7f9bb6125592fbd +F src/pragma.c 4c8f3665cb3e1b114d22319f944a0c73c9563869c1f01a322732a880a7a2f82a +F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -533,15 +533,15 @@ F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 3f7aecf64b08b018b89e4fe16ea621cc9a0e3f3801e9e5638cfe1a6035fa1581 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa -F src/sqlite.h.in 75d0304247a2154122d6d06f12219c1e29291d72304f0eeef4c1ec6b1409b443 +F src/sqlite.h.in 572ea78b08ee90529d7588cea966c350afbf9624fdf133378edb346a233c6625 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 27951f294f29cd875c6027f2707d644ef99f469bd97514568b5a8581a114db8c -F src/sqliteInt.h 59194e8ad25bb0ad27205cb356427371cff73af85d1a6f09ed8fd9389ab662ff +F src/sqliteInt.h ce2038197482723e6da107447d95e4d3a1afcfd630c955b6abef5dc9ff597567 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c 97590069efaba5a4928ecffb606e3771dd93ee8e6bf248a62a6507c37a2b2e46 -F src/test1.c 4d0ab2f67053a4fff87d1d3586ecc0e5322a1fc45dd4119ab11dc96de44f17a1 +F src/tclsqlite.c d0aa320416efe88c4dbb0156ed6c494f2f9958871a940e46984ee57b3e7fcc50 +F src/test1.c 5e8b8cc54e8c88906ea8a084387aa79bad245e539f4cee73149e5c0527e1db16 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -556,7 +556,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857 F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c e25826d693039cdd45963de378cbf39e3af0e8aa7a8a6fc159876f4e7b5a4f8c +F src/test_config.c 5ea19bf0972a9d91728518b4d30e91477acce80496003ecbef3a7fb18d0bd081 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91 F src/test_devsym.c 6109b45c3db3ef7b002320947ed448c027356ab8b885156ff535fd8684d4a571 @@ -586,7 +586,7 @@ F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 1073306ba2e9bfc886771871a13d3de281ed3939 F src/test_tclsh.c eeafce33ad2136d57e5dec10f1e9a4347447eb72ffd504a1c7b9c6bfe2e71578 F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc -F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 +F src/test_thread.c 269ea9e1fa5828dba550eb26f619aa18aedbc29fd92f8a5f6b93521fbb74a61c F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 F src/test_vfs.c 36822d696789535bdd0260f07d2c9a46546082fea8bb1d0a7354c7f9366e37ea F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 @@ -601,8 +601,8 @@ F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc F src/update.c 9ad19af96aff95dc02a923a99f97c1bc0b909009a29a2914b796f786b9ac0c60 F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c 736ff76753236ffbc8b5b939f5e0607f28aeaa7c780b3a56b419228f0a81c87b -F src/util.c d035b09df9cecbc0e8f07c34b815acbf0d43c8adc8d2c540e3dc92eecb27855a -F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf +F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a +F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9 F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8 F src/vdbe.h defd693289c7bb8d325f109be9490c77138061211a116827da7244b6015a4934 F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 @@ -614,7 +614,7 @@ F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587d F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c dbc77159e6734c2d64343cb8624ad245d89dd79a5010750fce8118b3fa7be2e8 +F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d F src/where.c 2005d0511e05e5f7b6fb3be514b44f264f23d45f3b0cc5e150c63e3006a003e5 @@ -1791,7 +1791,7 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa -F tool/mkpragmatab.tcl ca12b1c718ececdab2d3aacb437bc3c81ebf68467f19d7974e17f18844a3a48f +F tool/mkpragmatab.tcl 62663c65d9191aada624a787e1ee3420f268a3c27999ad0ffb77a6918ddc1e52 F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1858,7 +1858,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 cec5f920f5c2a963f88329a08a443fc04be2dd6f7f2d840be63c0ab1de898f0a -R b51f3dfb362da39a5cd79beb6cd6234e +P a8a7c05b16f6c73ac55c359fbf62cae4a76eb0d105a3c53e9f47cede9fd85916 +R 014522d0d8b6f7e2f23a6a5506d80ae9 U drh -Z 17a97c3ab44b587d0093a75b4dccf269 +Z bb09705c5da204b17eae60b0010baaaf diff --git a/manifest.uuid b/manifest.uuid index 58d9ad8533..6aa6ce42b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8a7c05b16f6c73ac55c359fbf62cae4a76eb0d105a3c53e9f47cede9fd85916 \ No newline at end of file +5a877221ce90e7523059353a68650c5fdd28ed032807afc2f10afbfbf864bdfe \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index fdd71854ed..21da21fe0a 100644 --- a/src/attach.c +++ b/src/attach.c @@ -187,42 +187,6 @@ static void attachFunc( if( rc==SQLITE_OK && pNew->zDbSName==0 ){ rc = SQLITE_NOMEM_BKPT; } - - -#ifdef SQLITE_HAS_CODEC - if( rc==SQLITE_OK ){ - extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); - extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); - int nKey; - char *zKey; - int t = sqlite3_value_type(argv[2]); - switch( t ){ - case SQLITE_INTEGER: - case SQLITE_FLOAT: - zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); - rc = SQLITE_ERROR; - break; - - case SQLITE_TEXT: - case SQLITE_BLOB: - nKey = sqlite3_value_bytes(argv[2]); - zKey = (char *)sqlite3_value_blob(argv[2]); - rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); - break; - - case SQLITE_NULL: - /* No key specified. Use the key from URI filename, or if none, - ** use the key from the main database. */ - if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){ - sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ - rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); - } - } - break; - } - } -#endif sqlite3_free( zPath ); /* If the file was opened successfully, read the schema for the new database. diff --git a/src/backup.c b/src/backup.c index 5e9c974ae1..233d0cee7f 100644 --- a/src/backup.c +++ b/src/backup.c @@ -235,13 +235,6 @@ static int backupOnePage( int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); const int nCopy = MIN(nSrcPgsz, nDestPgsz); const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; -#ifdef SQLITE_HAS_CODEC - /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is - ** guaranteed that the shared-mutex is held by this thread, handle - ** p->pSrc may not actually be the owner. */ - int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc); - int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest); -#endif int rc = SQLITE_OK; i64 iOff; @@ -258,26 +251,6 @@ static int backupOnePage( rc = SQLITE_READONLY; } -#ifdef SQLITE_HAS_CODEC - /* Backup is not possible if the page size of the destination is changing - ** and a codec is in use. - */ - if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){ - rc = SQLITE_READONLY; - } - - /* Backup is not possible if the number of bytes of reserve space differ - ** between source and destination. If there is a difference, try to - ** fix the destination to agree with the source. If that is not possible, - ** then the backup cannot proceed. - */ - if( nSrcReserve!=nDestReserve ){ - u32 newPgsz = nSrcPgsz; - rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); - if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY; - } -#endif - /* This loop runs once for each destination page spanned by the source ** page. For each iteration, variable iOff is set to the byte offset ** of the destination page. @@ -773,10 +746,6 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ b.pDest = pTo; b.iNext = 1; -#ifdef SQLITE_HAS_CODEC - sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom)); -#endif - /* 0x7FFFFFFF is the hard limit for the number of pages in a database ** file. By passing this as the number of pages to copy to ** sqlite3_backup_step(), we can guarantee that the copy finishes diff --git a/src/btree.c b/src/btree.c index 46615875cc..de05fd999c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2859,9 +2859,6 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ BtShared *pBt = p->pBt; assert( nReserve>=-1 && nReserve<=255 ); sqlite3BtreeEnter(p); -#if SQLITE_HAS_CODEC - if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve; -#endif if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ sqlite3BtreeLeave(p); return SQLITE_READONLY; @@ -2922,9 +2919,6 @@ int sqlite3BtreeGetOptimalReserve(Btree *p){ int n; sqlite3BtreeEnter(p); n = sqlite3BtreeGetReserveNoMutex(p); -#ifdef SQLITE_HAS_CODEC - if( npBt->optimalReserve ) n = p->pBt->optimalReserve; -#endif sqlite3BtreeLeave(p); return n; } diff --git a/src/btreeInt.h b/src/btreeInt.h index 7687a0f1ec..e5149d97ea 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -417,9 +417,6 @@ struct BtShared { #endif u8 inTransaction; /* Transaction state */ u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */ -#ifdef SQLITE_HAS_CODEC - u8 optimalReserve; /* Desired amount of reserved space per page */ -#endif u16 btsFlags; /* Boolean parameters. See BTS_* macros below */ u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */ u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */ diff --git a/src/ctime.c b/src/ctime.c index 013a0c2670..7a2ace9317 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -355,9 +355,6 @@ static const char * const sqlite3azCompileOpt[] = { #if SQLITE_FTS5_NO_WITHOUT_ROWID "FTS5_NO_WITHOUT_ROWID", #endif -#if SQLITE_HAS_CODEC - "HAS_CODEC", -#endif #if HAVE_ISNAN || SQLITE_HAVE_ISNAN "HAVE_ISNAN", #endif diff --git a/src/global.c b/src/global.c index a2c51f41fb..aeddada6f2 100644 --- a/src/global.c +++ b/src/global.c @@ -135,16 +135,9 @@ const unsigned char sqlite3CtypeMap[256] = { ** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** SQLITE_USE_URI symbol defined. -** -** URI filenames are enabled by default if SQLITE_HAS_CODEC is -** enabled. */ #ifndef SQLITE_USE_URI -# ifdef SQLITE_HAS_CODEC -# define SQLITE_USE_URI 1 -# else -# define SQLITE_USE_URI 0 -# endif +# define SQLITE_USE_URI 0 #endif /* EVIDENCE-OF: R-38720-18127 The default setting is determined by the diff --git a/src/main.c b/src/main.c index 1ceaa798a4..3eccd08ea7 100644 --- a/src/main.c +++ b/src/main.c @@ -3007,41 +3007,6 @@ static const char *uriParameter(const char *zFilename, const char *zParam){ return 0; } -#if defined(SQLITE_HAS_CODEC) -/* -** Process URI filename query parameters relevant to the SQLite Encryption -** Extension. Return true if any of the relevant query parameters are -** seen and return false if not. -*/ -int sqlite3CodecQueryParameters( - sqlite3 *db, /* Database connection */ - const char *zDb, /* Which schema is being created/attached */ - const char *zUri /* URI filename */ -){ - const char *zKey; - if( zUri==0 ){ - return 0; - }else if( (zKey = uriParameter(zUri, "hexkey"))!=0 && zKey[0] ){ - u8 iByte; - int i; - char zDecoded[40]; - for(i=0, iByte=0; ixCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; } -# define CODEC2(P,D,N,X,E,O) \ - if( P->xCodec==0 ){ O=(char*)D; }else \ - if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; } -#else -# define CODEC1(P,D,N,X,E) /* NO-OP */ -# define CODEC2(P,D,N,X,E,O) O=(char*)D -#endif - /* ** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. @@ -705,12 +691,6 @@ struct Pager { #endif void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */ -#ifdef SQLITE_HAS_CODEC - void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ - void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ - void (*xCodecFree)(void*); /* Destructor for the codec */ - void *pCodec; /* First argument to xCodec... methods */ -#endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ PCache *pPCache; /* Pointer to page cache object */ #ifndef SQLITE_OMIT_WAL @@ -837,9 +817,6 @@ static const unsigned char aJournalMagic[] = { int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ if( pPager->fd->pMethods==0 ) return 0; if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; -#ifdef SQLITE_HAS_CODEC - if( pPager->xCodec!=0 ) return 0; -#endif #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; @@ -1073,11 +1050,7 @@ static void setGetterMethod(Pager *pPager){ if( pPager->errCode ){ pPager->xGet = getPageError; #if SQLITE_MAX_MMAP_SIZE>0 - }else if( USEFETCH(pPager) -#ifdef SQLITE_HAS_CODEC - && pPager->xCodec==0 -#endif - ){ + }else if( USEFETCH(pPager) ){ pPager->xGet = getPageMMap; #endif /* SQLITE_MAX_MMAP_SIZE>0 */ }else{ @@ -2225,35 +2198,6 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){ return cksum; } -/* -** Report the current page size and number of reserved bytes back -** to the codec. -*/ -#ifdef SQLITE_HAS_CODEC -static void pagerReportSize(Pager *pPager){ - if( pPager->xCodecSizeChng ){ - pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, - (int)pPager->nReserve); - } -} -#else -# define pagerReportSize(X) /* No-op if we do not support a codec */ -#endif - -#ifdef SQLITE_HAS_CODEC -/* -** Make sure the number of reserved bits is the same in the destination -** pager as it is in the source. This comes up when a VACUUM changes the -** number of reserved bits to the "optimal" amount. -*/ -void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){ - if( pDest->nReserve!=pSrc->nReserve ){ - pDest->nReserve = pSrc->nReserve; - pagerReportSize(pDest); - } -} -#endif - /* ** Read a single page from either the journal file (if isMainJrnl==1) or ** from the sub-journal (if isMainJrnl==0) and playback that page. @@ -2305,11 +2249,6 @@ static int pager_playback_one_page( char *aData; /* Temporary storage for the page */ sqlite3_file *jfd; /* The file descriptor for the journal file */ int isSynced; /* True if journal page is synced */ -#ifdef SQLITE_HAS_CODEC - /* The jrnlEnc flag is true if Journal pages should be passed through - ** the codec. It is false for pure in-memory journals. */ - const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0); -#endif assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */ assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */ @@ -2372,7 +2311,6 @@ static int pager_playback_one_page( */ if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ pPager->nReserve = ((u8*)aData)[20]; - pagerReportSize(pPager); } /* If the pager is in CACHEMOD state, then there must be a copy of this @@ -2440,26 +2378,12 @@ static int pager_playback_one_page( ** is if the data was just read from an in-memory sub-journal. In that ** case it must be encrypted here before it is copied into the database ** file. */ -#ifdef SQLITE_HAS_CODEC - if( !jrnlEnc ){ - CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData); - rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); - CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); - }else -#endif rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } if( pPager->pBackup ){ -#ifdef SQLITE_HAS_CODEC - if( jrnlEnc ){ - CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); - sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); - CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData); - }else -#endif sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); } }else if( !isMainJrnl && pPg==0 ){ @@ -2510,11 +2434,6 @@ static int pager_playback_one_page( if( pgno==1 ){ memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers)); } - - /* Decode the page just read from disk */ -#if SQLITE_HAS_CODEC - if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); } -#endif sqlite3PcacheRelease(pPg); } return rc; @@ -3074,8 +2993,6 @@ static int readDbPage(PgHdr *pPg){ memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); } } - CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT); - PAGER_INCR(sqlite3_pager_readdb_count); PAGER_INCR(pPager->nRead); IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno)); @@ -3819,7 +3736,6 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ if( nReserve<0 ) nReserve = pPager->nReserve; assert( nReserve>=0 && nReserve<1000 ); pPager->nReserve = (i16)nReserve; - pagerReportSize(pPager); pagerFixMaplimit(pPager); } return rc; @@ -4215,11 +4131,6 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ sqlite3OsClose(pPager->fd); sqlite3PageFree(pTmp); sqlite3PcacheClose(pPager->pPCache); - -#ifdef SQLITE_HAS_CODEC - if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); -#endif - assert( !pPager->aSavepoint && !pPager->pInJournal ); assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); @@ -4470,8 +4381,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); if( pList->pgno==1 ) pager_write_changecounter(pList); - /* Encode the database */ - CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData); + pData = pList->pData; /* Write out the page data. */ rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); @@ -4560,12 +4470,6 @@ static int subjournalPage(PgHdr *pPg){ void *pData = pPg->pData; i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize); char *pData2; - -#if SQLITE_HAS_CODEC - if( !pPager->subjInMemory ){ - CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2); - }else -#endif pData2 = pData; PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); rc = write32bits(pPager->sjfd, offset, pPg->pgno); @@ -5647,9 +5551,6 @@ static int getPageMMap( ); assert( USEFETCH(pPager) ); -#ifdef SQLITE_HAS_CODEC - assert( pPager->xCodec==0 ); -#endif /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here ** allows the compiler optimizer to reuse the results of the "pgno>1" @@ -5978,7 +5879,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){ assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) ); assert( pPager->journalHdr<=pPager->journalOff ); - CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2); + pData2 = pPg->pData; cksum = pager_cksum(pPager, (u8*)pData2); /* Even if an IO or diskfull error occurs while journalling the @@ -6343,7 +6244,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ if( DIRECT_MODE ){ const void *zBuf; assert( pPager->dbFileSize>0 ); - CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf); + zBuf = pPgHdr->pData; if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); pPager->aStat[PAGER_STAT_WRITE]++; @@ -7102,54 +7003,6 @@ const char *sqlite3PagerJournalname(Pager *pPager){ return pPager->zJournal; } -#ifdef SQLITE_HAS_CODEC -/* -** Set or retrieve the codec for this pager -*/ -void sqlite3PagerSetCodec( - Pager *pPager, - void *(*xCodec)(void*,void*,Pgno,int), - void (*xCodecSizeChng)(void*,int,int), - void (*xCodecFree)(void*), - void *pCodec -){ - if( pPager->xCodecFree ){ - pPager->xCodecFree(pPager->pCodec); - }else{ - pager_reset(pPager); - } - pPager->xCodec = pPager->memDb ? 0 : xCodec; - pPager->xCodecSizeChng = xCodecSizeChng; - pPager->xCodecFree = xCodecFree; - pPager->pCodec = pCodec; - setGetterMethod(pPager); - pagerReportSize(pPager); -} -void *sqlite3PagerGetCodec(Pager *pPager){ - return pPager->pCodec; -} - -/* -** This function is called by the wal module when writing page content -** into the log file. -** -** This function returns a pointer to a buffer containing the encrypted -** page content. If a malloc fails, this function may return NULL. -*/ -void *sqlite3PagerCodec(PgHdr *pPg){ - void *aData = 0; - CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); - return aData; -} - -/* -** Return the current pager state -*/ -int sqlite3PagerState(Pager *pPager){ - return pPager->eState; -} -#endif /* SQLITE_HAS_CODEC */ - #ifndef SQLITE_OMIT_AUTOVACUUM /* ** Move the page pPg to location pgno in the file. diff --git a/src/pager.h b/src/pager.h index 904278944c..2c99d67a9b 100644 --- a/src/pager.h +++ b/src/pager.h @@ -128,9 +128,6 @@ int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); int sqlite3PagerSetPagesize(Pager*, u32*, int); -#ifdef SQLITE_HAS_CODEC -void sqlite3PagerAlignReserve(Pager*,Pager*); -#endif int sqlite3PagerMaxPageCount(Pager*, int); void sqlite3PagerSetCachesize(Pager*, int); int sqlite3PagerSetSpillsize(Pager*, int); @@ -224,10 +221,6 @@ void sqlite3PagerTruncateImage(Pager*,Pgno); void sqlite3PagerRekey(DbPage*, Pgno, u16); -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) -void *sqlite3PagerCodec(DbPage *); -#endif - /* Functions to support testing and debugging. */ #if !defined(NDEBUG) || defined(SQLITE_TEST) Pgno sqlite3PagerPagenumber(DbPage*); diff --git a/src/pragma.c b/src/pragma.c index 4d33e8c471..60e18e7f04 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -2215,59 +2215,11 @@ void sqlite3Pragma( } #endif -#ifdef SQLITE_HAS_CODEC - /* Pragma iArg - ** ---------- ------ - ** key 0 - ** rekey 1 - ** hexkey 2 - ** hexrekey 3 - ** textkey 4 - ** textrekey 5 - */ - case PragTyp_KEY: { - if( zRight ){ - char zBuf[40]; - const char *zKey = zRight; - int n; - if( pPragma->iArg==2 || pPragma->iArg==3 ){ - u8 iByte; - int i; - for(i=0, iByte=0; iiArg<4 ? sqlite3Strlen30(zRight) : -1; - } - if( (pPragma->iArg & 1)==0 ){ - rc = sqlite3_key_v2(db, zDb, zKey, n); - }else{ - rc = sqlite3_rekey_v2(db, zDb, zKey, n); - } - if( rc==SQLITE_OK && n!=0 ){ - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC); - returnSingleText(v, "ok"); - } - } - break; - } -#endif -#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) +#if defined(SQLITE_ENABLE_CEROD) case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){ -#ifdef SQLITE_HAS_CODEC - if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ - sqlite3_activate_see(&zRight[4]); - } -#endif -#ifdef SQLITE_ENABLE_CEROD if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ sqlite3_activate_cerod(&zRight[6]); } -#endif } break; #endif diff --git a/src/pragma.h b/src/pragma.h index 3edf5c1c30..7046695a5b 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -5,51 +5,50 @@ */ /* The various pragma types */ -#define PragTyp_HEADER_VALUE 0 -#define PragTyp_AUTO_VACUUM 1 -#define PragTyp_FLAG 2 -#define PragTyp_BUSY_TIMEOUT 3 -#define PragTyp_CACHE_SIZE 4 -#define PragTyp_CACHE_SPILL 5 -#define PragTyp_CASE_SENSITIVE_LIKE 6 -#define PragTyp_COLLATION_LIST 7 -#define PragTyp_COMPILE_OPTIONS 8 -#define PragTyp_DATA_STORE_DIRECTORY 9 -#define PragTyp_DATABASE_LIST 10 -#define PragTyp_DEFAULT_CACHE_SIZE 11 -#define PragTyp_ENCODING 12 -#define PragTyp_FOREIGN_KEY_CHECK 13 -#define PragTyp_FOREIGN_KEY_LIST 14 -#define PragTyp_FUNCTION_LIST 15 -#define PragTyp_HARD_HEAP_LIMIT 16 -#define PragTyp_INCREMENTAL_VACUUM 17 -#define PragTyp_INDEX_INFO 18 -#define PragTyp_INDEX_LIST 19 -#define PragTyp_INTEGRITY_CHECK 20 -#define PragTyp_JOURNAL_MODE 21 -#define PragTyp_JOURNAL_SIZE_LIMIT 22 -#define PragTyp_LOCK_PROXY_FILE 23 -#define PragTyp_LOCKING_MODE 24 -#define PragTyp_PAGE_COUNT 25 -#define PragTyp_MMAP_SIZE 26 -#define PragTyp_MODULE_LIST 27 -#define PragTyp_OPTIMIZE 28 -#define PragTyp_PAGE_SIZE 29 -#define PragTyp_PRAGMA_LIST 30 -#define PragTyp_SECURE_DELETE 31 -#define PragTyp_SHRINK_MEMORY 32 -#define PragTyp_SOFT_HEAP_LIMIT 33 -#define PragTyp_SYNCHRONOUS 34 -#define PragTyp_TABLE_INFO 35 -#define PragTyp_TEMP_STORE 36 -#define PragTyp_TEMP_STORE_DIRECTORY 37 -#define PragTyp_THREADS 38 -#define PragTyp_WAL_AUTOCHECKPOINT 39 -#define PragTyp_WAL_CHECKPOINT 40 -#define PragTyp_ACTIVATE_EXTENSIONS 41 -#define PragTyp_KEY 42 -#define PragTyp_LOCK_STATUS 43 -#define PragTyp_STATS 44 +#define PragTyp_ACTIVATE_EXTENSIONS 0 +#define PragTyp_HEADER_VALUE 1 +#define PragTyp_AUTO_VACUUM 2 +#define PragTyp_FLAG 3 +#define PragTyp_BUSY_TIMEOUT 4 +#define PragTyp_CACHE_SIZE 5 +#define PragTyp_CACHE_SPILL 6 +#define PragTyp_CASE_SENSITIVE_LIKE 7 +#define PragTyp_COLLATION_LIST 8 +#define PragTyp_COMPILE_OPTIONS 9 +#define PragTyp_DATA_STORE_DIRECTORY 10 +#define PragTyp_DATABASE_LIST 11 +#define PragTyp_DEFAULT_CACHE_SIZE 12 +#define PragTyp_ENCODING 13 +#define PragTyp_FOREIGN_KEY_CHECK 14 +#define PragTyp_FOREIGN_KEY_LIST 15 +#define PragTyp_FUNCTION_LIST 16 +#define PragTyp_HARD_HEAP_LIMIT 17 +#define PragTyp_INCREMENTAL_VACUUM 18 +#define PragTyp_INDEX_INFO 19 +#define PragTyp_INDEX_LIST 20 +#define PragTyp_INTEGRITY_CHECK 21 +#define PragTyp_JOURNAL_MODE 22 +#define PragTyp_JOURNAL_SIZE_LIMIT 23 +#define PragTyp_LOCK_PROXY_FILE 24 +#define PragTyp_LOCKING_MODE 25 +#define PragTyp_PAGE_COUNT 26 +#define PragTyp_MMAP_SIZE 27 +#define PragTyp_MODULE_LIST 28 +#define PragTyp_OPTIMIZE 29 +#define PragTyp_PAGE_SIZE 30 +#define PragTyp_PRAGMA_LIST 31 +#define PragTyp_SECURE_DELETE 32 +#define PragTyp_SHRINK_MEMORY 33 +#define PragTyp_SOFT_HEAP_LIMIT 34 +#define PragTyp_SYNCHRONOUS 35 +#define PragTyp_TABLE_INFO 36 +#define PragTyp_TEMP_STORE 37 +#define PragTyp_TEMP_STORE_DIRECTORY 38 +#define PragTyp_THREADS 39 +#define PragTyp_WAL_AUTOCHECKPOINT 40 +#define PragTyp_WAL_CHECKPOINT 41 +#define PragTyp_LOCK_STATUS 42 +#define PragTyp_STATS 43 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -133,7 +132,7 @@ typedef struct PragmaName { u64 iArg; /* Extra argument */ } PragmaName; static const PragmaName aPragmaName[] = { -#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) +#if defined(SQLITE_ENABLE_CEROD) {/* zName: */ "activate_extensions", /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS, /* ePragFlg: */ 0, @@ -329,18 +328,6 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_Result0, /* ColNames: */ 0, 0, /* iArg: */ 0 }, -#if defined(SQLITE_HAS_CODEC) - {/* zName: */ "hexkey", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, - /* iArg: */ 2 }, - {/* zName: */ "hexrekey", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, - /* iArg: */ 3 }, -#endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) #if !defined(SQLITE_OMIT_CHECK) {/* zName: */ "ignore_check_constraints", @@ -393,13 +380,6 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif -#if defined(SQLITE_HAS_CODEC) - {/* zName: */ "key", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, - /* iArg: */ 0 }, -#endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "legacy_alter_table", /* ePragTyp: */ PragTyp_FLAG, @@ -507,15 +487,6 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ SQLITE_RecTriggers }, -#endif -#if defined(SQLITE_HAS_CODEC) - {/* zName: */ "rekey", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, - /* iArg: */ 1 }, -#endif -#if !defined(SQLITE_OMIT_FLAG_PRAGMAS) {/* zName: */ "reverse_unordered_selects", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, @@ -599,18 +570,6 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_NoColumns1, /* ColNames: */ 0, 0, /* iArg: */ 0 }, -#endif -#if defined(SQLITE_HAS_CODEC) - {/* zName: */ "textkey", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, - /* iArg: */ 4 }, - {/* zName: */ "textrekey", - /* ePragTyp: */ PragTyp_KEY, - /* ePragFlg: */ 0, - /* ColNames: */ 0, 0, - /* iArg: */ 5 }, #endif {/* zName: */ "threads", /* ePragTyp: */ PragTyp_THREADS, @@ -680,4 +639,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 66 on by default, 82 total. */ +/* Number of pragmas: 66 on by default, 76 total. */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 6b32b6487a..367242bf27 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5817,51 +5817,6 @@ int sqlite3_collation_needed16( void(*)(void*,sqlite3*,int eTextRep,const void*) ); -#ifdef SQLITE_HAS_CODEC -/* -** Specify the key for an encrypted database. This routine should be -** called right after sqlite3_open(). -** -** The code to implement this API is not available in the public release -** of SQLite. -*/ -int sqlite3_key( - sqlite3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The key */ -); -int sqlite3_key_v2( - sqlite3 *db, /* Database to be rekeyed */ - const char *zDbName, /* Name of the database */ - const void *pKey, int nKey /* The key */ -); - -/* -** Change the key on an open database. If the current database is not -** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the -** database is decrypted. -** -** The code to implement this API is not available in the public release -** of SQLite. -*/ -int sqlite3_rekey( - sqlite3 *db, /* Database to be rekeyed */ - const void *pKey, int nKey /* The new key */ -); -int sqlite3_rekey_v2( - sqlite3 *db, /* Database to be rekeyed */ - const char *zDbName, /* Name of the database */ - const void *pKey, int nKey /* The new key */ -); - -/* -** Specify the activation key for a SEE database. Unless -** activated, none of the SEE routines will work. -*/ -void sqlite3_activate_see( - const char *zPassPhrase /* Activation phrase */ -); -#endif - #ifdef SQLITE_ENABLE_CEROD /* ** Specify the activation key for a CEROD database. Unless diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f0a63b16e9..76b37cb695 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4113,11 +4113,7 @@ void sqlite3AddGenerated(Parse*,Expr*,Token*); void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); -#ifdef SQLITE_HAS_CODEC - int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*); -#else -# define sqlite3CodecQueryParameters(A,B,C) 0 -#endif +#define sqlite3CodecQueryParameters(A,B,C) 0 Btree *sqlite3DbNameToBtree(sqlite3*,const char*); #ifdef SQLITE_UNTESTABLE diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 2cae5804a0..69da2ccd90 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3094,22 +3094,10 @@ deserialize_error: ** Change the encryption key on the currently open database. */ case DB_REKEY: { -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - int nKey; - void *pKey; -#endif if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "KEY"); return TCL_ERROR; } -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); - rc = sqlite3_rekey(pDb->db, pKey, nKey); - if( rc ){ - Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0); - rc = TCL_ERROR; - } -#endif break; } @@ -3678,9 +3666,6 @@ static int sqliteCmdUsage( "HANDLE ?FILENAME? ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" " ?-nofollow BOOLEAN?" " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - " ?-key CODECKEY?" -#endif ); return TCL_ERROR; } @@ -3715,10 +3700,6 @@ static int SQLITE_TCLAPI DbMain( const char *zVfs = 0; int flags; Tcl_DString translatedFilename; -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - void *pKey = 0; - int nKey = 0; -#endif int rc; /* In normal use, each TCL interpreter runs in a single thread. So @@ -3745,11 +3726,7 @@ static int SQLITE_TCLAPI DbMain( return TCL_OK; } if( strcmp(zArg,"-has-codec")==0 ){ -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - Tcl_AppendResult(interp,"1",(char*)0); -#else Tcl_AppendResult(interp,"0",(char*)0); -#endif return TCL_OK; } if( zArg[0]=='-' ) return sqliteCmdUsage(interp, objv); @@ -3764,9 +3741,7 @@ static int SQLITE_TCLAPI DbMain( if( i==objc-1 ) return sqliteCmdUsage(interp, objv); i++; if( strcmp(zArg,"-key")==0 ){ -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - pKey = Tcl_GetByteArrayFromObj(objv[i], &nKey); -#endif + /* no-op */ }else if( strcmp(zArg, "-vfs")==0 ){ zVfs = Tcl_GetString(objv[i]); }else if( strcmp(zArg, "-readonly")==0 ){ @@ -3842,11 +3817,6 @@ static int SQLITE_TCLAPI DbMain( }else{ zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc)); } -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - if( p->db ){ - sqlite3_key(p->db, pKey, nKey); - } -#endif if( p->db==0 ){ Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); Tcl_Free((char*)p); diff --git a/src/test1.c b/src/test1.c index 5b07aef2d5..29207d51ac 100644 --- a/src/test1.c +++ b/src/test1.c @@ -655,20 +655,6 @@ static int SQLITE_TCLAPI test_key( int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ -#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) - sqlite3 *db; - const char *zKey; - int nKey; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " FILENAME\"", 0); - return TCL_ERROR; - } - if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; - zKey = argv[2]; - nKey = strlen(zKey); - sqlite3_key(db, zKey, nKey); -#endif return TCL_OK; } @@ -683,20 +669,6 @@ static int SQLITE_TCLAPI test_rekey( int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ -#ifdef SQLITE_HAS_CODEC - sqlite3 *db; - const char *zKey; - int nKey; - if( argc!=3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " FILENAME\"", 0); - return TCL_ERROR; - } - if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; - zKey = argv[2]; - nKey = strlen(zKey); - sqlite3_rekey(db, zKey, nKey); -#endif return TCL_OK; } diff --git a/src/test_config.c b/src/test_config.c index e6c03308dc..362e92aa9a 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -226,11 +226,7 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY); #endif -#ifdef SQLITE_HAS_CODEC - Tcl_SetVar2(interp, "sqlite_options", "has_codec", "1", TCL_GLOBAL_ONLY); -#else Tcl_SetVar2(interp, "sqlite_options", "has_codec", "0", TCL_GLOBAL_ONLY); -#endif #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS Tcl_SetVar2(interp, "sqlite_options", "like_match_blobs", "0", TCL_GLOBAL_ONLY); diff --git a/src/test_thread.c b/src/test_thread.c index 20b4cf148b..de0fdb4346 100644 --- a/src/test_thread.c +++ b/src/test_thread.c @@ -287,22 +287,6 @@ static int SQLITE_TCLAPI sqlthread_open( zFilename = Tcl_GetString(objv[2]); sqlite3_open(zFilename, &db); -#ifdef SQLITE_HAS_CODEC - if( db && objc>=4 ){ - const char *zKey; - int nKey; - int rc; - zKey = Tcl_GetStringFromObj(objv[3], &nKey); - rc = sqlite3_key(db, zKey, nKey); - if( rc!=SQLITE_OK ){ - char *zErrMsg = sqlite3_mprintf("error %d: %s", rc, sqlite3_errmsg(db)); - sqlite3_close(db); - Tcl_AppendResult(interp, zErrMsg, (char*)0); - sqlite3_free(zErrMsg); - return TCL_ERROR; - } - } -#endif Md5_Register(db, 0, 0); sqlite3_busy_handler(db, xBusy, 0); diff --git a/src/util.c b/src/util.c index 3e3a9244ac..693759bffc 100644 --- a/src/util.c +++ b/src/util.c @@ -1256,7 +1256,7 @@ u8 sqlite3HexToInt(int h){ return (u8)(h & 0xf); } -#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) +#if !defined(SQLITE_OMIT_BLOB_LITERAL) /* ** Convert a BLOB literal of the form "x'hhhhhh'" into its binary ** value. Return a pointer to its binary value. Space to hold the @@ -1277,7 +1277,7 @@ void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ } return zBlob; } -#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */ +#endif /* !SQLITE_OMIT_BLOB_LITERAL */ /* ** Log an error that is an API call on a connection pointer that should diff --git a/src/vacuum.c b/src/vacuum.c index e8555ef522..ce9db649d2 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -235,17 +235,6 @@ SQLITE_NOINLINE int sqlite3RunVacuum( } nRes = sqlite3BtreeGetOptimalReserve(pMain); - /* A VACUUM cannot change the pagesize of an encrypted database. */ -#ifdef SQLITE_HAS_CODEC - if( db->nextPagesize ){ - extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); - int nKey; - char *zKey; - sqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey); - if( nKey ) db->nextPagesize = 0; - } -#endif - sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); diff --git a/src/wal.c b/src/wal.c index 9873f8bf0a..034a1624ea 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3253,11 +3253,7 @@ static int walWriteOneFrame( int rc; /* Result code from subfunctions */ void *pData; /* Data actually written */ u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ -#if defined(SQLITE_HAS_CODEC) - if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT; -#else pData = pPage->pData; -#endif walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); if( rc ) return rc; @@ -3440,11 +3436,7 @@ int sqlite3WalFrames( if( pWal->iReCksum==0 || iWriteiReCksum ){ pWal->iReCksum = iWrite; } -#if defined(SQLITE_HAS_CODEC) - if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; -#else pData = p->pData; -#endif rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff); if( rc ) return rc; p->flags &= ~PGHDR_WAL_APPEND; diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 9ce5bd40fe..7c8ffd3530 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -370,38 +370,8 @@ set pragma_def { COLS: database status IF: defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - NAME: key - TYPE: KEY - ARG: 0 - IF: defined(SQLITE_HAS_CODEC) - - NAME: rekey - TYPE: KEY - ARG: 1 - IF: defined(SQLITE_HAS_CODEC) - - NAME: hexkey - TYPE: KEY - ARG: 2 - IF: defined(SQLITE_HAS_CODEC) - - NAME: hexrekey - TYPE: KEY - ARG: 3 - IF: defined(SQLITE_HAS_CODEC) - - NAME: textkey - TYPE: KEY - ARG: 4 - IF: defined(SQLITE_HAS_CODEC) - - NAME: textrekey - TYPE: KEY - ARG: 5 - IF: defined(SQLITE_HAS_CODEC) - NAME: activate_extensions - IF: defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) + IF: defined(SQLITE_ENABLE_CEROD) NAME: soft_heap_limit FLAG: Result0 @@ -496,7 +466,7 @@ record_one set allnames [lsort [array names allbyname]] # Generate #defines for all pragma type names. Group the pragmas that are -# omit in default builds (defined(SQLITE_DEBUG) and defined(SQLITE_HAS_CODEC)) +# omit in default builds (ex: defined(SQLITE_DEBUG)) # at the end. # puts $fd "\n/* The various pragma types */" From dc4f6fc099b3fd2476f95286503985f1a22370bc Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Feb 2020 19:44:13 +0000 Subject: [PATCH 008/102] During byte-code generation, strive to avoid jumps that merely jump to the following instruction. FossilOrigin-Name: bcf876e67e75f6709f2b25683a3952bbbb87c672bb9d7af456feebc0ab9f6c31 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/delete.c | 4 +++- src/fkey.c | 2 +- src/select.c | 2 +- src/update.c | 4 +++- src/vdbe.h | 1 + src/vdbeaux.c | 28 ++++++++++++++++++++++++++++ 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 6e923b7e4b..b4353c625a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\scode\sby\sremoving\sthe\sunsupported\sand\sundocumented\s\nSQLITE_HAS_CODEC\scompile-time\soption -D 2020-02-07T01:12:53.927 +C During\sbyte-code\sgeneration,\sstrive\sto\savoid\sjumps\sthat\smerely\sjump\sto\sthe\nfollowing\sinstruction. +D 2020-02-07T19:44:13.184 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -482,10 +482,10 @@ F src/ctime.c 6a77ec9e0eb87aea929e002c816298907e337094a7b556898ae2d1e6be209f90 F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da -F src/delete.c a5c59b9c0251cf7682bc52af0d64f09b1aefc6781a63592c8f1136f7b73c66e4 +F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d F src/expr.c 6617ca8d4cc808b82348ae0c2844000b665de86aacc60fa0524f1b29b1918921 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 92a248ec0fa4ed8ab60c98d9b188ce173aaf218f32e7737ba77deb2a684f9847 +F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41 F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4 F src/global.c 79a988b56b06ce2d08ebefe1d35da9aa25b3851faa47ea5233361c4827185a64 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 @@ -531,7 +531,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 3f7aecf64b08b018b89e4fe16ea621cc9a0e3f3801e9e5638cfe1a6035fa1581 +F src/select.c 28defa337bd913e4d1c6430016e0669bae42778ebe94dbdd855d12de073aa8da F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa F src/sqlite.h.in 572ea78b08ee90529d7588cea966c350afbf9624fdf133378edb346a233c6625 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -598,16 +598,16 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d F src/treeview.c 438c1000587b33faba35e87596bebcf7f40638d98f33781cdd9e04711b18b09c F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc -F src/update.c 9ad19af96aff95dc02a923a99f97c1bc0b909009a29a2914b796f786b9ac0c60 +F src/update.c 3eb778c42155d944377a4ee5e440b04520f07094804ed6ce63d2528f619614d9 F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c 736ff76753236ffbc8b5b939f5e0607f28aeaa7c780b3a56b419228f0a81c87b F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9 F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8 -F src/vdbe.h defd693289c7bb8d325f109be9490c77138061211a116827da7244b6015a4934 +F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9 F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 -F src/vdbeaux.c eaf1df6465f410e69330864bfc152458208f9bb2edd99930432ae342662d2ecd +F src/vdbeaux.c c44f530a04e7a2461ac0c9e0e0d3dc91a4928ba4e027547ee0f5f7d8f3f65c3e F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c ff2a1fd86ea943efb7174bd74bc661815c449be6165e136e8849e1dc59e24353 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df @@ -1858,7 +1858,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 a8a7c05b16f6c73ac55c359fbf62cae4a76eb0d105a3c53e9f47cede9fd85916 -R 014522d0d8b6f7e2f23a6a5506d80ae9 +P 5a877221ce90e7523059353a68650c5fdd28ed032807afc2f10afbfbf864bdfe +R 0497976083176014d12d8c84100cdcac U drh -Z bb09705c5da204b17eae60b0010baaaf +Z 2fd9d06239e0afdc15eacc0b2447af10 diff --git a/manifest.uuid b/manifest.uuid index 6aa6ce42b4..fcf697e987 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a877221ce90e7523059353a68650c5fdd28ed032807afc2f10afbfbf864bdfe \ No newline at end of file +bcf876e67e75f6709f2b25683a3952bbbb87c672bb9d7af456feebc0ab9f6c31 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 0a83f1b640..60efc9d569 100644 --- a/src/delete.c +++ b/src/delete.c @@ -533,7 +533,9 @@ void sqlite3DeleteFrom( iTabCur, aToOpen, &iDataCur, &iIdxCur); assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); - if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce); + if( eOnePass==ONEPASS_MULTI ){ + sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce); + } } /* Set up a loop over the rowids/primary-keys that were found in the diff --git a/src/fkey.c b/src/fkey.c index 9698d343ce..7bc20fed0e 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -658,7 +658,7 @@ static void fkScanChildren( /* Clean up the WHERE clause constructed above. */ sqlite3ExprDelete(db, pWhere); if( iFkIfZero ){ - sqlite3VdbeJumpHere(v, iFkIfZero); + sqlite3VdbeJumpHereOrPopInst(v, iFkIfZero); } } diff --git a/src/select.c b/src/select.c index 595b6eb6b2..6f8d45c4eb 100644 --- a/src/select.c +++ b/src/select.c @@ -5493,7 +5493,7 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ pAggInfo->directMode = 0; if( addrHitTest ){ - sqlite3VdbeJumpHere(v, addrHitTest); + sqlite3VdbeJumpHereOrPopInst(v, addrHitTest); } } diff --git a/src/update.c b/src/update.c index 61b1740b42..d54a6cb9f0 100644 --- a/src/update.c +++ b/src/update.c @@ -616,7 +616,9 @@ void sqlite3Update( } sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, 0, 0); - if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); + if( addrOnce ){ + sqlite3VdbeJumpHereOrPopInst(v, addrOnce); + } } /* Top of the update loop */ diff --git a/src/vdbe.h b/src/vdbe.h index bfde25873f..482331effa 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -230,6 +230,7 @@ void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); void sqlite3VdbeChangeP5(Vdbe*, u16 P5); void sqlite3VdbeJumpHere(Vdbe*, int addr); +void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr); int sqlite3VdbeChangeToNoop(Vdbe*, int addr); int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); #ifdef SQLITE_DEBUG diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 52959a43ee..2a47415734 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1065,6 +1065,34 @@ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ sqlite3VdbeChangeP2(p, addr, p->nOp); } +/* +** Change the P2 operand of the jump instruction at addr so that +** the jump lands on the next opcode. Or if the jump instruction was +** the previous opcode (and is thus a no-op) then simply back up +** the next instruction counter by one slot so that the jump is +** overwritten by the next inserted opcode. +** +** This routine is an optimization of sqlite3VdbeJumpHere() that +** strives to omit useless byte-code like this: +** +** 7 Once 0 8 0 +** 8 ... +*/ +void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){ + if( addr==p->nOp-1 ){ + assert( p->aOp[addr].opcode==OP_Once + || p->aOp[addr].opcode==OP_If + || p->aOp[addr].opcode==OP_FkIfZero ); + assert( p->aOp[addr].p4type==0 ); +#ifdef SQLITE_VDBE_COVERAGE + sqlite3VdbeGetOp(v,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ +#endif + p->nOp--; + }else{ + sqlite3VdbeChangeP2(p, addr, p->nOp); + } +} + /* ** If the input FuncDef structure is ephemeral, then free it. If From b6664744c01005a3e6024351b14a2437e4f2fd0a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2020 13:29:10 +0000 Subject: [PATCH 009/102] Fix the build for when SQLITE_VDBE_COVERAGE is used. FossilOrigin-Name: 084381649edf374ccc5664f136055109a31d4c3a19c4ae2ee5275f630507a2a3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b4353c625a..dbb0055773 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C During\sbyte-code\sgeneration,\sstrive\sto\savoid\sjumps\sthat\smerely\sjump\sto\sthe\nfollowing\sinstruction. -D 2020-02-07T19:44:13.184 +C Fix\sthe\sbuild\sfor\swhen\sSQLITE_VDBE_COVERAGE\sis\sused. +D 2020-02-10T13:29:10.675 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8 F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9 F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 -F src/vdbeaux.c c44f530a04e7a2461ac0c9e0e0d3dc91a4928ba4e027547ee0f5f7d8f3f65c3e +F src/vdbeaux.c 4200161a1b249c33ac587c562e7dca155733694c6d4ad31914184294e4fa9e18 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c ff2a1fd86ea943efb7174bd74bc661815c449be6165e136e8849e1dc59e24353 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df @@ -1858,7 +1858,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 5a877221ce90e7523059353a68650c5fdd28ed032807afc2f10afbfbf864bdfe -R 0497976083176014d12d8c84100cdcac +P bcf876e67e75f6709f2b25683a3952bbbb87c672bb9d7af456feebc0ab9f6c31 +R 0b016e07e5f1424f9916291ff59e054f U drh -Z 2fd9d06239e0afdc15eacc0b2447af10 +Z 6f2686c0d85fb7d7b2f49c11ba326902 diff --git a/manifest.uuid b/manifest.uuid index fcf697e987..c252606d9f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcf876e67e75f6709f2b25683a3952bbbb87c672bb9d7af456feebc0ab9f6c31 \ No newline at end of file +084381649edf374ccc5664f136055109a31d4c3a19c4ae2ee5275f630507a2a3 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2a47415734..6ad25da8dd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1085,7 +1085,7 @@ void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){ || p->aOp[addr].opcode==OP_FkIfZero ); assert( p->aOp[addr].p4type==0 ); #ifdef SQLITE_VDBE_COVERAGE - sqlite3VdbeGetOp(v,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ + sqlite3VdbeGetOp(p,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */ #endif p->nOp--; }else{ From df9b5cab9354fa7863037c647131c10ad063f7ee Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Feb 2020 19:24:49 +0000 Subject: [PATCH 010/102] Mark the sha1() extension function as SQLITE_DETERMINISTIC. FossilOrigin-Name: 7d8dcfb95cea732e7588e7505bf80a171dd2e371b164c9435c6ac286060df6df --- ext/misc/sha1.c | 5 +++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ext/misc/sha1.c b/ext/misc/sha1.c index 0050fdfbdc..9fe6cae740 100644 --- a/ext/misc/sha1.c +++ b/ext/misc/sha1.c @@ -381,8 +381,9 @@ int sqlite3_sha_init( int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "sha1", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, - sha1Func, 0, 0); + rc = sqlite3_create_function(db, "sha1", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, sha1Func, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "sha1_query", 1, SQLITE_UTF8|SQLITE_DIRECTONLY, 0, diff --git a/manifest b/manifest index dbb0055773..5202b8d164 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuild\sfor\swhen\sSQLITE_VDBE_COVERAGE\sis\sused. -D 2020-02-10T13:29:10.675 +C Mark\sthe\ssha1()\sextension\sfunction\sas\sSQLITE_DETERMINISTIC. +D 2020-02-10T19:24:49.300 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -312,7 +312,7 @@ F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6 F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad F ext/misc/series.c 4057dda3579b38ff88b2d3b13b4dd92dbd9d6f90dac2b55c19b0a8ed87ee4959 -F ext/misc/sha1.c 1190aec0d9d886d9f5ffdf891142a626812327d11472c0cade3489db3b7b140a +F ext/misc/sha1.c c8f2253c8792ffab9517695ea7d88c079f0395a5505eefef5c8198fe184ed5ac F ext/misc/shathree.c 135b7c145db4a09b1650c3e7aff9cb538763a9a361e834c015dd1aaf8d5c9a00 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f @@ -1858,7 +1858,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 bcf876e67e75f6709f2b25683a3952bbbb87c672bb9d7af456feebc0ab9f6c31 -R 0b016e07e5f1424f9916291ff59e054f +P 084381649edf374ccc5664f136055109a31d4c3a19c4ae2ee5275f630507a2a3 +R 8339228306581c736abe177124af4c74 U drh -Z 6f2686c0d85fb7d7b2f49c11ba326902 +Z d816eb8a040f61cae9702436e03e9275 diff --git a/manifest.uuid b/manifest.uuid index c252606d9f..977c419e3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -084381649edf374ccc5664f136055109a31d4c3a19c4ae2ee5275f630507a2a3 \ No newline at end of file +7d8dcfb95cea732e7588e7505bf80a171dd2e371b164c9435c6ac286060df6df \ No newline at end of file From 41aa442cf4fd66cafbc37f3a1718aeb4c498a96f Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 12 Feb 2020 11:57:35 +0000 Subject: [PATCH 011/102] When determining whether an == or IS constraint in a WHERE clause makes an ORDER BY term redundant, consider the collation sequence used by the == or IS comparison, not the collation sequence of the comparison expression itself. Possible fix for [fb8c538a8f]. FossilOrigin-Name: 16aed5d0c63dcdc2054dbb8a4b6b992476640433bf81e19301e6db5a3fc82633 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 7 +++++-- test/orderby5.test | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 5202b8d164..c16742ddf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Mark\sthe\ssha1()\sextension\sfunction\sas\sSQLITE_DETERMINISTIC. -D 2020-02-10T19:24:49.300 +C When\sdetermining\swhether\san\s==\sor\sIS\sconstraint\sin\sa\sWHERE\sclause\smakes\san\sORDER\sBY\sterm\sredundant,\sconsider\sthe\scollation\ssequence\sused\sby\sthe\s==\sor\sIS\scomparison,\snot\sthe\scollation\ssequence\sof\sthe\scomparison\sexpression\sitself.\sPossible\sfix\sfor\s[fb8c538a8f]. +D 2020-02-12T11:57:35.462 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d -F src/where.c 2005d0511e05e5f7b6fb3be514b44f264f23d45f3b0cc5e150c63e3006a003e5 +F src/where.c 8fed0ab2c5efb1f1641ee73d1e98440637ac18726902fefcb7cb2e3923f54cdd F src/whereInt.h 9157228db086f436a574589f8cc5749bd971e94017c552305ad9ec472ed2e098 F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d F src/whereexpr.c 4b34be1434183e7bb8a05d4bf42bd53ea53021b0b060936fbd12062b4ff6b396 @@ -1207,7 +1207,7 @@ F test/orderby1.test 6bf0ce45cbfb1cf4779dd418ac5e8cf66abfa04de2c1d2edf1e0e85f152 F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04 F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99 F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4 -F test/orderby5.test 5f4d6cb93cc2f6d3f4228354310a2ce1fbd95d5bbffcba8c6482eeb62a466407 +F test/orderby5.test 8511a749d9ced17de7aeef6f03347d8f094e9977945517ee8c984e843516aa7b F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd @@ -1858,7 +1858,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 084381649edf374ccc5664f136055109a31d4c3a19c4ae2ee5275f630507a2a3 -R 8339228306581c736abe177124af4c74 -U drh -Z d816eb8a040f61cae9702436e03e9275 +P 7d8dcfb95cea732e7588e7505bf80a171dd2e371b164c9435c6ac286060df6df +R 59c1d18e534e5edddd3bf258cd0125ab +U dan +Z c51e7fa10130f64133da39d0e8b36324 diff --git a/manifest.uuid b/manifest.uuid index 977c419e3c..59f56c0a20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7d8dcfb95cea732e7588e7505bf80a171dd2e371b164c9435c6ac286060df6df \ No newline at end of file +16aed5d0c63dcdc2054dbb8a4b6b992476640433bf81e19301e6db5a3fc82633 \ No newline at end of file diff --git a/src/where.c b/src/where.c index e7447deec2..de384dd952 100644 --- a/src/where.c +++ b/src/where.c @@ -3752,8 +3752,11 @@ static i8 wherePathSatisfiesOrderBy( if( j>=pLoop->nLTerm ) continue; } if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ - if( sqlite3ExprCollSeqMatch(pWInfo->pParse, - pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){ + Parse *pParse = pWInfo->pParse; + CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr); + CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr); + assert( pColl1 && (pParse->nErr || pColl2) ); + if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){ continue; } testcase( pTerm->pExpr->op==TK_IS ); diff --git a/test/orderby5.test b/test/orderby5.test index e83116bae0..1ad79f9875 100644 --- a/test/orderby5.test +++ b/test/orderby5.test @@ -126,5 +126,51 @@ do_execsql_test 3.1 { SELECT a FROM t3 WHERE b=2 AND c=3 ORDER BY d DESC, e DESC, b, c, a DESC; } {~/B-TREE/} +#------------------------------------------------------------------------- +do_execsql_test 4.1.0 { + CREATE TABLE t4(b COLLATE nocase); + INSERT INTO t4 VALUES('abc'); + INSERT INTO t4 VALUES('ABC'); + INSERT INTO t4 VALUES('aBC'); +} +do_execsql_test 4.1.1 { + SELECT * FROM t4 ORDER BY b COLLATE binary +} {ABC aBC abc} +do_execsql_test 4.1.2 { + SELECT * FROM t4 WHERE b='abc' ORDER BY b COLLATE binary +} {ABC aBC abc} + +do_execsql_test 4.2.1 { + CREATE TABLE Records(typeID INTEGER, key TEXT COLLATE nocase, value TEXT); + CREATE INDEX RecordsIndex ON Records(typeID, key, value); +} +do_execsql_test 4.2.2 { + explain query plan + SELECT typeID, key, value FROM Records + WHERE typeID = 2 AND key = 'x' + ORDER BY key, value; +} {~/TEMP B-TREE/} +do_execsql_test 4.2.3 { + explain query plan + SELECT typeID, key, value FROM Records + WHERE typeID = 2 AND (key = 'x' COLLATE binary) + ORDER BY key, value; +} {~/TEMP B-TREE/} +do_execsql_test 4.2.4 { + explain query plan + SELECT typeID, key, value FROM Records + WHERE typeID = 2 + ORDER BY key, value; +} {~/TEMP B-TREE/} + +db collate hello [list string match] +do_execsql_test 4.3.1 { + CREATE TABLE t5(a INTEGER PRIMARY KEY, b COLLATE hello, c, d); +} +db close +sqlite3 db test.db +do_catchsql_test 4.3.2 { + SELECT a FROM t5 WHERE b='def' ORDER BY b; +} {1 {no such collation sequence: hello}} finish_test From efdba1a8b3c6c967e7fae9c1989c40d420ce64cc Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 12 Feb 2020 20:50:20 +0000 Subject: [PATCH 012/102] Increase the default upper bound on the number of parameters in a single SQL statement to 32766 (from 999). FossilOrigin-Name: 2def75693a8ae002375aff80db0e6c970c75f75e8b6ba64f2c518712badb0ae8 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqlite.h.in | 2 +- src/sqliteInt.h | 4 ++-- src/sqliteLimit.h | 5 ++++- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index c16742ddf2..d22800fa59 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdetermining\swhether\san\s==\sor\sIS\sconstraint\sin\sa\sWHERE\sclause\smakes\san\sORDER\sBY\sterm\sredundant,\sconsider\sthe\scollation\ssequence\sused\sby\sthe\s==\sor\sIS\scomparison,\snot\sthe\scollation\ssequence\sof\sthe\scomparison\sexpression\sitself.\sPossible\sfix\sfor\s[fb8c538a8f]. -D 2020-02-12T11:57:35.462 +C Increase\sthe\sdefault\supper\sbound\son\sthe\snumber\sof\sparameters\sin\sa\ssingle\nSQL\sstatement\sto\s32766\s(from\s999). +D 2020-02-12T20:50:20.663 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -533,11 +533,11 @@ F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 28defa337bd913e4d1c6430016e0669bae42778ebe94dbdd855d12de073aa8da F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa -F src/sqlite.h.in 572ea78b08ee90529d7588cea966c350afbf9624fdf133378edb346a233c6625 +F src/sqlite.h.in 0d9ef312509cb7c8445f4dc25fedfe103c147668a78a36a607a1064f1e0612a4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 27951f294f29cd875c6027f2707d644ef99f469bd97514568b5a8581a114db8c -F src/sqliteInt.h ce2038197482723e6da107447d95e4d3a1afcfd630c955b6abef5dc9ff597567 -F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b +F src/sqliteInt.h f5011c0f42a7f2d943ebc13819efb41f48c7730e5ad0111a52340e71c08d7383 +F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c d0aa320416efe88c4dbb0156ed6c494f2f9958871a940e46984ee57b3e7fcc50 @@ -1858,7 +1858,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 7d8dcfb95cea732e7588e7505bf80a171dd2e371b164c9435c6ac286060df6df -R 59c1d18e534e5edddd3bf258cd0125ab -U dan -Z c51e7fa10130f64133da39d0e8b36324 +P 16aed5d0c63dcdc2054dbb8a4b6b992476640433bf81e19301e6db5a3fc82633 +R 609d391b7d0a11e157e71c995c0e5807 +U drh +Z 0b06c4e19232243f80d66b8f3a5aacb0 diff --git a/manifest.uuid b/manifest.uuid index 59f56c0a20..54cdee59f3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16aed5d0c63dcdc2054dbb8a4b6b992476640433bf81e19301e6db5a3fc82633 \ No newline at end of file +2def75693a8ae002375aff80db0e6c970c75f75e8b6ba64f2c518712badb0ae8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 367242bf27..0537ab69f1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4199,7 +4199,7 @@ typedef struct sqlite3_context sqlite3_context; ** [sqlite3_bind_parameter_index()] API if desired. ^The index ** for "?NNN" parameters is the value of NNN. ** ^The NNN value must be between 1 and the [sqlite3_limit()] -** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). +** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766). ** ** ^The third argument is the value to bind to the parameter. ** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 76b37cb695..4040f01a49 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2512,10 +2512,10 @@ struct AggInfo { ** it uses less memory in the Expr object, which is a big memory user ** in systems with lots of prepared statements. And few applications ** need more than about 10 or 20 variables. But some extreme users want -** to have prepared statements with over 32767 variables, and for them +** to have prepared statements with over 32766 variables, and for them ** the option is available (at compile-time). */ -#if SQLITE_MAX_VARIABLE_NUMBER<=32767 +#if SQLITE_MAX_VARIABLE_NUMBER<32767 typedef i16 ynVar; #else typedef int ynVar; diff --git a/src/sqliteLimit.h b/src/sqliteLimit.h index 28e7a41cc3..a7302575c5 100644 --- a/src/sqliteLimit.h +++ b/src/sqliteLimit.h @@ -131,9 +131,12 @@ /* ** The maximum value of a ?nnn wildcard that the parser will accept. +** If the value exceeds 32767 then extra space is required for the Expr +** structure. But otherwise, we believe that the number can be as large +** as a signed 32-bit integer can hold. */ #ifndef SQLITE_MAX_VARIABLE_NUMBER -# define SQLITE_MAX_VARIABLE_NUMBER 999 +# define SQLITE_MAX_VARIABLE_NUMBER 32766 #endif /* Maximum page size. The upper bound on this value is 65536. This a limit From 77c9b3ccb36505e059587b35de15e48e53702501 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Feb 2020 11:46:47 +0000 Subject: [PATCH 013/102] Fix an incorrect assert() statement that was added yesterday. Tickets [41c1456a6e61c0e7] and [fb8c538a8f57ae2a]. FossilOrigin-Name: abfb043ebb0c55fdc2be58255bc852b13865d81fa4c2e0dbe8c375810557aafe --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/orderby5.test | 11 +++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d22800fa59..2b5c8f8599 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sdefault\supper\sbound\son\sthe\snumber\sof\sparameters\sin\sa\ssingle\nSQL\sstatement\sto\s32766\s(from\s999). -D 2020-02-12T20:50:20.663 +C Fix\san\sincorrect\sassert()\sstatement\sthat\swas\sadded\syesterday.\nTickets\s[41c1456a6e61c0e7]\sand\s[fb8c538a8f57ae2a]. +D 2020-02-13T11:46:47.621 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d -F src/where.c 8fed0ab2c5efb1f1641ee73d1e98440637ac18726902fefcb7cb2e3923f54cdd +F src/where.c 23c7744a3bd6c7d937fe96e97af6322349ccba93360e0be10cefcdae9f14786f F src/whereInt.h 9157228db086f436a574589f8cc5749bd971e94017c552305ad9ec472ed2e098 F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d F src/whereexpr.c 4b34be1434183e7bb8a05d4bf42bd53ea53021b0b060936fbd12062b4ff6b396 @@ -1207,7 +1207,7 @@ F test/orderby1.test 6bf0ce45cbfb1cf4779dd418ac5e8cf66abfa04de2c1d2edf1e0e85f152 F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04 F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99 F test/orderby4.test 4d39bfbaaa3ae64d026ca2ff166353d2edca4ba4 -F test/orderby5.test 8511a749d9ced17de7aeef6f03347d8f094e9977945517ee8c984e843516aa7b +F test/orderby5.test bd7d9e3380e87e5dcf6ea817ebaab6d15da213c7804b38767e1b3e695e85650b F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd @@ -1858,7 +1858,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 16aed5d0c63dcdc2054dbb8a4b6b992476640433bf81e19301e6db5a3fc82633 -R 609d391b7d0a11e157e71c995c0e5807 +P 2def75693a8ae002375aff80db0e6c970c75f75e8b6ba64f2c518712badb0ae8 +R 5b1afbb781378f6b65a725d2b15b77ab U drh -Z 0b06c4e19232243f80d66b8f3a5aacb0 +Z 8b3282fc49a988e2f90c863fe4275699 diff --git a/manifest.uuid b/manifest.uuid index 54cdee59f3..6933b22c16 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2def75693a8ae002375aff80db0e6c970c75f75e8b6ba64f2c518712badb0ae8 \ No newline at end of file +abfb043ebb0c55fdc2be58255bc852b13865d81fa4c2e0dbe8c375810557aafe \ No newline at end of file diff --git a/src/where.c b/src/where.c index de384dd952..54bbb7601f 100644 --- a/src/where.c +++ b/src/where.c @@ -3755,7 +3755,7 @@ static i8 wherePathSatisfiesOrderBy( Parse *pParse = pWInfo->pParse; CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[i].pExpr); CollSeq *pColl2 = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr); - assert( pColl1 && (pParse->nErr || pColl2) ); + assert( pColl1 ); if( pColl2==0 || sqlite3StrICmp(pColl1->zName, pColl2->zName) ){ continue; } diff --git a/test/orderby5.test b/test/orderby5.test index 1ad79f9875..ccdcf1de0c 100644 --- a/test/orderby5.test +++ b/test/orderby5.test @@ -173,4 +173,15 @@ do_catchsql_test 4.3.2 { SELECT a FROM t5 WHERE b='def' ORDER BY b; } {1 {no such collation sequence: hello}} +# 2020-02-13 ticket 41c1456a6e61c0e7 +do_execsql_test 4.4.0 { + DROP TABLE t1; + CREATE TABLE t1(a); + DROP TABLE t2; + CREATE TABLE t2(b INTEGER PRIMARY KEY, c INT); + SELECT DISTINCT * + FROM t1 LEFT JOIN t2 ON b=c AND b=(SELECT a FROM t1) + WHERE c>10; +} {} + finish_test From 0ba3621592a060a4dbabcac02c48bf3d9d603c42 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Feb 2020 13:45:04 +0000 Subject: [PATCH 014/102] Omit O_NOFOLLOW from the open() call when opening /dev/null, since /dev/null is a symlink on Solaris, we are told. FossilOrigin-Name: 0c683c43a62fe25c6cb765e4a31556ec91a7c21af79349b3d7eeb13f73dd1cdc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2b5c8f8599..2fc5d5ded9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\sassert()\sstatement\sthat\swas\sadded\syesterday.\nTickets\s[41c1456a6e61c0e7]\sand\s[fb8c538a8f57ae2a]. -D 2020-02-13T11:46:47.621 +C Omit\sO_NOFOLLOW\sfrom\sthe\sopen()\scall\swhen\sopening\s/dev/null,\ssince\s/dev/null\nis\sa\ssymlink\son\sSolaris,\swe\sare\stold. +D 2020-02-13T13:45:04.135 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -515,7 +515,7 @@ F src/os.c 669cc3839cc35d20f81faf0be1ab6d4581cea35e9d8f3a9d48a98d6571f7c285 F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c ad7640c04eed946052a3b12856362a773d0a717696707313037186df0e2b59f2 +F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c b1e79698f3903e64d7a8ab5f4b3163aa39ed25686289a68de20b6b5734de70e6 @@ -1858,7 +1858,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 2def75693a8ae002375aff80db0e6c970c75f75e8b6ba64f2c518712badb0ae8 -R 5b1afbb781378f6b65a725d2b15b77ab +P abfb043ebb0c55fdc2be58255bc852b13865d81fa4c2e0dbe8c375810557aafe +R d4cdcde20a4733b9029c60768cc19b63 U drh -Z 8b3282fc49a988e2f90c863fe4275699 +Z 24a71b5d93c7dee64e38be46600d1093 diff --git a/manifest.uuid b/manifest.uuid index 6933b22c16..fbe55af4f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abfb043ebb0c55fdc2be58255bc852b13865d81fa4c2e0dbe8c375810557aafe \ No newline at end of file +0c683c43a62fe25c6cb765e4a31556ec91a7c21af79349b3d7eeb13f73dd1cdc \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 07ae4bc03a..cf1c579fd0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -689,7 +689,7 @@ static int robust_open(const char *z, int f, mode_t m){ sqlite3_log(SQLITE_WARNING, "attempt to open \"%s\" as file descriptor %d", z, fd); fd = -1; - if( osOpen("/dev/null", f, m)<0 ) break; + if( osOpen("/dev/null", O_RDONLY, m)<0 ) break; } if( fd>=0 ){ if( m!=0 ){ From ab7fdca2eec1b6d5143214155aa9dfda40de1b83 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Feb 2020 14:51:54 +0000 Subject: [PATCH 015/102] Disallow the skip-scan optimization in the absence of sqlite_stat1 data. FossilOrigin-Name: e0c6b8bdb76fcd4f08c89ff20dce6a33ef3c11752e1e919fec5c4e7d423c4b93 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2fc5d5ded9..267fe1e7f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sO_NOFOLLOW\sfrom\sthe\sopen()\scall\swhen\sopening\s/dev/null,\ssince\s/dev/null\nis\sa\ssymlink\son\sSolaris,\swe\sare\stold. -D 2020-02-13T13:45:04.135 +C Disallow\sthe\sskip-scan\soptimization\sin\sthe\sabsence\sof\ssqlite_stat1\sdata. +D 2020-02-13T14:51:54.614 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d -F src/where.c 23c7744a3bd6c7d937fe96e97af6322349ccba93360e0be10cefcdae9f14786f +F src/where.c cbad14f1d8e11b9f052e937274315c7c17266a89eda408c86084ee894debb7d5 F src/whereInt.h 9157228db086f436a574589f8cc5749bd971e94017c552305ad9ec472ed2e098 F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d F src/whereexpr.c 4b34be1434183e7bb8a05d4bf42bd53ea53021b0b060936fbd12062b4ff6b396 @@ -1858,7 +1858,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 abfb043ebb0c55fdc2be58255bc852b13865d81fa4c2e0dbe8c375810557aafe -R d4cdcde20a4733b9029c60768cc19b63 +P 0c683c43a62fe25c6cb765e4a31556ec91a7c21af79349b3d7eeb13f73dd1cdc +R 39bdd561eec3a8801f1b8b81289ae5e3 U drh -Z 24a71b5d93c7dee64e38be46600d1093 +Z 0828bb01d9740c88eea0a472b36dac0f diff --git a/manifest.uuid b/manifest.uuid index fbe55af4f8..97fd3c4c28 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c683c43a62fe25c6cb765e4a31556ec91a7c21af79349b3d7eeb13f73dd1cdc \ No newline at end of file +e0c6b8bdb76fcd4f08c89ff20dce6a33ef3c11752e1e919fec5c4e7d423c4b93 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 54bbb7601f..da9c5a7233 100644 --- a/src/where.c +++ b/src/where.c @@ -2732,6 +2732,7 @@ static int whereLoopAddBtreeIndex( && saved_nEq+1nKeyCol && saved_nEq==pNew->nLTerm && pProbe->noSkipScan==0 + && pProbe->hasStat1!=0 && OptimizationEnabled(db, SQLITE_SkipScan) && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK From fdfd45aef3c8ed91278f4bddff6b421472e49f10 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Feb 2020 22:12:35 +0000 Subject: [PATCH 016/102] Fix problems in the constant propagation optimization that were introduced by check-in [1c3e5c20a9e6f501]. Fix for ticket [1dcb4d44964846ad] FossilOrigin-Name: c9a8defcef35a1fee6bcbb88252a2d0076dabe8381b0128b2257b5b5cc494e0f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 8 ++------ test/whereL.test | 12 ++++++++++++ 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 267fe1e7f7..281dbb7e10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disallow\sthe\sskip-scan\soptimization\sin\sthe\sabsence\sof\ssqlite_stat1\sdata. -D 2020-02-13T14:51:54.614 +C Fix\sproblems\sin\sthe\sconstant\spropagation\soptimization\sthat\swere\sintroduced\nby\scheck-in\s[1c3e5c20a9e6f501].\s\sFix\sfor\sticket\s[1dcb4d44964846ad] +D 2020-02-13T22:12:35.586 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -531,7 +531,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 28defa337bd913e4d1c6430016e0669bae42778ebe94dbdd855d12de073aa8da +F src/select.c 9e5b357f1c0952ff699effe3640be58a7e16497be6b74a2637495f5ef13859f0 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa F src/sqlite.h.in 0d9ef312509cb7c8445f4dc25fedfe103c147668a78a36a607a1064f1e0612a4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1710,7 +1710,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364 F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b -F test/whereL.test 976f100f412ce2f39bf923eb57794cdc39fc0a3fec8fab025d51706a7cc4845b +F test/whereL.test d19499a39c9e3e5a74460778b009558d328c8a230c0e6825c9996c9adff89058 F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0 @@ -1858,7 +1858,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 0c683c43a62fe25c6cb765e4a31556ec91a7c21af79349b3d7eeb13f73dd1cdc -R 39bdd561eec3a8801f1b8b81289ae5e3 +P e0c6b8bdb76fcd4f08c89ff20dce6a33ef3c11752e1e919fec5c4e7d423c4b93 +R 14e8d16c4b6e3dd990176f6f8e1d198c U drh -Z 0828bb01d9740c88eea0a472b36dac0f +Z 3ad2d5b6fd6cc60820c0dc8dc5c4b3e3 diff --git a/manifest.uuid b/manifest.uuid index 97fd3c4c28..d2a56f6d0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0c6b8bdb76fcd4f08c89ff20dce6a33ef3c11752e1e919fec5c4e7d423c4b93 \ No newline at end of file +c9a8defcef35a1fee6bcbb88252a2d0076dabe8381b0128b2257b5b5cc494e0f \ No newline at end of file diff --git a/src/select.c b/src/select.c index 6f8d45c4eb..d03322fcb2 100644 --- a/src/select.c +++ b/src/select.c @@ -4166,9 +4166,8 @@ static void constInsert( assert( pColumn->op==TK_COLUMN ); assert( sqlite3ExprIsConstant(pValue) ); - if( !ExprHasProperty(pValue, EP_FixedCol) && sqlite3ExprAffinity(pValue)!=0 ){ - return; - } + if( ExprHasProperty(pColumn, EP_FixedCol) ) return; + if( sqlite3ExprAffinity(pValue)!=0 ) return; if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ return; } @@ -4191,9 +4190,6 @@ static void constInsert( if( pConst->apExpr==0 ){ pConst->nConst = 0; }else{ - if( ExprHasProperty(pValue, EP_FixedCol) ){ - pValue = pValue->pLeft; - } pConst->apExpr[pConst->nConst*2-2] = pColumn; pConst->apExpr[pConst->nConst*2-1] = pValue; } diff --git a/test/whereL.test b/test/whereL.test index bd2f561607..0f577e06eb 100644 --- a/test/whereL.test +++ b/test/whereL.test @@ -144,5 +144,17 @@ do_execsql_test 530 { SELECT 200, * FROM t0, v0 WHERE t0.c0 = 0 AND v0.c0 = t0.c0; } {} +# 2020-02-13: ticket 1dcb4d44964846ad +# A problem introduced while making optimizations on the fixes above. +# +reset_db +do_execsql_test 600 { + CREATE TABLE t1(x TEXT); + CREATE TABLE t2(y TEXT); + INSERT INTO t1 VALUES('good'),('bad'); + INSERT INTO t2 VALUES('good'),('bad'); + SELECT * FROM t1 JOIN t2 ON x=y + WHERE x='good' AND y='good'; +} {good good} finish_test From ac9e184e1f35154cd710c5fe8bbd280dc7a2aedc Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 16 Feb 2020 17:40:35 +0000 Subject: [PATCH 017/102] Avoid an infinite recursion on an illegal recursive definition of an fts5vocab table. FossilOrigin-Name: 109ee07433b274a39954cef62bf67d47bcda960df9bef56127210ebf1c3c104c --- ext/fts5/fts5_vocab.c | 9 +++++++++ ext/fts5/test/fts5vocab.test | 13 ++++++++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 36a3673814..48aa6939c8 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -50,6 +50,7 @@ struct Fts5VocabTable { sqlite3 *db; /* Database handle */ Fts5Global *pGlobal; /* FTS5 global object for this database */ int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */ + unsigned bBusy; /* True if busy */ }; struct Fts5VocabCursor { @@ -332,6 +333,12 @@ static int fts5VocabOpenMethod( sqlite3_stmt *pStmt = 0; char *zSql = 0; + if( pTab->bBusy ){ + pVTab->zErrMsg = sqlite3_mprintf( + "recursive definition for %s.%s", pTab->zFts5Db, pTab->zFts5Tbl + ); + return SQLITE_ERROR; + } zSql = sqlite3Fts5Mprintf(&rc, "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'", pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl @@ -343,10 +350,12 @@ static int fts5VocabOpenMethod( assert( rc==SQLITE_OK || pStmt==0 ); if( rc==SQLITE_ERROR ) rc = SQLITE_OK; + pTab->bBusy = 1; if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ i64 iId = sqlite3_column_int64(pStmt, 0); pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId); } + pTab->bBusy = 0; if( rc==SQLITE_OK ){ if( pFts5==0 ){ diff --git a/ext/fts5/test/fts5vocab.test b/ext/fts5/test/fts5vocab.test index a1bf2a4ede..c457c5c210 100644 --- a/ext/fts5/test/fts5vocab.test +++ b/ext/fts5/test/fts5vocab.test @@ -542,5 +542,16 @@ do_execsql_test 10.7.3 { SELECT * FROM t2 WHERE term=?; } -finish_test +# 2020-02-16 Detect recursively define fts5vocab() tables. +# Error found by dbsqlfuzz. +# +reset_db +do_execsql_test 11.100 { + CREATE VIRTUAL TABLE t3 USING fts5vocab(rowid , 'col'); + CREATE VIRTUAL TABLE rowid USING fts5vocab(rowid , 'instance'); +} {} +do_catchsql_test 11.110 { + SELECT rowid+1,rowid, * FROM t3 WHERE null>rowid ; +} {1 {SQL logic error}} +finish_test diff --git a/manifest b/manifest index 281dbb7e10..fff861d4ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\sin\sthe\sconstant\spropagation\soptimization\sthat\swere\sintroduced\nby\scheck-in\s[1c3e5c20a9e6f501].\s\sFix\sfor\sticket\s[1dcb4d44964846ad] -D 2020-02-13T22:12:35.586 +C Avoid\san\sinfinite\srecursion\son\san\sillegal\srecursive\sdefinition\sof\san\nfts5vocab\stable. +D 2020-02-16T17:40:35.632 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -126,7 +126,7 @@ F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3 F ext/fts5/fts5_tokenize.c 2e508c6a3bd8ee56c48e98a38052e1a650e49b32a484cce9b189984114bc3b88 F ext/fts5/fts5_unicode2.c 8bd0cd07396b74c1a05590e4070d635bccfc849812c305619f109e6c0485e250 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 -F ext/fts5/fts5_vocab.c c3f12188570abb423303cd193b16dd19ba54e21c2e930e9b748d743de3b385f5 +F ext/fts5/fts5_vocab.c 7a071833064dc8bca236c3c323e56aac36f583aa2c46ce916d52e31ce87462c9 F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 @@ -223,7 +223,7 @@ F ext/fts5/test/fts5unicode4.test 6463301d669f963c83988017aa354108be0b947d325aef F ext/fts5/test/fts5unindexed.test 9021af86a0fb9fc616f7a69a996db0116e7936d0db63892db6bafabbec21af4d F ext/fts5/test/fts5update.test b8affd796e45c94a4d19ad5c26606ea06065a0f162a9562d9f005b5a80ccf0bc F ext/fts5/test/fts5version.test c8f2cc105f0abf0224965f93e584633dee3e06c91478bc67e468f7cfdf97fd6a -F ext/fts5/test/fts5vocab.test 648fb2fe86b55e08295e34504704718d92fba3e2cf3e1f5d72fa3682df4cd0f0 +F ext/fts5/test/fts5vocab.test 7ed80d9af1ddaaa1637da05e406327b5aac250848bc604c1c1cc667908b87760 F ext/fts5/test/fts5vocab2.test e0fdc3a3095f6eda68ac9bf9a443ff929a124d46f00af19933604085712e9d47 F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59 @@ -1858,7 +1858,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 e0c6b8bdb76fcd4f08c89ff20dce6a33ef3c11752e1e919fec5c4e7d423c4b93 -R 14e8d16c4b6e3dd990176f6f8e1d198c +P c9a8defcef35a1fee6bcbb88252a2d0076dabe8381b0128b2257b5b5cc494e0f +R 0101ab02a39ed4688807aaed2ccc70ad U drh -Z 3ad2d5b6fd6cc60820c0dc8dc5c4b3e3 +Z 56b3b85f6cc480b092cb7b99dbf6bceb diff --git a/manifest.uuid b/manifest.uuid index d2a56f6d0b..f8db7be617 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9a8defcef35a1fee6bcbb88252a2d0076dabe8381b0128b2257b5b5cc494e0f \ No newline at end of file +109ee07433b274a39954cef62bf67d47bcda960df9bef56127210ebf1c3c104c \ No newline at end of file From bf48ce49f7c25e5d4524de9fdc5c0d505218d06d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Feb 2020 00:12:04 +0000 Subject: [PATCH 018/102] Take care when checking the table of a TK_COLUMN expression node to see if the table is a virtual table to first ensure that the Expr.y.pTab pointer is not null due to generated column optimizations. Ticket [4374860b29383380]. FossilOrigin-Name: 9d0d4ab95dc0c56e053c2924ed322a9ea7b25439e6f74599f706905a1994e454 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 13 +++++++++++-- src/sqliteInt.h | 1 + src/whereexpr.c | 8 ++++---- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index fff861d4ea..a47448eb72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sinfinite\srecursion\son\san\sillegal\srecursive\sdefinition\sof\san\nfts5vocab\stable. -D 2020-02-16T17:40:35.632 +C Take\scare\swhen\schecking\sthe\stable\sof\sa\sTK_COLUMN\sexpression\snode\sto\ssee\sif\sthe\ntable\sis\sa\svirtual\stable\sto\sfirst\sensure\sthat\sthe\sExpr.y.pTab\spointer\sis\snot\nnull\sdue\sto\sgenerated\scolumn\soptimizations.\s\sTicket\s[4374860b29383380]. +D 2020-02-17T00:12:04.817 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d -F src/expr.c 6617ca8d4cc808b82348ae0c2844000b665de86aacc60fa0524f1b29b1918921 +F src/expr.c af70e9a131624dac1c482dd6ed4f73df24a905987447ec8f70a17c7ee55dd2d7 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41 F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4 @@ -536,7 +536,7 @@ F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1f F src/sqlite.h.in 0d9ef312509cb7c8445f4dc25fedfe103c147668a78a36a607a1064f1e0612a4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 27951f294f29cd875c6027f2707d644ef99f469bd97514568b5a8581a114db8c -F src/sqliteInt.h f5011c0f42a7f2d943ebc13819efb41f48c7730e5ad0111a52340e71c08d7383 +F src/sqliteInt.h a8979f41b823f4bc8ee0c446f5a9190074a14570fd4022194a7299c453f3c00c F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -620,7 +620,7 @@ F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d F src/where.c cbad14f1d8e11b9f052e937274315c7c17266a89eda408c86084ee894debb7d5 F src/whereInt.h 9157228db086f436a574589f8cc5749bd971e94017c552305ad9ec472ed2e098 F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d -F src/whereexpr.c 4b34be1434183e7bb8a05d4bf42bd53ea53021b0b060936fbd12062b4ff6b396 +F src/whereexpr.c 512b6d4b0c5710d45ec4efeec19523c457b86d47bb9f02e582d2ee47b423aa2e F src/window.c f8ba2ee12a19b51d3ba42c16277c74185ee9215306bc0d5a03974ade8b5bc98f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1858,7 +1858,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 c9a8defcef35a1fee6bcbb88252a2d0076dabe8381b0128b2257b5b5cc494e0f -R 0101ab02a39ed4688807aaed2ccc70ad +P 109ee07433b274a39954cef62bf67d47bcda960df9bef56127210ebf1c3c104c +R 6f9ad25842fa66c90901a82d5cd39115 U drh -Z 56b3b85f6cc480b092cb7b99dbf6bceb +Z 68fbba6154ce295a8c685f40a10cb886 diff --git a/manifest.uuid b/manifest.uuid index f8db7be617..abd4568ad9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -109ee07433b274a39954cef62bf67d47bcda960df9bef56127210ebf1c3c104c \ No newline at end of file +9d0d4ab95dc0c56e053c2924ed322a9ea7b25439e6f74599f706905a1994e454 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 46a3f9f57a..be23a5bd52 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2244,6 +2244,15 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){ return rc; } +/* +** Return true if p is a Column node that references a virtual table. +*/ +int sqlite3ExprIsVtabRef(Expr *p){ + if( p->op!=TK_COLUMN ) return 0; + if( p->y.pTab==0 ) return 0; + return IsVirtual(p->y.pTab); +} + /* ** Return FALSE if there is no chance that the expression can be NULL. ** @@ -5479,8 +5488,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_LE ); testcase( pExpr->op==TK_GT ); testcase( pExpr->op==TK_GE ); - if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab)) - || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab)) + if( sqlite3ExprIsVtabRef(pExpr->pLeft) + || sqlite3ExprIsVtabRef(pExpr->pRight) ){ return WRC_Prune; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4040f01a49..c42a9e8c64 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4278,6 +4278,7 @@ int sqlite3ExprIsTableConstant(Expr*,int); int sqlite3ExprContainsSubquery(Expr*); #endif int sqlite3ExprIsInteger(Expr*, int*); +int sqlite3ExprIsVtabRef(Expr*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); diff --git a/src/whereexpr.c b/src/whereexpr.c index cec0aefd8b..e99a44f15c 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -377,7 +377,7 @@ static int isAuxiliaryVtabOperator( ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; - if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ + if( sqlite3ExprIsVtabRef(pCol) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; @@ -399,7 +399,7 @@ static int isAuxiliaryVtabOperator( ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; - if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ + if( sqlite3ExprIsVtabRef(pCol) ){ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); @@ -422,10 +422,10 @@ static int isAuxiliaryVtabOperator( int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->y.pTab) ){ + if( sqlite3ExprIsVtabRef(pLeft) ){ res++; } - if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->y.pTab) ){ + if( pRight && sqlite3ExprIsVtabRef(pRight) ){ res++; SWAP(Expr*, pLeft, pRight); } From 78d1d225d87af40f5bdca57fa72f00b6ffaffa21 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Feb 2020 19:25:07 +0000 Subject: [PATCH 019/102] A better (smaller and faster) solution to ticket [4374860b29383380]. FossilOrigin-Name: abc473fb8fb999005dc79a360e34f97b3b25429decf1820dd2afa5c19577753d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 25 +++++++++++-------------- src/sqliteInt.h | 4 +++- src/whereexpr.c | 12 ++++++++---- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index a47448eb72..1cbd91987d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Take\scare\swhen\schecking\sthe\stable\sof\sa\sTK_COLUMN\sexpression\snode\sto\ssee\sif\sthe\ntable\sis\sa\svirtual\stable\sto\sfirst\sensure\sthat\sthe\sExpr.y.pTab\spointer\sis\snot\nnull\sdue\sto\sgenerated\scolumn\soptimizations.\s\sTicket\s[4374860b29383380]. -D 2020-02-17T00:12:04.817 +C A\sbetter\s(smaller\sand\sfaster)\ssolution\sto\sticket\s[4374860b29383380]. +D 2020-02-17T19:25:07.592 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712 F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d -F src/expr.c af70e9a131624dac1c482dd6ed4f73df24a905987447ec8f70a17c7ee55dd2d7 +F src/expr.c 4b25db7f9472b3532560242193bc4eefaefc7720dc4f2d7ec9a89ada410c6ea2 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41 F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4 @@ -536,7 +536,7 @@ F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1f F src/sqlite.h.in 0d9ef312509cb7c8445f4dc25fedfe103c147668a78a36a607a1064f1e0612a4 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 27951f294f29cd875c6027f2707d644ef99f469bd97514568b5a8581a114db8c -F src/sqliteInt.h a8979f41b823f4bc8ee0c446f5a9190074a14570fd4022194a7299c453f3c00c +F src/sqliteInt.h d736043dc6291d3af289d911237da0801b6c05be086ae322eedd47a089ae8d2f F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -620,7 +620,7 @@ F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d F src/where.c cbad14f1d8e11b9f052e937274315c7c17266a89eda408c86084ee894debb7d5 F src/whereInt.h 9157228db086f436a574589f8cc5749bd971e94017c552305ad9ec472ed2e098 F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d -F src/whereexpr.c 512b6d4b0c5710d45ec4efeec19523c457b86d47bb9f02e582d2ee47b423aa2e +F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7 F src/window.c f8ba2ee12a19b51d3ba42c16277c74185ee9215306bc0d5a03974ade8b5bc98f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1858,7 +1858,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 109ee07433b274a39954cef62bf67d47bcda960df9bef56127210ebf1c3c104c -R 6f9ad25842fa66c90901a82d5cd39115 +P 9d0d4ab95dc0c56e053c2924ed322a9ea7b25439e6f74599f706905a1994e454 +R 1c052b7cdf4947664b7043564b643ac3 U drh -Z 68fbba6154ce295a8c685f40a10cb886 +Z e960557a43b001a47933dacf8bc1d10e diff --git a/manifest.uuid b/manifest.uuid index abd4568ad9..26c2328b51 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d0d4ab95dc0c56e053c2924ed322a9ea7b25439e6f74599f706905a1994e454 \ No newline at end of file +abc473fb8fb999005dc79a360e34f97b3b25429decf1820dd2afa5c19577753d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index be23a5bd52..8b939de24f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2244,15 +2244,6 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){ return rc; } -/* -** Return true if p is a Column node that references a virtual table. -*/ -int sqlite3ExprIsVtabRef(Expr *p){ - if( p->op!=TK_COLUMN ) return 0; - if( p->y.pTab==0 ) return 0; - return IsVirtual(p->y.pTab); -} - /* ** Return FALSE if there is no chance that the expression can be NULL. ** @@ -5481,19 +5472,25 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ case TK_LT: case TK_LE: case TK_GT: - case TK_GE: + case TK_GE: { + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pRight; testcase( pExpr->op==TK_EQ ); testcase( pExpr->op==TK_NE ); testcase( pExpr->op==TK_LT ); testcase( pExpr->op==TK_LE ); testcase( pExpr->op==TK_GT ); testcase( pExpr->op==TK_GE ); - if( sqlite3ExprIsVtabRef(pExpr->pLeft) - || sqlite3ExprIsVtabRef(pExpr->pRight) + /* The y.pTab=0 assignment in wherecode.c always happens after the + ** impliesNotNullRow() test */ + if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0) + && IsVirtual(pLeft->y.pTab)) + || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0) + && IsVirtual(pRight->y.pTab)) ){ - return WRC_Prune; + return WRC_Prune; } - + } default: return WRC_Continue; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c42a9e8c64..517bb40b88 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2153,8 +2153,11 @@ struct Table { */ #ifndef SQLITE_OMIT_VIRTUALTABLE # define IsVirtual(X) ((X)->nModuleArg) +# define ExprIsVtab(X) \ + ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg) #else # define IsVirtual(X) 0 +# define ExprIsVtab(X) 0 #endif /* @@ -4278,7 +4281,6 @@ int sqlite3ExprIsTableConstant(Expr*,int); int sqlite3ExprContainsSubquery(Expr*); #endif int sqlite3ExprIsInteger(Expr*, int*); -int sqlite3ExprIsVtabRef(Expr*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); diff --git a/src/whereexpr.c b/src/whereexpr.c index e99a44f15c..3c91fc3539 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -377,7 +377,8 @@ static int isAuxiliaryVtabOperator( ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; - if( sqlite3ExprIsVtabRef(pCol) ){ + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); + if( ExprIsVtab(pCol) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; @@ -399,7 +400,8 @@ static int isAuxiliaryVtabOperator( ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; - if( sqlite3ExprIsVtabRef(pCol) ){ + testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); + if( ExprIsVtab(pCol) ){ sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); @@ -422,10 +424,12 @@ static int isAuxiliaryVtabOperator( int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - if( sqlite3ExprIsVtabRef(pLeft) ){ + testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); + if( ExprIsVtab(pLeft) ){ res++; } - if( pRight && sqlite3ExprIsVtabRef(pRight) ){ + testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); + if( pRight && ExprIsVtab(pRight) ){ res++; SWAP(Expr*, pLeft, pRight); } From 0184a256e3f4cc124ef0f72a207ba430796d28a6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Feb 2020 23:08:16 +0000 Subject: [PATCH 020/102] Convert invalid surrogates to 0xfffd when translating UTF. FossilOrigin-Name: 7fab1393c2b22b1f3b159b631e06e7e0d3900850ee249c38e4d3cdd0aacf637e --- manifest | 14 +++--- manifest.uuid | 2 +- src/utf.c | 97 +++++++++++++++++----------------------- test/tkt-3fe897352e.test | 8 ++-- 4 files changed, 52 insertions(+), 69 deletions(-) diff --git a/manifest b/manifest index 1cbd91987d..bb1d336591 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\sbetter\s(smaller\sand\sfaster)\ssolution\sto\sticket\s[4374860b29383380]. -D 2020-02-17T19:25:07.592 +C Convert\sinvalid\ssurrogates\sto\s0xfffd\swhen\stranslating\sUTF. +D 2020-02-17T23:08:16.564 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -600,7 +600,7 @@ F src/treeview.c 438c1000587b33faba35e87596bebcf7f40638d98f33781cdd9e04711b18b09 F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc F src/update.c 3eb778c42155d944377a4ee5e440b04520f07094804ed6ce63d2528f619614d9 F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 -F src/utf.c 736ff76753236ffbc8b5b939f5e0607f28aeaa7c780b3a56b419228f0a81c87b +F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7 F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9 F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8 @@ -1439,7 +1439,7 @@ F test/tkt-385a5b56b9.test 5204a7cba0e28c99df0acbf95af5e1af4d32965a7a14de6eccebf F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678 F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3a77c9714e.test 90e3e8455ee945a4076d4c44062b8845708af24a880355328fe7008f2047c9f0 -F test/tkt-3fe897352e.test 27e26eb0f1811aeba4d65aba43a4c52e99da5e70 +F test/tkt-3fe897352e.test 6849fde0a87165ff83f54f5047af7c743d72af26908fadb90174f3294450b3f4 F test/tkt-4a03edc4c8.test 91c0e135888cdc3d4eea82406a44b05c8c1648d0 F test/tkt-4c86b126f2.test cbcc611becd0396890169ab23102dd70048bbc9a F test/tkt-4dd95f6943.test 3d0ce415d2ee15d3d564121960016b9c7be79407 @@ -1858,7 +1858,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 9d0d4ab95dc0c56e053c2924ed322a9ea7b25439e6f74599f706905a1994e454 -R 1c052b7cdf4947664b7043564b643ac3 +P abc473fb8fb999005dc79a360e34f97b3b25429decf1820dd2afa5c19577753d +R 4bf2952c1b8e70d0751661faff1674f3 U drh -Z e960557a43b001a47933dacf8bc1d10e +Z 268df0dffaa8fc33ed45d27c33b3bdad diff --git a/manifest.uuid b/manifest.uuid index 26c2328b51..5af135d1b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abc473fb8fb999005dc79a360e34f97b3b25429decf1820dd2afa5c19577753d \ No newline at end of file +7fab1393c2b22b1f3b159b631e06e7e0d3900850ee249c38e4d3cdd0aacf637e \ No newline at end of file diff --git a/src/utf.c b/src/utf.c index f5fb3ef347..f6c8e79e50 100644 --- a/src/utf.c +++ b/src/utf.c @@ -105,26 +105,6 @@ static const unsigned char sqlite3Utf8Trans1[] = { } \ } -#define READ_UTF16LE(zIn, TERM, c){ \ - c = (*zIn++); \ - c += ((*zIn++)<<8); \ - if( c>=0xD800 && c<0xE000 && TERM ){ \ - int c2 = (*zIn++); \ - c2 += ((*zIn++)<<8); \ - c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ - } \ -} - -#define READ_UTF16BE(zIn, TERM, c){ \ - c = ((*zIn++)<<8); \ - c += (*zIn++); \ - if( c>=0xD800 && c<0xE000 && TERM ){ \ - int c2 = ((*zIn++)<<8); \ - c2 += (*zIn++); \ - c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \ - } \ -} - /* ** Translate a single UTF-8 character. Return the unicode value. ** @@ -301,13 +281,43 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ if( pMem->enc==SQLITE_UTF16LE ){ /* UTF-16 Little-endian -> UTF-8 */ while( zIn=0xd800 && c<0xe000 ){ + if( c>=0xdc00 || zIn>=zTerm ){ + c = 0xfffd; + }else{ + int c2 = *(zIn++); + c2 += (*(zIn++))<<8; + if( c2<0xdc00 || c2>=0xe000 ){ + zIn -= 2; + c = 0xfffd; + }else{ + c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000; + } + } + } WRITE_UTF8(z, c); } }else{ /* UTF-16 Big-endian -> UTF-8 */ while( zIn=0xd800 && c<0xe000 ){ + if( c>=0xdc00 || zIn>=zTerm ){ + c = 0xfffd; + }else{ + int c2 = (*(zIn++))<<8; + c2 += *(zIn++); + if( c2<0xdc00 || c2>=0xe000 ){ + zIn -= 2; + c = 0xfffd; + }else{ + c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000; + } + } + } WRITE_UTF8(z, c); } } @@ -466,18 +476,15 @@ int sqlite3Utf16ByteLen(const void *zIn, int nChar){ unsigned char const *z = zIn; int n = 0; - if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){ - while( n=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2; + n++; } - return (int)(z-(unsigned char const *)zIn); + return (int)(z-(unsigned char const *)zIn) + - (SQLITE_UTF16NATIVE==SQLITE_UTF16LE); } #if defined(SQLITE_TEST) @@ -507,30 +514,6 @@ void sqlite3UtfSelfTest(void){ assert( c==t ); assert( (z-zBuf)==n ); } - for(i=0; i<0x00110000; i++){ - if( i>=0xD800 && i<0xE000 ) continue; - z = zBuf; - WRITE_UTF16LE(z, i); - n = (int)(z-zBuf); - assert( n>0 && n<=4 ); - z[0] = 0; - z = zBuf; - READ_UTF16LE(z, 1, c); - assert( c==i ); - assert( (z-zBuf)==n ); - } - for(i=0; i<0x00110000; i++){ - if( i>=0xD800 && i<0xE000 ) continue; - z = zBuf; - WRITE_UTF16BE(z, i); - n = (int)(z-zBuf); - assert( n>0 && n<=4 ); - z[0] = 0; - z = zBuf; - READ_UTF16BE(z, 1, c); - assert( c==i ); - assert( (z-zBuf)==n ); - } } #endif /* SQLITE_TEST */ #endif /* SQLITE_OMIT_UTF16 */ diff --git a/test/tkt-3fe897352e.test b/test/tkt-3fe897352e.test index bc2b2033e7..fa70ac7658 100644 --- a/test/tkt-3fe897352e.test +++ b/test/tkt-3fe897352e.test @@ -33,28 +33,28 @@ do_test tkt-3fe89-1.1 { INSERT INTO t1 VALUES(hex_to_utf16be('D800')); SELECT hex(x) FROM t1; } -} {EDA080} +} {EFBFBD} do_test tkt-3fe89-1.2 { db eval { DELETE FROM t1; INSERT INTO t1 VALUES(hex_to_utf16le('00D8')); SELECT hex(x) FROM t1; } -} {EDA080} +} {EFBFBD} do_test tkt-3fe89-1.3 { db eval { DELETE FROM t1; INSERT INTO t1 VALUES(hex_to_utf16be('DFFF')); SELECT hex(x) FROM t1; } -} {EDBFBF} +} {EFBFBD} do_test tkt-3fe89-1.4 { db eval { DELETE FROM t1; INSERT INTO t1 VALUES(hex_to_utf16le('FFDF')); SELECT hex(x) FROM t1; } -} {EDBFBF} +} {EFBFBD} finish_test From 4defdddc31c9ad128ddc80860e794616664999ef Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Feb 2020 19:49:48 +0000 Subject: [PATCH 021/102] Add the new sqlite3_create_filename() and sqlite3_free_filename() interfaces for use by Shims. Use these interfaces inside the multiplexor. FossilOrigin-Name: 9469f36ac89e4b75d0ab25fefbeff25201992c53141da915dcaa017083cab6db --- manifest | 22 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 3 +++ src/main.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ src/pager.c | 5 ++++ src/sqlite.h.in | 53 +++++++++++++++++++++++++++++++++++++ src/sqlite3ext.h | 7 +++++ src/test_multiplex.c | 7 +++-- 8 files changed, 147 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index bb1d336591..8f6fde0861 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Convert\sinvalid\ssurrogates\sto\s0xfffd\swhen\stranslating\sUTF. -D 2020-02-17T23:08:16.564 +C Add\sthe\snew\ssqlite3_create_filename()\sand\ssqlite3_free_filename()\sinterfaces\nfor\suse\sby\sShims.\s\sUse\sthese\sinterfaces\sinside\sthe\smultiplexor. +D 2020-02-18T19:49:48.083 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -494,8 +494,8 @@ F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa -F src/loadext.c 8cd803f1747c03a50b32fe87ebfb5851998d0cdafefe02737daa95e0616b42bb -F src/main.c 12d42b43c331778f6e3a1ebc57b63470f1951350efbea377e03cac6660e03b57 +F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32 +F src/main.c 42577fa09d195dd0f09d4a3d95158ff7f4a677dc83ccb0d6d7e73ff86c2dc6f1 F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -518,7 +518,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c b1e79698f3903e64d7a8ab5f4b3163aa39ed25686289a68de20b6b5734de70e6 +F src/pager.c f1c92d05440f0f6826430b56e29addf453785f5c5651b8510d17d6310ba5df04 F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3 F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 @@ -533,9 +533,9 @@ F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9e5b357f1c0952ff699effe3640be58a7e16497be6b74a2637495f5ef13859f0 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa -F src/sqlite.h.in 0d9ef312509cb7c8445f4dc25fedfe103c147668a78a36a607a1064f1e0612a4 +F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 27951f294f29cd875c6027f2707d644ef99f469bd97514568b5a8581a114db8c +F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee F src/sqliteInt.h d736043dc6291d3af289d911237da0801b6c05be086ae322eedd47a089ae8d2f F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 @@ -570,7 +570,7 @@ F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c dec0aa821b230773aeb3dd11d652c1193f7cedb18a20b25659bc672288115242 F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c -F src/test_multiplex.c e5fac104a0eebf935e6732cda6abce79ea0b4b10949518d5dac7b0293173a40f +F src/test_multiplex.c 46e278397bef99b10530c1a695b4f6f23823fde6d6589b182f14e9bd43440b57 F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4 @@ -1858,7 +1858,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 abc473fb8fb999005dc79a360e34f97b3b25429decf1820dd2afa5c19577753d -R 4bf2952c1b8e70d0751661faff1674f3 +P 7fab1393c2b22b1f3b159b631e06e7e0d3900850ee249c38e4d3cdd0aacf637e +R 47e79e218da814ff1e7c3c3b23eeb83f U drh -Z 268df0dffaa8fc33ed45d27c33b3bdad +Z 32b0e509161127f47e57d0b5e1c85750 diff --git a/manifest.uuid b/manifest.uuid index 5af135d1b8..3e36b9046b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7fab1393c2b22b1f3b159b631e06e7e0d3900850ee249c38e4d3cdd0aacf637e \ No newline at end of file +9469f36ac89e4b75d0ab25fefbeff25201992c53141da915dcaa017083cab6db \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 245e9b004d..06297e6bb6 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -474,6 +474,9 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_filename_database, sqlite3_filename_journal, sqlite3_filename_wal, + /* Version 3.32.0 and later */ + sqlite3_create_filename, + sqlite3_free_filename, }; /* diff --git a/src/main.c b/src/main.c index 3eccd08ea7..4bfd943464 100644 --- a/src/main.c +++ b/src/main.c @@ -4242,6 +4242,68 @@ static const char *databaseName(const char *zName){ return zName; } +/* +** Append text z[] to the end of p[]. Return a pointer to the first +** character after then zero terminator on the new text in p[]. +*/ +static char *appendText(char *p, const char *z){ + size_t n = strlen(z); + memcpy(p, z, n+1); + return p+n+1; +} + +/* +** Allocate memory to hold names for a database, journal file, WAL file, +** and query parameters. The pointer returned is valid for use by +** sqlite3_filename_database() and sqlite3_uri_parameter() and related +** functions. +** +** Memory layout must be compatible with that generated by the pager +** and expected by sqlite3_uri_parameter() and databaseName(). +*/ +char *sqlite3_create_filename( + const char *zDatabase, + const char *zJournal, + const char *zWal, + int nParam, + const char **azParam +){ + sqlite3_int64 nByte; + int i; + char *pResult, *p; + nByte = strlen(zDatabase) + strlen(zJournal) + strlen(zWal) + 10; + for(i=0; i +**
  • [sqlite3_uri_parameter()], +**
  • [sqlite3_uri_boolean()], +**
  • [sqlite3_uri_int64()], +**
  • [sqlite3_uri_key()], +**
  • [sqlite3_filename_database()], +**
  • [sqlite3_filename_journal()], or +**
  • [sqlite3_filename_wal()]. +** +** If a memory allocation error occurs, sqlite3_create_filename() might +** return a NULL pointer. The memory obtained from sqlite3_create_filename(X) +** must be released by a corresponding call to sqlite3_free_filename(Y). +** +** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array +** of 2*N pointers to strings. Each pair of pointers in this array corresponds +** to a key and value for a query parameter. The P parameter may be a NULL +** pointer if N is zero. None of the 2*N pointers in the P array may be +** NULL pointers and key pointers should not be empty strings. +** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may +** be NULL pointers, though they can be empty strings. +** +** The sqlite3_free_filename(Y) routine releases a memory allocation +** previously obtained from sqlite3_create_filename(). Invoking +** sqlite3_free_filename(Y) is a NULL pointer is a harmless no-op. +** +** If the Y parameter to sqlite3_free_filename(Y) is anything other +** than a NULL pointer or a pointer previously acquired from +** sqlite3_create_filename(), then bad things such as heap +** corruption or segfaults may occur. The value Y should be +** used again after sqlite3_free_filename(Y) has been called. This means +** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, +** then the corresponding [sqlite3_module.xClose() method should also be +** invoked prior to calling sqlite3_free_filename(Y). +*/ +char *sqlite3_create_filename( + const char *zDatabase, + const char *zJournal, + const char *zWal, + int nParam, + const char **azParam +); +void sqlite3_free_filename(char*); /* ** CAPI3REF: Error Codes And Messages diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index bdd0a85ed7..a7c76a6784 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -330,6 +330,10 @@ struct sqlite3_api_routines { const char *(*filename_database)(const char*); const char *(*filename_journal)(const char*); const char *(*filename_wal)(const char*); + /* Version 3.32.0 and later */ + char *(*create_filename)(const char*,const char*,const char*, + int,const char**); + void (*free_filename)(char*); }; /* @@ -630,6 +634,9 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_filename_database sqlite3_api->filename_database #define sqlite3_filename_journal sqlite3_api->filename_journal #define sqlite3_filename_wal sqlite3_api->filename_wal +/* Version 3.32.0 and later */ +#define sqlite3_create_filename sqlite3_api->create_filename +#define sqlite3_free_filename sqlite3_api->free_filename #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff --git a/src/test_multiplex.c b/src/test_multiplex.c index 56e78c35f7..3c9aa034cc 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -267,11 +267,14 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){ char *z; int n = pGroup->nName; - pGroup->aReal[iChunk].z = z = sqlite3_malloc64( n+5 ); + z = sqlite3_malloc64( n+5 ); if( z==0 ){ return SQLITE_NOMEM; } multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z); + pGroup->aReal[iChunk].z = sqlite3_create_filename(z,"","",0,0); + sqlite3_free(z); + if( pGroup->aReal[iChunk].z==0 ) return SQLITE_NOMEM; } return SQLITE_OK; } @@ -438,7 +441,7 @@ static void multiplexSubClose( } sqlite3_free(pGroup->aReal[iChunk].p); } - sqlite3_free(pGroup->aReal[iChunk].z); + sqlite3_free_filename(pGroup->aReal[iChunk].z); memset(&pGroup->aReal[iChunk], 0, sizeof(pGroup->aReal[iChunk])); } From 4b9e73689857bd4449145515e7d45bec1020e090 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Feb 2020 23:58:58 +0000 Subject: [PATCH 022/102] Remove a NEVER() macro and add a test case to cause its argument to be true. FossilOrigin-Name: ee034fe916448e953ee7824e5c0db99a36a0ad138ebfb25f751bf84cb80a8fa7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- test/fuzzdata7.db | Bin 16819200 -> 16819200 bytes 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8f6fde0861..6be1c10aa4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\snew\ssqlite3_create_filename()\sand\ssqlite3_free_filename()\sinterfaces\nfor\suse\sby\sShims.\s\sUse\sthese\sinterfaces\sinside\sthe\smultiplexor. -D 2020-02-18T19:49:48.083 +C Remove\sa\sNEVER()\smacro\sand\sadd\sa\stest\scase\sto\scause\sits\sargument\sto\sbe\strue. +D 2020-02-18T23:58:58.305 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -472,7 +472,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 7cc1fb4086847a9089d78ebc3e52f5437d4aed20fc7d2da13219cba9fd5a8c8d +F src/btree.c 4dfab5862184da86103795ee2a31a22d2bbf9d8cf183bd3e05f3e32267c0855f F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471 F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175 F src/build.c 2394d2c853088106dfc1cf485d609f20e6421d7c84892b795824e454f78e50ad @@ -1021,7 +1021,7 @@ F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 -F test/fuzzdata7.db e7a86fd83dda151d160445d542e32e5c6019c541b3a74c2a525b6ac640639711 +F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 F test/fuzzdata8.db 8bd41f8e1b9c61af011bf5cf16a85fb7f718fdd3348e476b78ba36adab872653 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 @@ -1858,7 +1858,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 7fab1393c2b22b1f3b159b631e06e7e0d3900850ee249c38e4d3cdd0aacf637e -R 47e79e218da814ff1e7c3c3b23eeb83f +P 9469f36ac89e4b75d0ab25fefbeff25201992c53141da915dcaa017083cab6db +R d0b79cc11814a6451908b085864d64b9 U drh -Z 32b0e509161127f47e57d0b5e1c85750 +Z ef7cd4d2b1ba31f328f88505566c6b56 diff --git a/manifest.uuid b/manifest.uuid index 3e36b9046b..33f99d4f44 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9469f36ac89e4b75d0ab25fefbeff25201992c53141da915dcaa017083cab6db \ No newline at end of file +ee034fe916448e953ee7824e5c0db99a36a0ad138ebfb25f751bf84cb80a8fa7 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index de05fd999c..713358e1aa 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1449,7 +1449,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ int sz2 = 0; int sz = get2byte(&data[iFree+2]); int top = get2byte(&data[hdr+5]); - if( NEVER(top>=iFree) ){ + if( top>=iFree ){ return SQLITE_CORRUPT_PAGE(pPage); } if( iFree2 ){ diff --git a/test/fuzzdata7.db b/test/fuzzdata7.db index 8706be40d11d54231c2e2098f76172e4b59ef494..99daab109293d39651b2a0c9c4e9ce5d898023cc 100644 GIT binary patch delta 69418 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Ν9LVblK6_Va%&9LeGn^U`d~@wNId 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 delta 69189 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

    m3l|-CKOZ7PHsAY$h*ExHzbKzDtPCetE0_h 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 From 1cfee74a2812b8f09e8b8ecf419a69b19de16b79 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Feb 2020 15:39:46 +0000 Subject: [PATCH 023/102] Fix a potential NULL pointer dereference following OOM. Problem discovered by dbsqlfuzz. Test case in TH3. FossilOrigin-Name: 5aeb5a2d295e10d5fc1d456b3acaf8ac13c04cb5bb71a8c4571541d366e95887 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6be1c10aa4..c04bd35f1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sNEVER()\smacro\sand\sadd\sa\stest\scase\sto\scause\sits\sargument\sto\sbe\strue. -D 2020-02-18T23:58:58.305 +C Fix\sa\spotential\sNULL\spointer\sdereference\sfollowing\sOOM.\s\sProblem\sdiscovered\nby\sdbsqlfuzz.\s\sTest\scase\sin\sTH3. +D 2020-02-19T15:39:46.936 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -529,7 +529,7 @@ F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5 F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c f0781c9e180028b279bc4ff079ad54f4727223d470c8d2343643fcaf79b67740 +F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9e5b357f1c0952ff699effe3640be58a7e16497be6b74a2637495f5ef13859f0 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa @@ -1858,7 +1858,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 9469f36ac89e4b75d0ab25fefbeff25201992c53141da915dcaa017083cab6db -R d0b79cc11814a6451908b085864d64b9 +P ee034fe916448e953ee7824e5c0db99a36a0ad138ebfb25f751bf84cb80a8fa7 +R 2a8847f9c82a11b506ee531f16ba829e U drh -Z ef7cd4d2b1ba31f328f88505566c6b56 +Z 3d267f9a5c83ad9967ac22844ce82b39 diff --git a/manifest.uuid b/manifest.uuid index 33f99d4f44..7badba80a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee034fe916448e953ee7824e5c0db99a36a0ad138ebfb25f751bf84cb80a8fa7 \ No newline at end of file +5aeb5a2d295e10d5fc1d456b3acaf8ac13c04cb5bb71a8c4571541d366e95887 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 119a07fd2a..05ef0c06eb 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1051,7 +1051,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ - if( pRight->op==TK_ID ){ + if( pRight && pRight->op==TK_ID ){ int rc = resolveExprStep(pWalker, pRight); if( rc==WRC_Abort ) return WRC_Abort; if( pRight->op==TK_TRUEFALSE ){ From 5f69512404cd2e5153ddf90ea277fbba6dd58ab7 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Feb 2020 14:08:51 +0000 Subject: [PATCH 024/102] Early-out on the INTERSECT query processing following an error. FossilOrigin-Name: a67cf5b7d37d5b1484be32092635faafd8f76e5881898cd9435517c4b287d663 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index c04bd35f1a..f317c1c42a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sNULL\spointer\sdereference\sfollowing\sOOM.\s\sProblem\sdiscovered\nby\sdbsqlfuzz.\s\sTest\scase\sin\sTH3. -D 2020-02-19T15:39:46.936 +C Early-out\son\sthe\sINTERSECT\squery\sprocessing\sfollowing\san\serror. +D 2020-02-20T14:08:51.305 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -531,7 +531,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 9e5b357f1c0952ff699effe3640be58a7e16497be6b74a2637495f5ef13859f0 +F src/select.c 59ba85dce4c0ffb88fcda66b0c6c94b9a15f0fc30a3c454261468bd7e9063627 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1858,7 +1858,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 ee034fe916448e953ee7824e5c0db99a36a0ad138ebfb25f751bf84cb80a8fa7 -R 2a8847f9c82a11b506ee531f16ba829e +P 5aeb5a2d295e10d5fc1d456b3acaf8ac13c04cb5bb71a8c4571541d366e95887 +R e16a245c08b1d334873515473145c2a9 U drh -Z 3d267f9a5c83ad9967ac22844ce82b39 +Z de8f43e65e8ffd2358ef87b9dc3ccd7d diff --git a/manifest.uuid b/manifest.uuid index 7badba80a5..9b7e90f43f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5aeb5a2d295e10d5fc1d456b3acaf8ac13c04cb5bb71a8c4571541d366e95887 \ No newline at end of file +a67cf5b7d37d5b1484be32092635faafd8f76e5881898cd9435517c4b287d663 \ No newline at end of file diff --git a/src/select.c b/src/select.c index d03322fcb2..0f38c806c4 100644 --- a/src/select.c +++ b/src/select.c @@ -2806,6 +2806,7 @@ static int multiSelect( /* Generate code to take the intersection of the two temporary ** tables. */ + if( rc ) break; assert( p->pEList ); iBreak = sqlite3VdbeMakeLabel(pParse); iCont = sqlite3VdbeMakeLabel(pParse); From 8a64d62d31efd388720ed40ae1bf40b6e1e53173 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 20 Feb 2020 14:11:08 +0000 Subject: [PATCH 025/102] Add test case for previous commit. FossilOrigin-Name: 14d14eb537075c6ac77513b1e7305bed8bc01a9034dfb763fd96f76400f2b705 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/windowfault.test | 11 +++++++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f317c1c42a..006126d589 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Early-out\son\sthe\sINTERSECT\squery\sprocessing\sfollowing\san\serror. -D 2020-02-20T14:08:51.305 +C Add\stest\scase\sfor\sprevious\scommit. +D 2020-02-20T14:11:08.353 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1737,7 +1737,7 @@ F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b -F test/windowfault.test 8e3b69abe0eea9595ba3940afd9c63644e11966ed8815734b67f1479a8e9891a +F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad F test/with1.test 584580a5ae79868a91873863f8cb2d00040006dc1e4c332ef1d8642f2815dc6e F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab F test/with3.test 13b3336739da648a9e4dfa11bb04e73a920c97620041007c5f75d5d14084c346 @@ -1858,7 +1858,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 5aeb5a2d295e10d5fc1d456b3acaf8ac13c04cb5bb71a8c4571541d366e95887 -R e16a245c08b1d334873515473145c2a9 -U drh -Z de8f43e65e8ffd2358ef87b9dc3ccd7d +P a67cf5b7d37d5b1484be32092635faafd8f76e5881898cd9435517c4b287d663 +R ad63d3f6becd6d2d81908e2805dcc6e2 +U dan +Z caf14f0cd239063090f3593a5e2021c6 diff --git a/manifest.uuid b/manifest.uuid index 9b7e90f43f..aa306871dc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a67cf5b7d37d5b1484be32092635faafd8f76e5881898cd9435517c4b287d663 \ No newline at end of file +14d14eb537075c6ac77513b1e7305bed8bc01a9034dfb763fd96f76400f2b705 \ No newline at end of file diff --git a/test/windowfault.test b/test/windowfault.test index e97544f4c8..aea2340215 100644 --- a/test/windowfault.test +++ b/test/windowfault.test @@ -263,4 +263,15 @@ do_faultsim_test 11 -faults oom* -prep { faultsim_test_result {0 {}} } +do_faultsim_test 11 -faults oom* -prep { +} -body { + execsql { + VALUES(false),(current_date collate binary) + intersect + values(count() not like group_concat(cast(cast(0e00 as text) as integer) <= NULL || 0.4e-0 || 0x8 & true ) over () collate rtrim); + } +} -test { + faultsim_test_result {0 {}} +} + finish_test From e8c4f03266e1b89bc693c2294734c4f828a177f8 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 22 Feb 2020 13:01:19 +0000 Subject: [PATCH 026/102] In the OP_Column opcode, if the cursor is marked NullRow (due to being the right table of a LEFT JOIN that does not match) and the cursor is the table cursor for an OR-optimization with a covering index, then do not substitute the covering index cursor, since the covering index cursor does not have the NullRow flag set. Ticket [aa4378693018aa99] FossilOrigin-Name: f02030b3403d67734bba471a91ad5bfdb03ddf6fdc3ef14808a04495e43b0470 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- test/whereD.test | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 006126d589..8bec1d1c7e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sfor\sprevious\scommit. -D 2020-02-20T14:11:08.353 +C In\sthe\sOP_Column\sopcode,\sif\sthe\scursor\sis\smarked\sNullRow\s(due\sto\sbeing\sthe\nright\stable\sof\sa\sLEFT\sJOIN\sthat\sdoes\snot\smatch)\sand\sthe\scursor\sis\sthe\stable\ncursor\sfor\san\sOR-optimization\swith\sa\scovering\sindex,\sthen\sdo\snot\ssubstitute\nthe\scovering\sindex\scursor,\ssince\sthe\scovering\sindex\scursor\sdoes\snot\shave\nthe\sNullRow\sflag\sset.\s\sTicket\s[aa4378693018aa99] +D 2020-02-22T13:01:19.240 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8 F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9 F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 -F src/vdbeaux.c 4200161a1b249c33ac587c562e7dca155733694c6d4ad31914184294e4fa9e18 +F src/vdbeaux.c 2d8d863e6b85a5b4362a248c04d82f0df8df79be289b2fc75b488c3cd79ddb5f F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c ff2a1fd86ea943efb7174bd74bc661815c449be6165e136e8849e1dc59e24353 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df @@ -1702,7 +1702,7 @@ F test/where9.test 2c554b97bbdb2fdf26c57099f60db8a52bfcf7c147f2c256f9798fa0e267c F test/whereA.test 6c6a420ca7d313242f9b1bd471dc80e4d0f8323700ba9c78df0bb843d4daa3b4 F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 -F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002 +F test/whereD.test c1c335e914e28b122e000e9310f02d2be83e1c9dbca2e29f46bd732703944d1b F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89 F test/whereG.test c9378b285828754377ef47fbece7264018c0a3743e7eb686e89917bb9df10885 @@ -1858,7 +1858,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 a67cf5b7d37d5b1484be32092635faafd8f76e5881898cd9435517c4b287d663 -R ad63d3f6becd6d2d81908e2805dcc6e2 -U dan -Z caf14f0cd239063090f3593a5e2021c6 +P 14d14eb537075c6ac77513b1e7305bed8bc01a9034dfb763fd96f76400f2b705 +R 1f345124b6aafeeb9e600617cf39817f +U drh +Z 38c81c56b51d8e5ae42e4e25b041736c diff --git a/manifest.uuid b/manifest.uuid index aa306871dc..83685737a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14d14eb537075c6ac77513b1e7305bed8bc01a9034dfb763fd96f76400f2b705 \ No newline at end of file +f02030b3403d67734bba471a91ad5bfdb03ddf6fdc3ef14808a04495e43b0470 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6ad25da8dd..249ac888c0 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3540,7 +3540,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); if( p->deferredMoveto ){ int iMap; - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ + if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; return SQLITE_OK; diff --git a/test/whereD.test b/test/whereD.test index 8ced0ffc72..e727f47e20 100644 --- a/test/whereD.test +++ b/test/whereD.test @@ -337,6 +337,22 @@ do_searchcount_test 6.6.4 { SELECT c FROM x1 WHERE b=6 OR c=11 OR a=1 } {7 11 3 search 7} +# 2020-02-22 ticket aa4378693018aa99 +# In the OP_Column opcode, if a cursor is marked with OP_NullRow +# (because it is the right table of a LEFT JOIN that does not match) +# then do not substitute index cursors, as the index cursors do not +# have the VdbeCursor.nullRow flag set. +# +do_execsql_test 6.7 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + CREATE TABLE t1(a UNIQUE, b UNIQUE); + INSERT INTO t1(a,b) VALUES(null,2); + CREATE VIEW t2 AS SELECT * FROM t1 WHERE b<10 OR a<7 ORDER BY b; + SELECT t1.* FROM t1 LEFT JOIN t2 ON abs(t1.a)=abs(t2.b); +} {{} 2} + + #------------------------------------------------------------------------- # do_execsql_test 7.0 { From 89efac94fdfac50fac7f971edbde4850b008ecd8 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 22 Feb 2020 16:58:49 +0000 Subject: [PATCH 027/102] When stat4 information is available, try to use it to improve the truth probability of WHERE clause terms that do not participate in the index. FossilOrigin-Name: 1babd6ec5d60e2c34aa1c0285ead768a88004218468e97262411973fe3487022 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/where.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- src/whereInt.h | 10 +++++++--- 4 files changed, 60 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 8bec1d1c7e..d09662988a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sOP_Column\sopcode,\sif\sthe\scursor\sis\smarked\sNullRow\s(due\sto\sbeing\sthe\nright\stable\sof\sa\sLEFT\sJOIN\sthat\sdoes\snot\smatch)\sand\sthe\scursor\sis\sthe\stable\ncursor\sfor\san\sOR-optimization\swith\sa\scovering\sindex,\sthen\sdo\snot\ssubstitute\nthe\scovering\sindex\scursor,\ssince\sthe\scovering\sindex\scursor\sdoes\snot\shave\nthe\sNullRow\sflag\sset.\s\sTicket\s[aa4378693018aa99] -D 2020-02-22T13:01:19.240 +C When\sstat4\sinformation\sis\savailable,\stry\sto\suse\sit\sto\simprove\sthe\struth\nprobability\sof\sWHERE\sclause\sterms\sthat\sdo\snot\sparticipate\sin\sthe\sindex. +D 2020-02-22T16:58:49.287 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,8 +617,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d -F src/where.c cbad14f1d8e11b9f052e937274315c7c17266a89eda408c86084ee894debb7d5 -F src/whereInt.h 9157228db086f436a574589f8cc5749bd971e94017c552305ad9ec472ed2e098 +F src/where.c 74a2fc5a900eab9a2fdda2017a290f0eeaa9c5597fdb86322ea2ccbc3758c71d +F src/whereInt.h 94e3aadcf43b4d16279182d147c9e4f8ef6ed5a5bd1ecc021639c29336b0a3eb F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7 F src/window.c f8ba2ee12a19b51d3ba42c16277c74185ee9215306bc0d5a03974ade8b5bc98f @@ -1858,7 +1858,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 14d14eb537075c6ac77513b1e7305bed8bc01a9034dfb763fd96f76400f2b705 -R 1f345124b6aafeeb9e600617cf39817f +P f02030b3403d67734bba471a91ad5bfdb03ddf6fdc3ef14808a04495e43b0470 +R 0b7e29ed07d82aa79f09869cc21d3459 +T *branch * stat4-truthprob +T *sym-stat4-truthprob * +T -sym-trunk * U drh -Z 38c81c56b51d8e5ae42e4e25b041736c +Z b67db2665ec4d9de443f342c9e446178 diff --git a/manifest.uuid b/manifest.uuid index 83685737a8..0338a5dfbe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f02030b3403d67734bba471a91ad5bfdb03ddf6fdc3ef14808a04495e43b0470 \ No newline at end of file +1babd6ec5d60e2c34aa1c0285ead768a88004218468e97262411973fe3487022 \ No newline at end of file diff --git a/src/where.c b/src/where.c index da9c5a7233..58cf11ab1b 100644 --- a/src/where.c +++ b/src/where.c @@ -2307,7 +2307,10 @@ static void whereLoopOutputAdjust( }else{ k = 20; } - if( iReducewtFlags |= TERM_HEURTRUTH; + iReduce = k; + } } } } @@ -2489,9 +2492,9 @@ static int whereLoopAddBtreeIndex( } if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){ - pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE; + pBuilder->bldFlags1 |= SQLITE_BLDF1_UNIQUE; }else{ - pBuilder->bldFlags |= SQLITE_BLDF_INDEXED; + pBuilder->bldFlags1 |= SQLITE_BLDF1_INDEXED; } pNew->wsFlags = saved_wsFlags; pNew->u.btree.nEq = saved_nEq; @@ -2656,6 +2659,21 @@ static int whereLoopAddBtreeIndex( if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ if( nOut ){ pNew->nOut = sqlite3LogEst(nOut); + if( nEq==1 && pTerm->truthProb>0 ){ +#if WHERETRACE_ENABLED /* 0x01 */ + if( sqlite3WhereTrace & 0x01 ){ + sqlite3DebugPrintf("Update truthProb from %d to %d:\n", + pTerm->truthProb, pNew->nOut - pProbe->aiRowLogEst[0]); + sqlite3WhereTermPrint(pTerm, 999); + } +#endif + pTerm->truthProb = pNew->nOut - pProbe->aiRowLogEst[0]; + if( pTerm->wtFlags & TERM_HEURTRUTH ){ + /* If the old heuristic truthProb was previously used, signal + ** that all loops will need to be recomputed */ + pBuilder->bldFlags2 |= SQLITE_BLDF2_2NDPASS; + } + } if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; pNew->nOut -= nIn; } @@ -3080,9 +3098,9 @@ static int whereLoopAddBtree( } } - pBuilder->bldFlags = 0; + pBuilder->bldFlags1 = 0; rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); - if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){ + if( pBuilder->bldFlags1==SQLITE_BLDF1_INDEXED ){ /* If a non-unique index is used, or if a prefix of the key for ** unique index is used (making the index functionally non-unique) ** then the sqlite_stat1 data becomes important for scoring the @@ -4838,6 +4856,25 @@ WhereInfo *sqlite3WhereBegin( if( nTabList!=1 || whereShortCut(&sWLB)==0 ){ rc = whereLoopAddAll(&sWLB); if( rc ) goto whereBeginError; + +#ifdef SQLITE_ENABLE_STAT4 + /* If one or more WhereTerm.truthProb values were used in estimating + ** loop parameters, but then those truthProb values were subsequently + ** changed based on STAT4 information while computing subsequent loops, + ** then we need to rerun the whole loop building process so that all + ** loops will be built using the revised truthProb values. */ + if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ + WHERETRACE(0xffff, + ("**** Redo all loop computations due to truthProb changes ****\n")); + while( pWInfo->pLoops ){ + WhereLoop *p = pWInfo->pLoops; + pWInfo->pLoops = p->pNextLoop; + whereLoopDelete(db, p); + } + rc = whereLoopAddAll(&sWLB); + if( rc ) goto whereBeginError; + } +#endif #ifdef WHERETRACE_ENABLED if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ diff --git a/src/whereInt.h b/src/whereInt.h index 74101624d5..9d4559c742 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -291,6 +291,7 @@ struct WhereTerm { #define TERM_LIKE 0x0400 /* The original LIKE operator */ #define TERM_IS 0x0800 /* Term.pExpr is an IS operator */ #define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ +#define TERM_HEURTRUTH 0x2000 /* Heuristic truthProb used */ /* ** An instance of the WhereScan object is used as an iterator for locating @@ -405,13 +406,16 @@ struct WhereLoopBuilder { UnpackedRecord *pRec; /* Probe for stat4 (if required) */ int nRecValid; /* Number of valid fields currently in pRec */ #endif - unsigned int bldFlags; /* SQLITE_BLDF_* flags */ + unsigned char bldFlags1; /* First set of SQLITE_BLDF_* flags */ + unsigned char bldFlags2; /* Second set of SQLITE_BLDF_* flags */ unsigned int iPlanLimit; /* Search limiter */ }; /* Allowed values for WhereLoopBuider.bldFlags */ -#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */ -#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ +#define SQLITE_BLDF1_INDEXED 0x0001 /* An index is used */ +#define SQLITE_BLDF1_UNIQUE 0x0002 /* All keys of a UNIQUE index used */ + +#define SQLITE_BLDF2_2NDPASS 0x0004 /* Second builder pass needed */ /* The WhereLoopBuilder.iPlanLimit is used to limit the number of ** index+constraint combinations the query planner will consider for a From 5c193464510c43ef55f806adb8c5807c294a6b8a Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 22 Feb 2020 17:32:00 +0000 Subject: [PATCH 028/102] Add new test file analyzeG.test, containing a test for the change on this branch. FossilOrigin-Name: 243ab1852a2291595527ea1f26e78ad83eda285ae28f876bc1c703677f495cfa --- manifest | 16 ++++----- manifest.uuid | 2 +- test/analyzeG.test | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 test/analyzeG.test diff --git a/manifest b/manifest index d09662988a..e68e44817c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sstat4\sinformation\sis\savailable,\stry\sto\suse\sit\sto\simprove\sthe\struth\nprobability\sof\sWHERE\sclause\sterms\sthat\sdo\snot\sparticipate\sin\sthe\sindex. -D 2020-02-22T16:58:49.287 +C Add\snew\stest\sfile\sanalyzeG.test,\scontaining\sa\stest\sfor\sthe\schange\son\sthis\sbranch. +D 2020-02-22T17:32:00.691 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -655,6 +655,7 @@ F test/analyzeC.test 489fe2ea3be3f17548e8dd895f1b41c9669b52de1b0861f5bffe6eec46e F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb +F test/analyzeG.test c42be77a06331f8677c94b44ba35e170f0771a07d869dffb6b0d78f18b562747 F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b @@ -1858,10 +1859,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 f02030b3403d67734bba471a91ad5bfdb03ddf6fdc3ef14808a04495e43b0470 -R 0b7e29ed07d82aa79f09869cc21d3459 -T *branch * stat4-truthprob -T *sym-stat4-truthprob * -T -sym-trunk * -U drh -Z b67db2665ec4d9de443f342c9e446178 +P 1babd6ec5d60e2c34aa1c0285ead768a88004218468e97262411973fe3487022 +R 2b88c80f8c57b2c7447cf9a6931d1437 +U dan +Z e854d74d6063f88b5d388938dfbba4ed diff --git a/manifest.uuid b/manifest.uuid index 0338a5dfbe..2b78df281d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1babd6ec5d60e2c34aa1c0285ead768a88004218468e97262411973fe3487022 \ No newline at end of file +243ab1852a2291595527ea1f26e78ad83eda285ae28f876bc1c703677f495cfa \ No newline at end of file diff --git a/test/analyzeG.test b/test/analyzeG.test new file mode 100644 index 0000000000..5c729b9cb2 --- /dev/null +++ b/test/analyzeG.test @@ -0,0 +1,85 @@ +# 2020-02-23 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# Tests for functionality related to ANALYZE. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set testprefix analyzeG + +proc do_scan_order_test {tn sql expect} { + uplevel [list do_test $tn [subst -nocommands { + set res "" + db eval "explain query plan $sql" { + lappend res [set detail] + } + set res + }] [list {*}$expect]] +} + +#------------------------------------------------------------------------- +# Test cases 1.* seek to verify that even if an index is not used, its +# stat4 data may be used by the planner to estimate the number of +# rows that match an unindexed constraint on the same column. +# +do_execsql_test 1.0 { + PRAGMA automatic_index = 0; + CREATE TABLE t1(a, x); + CREATE TABLE t2(b, y); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO t1 SELECT (i%50), NULL FROM s; + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO t2 SELECT (CASE WHEN i<95 THEN 44 ELSE i END), NULL FROM s; +} + +# Join tables t1 and t2. Both contain 100 rows. (a=44) matches 2 rows +# in "t1", (b=44) matches 95 rows in table "t2". But the planner doesn't +# know this, so it has no preference as to which order the tables are +# scanned in. In practice this means that tables are scanned in the order +# they are specified in in the FROM clause. +do_scan_order_test 1.1.1 { + SELECT * FROM t1, t2 WHERE a=44 AND b=44; +} { + {SCAN TABLE t1} {SCAN TABLE t2} +} +do_scan_order_test 1.1.2 { + SELECT * FROM t2, t1 WHERE a=44 AND b=44 +} { + {SCAN TABLE t2} {SCAN TABLE t1} +} + +do_execsql_test 1.2 { + CREATE INDEX t2b ON t2(b); + ANALYZE; +} + +# Now, with the ANALYZE data, the planner knows that (b=44) matches a +# large number of rows. So it elects to scan table "t1" first, regardless +# of the order in which the tables are specified in the FROM clause. +do_scan_order_test 1.3.1 { + SELECT * FROM t1, t2 WHERE a=44 AND b=44; +} { + {SCAN TABLE t1} {SCAN TABLE t2} +} +do_scan_order_test 1.3.2 { + SELECT * FROM t2, t1 WHERE a=44 AND b=44 +} { + {SCAN TABLE t1} {SCAN TABLE t2} +} + + +finish_test + From cea1951e80a602a6cca083e45767e47e04d6e7f0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 22 Feb 2020 18:27:48 +0000 Subject: [PATCH 029/102] Do not activate the truthProb adjustment mechanism if the truth probability is less than the heuristic value, as there could be correlations unknown to stat4. Also add additional tracing output to make truthProb adjustments more visible. FossilOrigin-Name: c535fea147ce5c6e4aab25d3c85a3f53a7364c5b5ee10fb6d393c5911a02be7e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 47 ++++++++++++++++++++++++++++++++--------------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index e68e44817c..9f902b1841 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\stest\sfile\sanalyzeG.test,\scontaining\sa\stest\sfor\sthe\schange\son\sthis\sbranch. -D 2020-02-22T17:32:00.691 +C Do\snot\sactivate\sthe\struthProb\sadjustment\smechanism\sif\sthe\struth\sprobability\nis\sless\sthan\sthe\sheuristic\svalue,\sas\sthere\scould\sbe\scorrelations\sunknown\sto\nstat4.\s\sAlso\sadd\sadditional\stracing\soutput\sto\smake\struthProb\sadjustments\smore\nvisible. +D 2020-02-22T18:27:48.175 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d -F src/where.c 74a2fc5a900eab9a2fdda2017a290f0eeaa9c5597fdb86322ea2ccbc3758c71d +F src/where.c 44695e878a287d8c1d4976e2e85bea29994facec3972beb7ca22437d62cda6a5 F src/whereInt.h 94e3aadcf43b4d16279182d147c9e4f8ef6ed5a5bd1ecc021639c29336b0a3eb F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7 @@ -1859,7 +1859,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 1babd6ec5d60e2c34aa1c0285ead768a88004218468e97262411973fe3487022 -R 2b88c80f8c57b2c7447cf9a6931d1437 -U dan -Z e854d74d6063f88b5d388938dfbba4ed +P 243ab1852a2291595527ea1f26e78ad83eda285ae28f876bc1c703677f495cfa +R 2719b1105cf4d47b954b372c20702e91 +U drh +Z e3872ca3639b1687907dbcae881883fa diff --git a/manifest.uuid b/manifest.uuid index 2b78df281d..e6f868ae79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -243ab1852a2291595527ea1f26e78ad83eda285ae28f876bc1c703677f495cfa \ No newline at end of file +c535fea147ce5c6e4aab25d3c85a3f53a7364c5b5ee10fb6d393c5911a02be7e \ No newline at end of file diff --git a/src/where.c b/src/where.c index 58cf11ab1b..03bfad3b7d 100644 --- a/src/where.c +++ b/src/where.c @@ -2305,7 +2305,7 @@ static void whereLoopOutputAdjust( if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ k = 10; }else{ - k = 20; + k = 20; /* Keep the "20" value in sync. See tag-20200222-1 */ } if( iReducewtFlags |= TERM_HEURTRUTH; @@ -2659,7 +2659,13 @@ static int whereLoopAddBtreeIndex( if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ if( nOut ){ pNew->nOut = sqlite3LogEst(nOut); - if( nEq==1 && pTerm->truthProb>0 ){ + if( nEq==1 + && pTerm->truthProb>0 + /* TUNING: Adjust truthProb from the default heuristic only if the + ** probability is close to 1.0. The "20" constant is copied from + ** the heuristic at tag-20200222-1. Keep values in sync */ + && pNew->nOut+20 > pProbe->aiRowLogEst[0] + ){ #if WHERETRACE_ENABLED /* 0x01 */ if( sqlite3WhereTrace & 0x01 ){ sqlite3DebugPrintf("Update truthProb from %d to %d:\n", @@ -4555,6 +4561,28 @@ static int exprIsDeterministic(Expr *p){ return w.eCode; } + +#ifdef WHERETRACE_ENABLED +/* +** Display all WhereLoops in pWInfo +*/ +static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ + if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ + WhereLoop *p; + int i; + static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" + "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; + for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ + p->cId = zLabel[i%(sizeof(zLabel)-1)]; + sqlite3WhereLoopPrint(p, pWC); + } + } +} +# define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C) +#else +# define WHERETRACE_ALL_LOOPS(W,C) +#endif + /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains @@ -4864,6 +4892,7 @@ WhereInfo *sqlite3WhereBegin( ** then we need to rerun the whole loop building process so that all ** loops will be built using the revised truthProb values. */ if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ + WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); WHERETRACE(0xffff, ("**** Redo all loop computations due to truthProb changes ****\n")); while( pWInfo->pLoops ){ @@ -4875,19 +4904,7 @@ WhereInfo *sqlite3WhereBegin( if( rc ) goto whereBeginError; } #endif - -#ifdef WHERETRACE_ENABLED - if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ - WhereLoop *p; - int i; - static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" - "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; - for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ - p->cId = zLabel[i%(sizeof(zLabel)-1)]; - sqlite3WhereLoopPrint(p, sWLB.pWC); - } - } -#endif + WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); wherePathSolver(pWInfo, 0); if( db->mallocFailed ) goto whereBeginError; From 0990c415f65d2556a5e4122cbe5727d500411aeb Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 23 Feb 2020 17:34:45 +0000 Subject: [PATCH 030/102] Fix a problem with ALTER TABLE for views that have a nested FROM clause. Ticket [f50af3e8a565776b]. FossilOrigin-Name: c431b3fd8fd0f6a6974bba3e9366b0430ec003d570e7ce70ceefbcff5fe4b6fa --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- test/altertab.test | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8bec1d1c7e..f338ba88f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sOP_Column\sopcode,\sif\sthe\scursor\sis\smarked\sNullRow\s(due\sto\sbeing\sthe\nright\stable\sof\sa\sLEFT\sJOIN\sthat\sdoes\snot\smatch)\sand\sthe\scursor\sis\sthe\stable\ncursor\sfor\san\sOR-optimization\swith\sa\scovering\sindex,\sthen\sdo\snot\ssubstitute\nthe\scovering\sindex\scursor,\ssince\sthe\scovering\sindex\scursor\sdoes\snot\shave\nthe\sNullRow\sflag\sset.\s\sTicket\s[aa4378693018aa99] -D 2020-02-22T13:01:19.240 +C Fix\sa\sproblem\swith\sALTER\sTABLE\sfor\sviews\sthat\shave\sa\snested\sFROM\sclause.\nTicket\s[f50af3e8a565776b]. +D 2020-02-23T17:34:45.938 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -531,7 +531,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 59ba85dce4c0ffb88fcda66b0c6c94b9a15f0fc30a3c454261468bd7e9063627 +F src/select.c 466f57380528f1d7deeef87a3af09e0ad806fa2eef5e97384ec9376727fdd847 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -639,7 +639,7 @@ F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f1 F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b -F test/altertab.test bd61e5b73d495ec4707133db91b07f09d57e339d988de5ec5a76d34a2198e8f2 +F test/altertab.test 89735fee876427c3f25dc76d887295fbe3659a91bab92468de9f0e622d48bb57 F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b F test/altertab3.test 155b8dc225ce484454a7fb4c8ba745680b6fa0fc3e08919cbbc19f9309d128ff F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f @@ -1858,7 +1858,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 14d14eb537075c6ac77513b1e7305bed8bc01a9034dfb763fd96f76400f2b705 -R 1f345124b6aafeeb9e600617cf39817f +P f02030b3403d67734bba471a91ad5bfdb03ddf6fdc3ef14808a04495e43b0470 +R 27f30806e168cf65f551539c0795adeb U drh -Z 38c81c56b51d8e5ae42e4e25b041736c +Z b1d396f928d83f91cde5e969c202f590 diff --git a/manifest.uuid b/manifest.uuid index 83685737a8..fc3a50b794 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f02030b3403d67734bba471a91ad5bfdb03ddf6fdc3ef14808a04495e43b0470 \ No newline at end of file +c431b3fd8fd0f6a6974bba3e9366b0430ec003d570e7ce70ceefbcff5fe4b6fa \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0f38c806c4..231027b61d 100644 --- a/src/select.c +++ b/src/select.c @@ -5145,7 +5145,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); sqlite3TokenInit(&sColname, zColname); sqlite3ExprListSetName(pParse, pNew, &sColname, 0); - if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ + if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; sqlite3DbFree(db, pX->zEName); if( pSub ){ diff --git a/test/altertab.test b/test/altertab.test index 7dcf8a5e0d..5123c5f296 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -613,4 +613,21 @@ do_execsql_test 18.2.2 { SELECT sql FROM sqlite_master; } {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}} +# 2020-02-23 ticket f50af3e8a565776b +reset_db +do_execsql_test 19.100 { + CREATE TABLE t1(x); + CREATE VIEW t2 AS SELECT 1 FROM t1, (t1 AS a0, t1); + ALTER TABLE t1 RENAME TO t3; + SELECT sql FROM sqlite_master; +} {{CREATE TABLE "t3"(x)} {CREATE VIEW t2 AS SELECT 1 FROM "t3", ("t3" AS a0, "t3")}} +do_execsql_test 19.110 { + INSERT INTO t3(x) VALUES(123); + SELECT * FROM t2; +} {1} +do_execsql_test 19.120 { + INSERT INTO t3(x) VALUES('xyz'); + SELECT * FROM t2; +} {1 1 1 1 1 1 1 1} + finish_test From 35d3cb80c4eeeb7a583ba67bff6ad5d2bf8853e2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 24 Feb 2020 13:35:34 +0000 Subject: [PATCH 031/102] Disable the new analyzeG.test module if not building with STAT4. FossilOrigin-Name: 4a9d3005769e0398183b03a3e132e3946b9d1c48073af2e0559d7beeac3245c0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/analyzeG.test | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 36169e66e6..7ba7392d67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sbugfix\sfrom\strunk. -D 2020-02-24T13:26:29.409 +C Disable\sthe\snew\sanalyzeG.test\smodule\sif\snot\sbuilding\swith\sSTAT4. +D 2020-02-24T13:35:34.777 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -655,7 +655,7 @@ F test/analyzeC.test 489fe2ea3be3f17548e8dd895f1b41c9669b52de1b0861f5bffe6eec46e F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb -F test/analyzeG.test c42be77a06331f8677c94b44ba35e170f0771a07d869dffb6b0d78f18b562747 +F test/analyzeG.test a48c0f324dd14de9a40d52abe5ca2637f682b9a791d2523dd619f6efa14e345b F test/analyzer1.test 459fa02c445ddbf0101a3bad47b34290a35f2e49 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b @@ -1859,7 +1859,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 c535fea147ce5c6e4aab25d3c85a3f53a7364c5b5ee10fb6d393c5911a02be7e c431b3fd8fd0f6a6974bba3e9366b0430ec003d570e7ce70ceefbcff5fe4b6fa -R 540a6846dd3df06385ce1aa12449a267 +P b542dee9de843c19664c19df7435c6034d23d0d213804d588ec0ff599082d576 +R f29b5aa99c284afcd3f25a8fb29ee973 U drh -Z eee179433b7c26e18c07c4463c4efe9e +Z 9cae8ff3aee64bed711ead2769a79514 diff --git a/manifest.uuid b/manifest.uuid index b8c0a97d33..46fc370397 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b542dee9de843c19664c19df7435c6034d23d0d213804d588ec0ff599082d576 \ No newline at end of file +4a9d3005769e0398183b03a3e132e3946b9d1c48073af2e0559d7beeac3245c0 \ No newline at end of file diff --git a/test/analyzeG.test b/test/analyzeG.test index 5c729b9cb2..eb1853b1dc 100644 --- a/test/analyzeG.test +++ b/test/analyzeG.test @@ -14,6 +14,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +ifcapable !stat4 { + finish_test + return +} set testprefix analyzeG proc do_scan_order_test {tn sql expect} { @@ -82,4 +86,3 @@ do_scan_order_test 1.3.2 { finish_test - From f06cdde2cfb57d40c705044d95effa5b352ed125 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 24 Feb 2020 16:46:08 +0000 Subject: [PATCH 032/102] Rework this changes so that instead of setting the WhereTerm.truthProb when a term is seen to be of low selectivity, it merely sets a new flag (the TERM_HIGHTRUTH flag) which causes whereLoopOutputAdjust() to ignore that term. FossilOrigin-Name: 4558163b6a525990f0f1b6629dbb76daf49bcaf1ddbaf0c50fe05ce9ee480ff8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 29 ++++++++++++++++------------- src/whereInt.h | 5 +++++ 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 7ba7392d67..ac8c74c984 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\snew\sanalyzeG.test\smodule\sif\snot\sbuilding\swith\sSTAT4. -D 2020-02-24T13:35:34.777 +C Rework\sthis\schanges\sso\sthat\sinstead\sof\ssetting\sthe\sWhereTerm.truthProb\swhen\na\sterm\sis\sseen\sto\sbe\sof\slow\sselectivity,\sit\smerely\ssets\sa\snew\sflag\n(the\sTERM_HIGHTRUTH\sflag)\swhich\scauses\swhereLoopOutputAdjust()\sto\signore\nthat\sterm. +D 2020-02-24T16:46:08.182 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,8 +617,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d -F src/where.c 44695e878a287d8c1d4976e2e85bea29994facec3972beb7ca22437d62cda6a5 -F src/whereInt.h 94e3aadcf43b4d16279182d147c9e4f8ef6ed5a5bd1ecc021639c29336b0a3eb +F src/where.c 3b8c9bd013eb0736e16f60bdc109e83337ef99513a3aff5f16ddac036e6c277e +F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7 F src/window.c f8ba2ee12a19b51d3ba42c16277c74185ee9215306bc0d5a03974ade8b5bc98f @@ -1859,7 +1859,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 b542dee9de843c19664c19df7435c6034d23d0d213804d588ec0ff599082d576 -R f29b5aa99c284afcd3f25a8fb29ee973 +P 4a9d3005769e0398183b03a3e132e3946b9d1c48073af2e0559d7beeac3245c0 +R 2f59a601b560c09f0f628a3935395fd4 U drh -Z 9cae8ff3aee64bed711ead2769a79514 +Z 144378d74bf58f80a9e1ca77433de7e1 diff --git a/manifest.uuid b/manifest.uuid index 46fc370397..0f1166a39f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a9d3005769e0398183b03a3e132e3946b9d1c48073af2e0559d7beeac3245c0 \ No newline at end of file +4558163b6a525990f0f1b6629dbb76daf49bcaf1ddbaf0c50fe05ce9ee480ff8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 03bfad3b7d..d9f11296fa 100644 --- a/src/where.c +++ b/src/where.c @@ -2298,14 +2298,16 @@ static void whereLoopOutputAdjust( /* In the absence of explicit truth probabilities, use heuristics to ** guess a reasonable truth probability. */ pLoop->nOut--; - if( pTerm->eOperator&(WO_EQ|WO_IS) ){ + if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 + && (pTerm->wtFlags & TERM_HIGHTRUTH)==0 /* tag-20200224-1 */ + ){ Expr *pRight = pTerm->pExpr->pRight; int k = 0; testcase( pTerm->pExpr->op==TK_IS ); if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ k = 10; }else{ - k = 20; /* Keep the "20" value in sync. See tag-20200222-1 */ + k = 20; } if( iReducewtFlags |= TERM_HEURTRUTH; @@ -2660,23 +2662,23 @@ static int whereLoopAddBtreeIndex( if( nOut ){ pNew->nOut = sqlite3LogEst(nOut); if( nEq==1 - && pTerm->truthProb>0 - /* TUNING: Adjust truthProb from the default heuristic only if the - ** probability is close to 1.0. The "20" constant is copied from - ** the heuristic at tag-20200222-1. Keep values in sync */ - && pNew->nOut+20 > pProbe->aiRowLogEst[0] + /* TUNING: Mark terms as "low selectivity" if they seem likely + ** to be true for half or more of the rows in the table. + ** See tag-202002240-1 */ + && pNew->nOut+10 > pProbe->aiRowLogEst[0] ){ #if WHERETRACE_ENABLED /* 0x01 */ if( sqlite3WhereTrace & 0x01 ){ - sqlite3DebugPrintf("Update truthProb from %d to %d:\n", - pTerm->truthProb, pNew->nOut - pProbe->aiRowLogEst[0]); + sqlite3DebugPrintf( + "STAT4 determines term has low selectivity:\n"); sqlite3WhereTermPrint(pTerm, 999); } #endif - pTerm->truthProb = pNew->nOut - pProbe->aiRowLogEst[0]; + pTerm->wtFlags |= TERM_HIGHTRUTH; if( pTerm->wtFlags & TERM_HEURTRUTH ){ - /* If the old heuristic truthProb was previously used, signal - ** that all loops will need to be recomputed */ + /* If the term has previously been used with an assumption of + ** higher selectivity, then set the flag to rerun the + ** loop computations. */ pBuilder->bldFlags2 |= SQLITE_BLDF2_2NDPASS; } } @@ -4894,7 +4896,8 @@ WhereInfo *sqlite3WhereBegin( if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); WHERETRACE(0xffff, - ("**** Redo all loop computations due to truthProb changes ****\n")); + ("**** Redo all loop computations due to" + " TERM_HIGHTRUTH changes ****\n")); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; pWInfo->pLoops = p->pNextLoop; diff --git a/src/whereInt.h b/src/whereInt.h index 9d4559c742..e33dde55e2 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -292,6 +292,11 @@ struct WhereTerm { #define TERM_IS 0x0800 /* Term.pExpr is an IS operator */ #define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ #define TERM_HEURTRUTH 0x2000 /* Heuristic truthProb used */ +#ifdef SQLITE_ENABLE_STAT4 +# define TERM_HIGHTRUTH 0x4000 /* Term excludes few rows */ +#else +# define TERM_HIGHTRUTH 0 /* Only used with STAT4 */ +#endif /* ** An instance of the WhereScan object is used as an iterator for locating From a8781d9d932aaadc6bbfcecd36705eb6410871a0 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 25 Feb 2020 20:05:58 +0000 Subject: [PATCH 033/102] Update the fuzzcheck test module so that it avoids inserting text values that contain embedded NULs in the XSQL table. Fix some legacy entries in the test/fuzzdata8.db that had embedded NULs. Add in new dbsqlfuzz cases that have accumulated over on the dbsqlfuzz project for a while. FossilOrigin-Name: 47d4240c4a837e829f593bb2aad7563010838f55345e7a0d8e2ea79462aeeb3c --- manifest | 15 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 61 ++++++++++++++++++++++++++++++++++++++++++---- test/fuzzdata8.db | Bin 1741824 -> 1472512 bytes 4 files changed, 64 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index bff710da8f..94c1b57a2a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sSTAT4\sdetermines\sthat\sa\sWHERE\sclause\sterm\sthat\sis\snot\sused\sby\san\sindex\nhas\svery\shigh\sprobability\sof\sbeing\strue,\sthen\sdo\snot\suse\sthat\sterm\sto\sreduce\nthe\sestimated\soutput\srow\scount. -D 2020-02-24T17:05:09.915 +C Update\sthe\sfuzzcheck\stest\smodule\sso\sthat\sit\savoids\sinserting\stext\svalues\nthat\scontain\sembedded\sNULs\sin\sthe\sXSQL\stable.\s\sFix\ssome\slegacy\sentries\sin\nthe\stest/fuzzdata8.db\sthat\shad\sembedded\sNULs.\s\sAdd\sin\snew\sdbsqlfuzz\scases\nthat\shave\saccumulated\sover\son\sthe\sdbsqlfuzz\sproject\sfor\sa\swhile. +D 2020-02-25T20:05:58.963 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1015,7 +1015,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c a9746aa49843827f960bc875cc70e04b0cfcd3e10e6676e3abc402ad190e165f +F test/fuzzcheck.c f5ed4e174953a4f33cd90891349b9c3e96439a2bfccbd016a3ef4ae97e9aa5d9 F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1023,7 +1023,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db 8bd41f8e1b9c61af011bf5cf16a85fb7f718fdd3348e476b78ba36adab872653 +F test/fuzzdata8.db 00cd360c354083d69572e82e1da9f582a2ed60760baf9c04558ebadd885d390b F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1859,8 +1859,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 c431b3fd8fd0f6a6974bba3e9366b0430ec003d570e7ce70ceefbcff5fe4b6fa 4558163b6a525990f0f1b6629dbb76daf49bcaf1ddbaf0c50fe05ce9ee480ff8 -R 2f59a601b560c09f0f628a3935395fd4 -T +closed 4558163b6a525990f0f1b6629dbb76daf49bcaf1ddbaf0c50fe05ce9ee480ff8 +P 40739c793b0e98a3bae296d3a1f74944edcdd4cc33c26b417fde4eaf6f14d062 +R 02479c6654f151ff7effcb61dc46ff16 U drh -Z 88585aca481f88c3f165f1a6e9b07ffb +Z 417d1fe691d03d97f7ec8cbb9d1cf8da diff --git a/manifest.uuid b/manifest.uuid index a0c4891c50..dd2162fada 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -40739c793b0e98a3bae296d3a1f74944edcdd4cc33c26b417fde4eaf6f14d062 \ No newline at end of file +47d4240c4a837e829f593bb2aad7563010838f55345e7a0d8e2ea79462aeeb3c \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 5add53c19d..ce65cab805 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -11,8 +11,7 @@ ************************************************************************* ** ** This is a utility program designed to aid running regressions tests on -** the SQLite library using data from an external fuzzer, such as American -** Fuzzy Lop (AFL) (http://lcamtuf.coredump.cx/afl/). +** the SQLite library using data from external fuzzers. ** ** This program reads content from an SQLite database file with the following ** schema: @@ -63,6 +62,21 @@ ** If fuzzcheck does crash, it can be run in the debugger and the content ** of the global variable g.zTextName[] will identify the specific XSQL and ** DB values that were running when the crash occurred. +** +** DBSQLFUZZ: +** +** The dbsqlfuzz fuzzer includes both a database file and SQL to run against +** that database in its input. This utility can now process dbsqlfuzz +** input files. Load such files using the "--load-dbsql FILE ..." command-line +** option. +** +** Dbsqlfuzz inputs are ordinary text. The first part of the file is text +** that describes the content of the database (using a lot of hexadecimal), +** then there is a divider line followed by the SQL to run against the +** database. Because they are ordinary text, dbsqlfuzz inputs are stored +** in the XSQL table, as if they were ordinary SQL inputs. The isDbSql() +** function can look at a text string and determine whether or not it is +** a valid dbsqlfuzz input. */ #include #include @@ -322,6 +336,39 @@ static void readfileFunc( fclose(in); } +/* +** Implementation of the "readtextfile(X)" SQL function. The text content +** of the file named X through the end of the file or to the first \000 +** character, whichever comes first, is read and returned as TEXT. NULL +** is returned if the file does not exist or is unreadable. +*/ +static void readtextfileFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zName; + FILE *in; + long nIn; + char *pBuf; + + zName = (const char*)sqlite3_value_text(argv[0]); + if( zName==0 ) return; + in = fopen(zName, "rb"); + if( in==0 ) return; + fseek(in, 0, SEEK_END); + nIn = ftell(in); + rewind(in); + pBuf = sqlite3_malloc64( nIn+1 ); + if( pBuf && 1==fread(pBuf, nIn, 1, in) ){ + pBuf[nIn] = 0; + sqlite3_result_text(context, pBuf, -1, sqlite3_free); + }else{ + sqlite3_free(pBuf); + } + fclose(in); +} + /* ** Implementation of the "writefile(X,Y)" SQL function. The argument Y ** is written into file X. The number of bytes written is returned. Or @@ -466,7 +513,7 @@ static int lengthLimit = 1000000; static int depthLimit = 500; /* Limit on the amount of heap memory that can be used */ -static sqlite3_int64 heapLimit = 1000000000; +static sqlite3_int64 heapLimit = 100000000; /* Maximum byte-code program length in SQLite */ static int vdbeOpLimit = 25000; @@ -1425,7 +1472,8 @@ int main(int argc, char **argv){ vdbeLimitFlag = 1; }else if( strcmp(z,"load-sql")==0 ){ - zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))"; + zInsSql = "INSERT INTO xsql(sqltext)" + "VALUES(CAST(readtextfile(?1) AS text))"; iFirstInsArg = i+1; openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; break; @@ -1437,7 +1485,8 @@ int main(int argc, char **argv){ break; }else if( strcmp(z,"load-dbsql")==0 ){ - zInsSql = "INSERT INTO xsql(sqltext)VALUES(CAST(readfile(?1) AS text))"; + zInsSql = "INSERT INTO xsql(sqltext)" + "VALUES(CAST(readtextfile(?1) AS text))"; iFirstInsArg = i+1; openFlags4Data = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; dbSqlOnly = 1; @@ -1623,6 +1672,8 @@ int main(int argc, char **argv){ if( zInsSql ){ sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0, readfileFunc, 0, 0); + sqlite3_create_function(db, "readtextfile", 1, SQLITE_UTF8, 0, + readtextfileFunc, 0, 0); sqlite3_create_function(db, "isdbsql", 1, SQLITE_UTF8, 0, isDbSqlFunc, 0, 0); rc = sqlite3_prepare_v2(db, zInsSql, -1, &pStmt, 0); diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 5f6d7467daddc98b3f3fe0a334ca54bd7e5f2899..e9e11d21a22bd285a9ebbe3583bb9b4dc2ad18c5 100644 GIT binary patch delta 37454 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 J_r9CN{{q#CCy@XE delta 82143 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 bfhb2_Lktk}tv)=9@gSxXh`B(LEIs{yuB<~W From df97d439301fefc2d962b5619d22f82dc436d1c6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Feb 2020 11:32:14 +0000 Subject: [PATCH 034/102] Ensure that the filename passed into the xFullPathname method of the VFS is acceptable as an argument to sqlite3_uri_parameter(). The interface spec does not guarantee this, but it has been so historically and some applications have come to depends on it. FossilOrigin-Name: bfb09371d452d5d4dacab2ec476880bc729952f44ac0e5de90ea7ba203243c8c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/attach.c | 2 +- src/main.c | 27 ++++++++++++++++----------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 94c1b57a2a..f1c21895ed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sfuzzcheck\stest\smodule\sso\sthat\sit\savoids\sinserting\stext\svalues\nthat\scontain\sembedded\sNULs\sin\sthe\sXSQL\stable.\s\sFix\ssome\slegacy\sentries\sin\nthe\stest/fuzzdata8.db\sthat\shad\sembedded\sNULs.\s\sAdd\sin\snew\sdbsqlfuzz\scases\nthat\shave\saccumulated\sover\son\sthe\sdbsqlfuzz\sproject\sfor\sa\swhile. -D 2020-02-25T20:05:58.963 +C Ensure\sthat\sthe\sfilename\spassed\sinto\sthe\sxFullPathname\smethod\sof\sthe\sVFS\sis\nacceptable\sas\san\sargument\sto\ssqlite3_uri_parameter().\s\sThe\sinterface\sspec\sdoes\nnot\sguarantee\sthis,\sbut\sit\shas\sbeen\sso\shistorically\sand\ssome\sapplications\nhave\scome\sto\sdepends\son\sit. +D 2020-02-27T11:32:14.496 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -467,7 +467,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c -F src/attach.c fee2f4279474edad2df73f38ff17d8b6b250429c6e9b59a708fb48a090f3ad32 +F src/attach.c fa5addce233a2bb2dfdefeee3b37000e154c47214d3269cab1bb331416e330db F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -495,7 +495,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32 -F src/main.c 42577fa09d195dd0f09d4a3d95158ff7f4a677dc83ccb0d6d7e73ff86c2dc6f1 +F src/main.c 3dfcf24427d623a095df7fce0d92c3ddf7cfda82298016f2b6b11c93ff94a187 F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -1859,7 +1859,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 40739c793b0e98a3bae296d3a1f74944edcdd4cc33c26b417fde4eaf6f14d062 -R 02479c6654f151ff7effcb61dc46ff16 +P 47d4240c4a837e829f593bb2aad7563010838f55345e7a0d8e2ea79462aeeb3c +R 2699148e97a51982a1cc661fb8022dcc U drh -Z 417d1fe691d03d97f7ec8cbb9d1cf8da +Z 98b0045957d1e0558a5ad636c29fbb50 diff --git a/manifest.uuid b/manifest.uuid index dd2162fada..3c8b8b29bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47d4240c4a837e829f593bb2aad7563010838f55345e7a0d8e2ea79462aeeb3c \ No newline at end of file +bfb09371d452d5d4dacab2ec476880bc729952f44ac0e5de90ea7ba203243c8c \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 21da21fe0a..e7d31e3b9e 100644 --- a/src/attach.c +++ b/src/attach.c @@ -187,7 +187,7 @@ static void attachFunc( if( rc==SQLITE_OK && pNew->zDbSName==0 ){ rc = SQLITE_NOMEM_BKPT; } - sqlite3_free( zPath ); + sqlite3_free_filename( zPath ); /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and diff --git a/src/main.c b/src/main.c index 4bfd943464..74b5326677 100644 --- a/src/main.c +++ b/src/main.c @@ -2753,9 +2753,11 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ ** ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to ** the VFS that should be used to open the database file. *pzFile is set to -** point to a buffer containing the name of the file to open. It is the -** responsibility of the caller to eventually call sqlite3_free() to release -** this buffer. +** point to a buffer containing the name of the file to open. The value +** stored in *pzFile is a database name acceptable to sqlite3_uri_parameter() +** and is in the same format as names created using sqlite3_create_filename(). +** The caller must invoke sqlite3_free_filename() (not sqlite3_free()!) on +** the value returned in *pzFile to avoid a memory leak. ** ** If an error occurs, then an SQLite error code is returned and *pzErrMsg ** may be set to point to a buffer containing an English language error @@ -2787,7 +2789,7 @@ int sqlite3ParseUri( int eState; /* Parser state when parsing URI */ int iIn; /* Input character index */ int iOut = 0; /* Output character index */ - u64 nByte = nUri+2; /* Bytes of space to allocate */ + u64 nByte = nUri+8; /* Bytes of space to allocate */ /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen ** method that there may be extra parameters following the file-name. */ @@ -2797,6 +2799,9 @@ int sqlite3ParseUri( zFile = sqlite3_malloc64(nByte); if( !zFile ) return SQLITE_NOMEM_BKPT; + memset(zFile, 0, 4); /* 4-byte of 0x00 is the start of DB name marker */ + zFile += 4; + iIn = 5; #ifdef SQLITE_ALLOW_URI_AUTHORITY if( strncmp(zUri+5, "///", 3)==0 ){ @@ -2886,8 +2891,7 @@ int sqlite3ParseUri( zFile[iOut++] = c; } if( eState==1 ) zFile[iOut++] = '\0'; - zFile[iOut++] = '\0'; - zFile[iOut++] = '\0'; + memset(zFile+iOut, 0, 4); /* end-of-options + empty journal filenames */ /* Check if there were any options specified that should be interpreted ** here. Options that are interpreted here include "vfs" and those that @@ -2967,13 +2971,14 @@ int sqlite3ParseUri( } }else{ - zFile = sqlite3_malloc64(nUri+2); + zFile = sqlite3_malloc64(nUri+8); if( !zFile ) return SQLITE_NOMEM_BKPT; + memset(zFile, 0, 4); + zFile += 4; if( nUri ){ memcpy(zFile, zUri, nUri); } - zFile[nUri] = '\0'; - zFile[nUri+1] = '\0'; + memset(zFile+nUri, 0, 4); flags &= ~SQLITE_OPEN_URI; } @@ -2984,7 +2989,7 @@ int sqlite3ParseUri( } parse_uri_out: if( rc!=SQLITE_OK ){ - sqlite3_free(zFile); + sqlite3_free_filename(zFile); zFile = 0; } *pFlags = flags; @@ -3391,7 +3396,7 @@ opendb_out: sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); } #endif - sqlite3_free(zOpen); + sqlite3_free_filename(zOpen); return rc & 0xff; } From 47a60d45187fcc3cf220c9083be5769fba9bf90a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Feb 2020 13:54:18 +0000 Subject: [PATCH 035/102] Extra zero terminators on the end of the blank filename returned by sqlite3PagerFilename() for an in-memory database. This helps the result work better with sqlite3_filename_journal() and similar functions. FossilOrigin-Name: 63e533d28e87bbb10e0c611de4b79d22aae291b163fe59d1f95dcad9ab3939e4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f1c21895ed..28c9ec3b41 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sfilename\spassed\sinto\sthe\sxFullPathname\smethod\sof\sthe\sVFS\sis\nacceptable\sas\san\sargument\sto\ssqlite3_uri_parameter().\s\sThe\sinterface\sspec\sdoes\nnot\sguarantee\sthis,\sbut\sit\shas\sbeen\sso\shistorically\sand\ssome\sapplications\nhave\scome\sto\sdepends\son\sit. -D 2020-02-27T11:32:14.496 +C Extra\szero\sterminators\son\sthe\send\sof\sthe\sblank\sfilename\sreturned\sby\nsqlite3PagerFilename()\sfor\san\sin-memory\sdatabase.\s\sThis\shelps\sthe\sresult\nwork\sbetter\swith\ssqlite3_filename_journal()\sand\ssimilar\sfunctions. +D 2020-02-27T13:54:18.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -518,7 +518,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c f1c92d05440f0f6826430b56e29addf453785f5c5651b8510d17d6310ba5df04 +F src/pager.c 5bae6544b2ee6d74ff4ffad6e52b5058d96ca4fd615f6af0041559bb29f3a837 F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3 F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 @@ -1859,7 +1859,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 47d4240c4a837e829f593bb2aad7563010838f55345e7a0d8e2ea79462aeeb3c -R 2699148e97a51982a1cc661fb8022dcc +P bfb09371d452d5d4dacab2ec476880bc729952f44ac0e5de90ea7ba203243c8c +R 5ea099496e5d0aac03718d52a5e75d65 U drh -Z 98b0045957d1e0558a5ad636c29fbb50 +Z 3b819f0341c5afa503f11379a99ca43e diff --git a/manifest.uuid b/manifest.uuid index 3c8b8b29bf..70e8738c52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfb09371d452d5d4dacab2ec476880bc729952f44ac0e5de90ea7ba203243c8c \ No newline at end of file +63e533d28e87bbb10e0c611de4b79d22aae291b163fe59d1f95dcad9ab3939e4 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 21473bf253..e7b875592f 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6959,7 +6959,7 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ ** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. */ const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ - static const char zFake[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static const char zFake[8]; /* Initialized to zero by default */ return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename; } From 67e2bb92df88c2497a5bbbe82b3e3be4fce8b6fc Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 27 Feb 2020 15:07:16 +0000 Subject: [PATCH 036/102] Optimization for "SELECT min(x) FROM tbl" where "x" is indexed and NOT NULL. This also allows similar queries on NOT NULL virtual table columns to be optimized. FossilOrigin-Name: 59726777934e201d94e99ca693f0fda4ebfb1c7883d0258ce542f63f9924c28c --- manifest | 15 +++++++------- manifest.uuid | 2 +- src/select.c | 4 +++- test/fts4min.test | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 test/fts4min.test diff --git a/manifest b/manifest index 28c9ec3b41..909d8864bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extra\szero\sterminators\son\sthe\send\sof\sthe\sblank\sfilename\sreturned\sby\nsqlite3PagerFilename()\sfor\san\sin-memory\sdatabase.\s\sThis\shelps\sthe\sresult\nwork\sbetter\swith\ssqlite3_filename_journal()\sand\ssimilar\sfunctions. -D 2020-02-27T13:54:18.189 +C Optimization\sfor\s"SELECT\smin(x)\sFROM\stbl"\swhere\s"x"\sis\sindexed\sand\sNOT\sNULL.\sThis\salso\sallows\ssimilar\squeries\son\sNOT\sNULL\svirtual\stable\scolumns\sto\sbe\soptimized. +D 2020-02-27T15:07:16.973 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -531,7 +531,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 466f57380528f1d7deeef87a3af09e0ad806fa2eef5e97384ec9376727fdd847 +F src/select.c ba2280da7ead581518870d7c4b91e4a4cca529182f4ff0a77ee7b0dd11339598 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -994,6 +994,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b F test/fts4merge5.test 69932d85cda8a1c4dcfb742865900ed8fbda51724b8cf9a45bbe226dfd06c596 +F test/fts4min.test 1c11e4bde16674a0c795953509cbc3731a7d9cbd1ddc7f35467bf39d632d749f F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309 F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7 F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a @@ -1859,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bfb09371d452d5d4dacab2ec476880bc729952f44ac0e5de90ea7ba203243c8c -R 5ea099496e5d0aac03718d52a5e75d65 -U drh -Z 3b819f0341c5afa503f11379a99ca43e +P 63e533d28e87bbb10e0c611de4b79d22aae291b163fe59d1f95dcad9ab3939e4 +R 2f24ac4a9d4b9d59e52da72bc0c93415 +U dan +Z de649ec613ed7c522a2438da247b65f6 diff --git a/manifest.uuid b/manifest.uuid index 70e8738c52..bdfbdc0d6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63e533d28e87bbb10e0c611de4b79d22aae291b163fe59d1f95dcad9ab3939e4 \ No newline at end of file +59726777934e201d94e99ca693f0fda4ebfb1c7883d0258ce542f63f9924c28c \ No newline at end of file diff --git a/src/select.c b/src/select.c index 231027b61d..a00abcc3de 100644 --- a/src/select.c +++ b/src/select.c @@ -4477,7 +4477,9 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ zFunc = pFunc->u.zToken; if( sqlite3StrICmp(zFunc, "min")==0 ){ eRet = WHERE_ORDERBY_MIN; - sortFlags = KEYINFO_ORDER_BIGNULL; + if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){ + sortFlags = KEYINFO_ORDER_BIGNULL; + } }else if( sqlite3StrICmp(zFunc, "max")==0 ){ eRet = WHERE_ORDERBY_MAX; sortFlags = KEYINFO_ORDER_DESC; diff --git a/test/fts4min.test b/test/fts4min.test new file mode 100644 index 0000000000..ca63b39617 --- /dev/null +++ b/test/fts4min.test @@ -0,0 +1,53 @@ +# 2020 February 27 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/fts3_common.tcl +set ::testprefix fts4min + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts3 { + finish_test + return +} + +#------------------------------------------------------------------ +do_execsql_test 0.0 { + CREATE TABLE t1(a NOT NULL, b); + CREATE INDEX i1 ON t1(a); +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft USING fts3(c); + INSERT INTO ft(docid, c) VALUES(22, 'hello world'); + INSERT INTO ft(docid, c) VALUES(44, 'hello world'); + INSERT INTO ft(docid, c) VALUES(11, 'hello world'); +} + +do_eqp_test 1.1.1 { + SELECT max(rowid) FROM ft +} {VIRTUAL TABLE INDEX 0:DESC} + +do_eqp_test 1.1.2 { + SELECT min(rowid) FROM ft +} {VIRTUAL TABLE INDEX 0:ASC} + +do_execsql_test 1.2.1 { + SELECT max(rowid) FROM ft +} {44} + +do_execsql_test 1.2.2 { + SELECT min(rowid) FROM ft +} {11} + +finish_test From be284e4ecee23499b30f9c1f8f44ebf872e071ea Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Feb 2020 16:21:39 +0000 Subject: [PATCH 037/102] Fix harmless compiler warnings from MSVC. FossilOrigin-Name: 951b39ca74c9bd933139e099d5555283278db475f410f202c162e5d1e6aef933 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/pager.c | 2 +- src/select.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 909d8864bf..13c5d4bdb2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimization\sfor\s"SELECT\smin(x)\sFROM\stbl"\swhere\s"x"\sis\sindexed\sand\sNOT\sNULL.\sThis\salso\sallows\ssimilar\squeries\son\sNOT\sNULL\svirtual\stable\scolumns\sto\sbe\soptimized. -D 2020-02-27T15:07:16.973 +C Fix\sharmless\scompiler\swarnings\sfrom\sMSVC. +D 2020-02-27T16:21:39.193 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -518,7 +518,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 238ad16109b4160d0fba2597ef71459995ab5e304b3d8bbe290a8d5d6d6000e0 F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 5bae6544b2ee6d74ff4ffad6e52b5058d96ca4fd615f6af0041559bb29f3a837 +F src/pager.c a71ffd145f55e28cbdc1bdabb5e6bef063da428a6c0de3c3a36e9a0c41d4c8c0 F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3 F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 @@ -531,7 +531,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c ba2280da7ead581518870d7c4b91e4a4cca529182f4ff0a77ee7b0dd11339598 +F src/select.c c94eec317c8ba929bc228392eb3cac8124f2d0fbe3fc1bddecb44dfc7057bc78 F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 63e533d28e87bbb10e0c611de4b79d22aae291b163fe59d1f95dcad9ab3939e4 -R 2f24ac4a9d4b9d59e52da72bc0c93415 -U dan -Z de649ec613ed7c522a2438da247b65f6 +P 59726777934e201d94e99ca693f0fda4ebfb1c7883d0258ce542f63f9924c28c +R 68debee95da14e84b8e5d6535b8c4b96 +U drh +Z 9f65ffd2d1e11fc5b18a162990062be6 diff --git a/manifest.uuid b/manifest.uuid index bdfbdc0d6d..fe1ed6c0df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -59726777934e201d94e99ca693f0fda4ebfb1c7883d0258ce542f63f9924c28c \ No newline at end of file +951b39ca74c9bd933139e099d5555283278db475f410f202c162e5d1e6aef933 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index e7b875592f..5d2225590e 100644 --- a/src/pager.c +++ b/src/pager.c @@ -6959,7 +6959,7 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ ** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. */ const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ - static const char zFake[8]; /* Initialized to zero by default */ + static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename; } diff --git a/src/select.c b/src/select.c index a00abcc3de..a9ec1e852b 100644 --- a/src/select.c +++ b/src/select.c @@ -4466,7 +4466,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ const char *zFunc; /* Name of aggregate function pFunc */ ExprList *pOrderBy; - u8 sortFlags; + u8 sortFlags = 0; assert( *ppMinMax==0 ); assert( pFunc->op==TK_AGG_FUNCTION ); From 9e5ecdc1727bbf5a38a4fcdcd482813ddce7334d Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 27 Feb 2020 17:16:45 +0000 Subject: [PATCH 038/102] In sqlite3changeset_apply(), ensure that DELETE and UPDATE changes are always executed on main database tables, not similarly named temp tables, as documented. INSERT statements are already being handled correctly. FossilOrigin-Name: f71a13d072398c9fc3556f42d75159cc2d0edc2c42f6c47f64503a7fbbca6e37 --- ext/session/sessionH.test | 46 ++++++++++++++++++++++++++++++++++++ ext/session/sqlite3session.c | 4 ++-- manifest | 16 ++++++------- manifest.uuid | 2 +- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/ext/session/sessionH.test b/ext/session/sessionH.test index 3f5a28dc74..8ba23119c8 100644 --- a/ext/session/sessionH.test +++ b/ext/session/sessionH.test @@ -34,5 +34,51 @@ do_test 1.0 { compare_db db db2 } {} +#------------------------------------------------------------------------ +db2 close +reset_db + +do_execsql_test 2.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO main.t1 VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9); +} + +do_test 2.1 { + sqlite3session S db main + S attach * + db eval { + BEGIN; + INSERT INTO t1 VALUES(10, 11, 12); + DELETE FROM t1 WHERE a=1; + UPDATE t1 SET b='five', c='six' WHERE a=4; + } + + set C [S changeset] + db eval ROLLBACK + S delete + set {} {} +} {} + +do_execsql_test 2.2 { + CREATE TEMP TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO temp.t1 VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9); +} + +set ::conflict [list] +proc xConflict {args} { lappend ::conflict $args ; return "" } +do_test 2.3 { + sqlite3changeset_apply db $C xConflict + set ::conflict +} {} +do_execsql_test 2.4 { + SELECT * FROM main.t1; + SELECT '****'; + SELECT * FROM temp.t1; +} { + 4 five six 7 8 9 10 11 12 + **** + 1 2 3 4 5 6 7 8 9 +} + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index a14172df3f..78cc5875cd 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -3513,7 +3513,7 @@ static int sessionDeleteRow( SessionBuffer buf = {0, 0, 0}; int nPk = 0; - sessionAppendStr(&buf, "DELETE FROM ", &rc); + sessionAppendStr(&buf, "DELETE FROM main.", &rc); sessionAppendIdent(&buf, zTab, &rc); sessionAppendStr(&buf, " WHERE ", &rc); @@ -3596,7 +3596,7 @@ static int sessionUpdateRow( SessionBuffer buf = {0, 0, 0}; /* Append "UPDATE tbl SET " */ - sessionAppendStr(&buf, "UPDATE ", &rc); + sessionAppendStr(&buf, "UPDATE main.", &rc); sessionAppendIdent(&buf, zTab, &rc); sessionAppendStr(&buf, " SET ", &rc); diff --git a/manifest b/manifest index 13c5d4bdb2..0303614297 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sfrom\sMSVC. -D 2020-02-27T16:21:39.193 +C In\ssqlite3changeset_apply(),\sensure\sthat\sDELETE\sand\sUPDATE\schanges\sare\salways\sexecuted\son\smain\sdatabase\stables,\snot\ssimilarly\snamed\stemp\stables,\sas\sdocumented.\sINSERT\sstatements\sare\salready\sbeing\shandled\scorrectly. +D 2020-02-27T17:16:45.085 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -433,7 +433,7 @@ F ext/session/sessionD.test 4f91d0ca8afc4c3969c72c9f0b5ea9527e21de29039937d0d973 F ext/session/sessionE.test b2010949c9d7415306f64e3c2072ddabc4b8250c98478d3c0c4d064bce83111d F ext/session/sessionF.test d37ed800881e742c208df443537bf29aa49fd56eac520d0f0c6df3e6320f3401 F ext/session/sessionG.test 3828b944cd1285f4379340fd36f8b64c464fc84df6ff3ccbc95578fd87140b9c -F ext/session/sessionH.test a417559f29a7e775950fc5fc82b3d01256a7cbe793ddf1180df234df823d56e2 +F ext/session/sessionH.test b17afdbd3b8f17e9bab91e235acf167cf35485db2ab2df0ea8893fbb914741a4 F ext/session/session_common.tcl 29ec9910aca1e996ca1c8531b8cecabf96eb576aa53de65a8ff03d848b9a2a8b F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3 F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec @@ -444,7 +444,7 @@ F ext/session/sessioninvert.test ae1a003a9ab1f8d64227dbb5c3a4c97e65b561b01e7b295 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d -F ext/session/sqlite3session.c a4dfb372f270df93422b0dc7666fd46849e6979b62a152f11287c21eed4ac21b +F ext/session/sqlite3session.c e25b345896fa3646ff8b6c4058b3d9e365dc7eab4afe80b110808681098551c8 F ext/session/sqlite3session.h a2db5b72b938d12c727b4b4ec632254ca493670a9c0de597af3271a7f774fc57 F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 59726777934e201d94e99ca693f0fda4ebfb1c7883d0258ce542f63f9924c28c -R 68debee95da14e84b8e5d6535b8c4b96 -U drh -Z 9f65ffd2d1e11fc5b18a162990062be6 +P 951b39ca74c9bd933139e099d5555283278db475f410f202c162e5d1e6aef933 +R dd88e341e21323079ed67f1779da566e +U dan +Z 6cd252fcc235e2de4d2d712d6e335d9c diff --git a/manifest.uuid b/manifest.uuid index fe1ed6c0df..f3ee5aa3fe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -951b39ca74c9bd933139e099d5555283278db475f410f202c162e5d1e6aef933 \ No newline at end of file +f71a13d072398c9fc3556f42d75159cc2d0edc2c42f6c47f64503a7fbbca6e37 \ No newline at end of file From 2826918d10e7c391a2ddf28bdec057e524731cb4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Feb 2020 16:04:28 +0000 Subject: [PATCH 039/102] The RTREE extension behaves has if data columns have type REAL, so we should actually declare them as REAL so that automatic indexes handle them correctly. Ticket [e63b4d1a65546532] FossilOrigin-Name: 85a9b6a92fd5805d5936f02d555af395441607b9eb5f4dae63560b5e65663b00 --- ext/rtree/rtree.c | 4 +++- ext/rtree/rtree1.test | 14 +++++++++++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 1eef1a1b53..efaef813db 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3746,8 +3746,10 @@ static int rtreeInit( }else if( pRtree->nAux>0 ){ break; }else{ + static const char *azFormat[] = {",%.*s REAL", ",%.*s INT"}; pRtree->nDim2++; - sqlite3_str_appendf(pSql, ",%.*s NUM", rtreeTokenLength(zArg), zArg); + sqlite3_str_appendf(pSql, azFormat[eCoordType], + rtreeTokenLength(zArg), zArg); } } sqlite3_str_appendf(pSql, ");"); diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 447ef5dadd..c37a2a77d5 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -716,6 +716,18 @@ do_execsql_test 18.0 { SELECT rt0.c1 > '-1' FROM rt0; } {9 1} - expand_all_sql db + +# 2020-02-28 ticket e63b4d1a65546532 +reset_db +do_execsql_test 19.0 { + CREATE VIRTUAL TABLE rt0 USING rtree(a,b,c); + INSERT INTO rt0(a,b,c) VALUES(0,0.0,0.0); + CREATE VIEW v0(x) AS SELECT DISTINCT rt0.b FROM rt0; + SELECT v0.x FROM v0, rt0; +} {0.0} +do_execsql_test 19.1 { + SELECT v0.x FROM v0, rt0 WHERE v0.x = rt0.b; +} {0.0} + finish_test diff --git a/manifest b/manifest index 0303614297..58b1cc67a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssqlite3changeset_apply(),\sensure\sthat\sDELETE\sand\sUPDATE\schanges\sare\salways\sexecuted\son\smain\sdatabase\stables,\snot\ssimilarly\snamed\stemp\stables,\sas\sdocumented.\sINSERT\sstatements\sare\salready\sbeing\shandled\scorrectly. -D 2020-02-27T17:16:45.085 +C The\sRTREE\sextension\sbehaves\shas\sif\sdata\scolumns\shave\stype\sREAL,\sso\swe\nshould\sactually\sdeclare\sthem\sas\sREAL\sso\sthat\sautomatic\sindexes\shandle\nthem\scorrectly.\s\sTicket\s[e63b4d1a65546532] +D 2020-02-28T16:04:28.158 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -384,9 +384,9 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/geopoly.c cac70b5502742bd0ba8877a1329a74e86a379c78567546a2a18cf5f9c3787f73 -F ext/rtree/rtree.c 84b939a9a558edd0461bb976b98f60012e3e574b3b17a0f44533d6f2a9aa2f2e +F ext/rtree/rtree.c 0ee39cc787b95aa03a012e09e6090b0fa452154fa812af9a379898560fd6c00f F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 -F ext/rtree/rtree1.test 4092a8bd2b5eafc4fafe4fe9024249c12b13e4bab23c2c3eaff57412fdf805fa +F ext/rtree/rtree1.test 00792b030a4e188ff1b22e8530e8aa0452bb5dd81c2b18cb004afc7dc63e040e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499 F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 951b39ca74c9bd933139e099d5555283278db475f410f202c162e5d1e6aef933 -R dd88e341e21323079ed67f1779da566e -U dan -Z 6cd252fcc235e2de4d2d712d6e335d9c +P f71a13d072398c9fc3556f42d75159cc2d0edc2c42f6c47f64503a7fbbca6e37 +R e584e926a3f43231aaab0b4293c722be +U drh +Z 64c3887bc4bd00b14ac4e9288ce5788a diff --git a/manifest.uuid b/manifest.uuid index f3ee5aa3fe..72796f77e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f71a13d072398c9fc3556f42d75159cc2d0edc2c42f6c47f64503a7fbbca6e37 \ No newline at end of file +85a9b6a92fd5805d5936f02d555af395441607b9eb5f4dae63560b5e65663b00 \ No newline at end of file From 4a3a3eb3d75af89b9da530f63ee31c3b2e56b189 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 29 Feb 2020 15:53:48 +0000 Subject: [PATCH 040/102] In the CLI, add the ".oom" command for debugging builds. FossilOrigin-Name: 9c3136a722715952d155aae55cbc6d1fb921c6940d8e7d3e32fcba000f6ac1ed --- manifest | 12 +++---- manifest.uuid | 2 +- src/shell.c.in | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 58b1cc67a2..d4d88064f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sRTREE\sextension\sbehaves\shas\sif\sdata\scolumns\shave\stype\sREAL,\sso\swe\nshould\sactually\sdeclare\sthem\sas\sREAL\sso\sthat\sautomatic\sindexes\shandle\nthem\scorrectly.\s\sTicket\s[e63b4d1a65546532] -D 2020-02-28T16:04:28.158 +C In\sthe\sCLI,\sadd\sthe\s".oom"\scommand\sfor\sdebugging\sbuilds. +D 2020-02-29T15:53:48.614 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -532,7 +532,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c c94eec317c8ba929bc228392eb3cac8124f2d0fbe3fc1bddecb44dfc7057bc78 -F src/shell.c.in c2e20c43a44fb5588a6c27ce60589538fbf4794fd7686f5b2598eca22eaae1fa +F src/shell.c.in 3897f3f7302914da1f6df3a2a09ac4aafa14a571d7d18c51500cfb2ff04f05eb F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f71a13d072398c9fc3556f42d75159cc2d0edc2c42f6c47f64503a7fbbca6e37 -R e584e926a3f43231aaab0b4293c722be +P 85a9b6a92fd5805d5936f02d555af395441607b9eb5f4dae63560b5e65663b00 +R 2cdefa0603e77b0eb4b0ccaa79df3caf U drh -Z 64c3887bc4bd00b14ac4e9288ce5788a +Z 076cff7e0a1612f30cfec18b6a7cf8ce diff --git a/manifest.uuid b/manifest.uuid index 72796f77e7..e16eea23a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85a9b6a92fd5805d5936f02d555af395441607b9eb5f4dae63560b5e65663b00 \ No newline at end of file +9c3136a722715952d155aae55cbc6d1fb921c6940d8e7d3e32fcba000f6ac1ed \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 0532f046ce..149ba7ee1d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -397,6 +397,15 @@ static sqlite3 *globalDb = 0; */ static volatile int seenInterrupt = 0; +#ifdef SQLITE_DEBUG +/* +** Out-of-memory simulator variables +*/ +static unsigned int oomCounter = 0; /* Simulate OOM when equals 1 */ +static unsigned int oomRepeat = 0; /* Number of OOMs in a row */ +static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */ +#endif /* SQLITE_DEBUG */ + /* ** This is the name of our program. It is set in main(), used ** in a number of other places, mostly for error messages. @@ -448,6 +457,49 @@ static void shell_out_of_memory(void){ exit(1); } +#ifdef SQLITE_DEBUG +/* This routine is called when a simulated OOM occurs. It is broken +** out as a separate routine to make it easy to set a breakpoint on +** the OOM +*/ +void shellOomFault(void){ + if( oomRepeat>0 ){ + oomRepeat--; + }else{ + oomCounter--; + } +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* This routine is a replacement malloc() that is used to simulate +** Out-Of-Memory (OOM) errors for testing purposes. +*/ +static void *oomMalloc(int nByte){ + if( oomCounter ){ + if( oomCounter==1 ){ + shellOomFault(); + return 0; + }else{ + oomCounter--; + } + } + return defaultMalloc(nByte); +} +#endif /* SQLITE_DEBUG */ + +#ifdef SQLITE_DEBUG +/* Register the OOM simulator. This must occur before any memory +** allocations */ +static void registerOomSimulator(void){ + sqlite3_mem_methods mem; + sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem); + defaultMalloc = mem.xMalloc; + mem.xMalloc = oomMalloc; + sqlite3_config(SQLITE_CONFIG_MALLOC, &mem); +} +#endif + /* ** Write I/O traces to the following stream. */ @@ -3558,6 +3610,9 @@ static const char *(azHelp[]) = { " Other options:", " -e Invoke system text editor", " -x Open in a spreadsheet", +#ifdef SQLITE_DEBUG + ".oom [--repeat M] [N] Simulate an OOM error on the N-th allocation", +#endif ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", " Options:", " --append Use appendvfs to append database to the end of FILE", @@ -8039,6 +8094,34 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else +#ifdef SQLITE_DEBUG + if( c=='o' && strcmp(azArg[0],"oom")==0 ){ + int i; + for(i=1; iout, "missing argument on \"%s\"\n", azArg[i]); + rc = 1; + }else{ + oomRepeat = (int)integerValue(azArg[++i]); + } + }else if( IsDigit(z[0]) ){ + oomCounter = (int)integerValue(azArg[i]); + }else{ + raw_printf(p->out, "unknown argument: \"%s\"\n", azArg[i]); + raw_printf(p->out, "Usage: .oom [--repeat N] [M]\n"); + rc = 1; + } + } + if( rc==0 ){ + raw_printf(p->out, "oomCounter = %d\n", oomCounter); + raw_printf(p->out, "oomRepeat = %d\n", oomRepeat); + } + }else +#endif /* SQLITE_DEBUG */ + if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ char *zNewFilename; /* Name of the database file to open */ int iName = 1; /* Index in azArg[] of the filename */ @@ -10122,6 +10205,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); +#ifdef SQLITE_DEBUG + registerOomSimulator(); +#endif + #if !defined(_WIN32_WCE) if( getenv("SQLITE_DEBUG_BREAK") ){ if( isatty(0) && isatty(2) ){ From 0a21ea997dfcf520be78957dedd1e905b55446b2 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 29 Feb 2020 17:19:42 +0000 Subject: [PATCH 041/102] Fix a problem with window functions occuring within sub-selects that are part of an OR term in a WHERE clause of the outer SELECT. FossilOrigin-Name: 1e174ed0d29366eb56ad1a0cc8defcb440b426bfd9525aed2f93468248606efc --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/window.c | 5 ++++ test/window1.test | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d4d88064f1..0b333c9879 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sCLI,\sadd\sthe\s".oom"\scommand\sfor\sdebugging\sbuilds. -D 2020-02-29T15:53:48.614 +C Fix\sa\sproblem\swith\swindow\sfunctions\soccuring\swithin\ssub-selects\sthat\sare\spart\sof\san\sOR\sterm\sin\sa\sWHERE\sclause\sof\sthe\souter\sSELECT. +D 2020-02-29T17:19:42.906 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -621,7 +621,7 @@ F src/where.c 3b8c9bd013eb0736e16f60bdc109e83337ef99513a3aff5f16ddac036e6c277e F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7 -F src/window.c f8ba2ee12a19b51d3ba42c16277c74185ee9215306bc0d5a03974ade8b5bc98f +F src/window.c 0b824edbab94e473d0ade203645798ce80358d0c89ff6ac0ba0f7e2768543319 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1721,7 +1721,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc -F test/window1.test cec56b9a0a2e7ca4bd63b30590c7b049dce9acfd87478e2597e13b67152bd821 +F test/window1.test 879a1928c9a6b4f7abdad1a4f31fe1e6c7fe36422935606367fecfdee8b4d5b5 F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476 F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 85a9b6a92fd5805d5936f02d555af395441607b9eb5f4dae63560b5e65663b00 -R 2cdefa0603e77b0eb4b0ccaa79df3caf -U drh -Z 076cff7e0a1612f30cfec18b6a7cf8ce +P 9c3136a722715952d155aae55cbc6d1fb921c6940d8e7d3e32fcba000f6ac1ed +R cc83f16e5c11cb113e2fc90f743db35e +U dan +Z b36633fe9a2f3c01c4c4f90b64a11678 diff --git a/manifest.uuid b/manifest.uuid index e16eea23a4..09bf3a9248 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c3136a722715952d155aae55cbc6d1fb921c6940d8e7d3e32fcba000f6ac1ed \ No newline at end of file +1e174ed0d29366eb56ad1a0cc8defcb440b426bfd9525aed2f93468248606efc \ No newline at end of file diff --git a/src/window.c b/src/window.c index a72ec0d2db..3aafea5431 100644 --- a/src/window.c +++ b/src/window.c @@ -1910,6 +1910,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){ Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; + assert( pWin->regAccum ); sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); nArg = MAX(nArg, windowArgCount(pWin)); if( pMWin->regStartRowid==0 ){ @@ -2288,6 +2289,10 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ pNew->eStart = p->eStart; pNew->eExclude = p->eExclude; pNew->regResult = p->regResult; + pNew->regAccum = p->regAccum; + pNew->iArgCol = p->iArgCol; + pNew->iEphCsr = p->iEphCsr; + pNew->bExprArgs = p->bExprArgs; pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); pNew->pOwner = pOwner; diff --git a/test/window1.test b/test/window1.test index 833e211fbd..1328c3fed9 100644 --- a/test/window1.test +++ b/test/window1.test @@ -1593,5 +1593,66 @@ do_execsql_test 48.1 { FROM (SELECT (SELECT sum(a) FROM t1 GROUP BY a) AS x FROM t1); } {2 2 2} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 49.1 { + CREATE TABLE t1 (a PRIMARY KEY); + INSERT INTO t1 VALUES(1); +} + +do_execsql_test 49.2 { + SELECT b AS c FROM ( + SELECT a AS b FROM ( + SELECT a FROM t1 WHERE a=1 OR (SELECT sum(a) OVER ()) + ) + WHERE b=1 OR b<10 + ) + WHERE c=1 OR c>=10; +} {1} + + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 50.0 { + CREATE TABLE t1 (a DOUBLE PRIMARY KEY); + INSERT INTO t1 VALUES(10.0); +} + +do_execsql_test 50.1 { + SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2)) +} {10.0} + +do_execsql_test 50.2 { + SELECT * FROM ( + SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2)) + ) + WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 ) +} {10.0} + +do_execsql_test 50.3 { + SELECT a FROM ( + SELECT * FROM ( + SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2)) + ) + WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 ) + ) + WHERE a=1 OR a=10.0 +} {10.0} + +do_execsql_test 50.4 { + SELECT a FROM ( + SELECT * FROM ( + SELECT * FROM t1 WHERE a%1 OR (SELECT sum(a) OVER (ORDER BY a%2)) + ) + WHERE a=1 OR ( (SELECT sum(a) OVER (ORDER BY a%4)) AND a<=10 ) + ) + WHERE a=1 OR ((SELECT sum(a) OVER(ORDER BY a%8)) AND 10<=a) +} {10.0} + +do_execsql_test 50.5 { +SELECT * FROM (SELECT * FROM t1 NATURAL JOIN t1 WHERE a%1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum((SELECT * FROM (SELECT * FROM (SELECT * FROM t1 NATURAL JOIN t1 WHERE a%1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum((SELECT * FROM t1 NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND a<=10)))OVER(ORDER BY a% 1 )) AND a<=10)) NATURAL JOIN t1 WHERE a=1 OR ((SELECT sum(a)OVER(ORDER BY a)) AND 10<=a)))OVER(ORDER BY a%5)) AND a<=10); +} {10.0} finish_test + + From 7f05d52c4cb84b06c90c325e34d9d1a334357554 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Mar 2020 01:16:33 +0000 Subject: [PATCH 042/102] Ensure that the NULL-scan pass counter is initialized when a ORDER BY NULLS LAST is used on the right table of a LEFT JOIN. Ticket [e12a0ae526bb51c7]. FossilOrigin-Name: 704bb9a39acbee420c1d6ac9eb1466a02dd77d3334b938bfddf235973129b5fe --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 3 +++ test/nulls1.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0b333c9879..92b6796279 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\swindow\sfunctions\soccuring\swithin\ssub-selects\sthat\sare\spart\sof\san\sOR\sterm\sin\sa\sWHERE\sclause\sof\sthe\souter\sSELECT. -D 2020-02-29T17:19:42.906 +C Ensure\sthat\sthe\sNULL-scan\spass\scounter\sis\sinitialized\swhen\sa\sORDER\sBY\sNULLS\sLAST\nis\sused\son\sthe\sright\stable\sof\sa\sLEFT\sJOIN.\s\sTicket\s[e12a0ae526bb51c7]. +D 2020-03-02T01:16:33.765 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -619,7 +619,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d F src/where.c 3b8c9bd013eb0736e16f60bdc109e83337ef99513a3aff5f16ddac036e6c277e F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c -F src/wherecode.c f5df56e395ade2240cabb2d39500c681bd29f8cc0636c3301c4996ad160df94d +F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7 F src/window.c 0b824edbab94e473d0ade203645798ce80358d0c89ff6ac0ba0f7e2768543319 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1197,7 +1197,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test fe4153fd59a3786b4b9f3663a3e65a3aa43a318c7b4d7dcb3f6c3ed5652c9095 +F test/nulls1.test 82c5bc33148405f21205865abf13c786084438d573a4ac4e87e11b6091cde526 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9c3136a722715952d155aae55cbc6d1fb921c6940d8e7d3e32fcba000f6ac1ed -R cc83f16e5c11cb113e2fc90f743db35e -U dan -Z b36633fe9a2f3c01c4c4f90b64a11678 +P 1e174ed0d29366eb56ad1a0cc8defcb440b426bfd9525aed2f93468248606efc +R cdca29a15a163fde9b50954e8e025c9b +U drh +Z ae0a3137d8c4f716cc59f194c604a9c0 diff --git a/manifest.uuid b/manifest.uuid index 09bf3a9248..6af4bb84ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e174ed0d29366eb56ad1a0cc8defcb440b426bfd9525aed2f93468248606efc \ No newline at end of file +704bb9a39acbee420c1d6ac9eb1466a02dd77d3334b938bfddf235973129b5fe \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index e2e10f7615..4e8b211700 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1711,6 +1711,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( nExtraReg = 1; bSeekPastNull = 1; pLevel->regBignull = regBignull = ++pParse->nMem; + if( pLevel->iLeftJoin ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull); + } pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); } diff --git a/test/nulls1.test b/test/nulls1.test index 9f4402f916..b794f35b06 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -297,5 +297,47 @@ do_eqp_test 9.4 { } {SEARCH TABLE v0 USING COVERING INDEX v3 (ANY(c1) AND c2=?)} +# 2020-03-01 ticket e12a0ae526bb51c7 +# NULLS LAST on a LEFT JOIN +# +reset_db +do_execsql_test 10.10 { + CREATE TABLE t1(x); + INSERT INTO t1(x) VALUES('X'); + CREATE TABLE t2(c, d); + CREATE INDEX t2dc ON t2(d, c); + SELECT c FROM t1 LEFT JOIN t2 ON d=NULL ORDER BY d, c NULLS LAST; +} {{}} +do_execsql_test 10.20 { + INSERT INTO t2(c,d) VALUES(5,'X'),(6,'Y'),(7,'Z'),(3,'A'),(4,'B'); + SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d, c NULLS LAST; +} {5} +do_execsql_test 10.30 { + UPDATE t2 SET d='X'; + UPDATE t2 SET c=NULL WHERE c=6; + SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d NULLS FIRST, c NULLS FIRST; +} {{} 3 4 5 7} +do_execsql_test 10.40 { + SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY d NULLS LAST, c NULLS LAST; +} {3 4 5 7 {}} +do_execsql_test 10.41 { + SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY c NULLS LAST; +} {3 4 5 7 {}} +do_execsql_test 10.42 { + SELECT c FROM t1 LEFT JOIN t2 ON d=x ORDER BY +d NULLS LAST, +c NULLS LAST; +} {3 4 5 7 {}} +do_execsql_test 10.50 { + INSERT INTO t1(x) VALUES(NULL),('Y'); + SELECT x, c, d, '|' FROM t1 LEFT JOIN t2 ON d=x + ORDER BY d NULLS LAST, c NULLS LAST; +} {X 3 X | X 4 X | X 5 X | X 7 X | X {} X | {} {} {} | Y {} {} |} +do_execsql_test 10.51 { + SELECT x, c, d, '|' FROM t1 LEFT JOIN t2 ON d=x + ORDER BY +d NULLS LAST, +c NULLS LAST; +} {X 3 X | X 4 X | X 5 X | X 7 X | X {} X | {} {} {} | Y {} {} |} + + + + finish_test From a2ec2e48435c3c945f8c77b50f9386161846531a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Mar 2020 01:50:48 +0000 Subject: [PATCH 043/102] Fix a faulty assert() statement in the stale-register detection logic. Ticket [da5a09be6dabbf42]. FossilOrigin-Name: 219c296cc8cab13fa12b64c297bc4a98d8e21491309d97a031edf89ae77fce75 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 92b6796279..a41b960ca5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sNULL-scan\spass\scounter\sis\sinitialized\swhen\sa\sORDER\sBY\sNULLS\sLAST\nis\sused\son\sthe\sright\stable\sof\sa\sLEFT\sJOIN.\s\sTicket\s[e12a0ae526bb51c7]. -D 2020-03-02T01:16:33.765 +C Fix\sa\sfaulty\sassert()\sstatement\sin\sthe\sstale-register\sdetection\slogic.\nTicket\s[da5a09be6dabbf42]. +D 2020-03-02T01:50:48.069 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 F src/vdbeaux.c 2d8d863e6b85a5b4362a248c04d82f0df8df79be289b2fc75b488c3cd79ddb5f F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 -F src/vdbemem.c ff2a1fd86ea943efb7174bd74bc661815c449be6165e136e8849e1dc59e24353 +F src/vdbemem.c ddca442b006db5010c1cf799c708d3ca5e7644c20ba8a32ea6757d33c4ba3da2 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1e174ed0d29366eb56ad1a0cc8defcb440b426bfd9525aed2f93468248606efc -R cdca29a15a163fde9b50954e8e025c9b +P 704bb9a39acbee420c1d6ac9eb1466a02dd77d3334b938bfddf235973129b5fe +R 37d60611a24e10e0f7c6d9ef2a03c1d5 U drh -Z ae0a3137d8c4f716cc59f194c604a9c0 +Z 35d89853f7c8d0bfbe3e5e9e3a91aee4 diff --git a/manifest.uuid b/manifest.uuid index 6af4bb84ed..32cc3b31c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -704bb9a39acbee420c1d6ac9eb1466a02dd77d3334b938bfddf235973129b5fe \ No newline at end of file +219c296cc8cab13fa12b64c297bc4a98d8e21491309d97a031edf89ae77fce75 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 27f1c7dce3..08603f8088 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -972,8 +972,8 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ /* assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); */ /* ^^ */ /* Cannot reliably compare doubles for equality */ - assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); - assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); + assert( (mFlags&(MEM_Str|MEM_Blob))==0 + || (pMem->n==pX->n && pMem->z==pX->z) ); /* pMem is the register that is changing. But also mark pX as ** undefined so that we can quickly detect the shallow-copy error */ From 39b3bcf8ef3a069a9b98bf0ea52d5ad658ef05cd Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Mar 2020 16:31:21 +0000 Subject: [PATCH 044/102] Enhance the fuzzcheck test program so that it is able to simulate OOM errors in the same way that dbsqlfuzz does. FossilOrigin-Name: a65c8d4e26b2428ecb8232a4a6a44443aa1701319223397e61a823a5aa1827de --- manifest | 12 +++++----- manifest.uuid | 2 +- test/fuzzcheck.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index a41b960ca5..6dc750a9e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sfaulty\sassert()\sstatement\sin\sthe\sstale-register\sdetection\slogic.\nTicket\s[da5a09be6dabbf42]. -D 2020-03-02T01:50:48.069 +C Enhance\sthe\sfuzzcheck\stest\sprogram\sso\sthat\sit\sis\sable\sto\ssimulate\sOOM\serrors\nin\sthe\ssame\sway\sthat\sdbsqlfuzz\sdoes. +D 2020-03-02T16:31:21.682 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1016,7 +1016,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c f5ed4e174953a4f33cd90891349b9c3e96439a2bfccbd016a3ef4ae97e9aa5d9 +F test/fuzzcheck.c cdd94f1710957b8b907019b25c6cf4f7b63815a08b19021e8b215bc2419bb7f9 F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 704bb9a39acbee420c1d6ac9eb1466a02dd77d3334b938bfddf235973129b5fe -R 37d60611a24e10e0f7c6d9ef2a03c1d5 +P 219c296cc8cab13fa12b64c297bc4a98d8e21491309d97a031edf89ae77fce75 +R 17d29216190d0b7754fc3170b52eb5e5 U drh -Z 35d89853f7c8d0bfbe3e5e9e3a91aee4 +Z 401be2bfffbe1801f75607da61f73c58 diff --git a/manifest.uuid b/manifest.uuid index 32cc3b31c0..9bce01f519 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -219c296cc8cab13fa12b64c297bc4a98d8e21491309d97a031edf89ae77fce75 \ No newline at end of file +a65c8d4e26b2428ecb8232a4a6a44443aa1701319223397e61a823a5aa1827de \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index ce65cab805..3785024368 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -520,6 +520,57 @@ static int vdbeOpLimit = 25000; /* Maximum size of the in-memory database */ static sqlite3_int64 maxDbSize = 104857600; +/* OOM simulation parameters */ +static unsigned int oomCounter = 0; /* Simulate OOM when equals 1 */ +static unsigned int oomRepeat = 0; /* Number of OOMs in a row */ +static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */ + +/* This routine is called when a simulated OOM occurs. It is broken +** out as a separate routine to make it easy to set a breakpoint on +** the OOM +*/ +void oomFault(void){ + if( eVerbosity ){ + printf("Simulated OOM fault\n"); + } + if( oomRepeat>0 ){ + oomRepeat--; + }else{ + oomCounter--; + } +} + +/* This routine is a replacement malloc() that is used to simulate +** Out-Of-Memory (OOM) errors for testing purposes. +*/ +static void *oomMalloc(int nByte){ + if( oomCounter ){ + if( oomCounter==1 ){ + oomFault(); + return 0; + }else{ + oomCounter--; + } + } + return defaultMalloc(nByte); +} + +/* Register the OOM simulator. This must occur before any memory +** allocations */ +static void registerOomSimulator(void){ + sqlite3_mem_methods mem; + sqlite3_shutdown(); + sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem); + defaultMalloc = mem.xMalloc; + mem.xMalloc = oomMalloc; + sqlite3_config(SQLITE_CONFIG_MALLOC, &mem); +} + +/* Turn off any pending OOM simulation */ +static void disableOom(void){ + oomCounter = 0; + oomRepeat = 0; +} /* ** Translate a single byte of Hex into an integer. @@ -700,6 +751,9 @@ static int block_troublesome_sql( ){ return SQLITE_DENY; } + if( sqlite3_stricmp("oom",zArg1)==0 && zArg2!=0 && zArg2[0]!=0 ){ + oomCounter = atoi(zArg2); + } }else if( (eCode==SQLITE_ATTACH || eCode==SQLITE_DETACH) && zArg1 && zArg1[0] ){ return SQLITE_DENY; @@ -1421,6 +1475,7 @@ int main(int argc, char **argv){ int openFlags4Data; /* Flags for sqlite3_open_v2() */ int nV; /* How much to increase verbosity with -vvvv */ + registerOomSimulator(); sqlite3_initialize(); iBegin = timeOfDay(); #ifdef __unix__ @@ -1792,6 +1847,7 @@ int main(int argc, char **argv){ /* Limit available memory, if requested */ sqlite3_shutdown(); + if( nMemThisDb>0 && nMem==0 ){ if( !nativeMalloc ){ pHeap = realloc(pHeap, nMemThisDb); @@ -1836,6 +1892,7 @@ int main(int argc, char **argv){ runCombinedDbSqlInput(pSql->a, pSql->sz); nTest++; g.zTestName[0] = 0; + disableOom(); continue; } for(pDb=g.pFirstDb; pDb; pDb=pDb->pNext){ From b3f0d92b918b9c79b2fbce26bf08eae10aef890f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Mar 2020 01:16:04 +0000 Subject: [PATCH 045/102] Improved detection of corruption in the interior nodes of a segment btree in FTS3/4. FossilOrigin-Name: cc99447ac923166104e8a7c75088ed95279f4491b30cfa37dc3ee5e005dd9fac --- ext/fts3/fts3.c | 6 +++++- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts3corrupt.test | 12 ++++++++++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 77738eb543..d03f3adf87 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -1884,6 +1884,7 @@ static int fts3ScanInteriorNode( i64 nAlloc = 0; /* Size of allocated buffer */ int isFirstTerm = 1; /* True when processing first term on page */ sqlite3_int64 iChild; /* Block id of child node to descend to */ + int nBuffer = 0; /* Total term size */ /* Skip over the 'height' varint that occurs at the start of every ** interior node. Then load the blockid of the left-child of the b-tree @@ -1908,12 +1909,15 @@ static int fts3ScanInteriorNode( int cmp; /* memcmp() result */ int nSuffix; /* Size of term suffix */ int nPrefix = 0; /* Size of term prefix */ - int nBuffer; /* Total term size */ /* Load the next term on the node into zBuffer. Use realloc() to expand ** the size of zBuffer if required. */ if( !isFirstTerm ){ zCsr += fts3GetVarint32(zCsr, &nPrefix); + if( nPrefix>nBuffer ){ + rc = FTS_CORRUPT_VTAB; + goto finish_scan; + } } isFirstTerm = 0; zCsr += fts3GetVarint32(zCsr, &nSuffix); diff --git a/manifest b/manifest index 6dc750a9e2..07f7cf9723 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sfuzzcheck\stest\sprogram\sso\sthat\sit\sis\sable\sto\ssimulate\sOOM\serrors\nin\sthe\ssame\sway\sthat\sdbsqlfuzz\sdoes. -D 2020-03-02T16:31:21.682 +C Improved\sdetection\sof\scorruption\sin\sthe\sinterior\snodes\sof\sa\ssegment\sbtree\nin\sFTS3/4. +D 2020-03-03T01:16:04.083 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -82,7 +82,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 52c09f459364732b5df73eff0373f991fd6af8f0f60fcdbb4b649205e88a7568 +F ext/fts3/fts3.c 2a9dd452003a143248e68449302da80dd0c43df72195b56577e3562e43c408a0 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h f091030b976045e7df91af2337935952b477cdbd9f48058c44c965684484cb50 F ext/fts3/fts3_aux.c 96708c8b3a7d9b8ca1b68ea2b7e503e283f20e95f145becadedfad096dbd0f34 @@ -942,7 +942,7 @@ F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd4 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f5a76b -F test/fts3corrupt.test ce7f7b5eaeee5f1804584d061b978d85e64abf2af9adaa7577589fac6f7eae01 +F test/fts3corrupt.test 79a32ffdcd5254e2f7fa121d9656e61949ad049c3c6554229911b7ceac37c9c6 F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f F test/fts3corrupt4.test e8ad49403179cbf714b6b669d2e0f9234ae95f4ca258a253b0f29ce28c1b027c @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 219c296cc8cab13fa12b64c297bc4a98d8e21491309d97a031edf89ae77fce75 -R 17d29216190d0b7754fc3170b52eb5e5 +P a65c8d4e26b2428ecb8232a4a6a44443aa1701319223397e61a823a5aa1827de +R 47528955cb3606b0afdcad4fc80a64ba U drh -Z 401be2bfffbe1801f75607da61f73c58 +Z 210b00ab6edc4a4aa29d4797eca25a55 diff --git a/manifest.uuid b/manifest.uuid index 9bce01f519..0386a9400f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a65c8d4e26b2428ecb8232a4a6a44443aa1701319223397e61a823a5aa1827de \ No newline at end of file +cc99447ac923166104e8a7c75088ed95279f4491b30cfa37dc3ee5e005dd9fac \ No newline at end of file diff --git a/test/fts3corrupt.test b/test/fts3corrupt.test index 4019509a0e..828964b1bc 100644 --- a/test/fts3corrupt.test +++ b/test/fts3corrupt.test @@ -181,4 +181,16 @@ do_catchsql_test 6.10 { INSERT INTO f(f) VALUES ("merge=1"); } {1 {database disk image is malformed}} +# 2020-03-02 https://bugs.chromium.org/p/chromium/issues/detail?id=1057441 +# The ticket complains of use of an uninitialized value. That part is harmless. +# The only reason to fix this is the failure to detect a subtly corrupt +# inverted index. +# +reset_db +do_catchsql_test 7.10 { + CREATE VIRTUAL TABLE f USING fts3(a,b); + INSERT INTO f_segdir VALUES (0,0,1,0,'0 0',x'01010101020101'); + SELECT matchinfo( f , 'pcx') FROM f WHERE b MATCH x'c533'; +} {1 {database disk image is malformed}} + finish_test From d346fe0ab52e8169ab8c91114617bb244ad2d457 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Mar 2020 20:04:29 +0000 Subject: [PATCH 046/102] Remove an invalid assert() on the debugging logic that checks to ensure that register values are not used after they go stale. Ticket [d165ad781b39d574]. FossilOrigin-Name: bd94d7d052734460904c687756231f8aa243a2252f07f742dd1e437aa940f536 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 7 +------ 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 07f7cf9723..0d28ba1ab3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdetection\sof\scorruption\sin\sthe\sinterior\snodes\sof\sa\ssegment\sbtree\nin\sFTS3/4. -D 2020-03-03T01:16:04.083 +C Remove\san\sinvalid\sassert()\son\sthe\sdebugging\slogic\sthat\schecks\sto\sensure\sthat\nregister\svalues\sare\snot\sused\safter\sthey\sgo\sstale.\s\sTicket\s[d165ad781b39d574]. +D 2020-03-03T20:04:29.120 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 F src/vdbeaux.c 2d8d863e6b85a5b4362a248c04d82f0df8df79be289b2fc75b488c3cd79ddb5f F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 -F src/vdbemem.c ddca442b006db5010c1cf799c708d3ca5e7644c20ba8a32ea6757d33c4ba3da2 +F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a65c8d4e26b2428ecb8232a4a6a44443aa1701319223397e61a823a5aa1827de -R 47528955cb3606b0afdcad4fc80a64ba +P cc99447ac923166104e8a7c75088ed95279f4491b30cfa37dc3ee5e005dd9fac +R 8f0f3c6d7f9f80265473494f8304b7c4 U drh -Z 210b00ab6edc4a4aa29d4797eca25a55 +Z c1b83b00436d3b4454df5dff5b6ce418 diff --git a/manifest.uuid b/manifest.uuid index 0386a9400f..c9584b6988 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc99447ac923166104e8a7c75088ed95279f4491b30cfa37dc3ee5e005dd9fac \ No newline at end of file +bd94d7d052734460904c687756231f8aa243a2252f07f742dd1e437aa940f536 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 08603f8088..16d1ac8b08 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -961,7 +961,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n", (int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem)); } - /* If pX is marked as a shallow copy of pMem, then verify that + /* If pX is marked as a shallow copy of pMem, then try to verify that ** no significant changes have been made to pX since the OP_SCopy. ** A significant change would indicated a missed call to this ** function for pX. Minor changes, such as adding or removing a @@ -969,11 +969,6 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ ** same. */ mFlags = pMem->flags & pX->flags & pX->mScopyFlags; assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i ); - /* assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); */ - /* ^^ */ - /* Cannot reliably compare doubles for equality */ - assert( (mFlags&(MEM_Str|MEM_Blob))==0 - || (pMem->n==pX->n && pMem->z==pX->z) ); /* pMem is the register that is changing. But also mark pX as ** undefined so that we can quickly detect the shallow-copy error */ From f5cfe6f2c4ccdc76963ee16ee85beab4f48782db Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Mar 2020 20:48:12 +0000 Subject: [PATCH 047/102] Fix a false-positive in the debugging logic that attempts to detect the use of uninitialized registers inside triggers. Ticket [c4c56482ced89d90] FossilOrigin-Name: 0463576b5de0a1ee71530f0e4988fc9cceda79148520bea2c67f1fbc4a99cea9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0d28ba1ab3..360f4e2816 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sinvalid\sassert()\son\sthe\sdebugging\slogic\sthat\schecks\sto\sensure\sthat\nregister\svalues\sare\snot\sused\safter\sthey\sgo\sstale.\s\sTicket\s[d165ad781b39d574]. -D 2020-03-03T20:04:29.120 +C Fix\sa\sfalse-positive\sin\sthe\sdebugging\slogic\sthat\sattempts\sto\sdetect\sthe\nuse\sof\suninitialized\sregisters\sinside\striggers.\nTicket\s[c4c56482ced89d90] +D 2020-03-03T20:48:12.641 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -603,7 +603,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7 F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9 -F src/vdbe.c 15cae95de3c1301747f7ee17a70046772741e7e630b6d5554c685b613798b8e8 +F src/vdbe.c 8ad7906cf9aca841b97064fbf62323f53aaf8e4f8251ffa5e152abc5bda806d3 F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9 F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cc99447ac923166104e8a7c75088ed95279f4491b30cfa37dc3ee5e005dd9fac -R 8f0f3c6d7f9f80265473494f8304b7c4 +P bd94d7d052734460904c687756231f8aa243a2252f07f742dd1e437aa940f536 +R 0f71af2e8e80ccdf0b7d36f886e9acf8 U drh -Z c1b83b00436d3b4454df5dff5b6ce418 +Z ceca558695865cc74aa546ee62ecf8a0 diff --git a/manifest.uuid b/manifest.uuid index c9584b6988..ae13b64c30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd94d7d052734460904c687756231f8aa243a2252f07f742dd1e437aa940f536 \ No newline at end of file +0463576b5de0a1ee71530f0e4988fc9cceda79148520bea2c67f1fbc4a99cea9 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e3a920ffcc..8501e7319e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6476,7 +6476,7 @@ case OP_Program: { /* jump */ int i; for(i=0; inMem; i++){ aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */ - aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */ + MemSetTypeFlag(&aMem[i], MEM_Undefined); /* Fault if this reg is reused */ } } #endif From 4cf2121e1c0adfcae41d89426e1e5e81ca4721a9 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Mar 2020 14:19:49 +0000 Subject: [PATCH 048/102] When printing the OP_CollSeq opcode for EXPLAIN listings, include the text encoding with the name of the collating sequence. FossilOrigin-Name: eb5c1b77d1c55fc286ff8fccfd61e21cb67aec92d6f93b093b9af5c32165d82b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 360f4e2816..e23f4a8c00 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sfalse-positive\sin\sthe\sdebugging\slogic\sthat\sattempts\sto\sdetect\sthe\nuse\sof\suninitialized\sregisters\sinside\striggers.\nTicket\s[c4c56482ced89d90] -D 2020-03-03T20:48:12.641 +C When\sprinting\sthe\sOP_CollSeq\sopcode\sfor\sEXPLAIN\slistings,\sinclude\sthe\ntext\sencoding\swith\sthe\sname\sof\sthe\scollating\ssequence. +D 2020-03-05T14:19:49.156 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/vdbe.c 8ad7906cf9aca841b97064fbf62323f53aaf8e4f8251ffa5e152abc5bda806d3 F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9 F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051 F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02 -F src/vdbeaux.c 2d8d863e6b85a5b4362a248c04d82f0df8df79be289b2fc75b488c3cd79ddb5f +F src/vdbeaux.c 1ca2d4b3f913ecc4759becfab72952f25493390d674714586ab356c9f06ac279 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22 F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bd94d7d052734460904c687756231f8aa243a2252f07f742dd1e437aa940f536 -R 0f71af2e8e80ccdf0b7d36f886e9acf8 +P 0463576b5de0a1ee71530f0e4988fc9cceda79148520bea2c67f1fbc4a99cea9 +R f92a8c47174bbadb30078c19e201b0fd U drh -Z ceca558695865cc74aa546ee62ecf8a0 +Z 012a8ab6e668de71f86a41d053b68dc7 diff --git a/manifest.uuid b/manifest.uuid index ae13b64c30..c820e93f76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0463576b5de0a1ee71530f0e4988fc9cceda79148520bea2c67f1fbc4a99cea9 \ No newline at end of file +eb5c1b77d1c55fc286ff8fccfd61e21cb67aec92d6f93b093b9af5c32165d82b \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 249ac888c0..4ef1c72fe1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1658,8 +1658,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } #endif case P4_COLLSEQ: { + static const char *const encnames[] = {"?", "8", "16LE", "16BE"}; CollSeq *pColl = pOp->p4.pColl; - sqlite3_str_appendf(&x, "(%.20s)", pColl->zName); + assert( pColl->enc>=0 && pColl->enc<4 ); + sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName, + encnames[pColl->enc]); break; } case P4_FUNCDEF: { From 42a630b1daf1df13850095251cc73be84dbdeac8 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 5 Mar 2020 16:13:24 +0000 Subject: [PATCH 049/102] Change the sqlite3.pDfltColl (the default collating sequence for the database connection) so that it is the collating sequence appropriate for the database encoding, not the UTF8 collating sequence. This helps to ensure that the database encoding collation is always used, even for expressions that do not have an defined collating sequence. Ticket [1b8d7264567eb6fc]. FossilOrigin-Name: 4a5851893c3d71cc823b6ab5df5e58a852cd322fff26290f1ea05b63d67f564a --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/callback.c | 19 ++++++++++++++++--- src/main.c | 9 +++------ src/pragma.c | 5 +++-- src/prepare.c | 6 +++--- src/sqliteInt.h | 3 ++- 7 files changed, 38 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index e23f4a8c00..a4b7c2fd0a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sprinting\sthe\sOP_CollSeq\sopcode\sfor\sEXPLAIN\slistings,\sinclude\sthe\ntext\sencoding\swith\sthe\sname\sof\sthe\scollating\ssequence. -D 2020-03-05T14:19:49.156 +C Change\sthe\ssqlite3.pDfltColl\s(the\sdefault\scollating\ssequence\sfor\sthe\ndatabase\sconnection)\sso\sthat\sit\sis\sthe\scollating\ssequence\sappropriate\sfor\nthe\sdatabase\sencoding,\snot\sthe\sUTF8\scollating\ssequence.\s\sThis\shelps\sto\nensure\sthat\sthe\sdatabase\sencoding\scollation\sis\salways\sused,\seven\sfor\nexpressions\sthat\sdo\snot\shave\san\sdefined\scollating\ssequence.\nTicket\s[1b8d7264567eb6fc]. +D 2020-03-05T16:13:24.200 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,7 +476,7 @@ F src/btree.c 4dfab5862184da86103795ee2a31a22d2bbf9d8cf183bd3e05f3e32267c0855f F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471 F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175 F src/build.c 2394d2c853088106dfc1cf485d609f20e6421d7c84892b795824e454f78e50ad -F src/callback.c c547d00963ae28100117b4fb1f0f32242109b5804374ee3bfe01138a54da7f76 +F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 6a77ec9e0eb87aea929e002c816298907e337094a7b556898ae2d1e6be209f90 F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712 @@ -495,7 +495,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32 -F src/main.c 3dfcf24427d623a095df7fce0d92c3ddf7cfda82298016f2b6b11c93ff94a187 +F src/main.c b11eec03807a038b4075d310936dc33ce597078ab78c35dacdf5f05446ed53de F src/malloc.c eaa4dc9602ce28b077f7de2eb275db2be270c5cc56d7fec5466301bd9b80e2f5 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -524,9 +524,9 @@ F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c 4c8f3665cb3e1b114d22319f944a0c73c9563869c1f01a322732a880a7a2f82a +F src/pragma.c 26a2d92028e69abbae7e58e5c40d360337de63bf7a4043299139298d50f4d9ab F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5 -F src/prepare.c 6049beb71385f017af6fc320d2c75a4e50b75e280c54232442b785fbb83df057 +F src/prepare.c d9b7b36b7ac5c07ba00fd3964ac6cff59b93a0b2c7d17ec27bb80c59975c1c64 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf @@ -536,7 +536,7 @@ F src/shell.c.in 3897f3f7302914da1f6df3a2a09ac4aafa14a571d7d18c51500cfb2ff04f05e F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee -F src/sqliteInt.h d736043dc6291d3af289d911237da0801b6c05be086ae322eedd47a089ae8d2f +F src/sqliteInt.h a02a77e59056fbe1cf8705e1149d817b54797bb41cacb114562bcc9ef431c735 F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0463576b5de0a1ee71530f0e4988fc9cceda79148520bea2c67f1fbc4a99cea9 -R f92a8c47174bbadb30078c19e201b0fd +P eb5c1b77d1c55fc286ff8fccfd61e21cb67aec92d6f93b093b9af5c32165d82b +R 59b3562f907df451b0aff10dac9e4108 U drh -Z 012a8ab6e668de71f86a41d053b68dc7 +Z 48636fd7ed659b86f47f5ef00fcfb4ed diff --git a/manifest.uuid b/manifest.uuid index c820e93f76..75cb23563e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb5c1b77d1c55fc286ff8fccfd61e21cb67aec92d6f93b093b9af5c32165d82b \ No newline at end of file +4a5851893c3d71cc823b6ab5df5e58a852cd322fff26290f1ea05b63d67f564a \ No newline at end of file diff --git a/src/callback.c b/src/callback.c index 3d991901d1..421cef2814 100644 --- a/src/callback.c +++ b/src/callback.c @@ -163,17 +163,30 @@ CollSeq *sqlite3FindCollSeq( int create /* True to create CollSeq if doesn't already exist */ ){ CollSeq *pColl; + assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); + assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); if( zName ){ pColl = findCollSeqEntry(db, zName, create); + if( pColl ) pColl += enc-1; }else{ pColl = db->pDfltColl; } - assert( SQLITE_UTF8==1 && SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); - assert( enc>=SQLITE_UTF8 && enc<=SQLITE_UTF16BE ); - if( pColl ) pColl += enc-1; return pColl; } +/* +** Change the text encoding for a database connection. This means that +** the pDfltColl must change as well. +*/ +void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){ + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + db->enc = enc; + /* EVIDENCE-OF: R-08308-17224 The default collating function for all + ** strings is BINARY. + */ + db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0); +} + /* ** This function is responsible for invoking the collation factory callback ** or substituting a collation sequence of a different encoding when the diff --git a/src/main.c b/src/main.c index 74b5326677..98e030fad1 100644 --- a/src/main.c +++ b/src/main.c @@ -3199,11 +3199,6 @@ static int openDatabase( if( db->mallocFailed ){ goto opendb_out; } - /* EVIDENCE-OF: R-08308-17224 The default collating function for all - ** strings is BINARY. - */ - db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0); - assert( db->pDfltColl!=0 ); /* Parse the filename/URI argument ** @@ -3248,7 +3243,9 @@ static int openDatabase( } sqlite3BtreeEnter(db->aDb[0].pBt); db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); - if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db); + if( !db->mallocFailed ){ + sqlite3SetTextEncoding(db, SCHEMA_ENC(db)); + } sqlite3BtreeLeave(db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); diff --git a/src/pragma.c b/src/pragma.c index 60e18e7f04..504f51ec0f 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1837,8 +1837,9 @@ void sqlite3Pragma( if( canChangeEnc ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ - SCHEMA_ENC(db) = ENC(db) = - pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; + u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; + SCHEMA_ENC(db) = enc; + sqlite3SetTextEncoding(db, enc); break; } } diff --git a/src/prepare.c b/src/prepare.c index 2d928f16e7..67995f33ce 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -267,15 +267,15 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ */ if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ if( iDb==0 ){ -#ifndef SQLITE_OMIT_UTF16 u8 encoding; +#ifndef SQLITE_OMIT_UTF16 /* If opening the main database, set ENC(db). */ encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3; if( encoding==0 ) encoding = SQLITE_UTF8; - ENC(db) = encoding; #else - ENC(db) = SQLITE_UTF8; + encoding = SQLITE_UTF8; #endif + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 517bb40b88..814a7d8061 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1422,7 +1422,7 @@ void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); struct sqlite3 { sqlite3_vfs *pVfs; /* OS Interface */ struct Vdbe *pVdbe; /* List of active virtual machines */ - CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ + CollSeq *pDfltColl; /* BINARY collseq for the database encoding */ sqlite3_mutex *mutex; /* Connection mutex */ Db *aDb; /* All backends */ int nDb; /* Number of backends currently in use */ @@ -4465,6 +4465,7 @@ int sqlite3ReadSchema(Parse *pParse); CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); int sqlite3IsBinary(const CollSeq*); CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); +void sqlite3SetTextEncoding(sqlite3 *db, u8); CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr); int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*); From 0ea2d42ac3e76c7e2b2fd8d5fdf53f76f09429f3 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 5 Mar 2020 18:04:09 +0000 Subject: [PATCH 050/102] Report an error if the main, or any other, database encoding is modified by an external process (perhaps using the backup API) after the db has been opened. FossilOrigin-Name: 895bd20b29e223496e1585483c6ce3335ae9050f2e5de4d6b69d0e40df396862 --- manifest | 20 ++++++------- manifest.uuid | 2 +- src/pragma.c | 12 +------- src/prepare.c | 13 ++++---- src/sqliteInt.h | 2 +- test/enc.test | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 99 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index a4b7c2fd0a..2f7d0852ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\ssqlite3.pDfltColl\s(the\sdefault\scollating\ssequence\sfor\sthe\ndatabase\sconnection)\sso\sthat\sit\sis\sthe\scollating\ssequence\sappropriate\sfor\nthe\sdatabase\sencoding,\snot\sthe\sUTF8\scollating\ssequence.\s\sThis\shelps\sto\nensure\sthat\sthe\sdatabase\sencoding\scollation\sis\salways\sused,\seven\sfor\nexpressions\sthat\sdo\snot\shave\san\sdefined\scollating\ssequence.\nTicket\s[1b8d7264567eb6fc]. -D 2020-03-05T16:13:24.200 +C Report\san\serror\sif\sthe\smain,\sor\sany\sother,\sdatabase\sencoding\sis\smodified\sby\san\sexternal\sprocess\s(perhaps\susing\sthe\sbackup\sAPI)\safter\sthe\sdb\shas\sbeen\sopened. +D 2020-03-05T18:04:09.456 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,9 +524,9 @@ F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c 26a2d92028e69abbae7e58e5c40d360337de63bf7a4043299139298d50f4d9ab +F src/pragma.c 5fd004b89c77319008ddff6d65dcc83ccca9584d3048f4f66b108b5906a20dba F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5 -F src/prepare.c d9b7b36b7ac5c07ba00fd3964ac6cff59b93a0b2c7d17ec27bb80c59975c1c64 +F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28 F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf @@ -536,7 +536,7 @@ F src/shell.c.in 3897f3f7302914da1f6df3a2a09ac4aafa14a571d7d18c51500cfb2ff04f05e F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee -F src/sqliteInt.h a02a77e59056fbe1cf8705e1149d817b54797bb41cacb114562bcc9ef431c735 +F src/sqliteInt.h 37511a5bd13dab6c61242b8d6525c7efdea7a90a7fd00e5ca8e809fa292efe7c F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032 F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -849,7 +849,7 @@ F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66 F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62 -F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea +F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P eb5c1b77d1c55fc286ff8fccfd61e21cb67aec92d6f93b093b9af5c32165d82b -R 59b3562f907df451b0aff10dac9e4108 -U drh -Z 48636fd7ed659b86f47f5ef00fcfb4ed +P 4a5851893c3d71cc823b6ab5df5e58a852cd322fff26290f1ea05b63d67f564a +R 74e2a598b7c2d32d296c9fb5e4ea1cd7 +U dan +Z 79597c4800c4e22dc765415fcd19e860 diff --git a/manifest.uuid b/manifest.uuid index 75cb23563e..e558f20ced 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a5851893c3d71cc823b6ab5df5e58a852cd322fff26290f1ea05b63d67f564a \ No newline at end of file +895bd20b29e223496e1585483c6ce3335ae9050f2e5de4d6b69d0e40df396862 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 504f51ec0f..c5b5bb6670 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1824,17 +1824,7 @@ void sqlite3Pragma( ** will be overwritten when the schema is next loaded. If it does not ** already exists, it will be created to use the new encoding value. */ - int canChangeEnc = 1; /* True if allowed to change the encoding */ - int i; /* For looping over all attached databases */ - for(i=0; inDb; i++){ - if( db->aDb[i].pBt!=0 - && DbHasProperty(db,i,DB_SchemaLoaded) - && !DbHasProperty(db,i,DB_Empty) - ){ - canChangeEnc = 0; - } - } - if( canChangeEnc ){ + if( (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ u8 enc = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; diff --git a/src/prepare.c b/src/prepare.c index 67995f33ce..228d14876e 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -91,7 +91,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ assert( argc==5 ); UNUSED_PARAMETER2(NotUsed, argc); assert( sqlite3_mutex_held(db->mutex) ); - DbClearProperty(db, iDb, DB_Empty); + db->mDbFlags |= DBFLAG_EncodingFixed; pData->nInitRow++; if( db->mallocFailed ){ corruptSchema(pData, argv[1], 0); @@ -179,6 +179,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ InitData initData; const char *zMasterName; int openedTransaction = 0; + int mask = ((db->mDbFlags & DBFLAG_EncodingFixed) | ~DBFLAG_EncodingFixed); assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDbnDb ); @@ -207,6 +208,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ initData.mInitFlags = mFlags; initData.nInitRow = 0; sqlite3InitCallback(&initData, 5, (char **)azArg, 0); + db->mDbFlags &= mask; if( initData.rc ){ rc = initData.rc; goto error_out; @@ -266,7 +268,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ ** as sqlite3.enc. */ if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */ - if( iDb==0 ){ + if( iDb==0 && (db->mDbFlags & DBFLAG_EncodingFixed)==0 ){ u8 encoding; #ifndef SQLITE_OMIT_UTF16 /* If opening the main database, set ENC(db). */ @@ -278,15 +280,13 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ - if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){ + if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ sqlite3SetString(pzErrMsg, db, "attached databases must use the same" " text encoding as main database"); rc = SQLITE_ERROR; goto initone_error_out; } } - }else{ - DbSetProperty(db, iDb, DB_Empty); } pDb->pSchema->enc = ENC(db); @@ -398,8 +398,7 @@ error_out: ** error occurs, write an error message into *pzErrMsg. ** ** After a database is initialized, the DB_SchemaLoaded bit is set -** bit is set in the flags field of the Db structure. If the database -** file was of zero-length, then the DB_Empty flag is also set. +** bit is set in the flags field of the Db structure. */ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int i, rc; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 814a7d8061..c338dabca1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1264,7 +1264,6 @@ struct Schema { */ #define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ #define DB_UnresetViews 0x0002 /* Some views have defined column names */ -#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ #define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */ /* @@ -1631,6 +1630,7 @@ struct sqlite3 { #define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */ #define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */ #define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */ +#define DBFLAG_EncodingFixed 0x0040 /* No longer possible to change enc. */ /* ** Bits of the sqlite3.dbOptFlags field that are used by the diff --git a/test/enc.test b/test/enc.test index 5c24bbb7f6..ffe24164bd 100644 --- a/test/enc.test +++ b/test/enc.test @@ -169,4 +169,84 @@ do_test enc-11.2 { } } {2} +#------------------------------------------------------------------------- +reset_db +forcedelete test.db2 +forcedelete test.db3 + +do_execsql_test enc-12.0 { + PRAGMA encoding = 'utf-8'; + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES('a', 'b', 'c'); + ATTACH 'test.db3' AS aux; + CREATE TABLE aux.t3(x, y, z); + INSERT INTO t3 VALUES('xxx', 'yyy', 'zzz'); + PRAGMA encoding; +} {UTF-8} + +do_test enc-12.1 { + sqlite3 db2 test.db2 + db2 eval { + PRAGMA encoding = 'UTF-16le'; + CREATE TABLE t2(d, e, f); + INSERT INTO t2 VALUES('d', 'e', 'f'); + PRAGMA encoding; + } +} {UTF-16le} + +do_test enc-12.2 { + db2 backup test.db + db2 close +} {} + +do_catchsql_test enc-12.3 { + SELECT * FROM t2; +} {1 {attached databases must use the same text encoding as main database}} + +db close +sqlite3 db test.db3 +do_execsql_test enc-12.4 { + SELECT * FROM t3; + PRAGMA encoding = 'UTF-16le'; + SELECT * FROM t3; +} {xxx yyy zzz xxx yyy zzz} + +db close +sqlite3 db test.db3 +breakpoint +do_execsql_test enc-12.5 { + PRAGMA encoding = 'UTF-16le'; + PRAGMA encoding; +} {UTF-8} + +reset_db +do_execsql_test enc-12.6 { + PRAGMA encoding = 'UTF-8'; + CREATE TEMP TABLE t1(a, b, c); + INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz'); +} +do_test enc-12.7 { + sqlite3 db2 test.db2 + db2 backup test.db + db2 close + db eval { + SELECT * FROM t1; + } +} {xxx yyy zzz} +do_catchsql_test enc-12.8 { + SELECT * FROM t2; + SELECT * FROM t1; +} {1 {attached databases must use the same text encoding as main database}} + +db close +sqlite3 db test.db +do_execsql_test enc-12.9 { + CREATE TEMP TABLE t1(a, b, c); + INSERT INTO t1 VALUES('xxx', 'yyy', 'zzz'); +} +do_execsql_test enc-12.10 { + SELECT * FROM t2; + SELECT * FROM t1; +} {d e f xxx yyy zzz} + finish_test From db9cb17dc7db1b51b4f1c80b25bcd1083a5caf08 Mon Sep 17 00:00:00 2001 From: pdr Date: Sun, 8 Mar 2020 13:33:58 +0000 Subject: [PATCH 051/102] Avoid a redundant NULL check FossilOrigin-Name: 25dc53f6608dd9b8b4e8d8ee22e194a6d41d15811781752797cb42fc22ee1317 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2f7d0852ef..68b45bfae9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Report\san\serror\sif\sthe\smain,\sor\sany\sother,\sdatabase\sencoding\sis\smodified\sby\san\sexternal\sprocess\s(perhaps\susing\sthe\sbackup\sAPI)\safter\sthe\sdb\shas\sbeen\sopened. -D 2020-03-05T18:04:09.456 +C Avoid\sa\sredundant\sNULL\scheck +D 2020-03-08T13:33:58.464 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -472,7 +472,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 4dfab5862184da86103795ee2a31a22d2bbf9d8cf183bd3e05f3e32267c0855f +F src/btree.c 7271a120a66dfd12edcee942443fcd7b3860514a5621cb26a374781af1462117 F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471 F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175 F src/build.c 2394d2c853088106dfc1cf485d609f20e6421d7c84892b795824e454f78e50ad @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4a5851893c3d71cc823b6ab5df5e58a852cd322fff26290f1ea05b63d67f564a -R 74e2a598b7c2d32d296c9fb5e4ea1cd7 -U dan -Z 79597c4800c4e22dc765415fcd19e860 +P 895bd20b29e223496e1585483c6ce3335ae9050f2e5de4d6b69d0e40df396862 +R 9b9e9f3f550db78646d6369868fb6688 +U pdr +Z b6c0130d3b40d3b8d77c93bf8f1759d5 diff --git a/manifest.uuid b/manifest.uuid index e558f20ced..0eae4efa8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -895bd20b29e223496e1585483c6ce3335ae9050f2e5de4d6b69d0e40df396862 \ No newline at end of file +25dc53f6608dd9b8b4e8d8ee22e194a6d41d15811781752797cb42fc22ee1317 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 713358e1aa..0839683919 100644 --- a/src/btree.c +++ b/src/btree.c @@ -611,7 +611,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ */ static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ Bitvec *p = pBt->pHasContent; - return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno))); + return p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTestNotNull(p, pgno)); } /* From ed5e66881e0b29668a160195c8ddd98b9df56e23 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Mar 2020 01:02:45 +0000 Subject: [PATCH 052/102] Fix typos in the Lemon documentation. FossilOrigin-Name: 35f1f151ac478d6b46f3685d2565c35108ef74bd33ce96fb65300d3c303b289b --- doc/lemon.html | 12 ++++++------ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/lemon.html b/doc/lemon.html index 056ae5f5b2..17988deef4 100644 --- a/doc/lemon.html +++ b/doc/lemon.html @@ -123,7 +123,7 @@ Suppress generation of the report file.

  • -r Do not sort or renumber the parser states as part of optimization.
  • -s -Show parser statistics before existing. +Show parser statistics before exiting.
  • -Tfile Use file as the template for the generated C-code parser implementation.
  • -x @@ -488,7 +488,7 @@ is an error.

    The precedence of a grammar rule is equal to the precedence of the left-most terminal symbol in the rule for which a precedence is defined. This is normally what you want, but in those cases where -you want to precedence of a grammar rule to be something different, +you want the precedence of a grammar rule to be something different, you can specify an alternative precedence symbol by putting the symbol in square braces after the period at the end of the rule and before any C-code. For example:

    @@ -689,7 +689,7 @@ on Parse().

    The %extra_context directive

    -The %extra_context directive instructs Lemon to add a 2th parameter +The %extra_context directive instructs Lemon to add a 2nd parameter to the parameter list of the ParseAlloc() and ParseInif() functions. Lemon doesn't do anything itself with these extra argument, but it does store the value make it available to C-code action routines, destructors, @@ -699,9 +699,9 @@ and so forth. For example, if the grammar file contains:

    %extra_context { MyStruct *pAbc }

    -

    Then the ParseAlloc() and ParseInit() functions will have an 2th parameter +

    Then the ParseAlloc() and ParseInit() functions will have an 2nd parameter of type "MyStruct*" and all action routines will have access to -a variable named "pAbc" that is the value of that 2th parameter.

    +a variable named "pAbc" that is the value of that 2nd parameter.

    The %extra_argument directive works the same except that it is passed in on the Parse() routine instead of on ParseAlloc()/ParseInit(). @@ -996,7 +996,7 @@ on the parser's stack associated with terminal and non-terminal symbols. The values of all terminal symbols must be of the same type. This turns out to be the same data type as the 3rd parameter to the Parse() function generated by Lemon. Typically, you will -make the value of a terminal symbol by a pointer to some kind of +make the value of a terminal symbol be a pointer to some kind of token structure. Like this:

    diff --git a/manifest b/manifest
    index 68b45bfae9..e44373be5b 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Avoid\sa\sredundant\sNULL\scheck
    -D 2020-03-08T13:33:58.464
    +C Fix\stypos\sin\sthe\sLemon\sdocumentation.
    +D 2020-03-09T01:02:45.546
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -38,7 +38,7 @@ F configure 4bbb5f13998f2faf929b9ae708aea9fbcb08a46cb6dd3150e36c3f09c0a05a75 x
     F configure.ac 798a24cee2879325ca5b688a618199eb32cc77ed8136edbaa43d9137b470d54e
     F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
     F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
    -F doc/lemon.html 24956ab2995e55fe171e55bdd04f22b553957dc8bb43501dbb9311e30187e0d3
    +F doc/lemon.html 857495c0ce060a4e2f2ad7111135ad7e28041a32c10612279ab398eddf678f58
     F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
     F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
     F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 895bd20b29e223496e1585483c6ce3335ae9050f2e5de4d6b69d0e40df396862
    -R 9b9e9f3f550db78646d6369868fb6688
    -U pdr
    -Z b6c0130d3b40d3b8d77c93bf8f1759d5
    +P 25dc53f6608dd9b8b4e8d8ee22e194a6d41d15811781752797cb42fc22ee1317
    +R 7bdd85c5e549845146cab9e816d7c278
    +U drh
    +Z 07ddcdd1ff64cc99853935a2ba202c77
    diff --git a/manifest.uuid b/manifest.uuid
    index 0eae4efa8f..ab8bd9954b 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -25dc53f6608dd9b8b4e8d8ee22e194a6d41d15811781752797cb42fc22ee1317
    \ No newline at end of file
    +35f1f151ac478d6b46f3685d2565c35108ef74bd33ce96fb65300d3c303b289b
    \ No newline at end of file
    
    From 45dc9ca46bd0604e0199a4956f17eef82ec4e3cd Mon Sep 17 00:00:00 2001
    From: pdr 
    Date: Mon, 9 Mar 2020 03:21:33 +0000
    Subject: [PATCH 053/102] Fix typos in RowSet.
    
    FossilOrigin-Name: 86465c08f4d629a296332a7985937326ac43ea2822c5651bf03862cd79d370fc
    ---
     manifest      | 14 +++++++-------
     manifest.uuid |  2 +-
     src/rowset.c  |  4 ++--
     3 files changed, 10 insertions(+), 10 deletions(-)
    
    diff --git a/manifest b/manifest
    index e44373be5b..6c007c55b5 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Fix\stypos\sin\sthe\sLemon\sdocumentation.
    -D 2020-03-09T01:02:45.546
    +C Fix\stypos\sin\sRowSet.
    +D 2020-03-09T03:21:33.427
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -530,7 +530,7 @@ F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28
     F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
     F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
     F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf
    -F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
    +F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
     F src/select.c c94eec317c8ba929bc228392eb3cac8124f2d0fbe3fc1bddecb44dfc7057bc78
     F src/shell.c.in 3897f3f7302914da1f6df3a2a09ac4aafa14a571d7d18c51500cfb2ff04f05eb
     F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 25dc53f6608dd9b8b4e8d8ee22e194a6d41d15811781752797cb42fc22ee1317
    -R 7bdd85c5e549845146cab9e816d7c278
    -U drh
    -Z 07ddcdd1ff64cc99853935a2ba202c77
    +P 35f1f151ac478d6b46f3685d2565c35108ef74bd33ce96fb65300d3c303b289b
    +R 3ad66a51f32de0dab569042c4aa4c3c6
    +U pdr
    +Z ab82beefd8209a83b9f274edf5605106
    diff --git a/manifest.uuid b/manifest.uuid
    index ab8bd9954b..7deff47aa2 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -35f1f151ac478d6b46f3685d2565c35108ef74bd33ce96fb65300d3c303b289b
    \ No newline at end of file
    +86465c08f4d629a296332a7985937326ac43ea2822c5651bf03862cd79d370fc
    \ No newline at end of file
    diff --git a/src/rowset.c b/src/rowset.c
    index 703cf499bc..0562320ab4 100644
    --- a/src/rowset.c
    +++ b/src/rowset.c
    @@ -177,7 +177,7 @@ void sqlite3RowSetDelete(void *pArg){
     /*
     ** Allocate a new RowSetEntry object that is associated with the
     ** given RowSet.  Return a pointer to the new and completely uninitialized
    -** objected.
    +** object.
     **
     ** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
     ** routine returns NULL.
    @@ -453,7 +453,7 @@ int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
         if( p ){
           struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
           if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
    -        /* Only sort the current set of entiries if they need it */
    +        /* Only sort the current set of entries if they need it */
             p = rowSetEntrySort(p);
           }
           for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
    
    From ccb37816731acf41cb60648c0eb73ced069a8915 Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Mon, 9 Mar 2020 15:39:39 +0000
    Subject: [PATCH 054/102] Enhancements to the ".import" command of the CLI.
    
    FossilOrigin-Name: cab1834cfc71f71bfed3c5170a0ba40a39385c3b2c50b7c6b6f09cc830dd1b1e
    ---
     manifest         |  18 ++---
     manifest.uuid    |   2 +-
     src/shell.c.in   | 192 +++++++++++++++++++++++++++++++++++------------
     test/shell1.test |   9 +--
     test/shell5.test |   9 +--
     5 files changed, 161 insertions(+), 69 deletions(-)
    
    diff --git a/manifest b/manifest
    index 6c007c55b5..04435eea73 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Fix\stypos\sin\sRowSet.
    -D 2020-03-09T03:21:33.427
    +C Enhancements\sto\sthe\s".import"\scommand\sof\sthe\sCLI.
    +D 2020-03-09T15:39:39.029
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -532,7 +532,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
     F src/resolve.c 38e3a5636f5bdc92e3683e4cafbba6418c0aa15e0d89ca5b28bd0b621dbb80bf
     F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
     F src/select.c c94eec317c8ba929bc228392eb3cac8124f2d0fbe3fc1bddecb44dfc7057bc78
    -F src/shell.c.in 3897f3f7302914da1f6df3a2a09ac4aafa14a571d7d18c51500cfb2ff04f05eb
    +F src/shell.c.in f76590931c0cbbfef347f44f81ade6b335f80c46bc6e59b8b6114383a8df30e0
     F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
     F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
     F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
    @@ -1333,11 +1333,11 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
     F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
     F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
     F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
    -F test/shell1.test 3c9707dce15e8fdca529503378660f099777d3ddcedccf801a37589a405c5942
    +F test/shell1.test 43e12c7d4ff65f041803ad24a93fd3818deb2cb83e721810f27d0fde61d64a13
     F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
     F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
     F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce
    -F test/shell5.test 23939a4c51f0421330ea61dbd3c74f9c215f5f8d3d1a94846da6ffc777a35458
    +F test/shell5.test 84a30b55722a95a5b72989e691c469a999ca7591e7aa00b7fabc783ea5c9a6fe
     F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
     F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
     F test/shell8.test 96be02ea0c21f05b24c1883d7b711a1fa8525a68ab7b636aacf6057876941013
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 35f1f151ac478d6b46f3685d2565c35108ef74bd33ce96fb65300d3c303b289b
    -R 3ad66a51f32de0dab569042c4aa4c3c6
    -U pdr
    -Z ab82beefd8209a83b9f274edf5605106
    +P 86465c08f4d629a296332a7985937326ac43ea2822c5651bf03862cd79d370fc
    +R 59ca84b4f9c863c565a73d91cc01fad5
    +U drh
    +Z ca4df02a4f4403d62ad30a31c55381b8
    diff --git a/manifest.uuid b/manifest.uuid
    index 7deff47aa2..39e7d10901 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -86465c08f4d629a296332a7985937326ac43ea2822c5651bf03862cd79d370fc
    \ No newline at end of file
    +cab1834cfc71f71bfed3c5170a0ba40a39385c3b2c50b7c6b6f09cc830dd1b1e
    \ No newline at end of file
    diff --git a/src/shell.c.in b/src/shell.c.in
    index 149ba7ee1d..728a4d051d 100644
    --- a/src/shell.c.in
    +++ b/src/shell.c.in
    @@ -3575,6 +3575,18 @@ static const char *(azHelp[]) = {
       ".headers on|off          Turn display of headers on or off",
       ".help ?-all? ?PATTERN?   Show help text for PATTERN",
       ".import FILE TABLE       Import data from FILE into TABLE",
    +  "   Options:",
    +  "     --ascii               Use \\037 and \\036 as column and row separators",
    +  "     --csv                 Use , and \\n as column and row separators",
    +  "     --skip N              Skip the first N rows of input",
    +  "     -v                    \"Verbose\" - increase auxiliary output",
    +  "   Notes:",
    +  "     *  If TABLE does not exist, it is created.  The first row of input",
    +  "        determines the column names.",
    +  "     *  If neither --csv or --ascii are used, the input mode is derived",
    +  "        from the \".mode\" output mode",
    +  "     *  If FILE begins with \"|\" then it is a command that generates the",
    +  "        input text.",
     #ifndef SQLITE_OMIT_TEST_CONTROL
       ".imposter INDEX TABLE    Create imposter table TABLE on index INDEX",
     #endif
    @@ -4563,6 +4575,8 @@ struct ImportCtx {
       int n;              /* Number of bytes in z */
       int nAlloc;         /* Space allocated for z[] */
       int nLine;          /* Current line number */
    +  int nRow;           /* Number of rows imported */
    +  int nErr;           /* Number of errors encountered */
       int bNotFirst;      /* True if one or more bytes already read */
       int cTerm;          /* Character that terminated the most recent field */
       int cColSep;        /* The column separator character.  (Usually ",") */
    @@ -7623,8 +7637,8 @@ static int do_meta_command(char *zLine, ShellState *p){
       }else
     
       if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
    -    char *zTable;               /* Insert data into this table */
    -    char *zFile;                /* Name of file to extra content from */
    +    char *zTable = 0;           /* Insert data into this table */
    +    char *zFile = 0;            /* Name of file to extra content from */
         sqlite3_stmt *pStmt = NULL; /* A statement */
         int nCol;                   /* Number of columns in the table */
         int nByte;                  /* Number of bytes in an SQL string */
    @@ -7635,51 +7649,108 @@ static int do_meta_command(char *zLine, ShellState *p){
         ImportCtx sCtx;             /* Reader context */
         char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
         int (SQLITE_CDECL *xCloser)(FILE*);      /* Func to close file */
    +    int eVerbose = 0;           /* Larger for more console output */
    +    int nSkip = 0;              /* Initial lines to skip */
    +    int useOutputMode = 1;      /* Use output mode to determine separators */
     
    -    if( nArg!=3 ){
    -      raw_printf(stderr, "Usage: .import FILE TABLE\n");
    +    memset(&sCtx, 0, sizeof(sCtx));
    +    if( p->mode==MODE_Ascii ){
    +      xRead = ascii_read_one_field;
    +    }else{
    +      xRead = csv_read_one_field;
    +    }
    +    for(i=1; iout, "ERROR: extra argument: \"%s\".  Usage:\n", z);
    +          showHelp(p->out, "import");
    +          rc = 1;
    +          goto meta_command_exit;
    +        }
    +      }else if( strcmp(z,"-v")==0 ){
    +        eVerbose++;
    +      }else if( strcmp(z,"-skip")==0 && iout, "ERROR: unknown option: \"%s\".  Usage:\n", z);
    +        showHelp(p->out, "import");
    +        rc = 1;
    +        goto meta_command_exit;
    +      }
    +    }
    +    if( zTable==0 ){
    +      utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
    +                  zFile==0 ? "FILE" : "TABLE");
    +      showHelp(p->out, "import");
    +      rc = 1;
           goto meta_command_exit;
         }
    -    zFile = azArg[1];
    -    zTable = azArg[2];
         seenInterrupt = 0;
    -    memset(&sCtx, 0, sizeof(sCtx));
         open_db(p, 0);
    -    nSep = strlen30(p->colSeparator);
    -    if( nSep==0 ){
    -      raw_printf(stderr,
    -                 "Error: non-null column separator required for import\n");
    -      return 1;
    -    }
    -    if( nSep>1 ){
    -      raw_printf(stderr, "Error: multi-character column separators not allowed"
    -                      " for import\n");
    -      return 1;
    -    }
    -    nSep = strlen30(p->rowSeparator);
    -    if( nSep==0 ){
    -      raw_printf(stderr, "Error: non-null row separator required for import\n");
    -      return 1;
    -    }
    -    if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
    -      /* When importing CSV (only), if the row separator is set to the
    -      ** default output row separator, change it to the default input
    -      ** row separator.  This avoids having to maintain different input
    -      ** and output row separators. */
    -      sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
    +    if( useOutputMode ){
    +      /* If neither the --csv or --ascii options are specified, then set
    +      ** the column and row separator characters from the output mode. */
    +      nSep = strlen30(p->colSeparator);
    +      if( nSep==0 ){
    +        raw_printf(stderr,
    +                   "Error: non-null column separator required for import\n");
    +        rc = 1;
    +        goto meta_command_exit;
    +      }
    +      if( nSep>1 ){
    +        raw_printf(stderr, 
    +              "Error: multi-character column separators not allowed"
    +              " for import\n");
    +        rc = 1;
    +        goto meta_command_exit;
    +      }
           nSep = strlen30(p->rowSeparator);
    -    }
    -    if( nSep>1 ){
    -      raw_printf(stderr, "Error: multi-character row separators not allowed"
    -                      " for import\n");
    -      return 1;
    +      if( nSep==0 ){
    +        raw_printf(stderr,
    +            "Error: non-null row separator required for import\n");
    +        rc = 1;
    +        goto meta_command_exit;
    +      }
    +      if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
    +        /* When importing CSV (only), if the row separator is set to the
    +        ** default output row separator, change it to the default input
    +        ** row separator.  This avoids having to maintain different input
    +        ** and output row separators. */
    +        sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
    +        nSep = strlen30(p->rowSeparator);
    +      }
    +      if( nSep>1 ){
    +        raw_printf(stderr, "Error: multi-character row separators not allowed"
    +                           " for import\n");
    +        rc = 1;
    +        goto meta_command_exit;
    +      }
    +      sCtx.cColSep = p->colSeparator[0];
    +      sCtx.cRowSep = p->rowSeparator[0];
         }
         sCtx.zFile = zFile;
         sCtx.nLine = 1;
         if( sCtx.zFile[0]=='|' ){
     #ifdef SQLITE_OMIT_POPEN
           raw_printf(stderr, "Error: pipes are not supported in this OS\n");
    -      return 1;
    +      rc = 1;
    +      goto meta_command_exit;
     #else
           sCtx.in = popen(sCtx.zFile+1, "r");
           sCtx.zFile = "";
    @@ -7689,17 +7760,26 @@ static int do_meta_command(char *zLine, ShellState *p){
           sCtx.in = fopen(sCtx.zFile, "rb");
           xCloser = fclose;
         }
    -    if( p->mode==MODE_Ascii ){
    -      xRead = ascii_read_one_field;
    -    }else{
    -      xRead = csv_read_one_field;
    -    }
         if( sCtx.in==0 ){
           utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
    -      return 1;
    +      rc = 1;
    +      goto meta_command_exit;
    +    }
    +    if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
    +      char zSep[2];
    +      zSep[1] = 0;
    +      zSep[0] = sCtx.cColSep;
    +      utf8_printf(p->out, "Column separator ");
    +      output_c_string(p->out, zSep);
    +      utf8_printf(p->out, ", row separator ");
    +      zSep[0] = sCtx.cRowSep;
    +      output_c_string(p->out, zSep);
    +      utf8_printf(p->out, "\n");
    +    }
    +    while( (nSkip--)>0 ){
    +      while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
    +      sCtx.nLine++;
         }
    -    sCtx.cColSep = p->colSeparator[0];
    -    sCtx.cRowSep = p->rowSeparator[0];
         zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
         if( zSql==0 ){
           xCloser(sCtx.in);
    @@ -7721,9 +7801,13 @@ static int do_meta_command(char *zLine, ShellState *p){
             sqlite3_free(sCtx.z);
             xCloser(sCtx.in);
             utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
    -        return 1;
    +        rc = 1;
    +        goto meta_command_exit;
           }
           zCreate = sqlite3_mprintf("%z\n)", zCreate);
    +      if( eVerbose>=1 ){
    +        utf8_printf(p->out, "%s\n", zCreate);
    +      }
           rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
           sqlite3_free(zCreate);
           if( rc ){
    @@ -7731,7 +7815,8 @@ static int do_meta_command(char *zLine, ShellState *p){
                     sqlite3_errmsg(p->db));
             sqlite3_free(sCtx.z);
             xCloser(sCtx.in);
    -        return 1;
    +        rc = 1;
    +        goto meta_command_exit;
           }
           rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
         }
    @@ -7740,7 +7825,8 @@ static int do_meta_command(char *zLine, ShellState *p){
           if (pStmt) sqlite3_finalize(pStmt);
           utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
           xCloser(sCtx.in);
    -      return 1;
    +      rc = 1;
    +      goto meta_command_exit;
         }
         nCol = sqlite3_column_count(pStmt);
         sqlite3_finalize(pStmt);
    @@ -7759,13 +7845,17 @@ static int do_meta_command(char *zLine, ShellState *p){
         }
         zSql[j++] = ')';
         zSql[j] = 0;
    +    if( eVerbose>=2 ){
    +      utf8_printf(p->out, "Insert using: %s\n", zSql);
    +    }
         rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
         sqlite3_free(zSql);
         if( rc ){
           utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
           if (pStmt) sqlite3_finalize(pStmt);
           xCloser(sCtx.in);
    -      return 1;
    +      rc = 1;
    +      goto meta_command_exit;
         }
         needCommit = sqlite3_get_autocommit(p->db);
         if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
    @@ -7808,6 +7898,9 @@ static int do_meta_command(char *zLine, ShellState *p){
             if( rc!=SQLITE_OK ){
               utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
                           startLine, sqlite3_errmsg(p->db));
    +          sCtx.nErr++;
    +        }else{
    +          sCtx.nRow++;
             }
           }
         }while( sCtx.cTerm!=EOF );
    @@ -7816,6 +7909,11 @@ static int do_meta_command(char *zLine, ShellState *p){
         sqlite3_free(sCtx.z);
         sqlite3_finalize(pStmt);
         if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
    +    if( eVerbose>0 ){
    +      utf8_printf(p->out,
    +          "Added %d rows with %d errors using %d lines of input\n",
    +          sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
    +    }
       }else
     
     #ifndef SQLITE_UNTESTABLE
    diff --git a/test/shell1.test b/test/shell1.test
    index 734a21a2f8..9273adeeb8 100644
    --- a/test/shell1.test
    +++ b/test/shell1.test
    @@ -388,17 +388,14 @@ do_test shell1-3.10.2 {
     # .import FILE TABLE     Import data from FILE into TABLE
     do_test shell1-3.11.1 {
       catchcmd "test.db" ".import"
    -} {1 {Usage: .import FILE TABLE}}
    +} {/1 .ERROR: missing FILE argument.*/}
     do_test shell1-3.11.2 {
       catchcmd "test.db" ".import FOO"
    -} {1 {Usage: .import FILE TABLE}}
    -#do_test shell1-3.11.2 {
    -#  catchcmd "test.db" ".import FOO BAR"
    -#} {1 {Error: no such table: BAR}}
    +} {/1 .ERROR: missing TABLE argument.*/}
     do_test shell1-3.11.3 {
       # too many arguments
       catchcmd "test.db" ".import FOO BAR BAD"
    -} {1 {Usage: .import FILE TABLE}}
    +} {/1 .ERROR: extra argument: "BAD".*./}
     
     # .indexes ?TABLE?       Show names of all indexes
     #                          If TABLE specified, only show indexes for tables
    diff --git a/test/shell5.test b/test/shell5.test
    index 72f20ca3a6..8ec9a632bf 100644
    --- a/test/shell5.test
    +++ b/test/shell5.test
    @@ -32,17 +32,14 @@ forcedelete test.db test.db-journal test.db-wal
     # .import FILE TABLE     Import data from FILE into TABLE
     do_test shell5-1.1.1 {
       catchcmd "test.db" ".import"
    -} {1 {Usage: .import FILE TABLE}}
    +} {/1 .ERROR: missing FILE argument.*/}
     do_test shell5-1.1.2 {
       catchcmd "test.db" ".import FOO"
    -} {1 {Usage: .import FILE TABLE}}
    -#do_test shell5-1.1.2 {
    -#  catchcmd "test.db" ".import FOO BAR"
    -#} {1 {Error: no such table: BAR}}
    +} {/1 .ERROR: missing TABLE argument.*/}
     do_test shell5-1.1.3 {
       # too many arguments
       catchcmd "test.db" ".import FOO BAR BAD"
    -} {1 {Usage: .import FILE TABLE}}
    +} {/1 .ERROR: extra argument.*/}
     
     # .separator STRING      Change separator used by output mode and .import
     do_test shell5-1.2.1 {
    
    From afa1ecac9b6fba76861dca85b211ca1022f9e378 Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Mon, 9 Mar 2020 18:26:11 +0000
    Subject: [PATCH 055/102] Cleaner separation of the STAT4-specific logic in the
     implementation of ANALYZE.
    
    FossilOrigin-Name: 3df07e5a9a3781a4cf866fc6ee0e5c6f9cd7ca35ce0a6eb3aa7f5f3502e0ffae
    ---
     manifest      |  12 ++---
     manifest.uuid |   2 +-
     src/analyze.c | 123 +++++++++++++++++++++++++-------------------------
     3 files changed, 68 insertions(+), 69 deletions(-)
    
    diff --git a/manifest b/manifest
    index 04435eea73..9f3c8dd408 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Enhancements\sto\sthe\s".import"\scommand\sof\sthe\sCLI.
    -D 2020-03-09T15:39:39.029
    +C Cleaner\sseparation\sof\sthe\sSTAT4-specific\slogic\sin\sthe\simplementation\sof\nANALYZE.
    +D 2020-03-09T18:26:11.821
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -466,7 +466,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
     F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
     F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
     F src/alter.c f48a4423c8f198d7f1ae4940f74b606707d05384ac79fb219be8e3323af2a2de
    -F src/analyze.c b3ceec3fc052df8a96ca8a8c858d455dc5029ba681b4be98bb5c5a9162cfa58c
    +F src/analyze.c 831bb090988477a00d3b4c000746e1b0454dcc93b10b793e6ebe1c47f25d193a
     F src/attach.c fa5addce233a2bb2dfdefeee3b37000e154c47214d3269cab1bb331416e330db
     F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
     F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 86465c08f4d629a296332a7985937326ac43ea2822c5651bf03862cd79d370fc
    -R 59ca84b4f9c863c565a73d91cc01fad5
    +P cab1834cfc71f71bfed3c5170a0ba40a39385c3b2c50b7c6b6f09cc830dd1b1e
    +R c62e646df7b5e5719c4a0602837bf1ef
     U drh
    -Z ca4df02a4f4403d62ad30a31c55381b8
    +Z 8147aa7ce1e35e16be35124cd1704d38
    diff --git a/manifest.uuid b/manifest.uuid
    index 39e7d10901..e08451b6b2 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -cab1834cfc71f71bfed3c5170a0ba40a39385c3b2c50b7c6b6f09cc830dd1b1e
    \ No newline at end of file
    +3df07e5a9a3781a4cf866fc6ee0e5c6f9cd7ca35ce0a6eb3aa7f5f3502e0ffae
    \ No newline at end of file
    diff --git a/src/analyze.c b/src/analyze.c
    index 2a071ef126..eee71fbbde 100644
    --- a/src/analyze.c
    +++ b/src/analyze.c
    @@ -256,9 +256,9 @@ static void openStatTable(
     ** share an instance of the following structure to hold their state
     ** information.
     */
    -typedef struct Stat4Accum Stat4Accum;
    -typedef struct Stat4Sample Stat4Sample;
    -struct Stat4Sample {
    +typedef struct StatAccum StatAccum;
    +typedef struct StatSample StatSample;
    +struct StatSample {
       tRowcnt *anEq;                  /* sqlite_stat4.nEq */
       tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
     #ifdef SQLITE_ENABLE_STAT4
    @@ -273,27 +273,29 @@ struct Stat4Sample {
       u32 iHash;                      /* Tiebreaker hash */
     #endif
     };                                                    
    -struct Stat4Accum {
    +struct StatAccum {
    +  sqlite3 *db;              /* Database connection, for malloc() */
       tRowcnt nRow;             /* Number of rows in the entire table */
    -  tRowcnt nPSample;         /* How often to do a periodic sample */
       int nCol;                 /* Number of columns in index + pk/rowid */
       int nKeyCol;              /* Number of index columns w/o the pk/rowid */
    +  StatSample current;       /* Current row as a StatSample */
    +#ifdef SQLITE_ENABLE_STAT4
    +  tRowcnt nPSample;         /* How often to do a periodic sample */
       int mxSample;             /* Maximum number of samples to accumulate */
    -  Stat4Sample current;      /* Current row as a Stat4Sample */
       u32 iPrn;                 /* Pseudo-random number used for sampling */
    -  Stat4Sample *aBest;       /* Array of nCol best samples */
    +  StatSample *aBest;        /* Array of nCol best samples */
       int iMin;                 /* Index in a[] of entry with minimum score */
       int nSample;              /* Current number of samples */
       int nMaxEqZero;           /* Max leading 0 in anEq[] for any a[] entry */
       int iGet;                 /* Index of current sample accessed by stat_get() */
    -  Stat4Sample *a;           /* Array of mxSample Stat4Sample objects */
    -  sqlite3 *db;              /* Database connection, for malloc() */
    +  StatSample *a;            /* Array of mxSample StatSample objects */
    +#endif
     };
     
    -/* Reclaim memory used by a Stat4Sample
    +/* Reclaim memory used by a StatSample
     */
     #ifdef SQLITE_ENABLE_STAT4
    -static void sampleClear(sqlite3 *db, Stat4Sample *p){
    +static void sampleClear(sqlite3 *db, StatSample *p){
       assert( db!=0 );
       if( p->nRowid ){
         sqlite3DbFree(db, p->u.aRowid);
    @@ -305,7 +307,7 @@ static void sampleClear(sqlite3 *db, Stat4Sample *p){
     /* Initialize the BLOB value of a ROWID
     */
     #ifdef SQLITE_ENABLE_STAT4
    -static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
    +static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){
       assert( db!=0 );
       if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
       p->u.aRowid = sqlite3DbMallocRawNN(db, n);
    @@ -321,7 +323,7 @@ static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
     /* Initialize the INTEGER value of a ROWID.
     */
     #ifdef SQLITE_ENABLE_STAT4
    -static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
    +static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){
       assert( db!=0 );
       if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
       p->nRowid = 0;
    @@ -334,7 +336,7 @@ static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
     ** Copy the contents of object (*pFrom) into (*pTo).
     */
     #ifdef SQLITE_ENABLE_STAT4
    -static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
    +static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
       pTo->isPSample = pFrom->isPSample;
       pTo->iCol = pFrom->iCol;
       pTo->iHash = pFrom->iHash;
    @@ -350,10 +352,10 @@ static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
     #endif
     
     /*
    -** Reclaim all memory of a Stat4Accum structure.
    +** Reclaim all memory of a StatAccum structure.
     */
    -static void stat4Destructor(void *pOld){
    -  Stat4Accum *p = (Stat4Accum*)pOld;
    +static void statAccumDestructor(void *pOld){
    +  StatAccum *p = (StatAccum*)pOld;
     #ifdef SQLITE_ENABLE_STAT4
       int i;
       for(i=0; inCol; i++) sampleClear(p->db, p->aBest+i);
    @@ -381,9 +383,9 @@ static void stat4Destructor(void *pOld){
     ** PRIMARY KEY of the table.  The covering index that implements the
     ** original WITHOUT ROWID table as N==K as a special case.
     **
    -** This routine allocates the Stat4Accum object in heap memory. The return 
    -** value is a pointer to the Stat4Accum object.  The datatype of the
    -** return value is BLOB, but it is really just a pointer to the Stat4Accum
    +** This routine allocates the StatAccum object in heap memory. The return 
    +** value is a pointer to the StatAccum object.  The datatype of the
    +** return value is BLOB, but it is really just a pointer to the StatAccum
     ** object.
     */
     static void statInit(
    @@ -391,7 +393,7 @@ static void statInit(
       int argc,
       sqlite3_value **argv
     ){
    -  Stat4Accum *p;
    +  StatAccum *p;
       int nCol;                       /* Number of columns in index being sampled */
       int nKeyCol;                    /* Number of key columns */
       int nColUp;                     /* nCol rounded up for alignment */
    @@ -410,13 +412,13 @@ static void statInit(
       assert( nKeyCol<=nCol );
       assert( nKeyCol>0 );
     
    -  /* Allocate the space required for the Stat4Accum object */
    +  /* Allocate the space required for the StatAccum object */
       n = sizeof(*p) 
    -    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anEq */
    -    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
    +    + sizeof(tRowcnt)*nColUp                  /* StatAccum.anEq */
    +    + sizeof(tRowcnt)*nColUp                  /* StatAccum.anDLt */
     #ifdef SQLITE_ENABLE_STAT4
    -    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anLt */
    -    + sizeof(Stat4Sample)*(nCol+mxSample)     /* Stat4Accum.aBest[], a[] */
    +    + sizeof(tRowcnt)*nColUp                  /* StatAccum.anLt */
    +    + sizeof(StatSample)*(nCol+mxSample)      /* StatAccum.aBest[], a[] */
         + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
     #endif
       ;
    @@ -445,8 +447,8 @@ static void statInit(
         p->current.anLt = &p->current.anEq[nColUp];
         p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
       
    -    /* Set up the Stat4Accum.a[] and aBest[] arrays */
    -    p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
    +    /* Set up the StatAccum.a[] and aBest[] arrays */
    +    p->a = (struct StatSample*)&p->current.anLt[nColUp];
         p->aBest = &p->a[mxSample];
         pSpace = (u8*)(&p->a[mxSample+nCol]);
         for(i=0; i<(mxSample+nCol); i++){
    @@ -466,7 +468,7 @@ static void statInit(
       ** only the pointer (the 2nd parameter) matters.  The size of the object
       ** (given by the 3rd parameter) is never used and can be any positive
       ** value. */
    -  sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
    +  sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
     }
     static const FuncDef statInitFuncdef = {
       2+IsStat4,       /* nArg */
    @@ -493,9 +495,9 @@ static const FuncDef statInitFuncdef = {
     ** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. 
     */
     static int sampleIsBetterPost(
    -  Stat4Accum *pAccum, 
    -  Stat4Sample *pNew, 
    -  Stat4Sample *pOld
    +  StatAccum *pAccum, 
    +  StatSample *pNew, 
    +  StatSample *pOld
     ){
       int nCol = pAccum->nCol;
       int i;
    @@ -517,9 +519,9 @@ static int sampleIsBetterPost(
     ** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. 
     */
     static int sampleIsBetter(
    -  Stat4Accum *pAccum, 
    -  Stat4Sample *pNew, 
    -  Stat4Sample *pOld
    +  StatAccum *pAccum, 
    +  StatSample *pNew, 
    +  StatSample *pOld
     ){
       tRowcnt nEqNew = pNew->anEq[pNew->iCol];
       tRowcnt nEqOld = pOld->anEq[pOld->iCol];
    @@ -539,21 +541,21 @@ static int sampleIsBetter(
     ** Copy the contents of sample *pNew into the p->a[] array. If necessary,
     ** remove the least desirable sample from p->a[] to make room.
     */
    -static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
    -  Stat4Sample *pSample = 0;
    +static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){
    +  StatSample *pSample = 0;
       int i;
     
       assert( IsStat4 || nEqZero==0 );
     
    -  /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
    -  ** values in the anEq[] array of any sample in Stat4Accum.a[]. In
    +  /* StatAccum.nMaxEqZero is set to the maximum number of leading 0
    +  ** values in the anEq[] array of any sample in StatAccum.a[]. In
       ** other words, if nMaxEqZero is n, then it is guaranteed that there
    -  ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
    +  ** are no samples with StatSample.anEq[m]==0 for (m>=n). */
       if( nEqZero>p->nMaxEqZero ){
         p->nMaxEqZero = nEqZero;
       }
       if( pNew->isPSample==0 ){
    -    Stat4Sample *pUpgrade = 0;
    +    StatSample *pUpgrade = 0;
         assert( pNew->anEq[pNew->iCol]>0 );
     
         /* This sample is being added because the prefix that ends in column 
    @@ -562,7 +564,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
         ** this one. Instead, upgrade the priority of the highest priority
         ** existing sample that shares this prefix.  */
         for(i=p->nSample-1; i>=0; i--){
    -      Stat4Sample *pOld = &p->a[i];
    +      StatSample *pOld = &p->a[i];
           if( pOld->anEq[pNew->iCol]==0 ){
             if( pOld->isPSample ) return;
             assert( pOld->iCol>pNew->iCol );
    @@ -581,7 +583,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
     
       /* If necessary, remove sample iMin to make room for the new sample. */
       if( p->nSample>=p->mxSample ){
    -    Stat4Sample *pMin = &p->a[p->iMin];
    +    StatSample *pMin = &p->a[p->iMin];
         tRowcnt *anEq = pMin->anEq;
         tRowcnt *anLt = pMin->anLt;
         tRowcnt *anDLt = pMin->anDLt;
    @@ -624,20 +626,20 @@ find_new_min:
     }
     #endif /* SQLITE_ENABLE_STAT4 */
     
    +#ifdef SQLITE_ENABLE_STAT4
     /*
     ** Field iChng of the index being scanned has changed. So at this point
     ** p->current contains a sample that reflects the previous row of the
     ** index. The value of anEq[iChng] and subsequent anEq[] elements are
     ** correct at this point.
     */
    -static void samplePushPrevious(Stat4Accum *p, int iChng){
    -#ifdef SQLITE_ENABLE_STAT4
    +static void samplePushPrevious(StatAccum *p, int iChng){
       int i;
     
       /* Check if any samples from the aBest[] array should be pushed
       ** into IndexSample.a[] at this point.  */
       for(i=(p->nCol-2); i>=iChng; i--){
    -    Stat4Sample *pBest = &p->aBest[i];
    +    StatSample *pBest = &p->aBest[i];
         pBest->anEq[i] = p->current.anEq[i];
         if( p->nSamplemxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
           sampleInsert(p, pBest, i);
    @@ -661,25 +663,20 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
         }
         p->nMaxEqZero = iChng;
       }
    -#endif
    -
    -#ifndef SQLITE_ENABLE_STAT4
    -  UNUSED_PARAMETER( p );
    -  UNUSED_PARAMETER( iChng );
    -#endif
     }
    +#endif /* SQLITE_ENABLE_STAT4 */
     
     /*
     ** Implementation of the stat_push SQL function:  stat_push(P,C,R)
     ** Arguments:
     **
    -**    P     Pointer to the Stat4Accum object created by stat_init()
    +**    P     Pointer to the StatAccum object created by stat_init()
     **    C     Index of left-most column to differ from previous row
     **    R     Rowid for the current row.  Might be a key record for
     **          WITHOUT ROWID tables.
     **
     ** This SQL function always returns NULL.  It's purpose it to accumulate
    -** statistical data and/or samples in the Stat4Accum object about the
    +** statistical data and/or samples in the StatAccum object about the
     ** index being analyzed.  The stat_get() SQL function will later be used to
     ** extract relevant information for constructing the sqlite_statN tables.
     **
    @@ -693,7 +690,7 @@ static void statPush(
       int i;
     
       /* The three function arguments */
    -  Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
    +  StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
       int iChng = sqlite3_value_int(argv[1]);
     
       UNUSED_PARAMETER( argc );
    @@ -706,7 +703,9 @@ static void statPush(
         for(i=0; inCol; i++) p->current.anEq[i] = 1;
       }else{
         /* Second and subsequent calls get processed here */
    +#ifdef SQLITE_ENABLE_STAT4
         samplePushPrevious(p, iChng);
    +#endif
     
         /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
         ** to the current row of the index. */
    @@ -775,15 +774,15 @@ static const FuncDef statPushFuncdef = {
     /*
     ** Implementation of the stat_get(P,J) SQL function.  This routine is
     ** used to query statistical information that has been gathered into
    -** the Stat4Accum object by prior calls to stat_push().  The P parameter
    -** has type BLOB but it is really just a pointer to the Stat4Accum object.
    +** the StatAccum object by prior calls to stat_push().  The P parameter
    +** has type BLOB but it is really just a pointer to the StatAccum object.
     ** The content to returned is determined by the parameter J
     ** which is one of the STAT_GET_xxxx values defined above.
     **
     ** The stat_get(P,J) function is not available to generic SQL.  It is
     ** inserted as part of a manually constructed bytecode program.  (See
     ** the callStatGet() routine below.)  It is guaranteed that the P
    -** parameter will always be a poiner to a Stat4Accum object, never a
    +** parameter will always be a pointer to a StatAccum object, never a
     ** NULL.
     **
     ** If STAT4 is not enabled, then J is always
    @@ -796,7 +795,7 @@ static void statGet(
       int argc,
       sqlite3_value **argv
     ){
    -  Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
    +  StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
     #ifdef SQLITE_ENABLE_STAT4
       /* STAT4 has a parameter on this routine. */
       int eCall = sqlite3_value_int(argv[1]);
    @@ -817,7 +816,7 @@ static void statGet(
         ** the index. The first integer in the list is the total number of 
         ** entries in the index. There is one additional integer in the list 
         ** for each indexed column. This additional integer is an estimate of
    -    ** the number of rows matched by a stabbing query on the index using
    +    ** the number of rows matched by a equality query on the index using
         ** a key with the corresponding number of fields. In other words,
         ** if the index is on columns (a,b) and the sqlite_stat1 value is 
         ** "100 10 2", then SQLite estimates that:
    @@ -860,7 +859,7 @@ static void statGet(
           p->iGet = 0;
         }
         if( p->iGetnSample ){
    -      Stat4Sample *pS = p->a + p->iGet;
    +      StatSample *pS = p->a + p->iGet;
           if( pS->nRowid==0 ){
             sqlite3_result_int64(context, pS->u.iRowid);
           }else{
    @@ -951,7 +950,7 @@ static void analyzeOneTable(
       int iDb;                     /* Index of database containing pTab */
       u8 needTableCnt = 1;         /* True to count the table */
       int regNewRowid = iMem++;    /* Rowid for the inserted record */
    -  int regStat4 = iMem++;       /* Register to hold Stat4Accum object */
    +  int regStat4 = iMem++;       /* Register to hold StatAccum object */
       int regChng = iMem++;        /* Index of changed index field */
     #ifdef SQLITE_ENABLE_STAT4
       int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
    
    From 088489e8d9ebbcbbbd99093a83bc93bfcd1a39a0 Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Tue, 10 Mar 2020 02:57:37 +0000
    Subject: [PATCH 056/102] The sqlite3ExprCodeFactorable() routine should make a
     copy of non-factorable expressions, as they might be coming from a DEFAULT or
     generated column in a table constraint.
    
    FossilOrigin-Name: a2d6f108c5d07559b125823a04c9cb072c80be80d7913097891a6192c7e1e225
    ---
     manifest          | 14 +++++++-------
     manifest.uuid     |  2 +-
     src/expr.c        |  3 ++-
     test/default.test |  9 +++++++++
     4 files changed, 19 insertions(+), 9 deletions(-)
    
    diff --git a/manifest b/manifest
    index 9f3c8dd408..67a73f554c 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Cleaner\sseparation\sof\sthe\sSTAT4-specific\slogic\sin\sthe\simplementation\sof\nANALYZE.
    -D 2020-03-09T18:26:11.821
    +C The\ssqlite3ExprCodeFactorable()\sroutine\sshould\smake\sa\scopy\sof\snon-factorable\nexpressions,\sas\sthey\smight\sbe\scoming\sfrom\sa\sDEFAULT\sor\sgenerated\scolumn\nin\sa\stable\sconstraint.
    +D 2020-03-10T02:57:37.726
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
     F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
     F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
     F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
    -F src/expr.c 4b25db7f9472b3532560242193bc4eefaefc7720dc4f2d7ec9a89ada410c6ea2
    +F src/expr.c 4efd019be610f8e24008a6e89c6c5dbf204edaeaade0cc996a88f285ce1d4a06
     F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
     F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
     F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
    @@ -810,7 +810,7 @@ F test/dbfuzz2.c c2c9cb40082a77b7e95ffb8b2da1e93322efadfb1c8c1e0001c95a0af1e156c
     F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38
     F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759
     F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
    -F test/default.test 3e46c421eebefd2787c2f96673efabf792d360f3a1d5073918cbe450ce672a62
    +F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50
     F test/delete.test 31832b0c45ecb51a54348c68db173be462985901e6ed7f403d6d7a8f70ab4ef0
     F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
     F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P cab1834cfc71f71bfed3c5170a0ba40a39385c3b2c50b7c6b6f09cc830dd1b1e
    -R c62e646df7b5e5719c4a0602837bf1ef
    +P 3df07e5a9a3781a4cf866fc6ee0e5c6f9cd7ca35ce0a6eb3aa7f5f3502e0ffae
    +R 7d49dd66db353572ddc6eafd9c0a8b97
     U drh
    -Z 8147aa7ce1e35e16be35124cd1704d38
    +Z 57a026e3bb6ad1f9a47d83e58f8523e1
    diff --git a/manifest.uuid b/manifest.uuid
    index e08451b6b2..9fcda7ce22 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -3df07e5a9a3781a4cf866fc6ee0e5c6f9cd7ca35ce0a6eb3aa7f5f3502e0ffae
    \ No newline at end of file
    +a2d6f108c5d07559b125823a04c9cb072c80be80d7913097891a6192c7e1e225
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index 8b939de24f..01cc37cc0c 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -2850,6 +2850,7 @@ void sqlite3CodeRhsOfIN(
     
         /* Begin coding the subroutine */
         ExprSetProperty(pExpr, EP_Subrtn);
    +    assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
         pExpr->y.sub.regReturn = ++pParse->nMem;
         pExpr->y.sub.iAddr =
           sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
    @@ -4604,7 +4605,7 @@ void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
       if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
         sqlite3ExprCodeAtInit(pParse, pExpr, target);
       }else{
    -    sqlite3ExprCode(pParse, pExpr, target);
    +    sqlite3ExprCodeCopy(pParse, pExpr, target);
       }
     }
     
    diff --git a/test/default.test b/test/default.test
    index d691303485..06a180c1de 100644
    --- a/test/default.test
    +++ b/test/default.test
    @@ -128,4 +128,13 @@ do_catchsql_test default-4.4 {
       CREATE TABLE t2(a TEXT, b TEXT DEFAULT(98+coalesce(5,:xyz)));
     } {1 {default value of column [b] is not constant}}
     
    +# 2020-03-09 out-of-bounds memory access discovered by "Eternal Sakura"
    +# and reported to chromium.
    +#
    +reset_db
    +do_catchsql_test default-5.1 {
    +  CREATE TABLE t1 (a,b DEFAULT(random() NOTNULL IN (RAISE(IGNORE),2,3)));
    +  INSERT INTO t1(a) VALUES(1);
    +} {1 {RAISE() may only be used within a trigger-program}}
    +
     finish_test
    
    From 0c76e892d9622dc5c13b168b39f40aa51884cef6 Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Tue, 10 Mar 2020 11:50:43 +0000
    Subject: [PATCH 057/102] Apply the correct affinity transformations when
     pulling values off of the sorter index used for GROUP BY.  Ticket
     [e0c2ad1aa8a9c691]
    
    FossilOrigin-Name: 101f7dea75a203f1f3aa422a607ef701eb0901ba4d5e8d1075cd350454a61956
    ---
     manifest          | 14 +++++++-------
     manifest.uuid     |  2 +-
     src/expr.c        |  4 ++++
     test/select3.test |  8 ++++++++
     4 files changed, 20 insertions(+), 8 deletions(-)
    
    diff --git a/manifest b/manifest
    index 67a73f554c..1497d04cf9 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C The\ssqlite3ExprCodeFactorable()\sroutine\sshould\smake\sa\scopy\sof\snon-factorable\nexpressions,\sas\sthey\smight\sbe\scoming\sfrom\sa\sDEFAULT\sor\sgenerated\scolumn\nin\sa\stable\sconstraint.
    -D 2020-03-10T02:57:37.726
    +C Apply\sthe\scorrect\saffinity\stransformations\swhen\spulling\svalues\soff\sof\sthe\nsorter\sindex\sused\sfor\sGROUP\sBY.\s\sTicket\s[e0c2ad1aa8a9c691]
    +D 2020-03-10T11:50:43.810
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
     F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
     F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
     F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
    -F src/expr.c 4efd019be610f8e24008a6e89c6c5dbf204edaeaade0cc996a88f285ce1d4a06
    +F src/expr.c 92fa379dabdb55e45811c7650a2337af91035a44ecec32b0fbc5c6682d68f575
     F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
     F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
     F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
    @@ -1303,7 +1303,7 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f
     F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
     F test/select1.test 009a6d8eacd9684d046302b8d13b50846a87e39d6f08e92178aa13e95ea29a2d
     F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
    -F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9
    +F test/select3.test ddd1bc6d0c8dece136321c11bd26d0d8ad17f2b27c72935fdd6574d8cb99d1d4
     F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328
     F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546
     F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 3df07e5a9a3781a4cf866fc6ee0e5c6f9cd7ca35ce0a6eb3aa7f5f3502e0ffae
    -R 7d49dd66db353572ddc6eafd9c0a8b97
    +P a2d6f108c5d07559b125823a04c9cb072c80be80d7913097891a6192c7e1e225
    +R 3dd418ad329a8afd1cad637d51a1b1fd
     U drh
    -Z 57a026e3bb6ad1f9a47d83e58f8523e1
    +Z 43126d534c48a0ddd9165f34c835e3bc
    diff --git a/manifest.uuid b/manifest.uuid
    index 9fcda7ce22..968add9a60 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -a2d6f108c5d07559b125823a04c9cb072c80be80d7913097891a6192c7e1e225
    \ No newline at end of file
    +101f7dea75a203f1f3aa422a607ef701eb0901ba4d5e8d1075cd350454a61956
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index 01cc37cc0c..f3ce1de75e 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -3791,8 +3791,12 @@ expr_code_doover:
             assert( pCol->iMem>0 );
             return pCol->iMem;
           }else if( pAggInfo->useSortingIdx ){
    +        Table *pTab = pCol->pTab;
             sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
                                   pCol->iSorterColumn, target);
    +        if( ALWAYS(pTab) && pCol->iColumn>=0 ){
    +          sqlite3ColumnDefault(v, pTab, pCol->iColumn, target);
    +        }
             return target;
           }
           /* Otherwise, fall thru into the TK_COLUMN case */
    diff --git a/test/select3.test b/test/select3.test
    index e15464ff5a..50039c551e 100644
    --- a/test/select3.test
    +++ b/test/select3.test
    @@ -306,4 +306,12 @@ foreach {id x} {
       } {{} 1.0 ok}
     }
     
    +# 2020-03-10 ticket e0c2ad1aa8a9c691
    +reset_db
    +do_execsql_test select3-9.100 {
    +  CREATE TABLE t0(c0 REAL, c1 REAL GENERATED ALWAYS AS (c0));
    +  INSERT INTO t0(c0) VALUES (1);
    +  SELECT * FROM t0 GROUP BY c0;
    +} {1.0 1.0}
    +
     finish_test
    
    From 24e399038bfb59823ea6bf1939c2282eeaf4401a Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Tue, 10 Mar 2020 13:35:04 +0000
    Subject: [PATCH 058/102] Make a copy of the expression that defines a value of
     a generated column before sending it to the code generator routines.
    
    FossilOrigin-Name: 03d201c041c17579e791c73fe6babd60b9f892a84ffd1470851f8eb2857d3990
    ---
     manifest      | 12 ++++++------
     manifest.uuid |  2 +-
     src/expr.c    |  2 +-
     3 files changed, 8 insertions(+), 8 deletions(-)
    
    diff --git a/manifest b/manifest
    index 1497d04cf9..05ecbf189e 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Apply\sthe\scorrect\saffinity\stransformations\swhen\spulling\svalues\soff\sof\sthe\nsorter\sindex\sused\sfor\sGROUP\sBY.\s\sTicket\s[e0c2ad1aa8a9c691]
    -D 2020-03-10T11:50:43.810
    +C Make\sa\scopy\sof\sthe\sexpression\sthat\sdefines\sa\svalue\sof\sa\sgenerated\scolumn\nbefore\ssending\sit\sto\sthe\scode\sgenerator\sroutines.
    +D 2020-03-10T13:35:04.074
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
     F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
     F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
     F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
    -F src/expr.c 92fa379dabdb55e45811c7650a2337af91035a44ecec32b0fbc5c6682d68f575
    +F src/expr.c 6454893aab3ed99aff11d36a22735a83225759e85ca781b9568f4f620f958b10
     F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
     F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
     F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P a2d6f108c5d07559b125823a04c9cb072c80be80d7913097891a6192c7e1e225
    -R 3dd418ad329a8afd1cad637d51a1b1fd
    +P 101f7dea75a203f1f3aa422a607ef701eb0901ba4d5e8d1075cd350454a61956
    +R 4992fbbdcecc97b906ef590b9997e218
     U drh
    -Z 43126d534c48a0ddd9165f34c835e3bc
    +Z 2bc45efe28100ac60ec8a2886907a19f
    diff --git a/manifest.uuid b/manifest.uuid
    index 968add9a60..067bd1d06f 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -101f7dea75a203f1f3aa422a607ef701eb0901ba4d5e8d1075cd350454a61956
    \ No newline at end of file
    +03d201c041c17579e791c73fe6babd60b9f892a84ffd1470851f8eb2857d3990
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index f3ce1de75e..6bbefc12fb 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -3497,7 +3497,7 @@ void sqlite3ExprCodeGeneratedColumn(
       }else{
         iAddr = 0;
       }
    -  sqlite3ExprCode(pParse, pCol->pDflt, regOut);
    +  sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut);
       if( pCol->affinity>=SQLITE_AFF_TEXT ){
         sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
       }
    
    From 5cf1b611a20201aa141b258901cbfc2950e2037e Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Tue, 10 Mar 2020 18:55:41 +0000
    Subject: [PATCH 059/102] Further changes to ensure that expressions held in
     table and index definitions do not get passed down into code generator logic
     where they might be modified.
    
    FossilOrigin-Name: f45f5de000834da5b23cdcf12c3f0e3073287756afe06bdb77b95fb65b250258
    ---
     manifest      | 12 ++++++------
     manifest.uuid |  2 +-
     src/insert.c  |  9 +++++++--
     3 files changed, 14 insertions(+), 9 deletions(-)
    
    diff --git a/manifest b/manifest
    index 05ecbf189e..4959ed75fa 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Make\sa\scopy\sof\sthe\sexpression\sthat\sdefines\sa\svalue\sof\sa\sgenerated\scolumn\nbefore\ssending\sit\sto\sthe\scode\sgenerator\sroutines.
    -D 2020-03-10T13:35:04.074
    +C Further\schanges\sto\sensure\sthat\sexpressions\sheld\sin\stable\sand\sindex\sdefinitions\ndo\snot\sget\spassed\sdown\sinto\scode\sgenerator\slogic\swhere\sthey\smight\sbe\smodified.
    +D 2020-03-10T18:55:41.227
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -492,7 +492,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
     F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
     F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
     F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
    -F src/insert.c 9b487eb4b756a2bab16fa5ba19d207375551f7d0b8da3f4dff769f3035dc6bab
    +F src/insert.c 8e4211d04eb460c0694d486c6ba1c068d468c6f653c3f237869a802ad82854de
     F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
     F src/loadext.c b179df50e6e8bb0c36c149e95d958d49bd8c6c7469e59c01b53d164360bc6c32
     F src/main.c b11eec03807a038b4075d310936dc33ce597078ab78c35dacdf5f05446ed53de
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 101f7dea75a203f1f3aa422a607ef701eb0901ba4d5e8d1075cd350454a61956
    -R 4992fbbdcecc97b906ef590b9997e218
    +P 03d201c041c17579e791c73fe6babd60b9f892a84ffd1470851f8eb2857d3990
    +R 15f3f41fa383817c4f7bc848e5f606e0
     U drh
    -Z 2bc45efe28100ac60ec8a2886907a19f
    +Z aac525d59390e43f110256e9523cebc2
    diff --git a/manifest.uuid b/manifest.uuid
    index 067bd1d06f..5d1b8e4f41 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -03d201c041c17579e791c73fe6babd60b9f892a84ffd1470851f8eb2857d3990
    \ No newline at end of file
    +f45f5de000834da5b23cdcf12c3f0e3073287756afe06bdb77b95fb65b250258
    \ No newline at end of file
    diff --git a/src/insert.c b/src/insert.c
    index 43d2f11c14..f4049fb3de 100644
    --- a/src/insert.c
    +++ b/src/insert.c
    @@ -1606,7 +1606,7 @@ void sqlite3GenerateConstraintChecks(
                 VdbeCoverage(v);
                 assert( (pCol->colFlags & COLFLAG_GENERATED)==0 );
                 nSeenReplace++;
    -            sqlite3ExprCode(pParse, pCol->pDflt, iReg);
    +            sqlite3ExprCodeCopy(pParse, pCol->pDflt, iReg);
                 sqlite3VdbeJumpHere(v, addr1);
                 break;
               }
    @@ -1661,6 +1661,7 @@ void sqlite3GenerateConstraintChecks(
         onError = overrideError!=OE_Default ? overrideError : OE_Abort;
         for(i=0; inExpr; i++){
           int allOk;
    +      Expr *pCopy;
           Expr *pExpr = pCheck->a[i].pExpr;
           if( aiChng
            && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
    @@ -1675,7 +1676,11 @@ void sqlite3GenerateConstraintChecks(
           }
           allOk = sqlite3VdbeMakeLabel(pParse);
           sqlite3VdbeVerifyAbortable(v, onError);
    -      sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
    +      pCopy = sqlite3ExprDup(db, pExpr, 0);
    +      if( !db->mallocFailed ){
    +        sqlite3ExprIfTrue(pParse, pCopy, allOk, SQLITE_JUMPIFNULL);
    +      }
    +      sqlite3ExprDelete(db, pCopy);
           if( onError==OE_Ignore ){
             sqlite3VdbeGoto(v, ignoreDest);
           }else{
    
    From e7375bfa727bfa12649897fd6a655f81b703f0db Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Tue, 10 Mar 2020 19:24:38 +0000
    Subject: [PATCH 060/102] Enhanced detection logic for preventing the use of
     static schema expressions by code generating routines.
    
    FossilOrigin-Name: 5f60b527b938c0778e8f725c635ce0dc5ed7a4e01fd6252aa2cdb64da2f625bc
    ---
     manifest        | 20 +++++++++----------
     manifest.uuid   |  2 +-
     src/build.c     | 28 ++++++++++++++++++++++++++
     src/expr.c      | 52 ++++++++++++++++++++++++++++++-------------------
     src/parse.y     |  1 +
     src/sqliteInt.h | 34 ++++++++++++++++++++++----------
     src/treeview.c  |  8 ++++++--
     7 files changed, 102 insertions(+), 43 deletions(-)
    
    diff --git a/manifest b/manifest
    index 4959ed75fa..06cd979aa0 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Further\schanges\sto\sensure\sthat\sexpressions\sheld\sin\stable\sand\sindex\sdefinitions\ndo\snot\sget\spassed\sdown\sinto\scode\sgenerator\slogic\swhere\sthey\smight\sbe\smodified.
    -D 2020-03-10T18:55:41.227
    +C Enhanced\sdetection\slogic\sfor\spreventing\sthe\suse\sof\sstatic\sschema\sexpressions\nby\scode\sgenerating\sroutines.
    +D 2020-03-10T19:24:38.960
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -475,7 +475,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
     F src/btree.c 7271a120a66dfd12edcee942443fcd7b3860514a5621cb26a374781af1462117
     F src/btree.h 6111552f19ed7a40f029cf4b33badc6fef9880314fffd80a945f0b7f43ab7471
     F src/btreeInt.h dee1a1d0c621524e006bb260bd6b66d5d1867da6fe38cba9ad7b6a9bb9c0c175
    -F src/build.c 2394d2c853088106dfc1cf485d609f20e6421d7c84892b795824e454f78e50ad
    +F src/build.c 406645db37154920075d90a4ea3c47f33d5f5b6e0769010a54ea8247ee433c1a
     F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
     F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
     F src/ctime.c 6a77ec9e0eb87aea929e002c816298907e337094a7b556898ae2d1e6be209f90
    @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
     F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
     F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
     F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
    -F src/expr.c 6454893aab3ed99aff11d36a22735a83225759e85ca781b9568f4f620f958b10
    +F src/expr.c 117997508b41b1d02b4c376bdca16da04e813c0f36d0811e3ea13d1c786f53f4
     F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
     F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
     F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
    @@ -520,7 +520,7 @@ F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7
     F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
     F src/pager.c a71ffd145f55e28cbdc1bdabb5e6bef063da428a6c0de3c3a36e9a0c41d4c8c0
     F src/pager.h 3b33619a90180e0874c7eca31d6f6ceb464d9322c6fb4e9a7bbb318c8a17bdb3
    -F src/parse.y 61ae75b1764c86f56fdfe384d736e4ba9b0d54015a5ca61925d8cb6b94943d4c
    +F src/parse.y 8575183809cf30f8c9d1fbea65ca34d1de78b659792bc7c42681e01fc596b520
     F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
     F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
     F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
    @@ -536,7 +536,7 @@ F src/shell.c.in f76590931c0cbbfef347f44f81ade6b335f80c46bc6e59b8b6114383a8df30e
     F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
     F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
     F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
    -F src/sqliteInt.h 37511a5bd13dab6c61242b8d6525c7efdea7a90a7fd00e5ca8e809fa292efe7c
    +F src/sqliteInt.h ed6885bb0ec82db2503c931fd96c795fc7a4b474dc075c3442a45c3a8523c797
     F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
     F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
     F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
    @@ -596,7 +596,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
     F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
     F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
     F src/tokenize.c 7b17f6e2f20f6cbcb0b215025a86b7457c38451fc7622f705e553d7a488c572d
    -F src/treeview.c 438c1000587b33faba35e87596bebcf7f40638d98f33781cdd9e04711b18b09c
    +F src/treeview.c f78cd9cd79a889e70cd98bd6edd4a464c421452da833e65e987d97d8c41f71fe
     F src/trigger.c a40d50e88bd3355f1d2a73f0a3b2d6b42eae26ca4219001b82ef0d064439badc
     F src/update.c 3eb778c42155d944377a4ee5e440b04520f07094804ed6ce63d2528f619614d9
     F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P 03d201c041c17579e791c73fe6babd60b9f892a84ffd1470851f8eb2857d3990
    -R 15f3f41fa383817c4f7bc848e5f606e0
    +P f45f5de000834da5b23cdcf12c3f0e3073287756afe06bdb77b95fb65b250258
    +R f078265eb0d8f8487aa3c2a1c341660a
     U drh
    -Z aac525d59390e43f110256e9523cebc2
    +Z 1d0ba7c8bbe7247314d90dba25e45a8e
    diff --git a/manifest.uuid b/manifest.uuid
    index 5d1b8e4f41..c22469d699 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -f45f5de000834da5b23cdcf12c3f0e3073287756afe06bdb77b95fb65b250258
    \ No newline at end of file
    +5f60b527b938c0778e8f725c635ce0dc5ed7a4e01fd6252aa2cdb64da2f625bc
    \ No newline at end of file
    diff --git a/src/build.c b/src/build.c
    index a7dc36ff54..73e4cea7cc 100644
    --- a/src/build.c
    +++ b/src/build.c
    @@ -2157,6 +2157,32 @@ int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
     }
     #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
     
    +#ifdef SQLITE_DEBUG
    +/*
    +** Mark all nodes of an expression as EP_Immutable, indicating that
    +** they should not be changed.  Expressions attached to a table or
    +** index definition are tagged this way to help ensure that we do
    +** not pass them into code generator routines by mistake.
    +*/
    +static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){
    +  ExprSetVVAProperty(pExpr, EP_Immutable);
    +  return WRC_Continue;
    +}
    +static void markExprListImmutable(ExprList *pList){
    +  if( pList ){
    +    Walker w;
    +    memset(&w, 0, sizeof(w));
    +    w.xExprCallback = markImmutableExprStep;
    +    w.xSelectCallback = sqlite3SelectWalkNoop;
    +    w.xSelectCallback2 = 0;
    +    sqlite3WalkExprList(&w, pList);
    +  }
    +}
    +#else
    +#define markExprListImmutable(X)  /* no-op */
    +#endif /* SQLITE_DEBUG */
    +
    +
     /*
     ** This routine is called to report the final ")" that terminates
     ** a CREATE TABLE statement.
    @@ -2249,6 +2275,8 @@ void sqlite3EndTable(
           ** actually be used if PRAGMA writable_schema=ON is set. */
           sqlite3ExprListDelete(db, p->pCheck);
           p->pCheck = 0;
    +    }else{
    +      markExprListImmutable(p->pCheck);
         }
       }
     #endif /* !defined(SQLITE_OMIT_CHECK) */
    diff --git a/src/expr.c b/src/expr.c
    index 6bbefc12fb..03d58df32e 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -42,7 +42,7 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){
     ** SELECT a AS b FROM t1 WHERE b;
     ** SELECT * FROM t1 WHERE (select a from t1);
     */
    -char sqlite3ExprAffinity(Expr *pExpr){
    +char sqlite3ExprAffinity(const Expr *pExpr){
       int op;
       while( ExprHasProperty(pExpr, EP_Skip) ){
         assert( pExpr->op==TK_COLLATE );
    @@ -152,10 +152,10 @@ Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
     ** COLLATE operators take first precedence.  Left operands take
     ** precedence over right operands.
     */
    -CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
    +CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
       sqlite3 *db = pParse->db;
       CollSeq *pColl = 0;
    -  Expr *p = pExpr;
    +  const Expr *p = pExpr;
       while( p ){
         int op = p->op;
         if( op==TK_REGISTER ) op = p->op2;
    @@ -224,7 +224,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
     ** The sqlite3ExprCollSeq() routine works the same except that it
     ** returns NULL if there is no defined collation.
     */
    -CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
    +CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
       CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
       if( p==0 ) p = pParse->db->pDfltColl;
       assert( p!=0 );
    @@ -234,7 +234,7 @@ CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
     /*
     ** Return TRUE if the two expressions have equivalent collating sequences.
     */
    -int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
    +int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
       CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
       CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
       return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
    @@ -245,7 +245,7 @@ int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
     ** type affinity of the other operand.  This routine returns the
     ** type affinity that should be used for the comparison operator.
     */
    -char sqlite3CompareAffinity(Expr *pExpr, char aff2){
    +char sqlite3CompareAffinity(const Expr *pExpr, char aff2){
       char aff1 = sqlite3ExprAffinity(pExpr);
       if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
         /* Both sides of the comparison are columns. If one has numeric
    @@ -267,7 +267,7 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2){
     ** pExpr is a comparison operator.  Return the type affinity that should
     ** be applied to both operands prior to doing the comparison.
     */
    -static char comparisonAffinity(Expr *pExpr){
    +static char comparisonAffinity(const Expr *pExpr){
       char aff;
       assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
               pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
    @@ -290,7 +290,7 @@ static char comparisonAffinity(Expr *pExpr){
     ** if the index with affinity idx_affinity may be used to implement
     ** the comparison in pExpr.
     */
    -int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
    +int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){
       char aff = comparisonAffinity(pExpr);
       if( affpRight, p->pLeft);
       }else{
    @@ -594,6 +598,7 @@ static void codeVectorCompare(
       int addrDone = sqlite3VdbeMakeLabel(pParse);
       int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
     
    +  assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
       if( pParse->nErr ) return;
       if( nLeft!=sqlite3ExprVectorSize(pRight) ){
         sqlite3ErrorMsg(pParse, "row value misused");
    @@ -1206,7 +1211,7 @@ static int dupedExprStructSize(Expr *p, int flags){
         assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
         assert( !ExprHasProperty(p, EP_FromJoin) ); 
         assert( !ExprHasProperty(p, EP_MemToken) );
    -    assert( !ExprHasProperty(p, EP_NoReduce) );
    +    assert( !ExprHasVVAProperty(p, EP_NoReduce) );
         if( p->pLeft || p->x.pList ){
           nSize = EXPR_REDUCEDSIZE | EP_Reduced;
         }else{
    @@ -1311,6 +1316,10 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
         pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
         pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
         pNew->flags |= staticFlag;
    +    ExprClearVVAProperties(pNew);
    +    if( dupFlags ){
    +      ExprSetVVAProperty(pNew, EP_Immutable);
    +    }
     
         /* Copy the p->u.zToken string, if any. */
         if( nToken ){
    @@ -3171,6 +3180,7 @@ static void sqlite3ExprCodeIN(
       int addrTop;          /* Top of the step-6 loop */ 
       int iTab = 0;         /* Index to use */
     
    +  assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
       pLeft = pExpr->pLeft;
       if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
       zAff = exprINAffinity(pParse, pExpr);
    @@ -3781,6 +3791,7 @@ expr_code_doover:
       if( pExpr==0 ){
         op = TK_NULL;
       }else{
    +    assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
         op = pExpr->op;
       }
       switch( op ){
    @@ -4039,6 +4050,7 @@ expr_code_doover:
             tempX.op = TK_INTEGER;
             tempX.flags = EP_IntValue|EP_TokenOnly;
             tempX.u.iValue = 0;
    +        ExprClearVVAProperties(&tempX);
             r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1);
             r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2);
             sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
    @@ -4115,11 +4127,8 @@ expr_code_doover:
             return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
           }
           assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
    -      if( ExprHasProperty(pExpr, EP_TokenOnly) ){
    -        pFarg = 0;
    -      }else{
    -        pFarg = pExpr->x.pList;
    -      }
    +      assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
    +      pFarg = pExpr->x.pList;
           nFarg = pFarg ? pFarg->nExpr : 0;
           assert( !ExprHasProperty(pExpr, EP_IntValue) );
           zId = pExpr->u.zToken;
    @@ -4573,6 +4582,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
     void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
       int inReg;
     
    +  assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
       assert( target>0 && target<=pParse->nMem );
       inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
       assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
    @@ -4790,6 +4800,7 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
       assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
       if( NEVER(v==0) )     return;  /* Existence of VDBE checked by caller */
       if( NEVER(pExpr==0) ) return;  /* No way this can happen */
    +  assert( !ExprHasVVAProperty(pExpr, EP_Immutable) );
       op = pExpr->op;
       switch( op ){
         case TK_AND:
    @@ -4931,6 +4942,7 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
       assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
       if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
       if( pExpr==0 )    return;
    +  assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
     
       /* The value of pExpr->op and op are related as follows:
       **
    @@ -5214,7 +5226,7 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
       }
       if( (pA->flags & (EP_Distinct|EP_Commuted))
          != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
    -  if( (combinedFlags & EP_TokenOnly)==0 ){
    +  if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
         if( combinedFlags & EP_xIsSelect ) return 2;
         if( (combinedFlags & EP_FixedCol)==0
          && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
    @@ -5222,7 +5234,7 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
         if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
         if( pA->op!=TK_STRING
          && pA->op!=TK_TRUEFALSE
    -     && (combinedFlags & EP_Reduced)==0
    +     && ALWAYS((combinedFlags & EP_Reduced)==0)
         ){
           if( pA->iColumn!=pB->iColumn ) return 2;
           if( pA->op2!=pB->op2 ){
    diff --git a/src/parse.y b/src/parse.y
    index c783c6969a..c321daf195 100644
    --- a/src/parse.y
    +++ b/src/parse.y
    @@ -965,6 +965,7 @@ idlist(A) ::= nm(Y).
           p->op = (u8)op;
           p->affExpr = 0;
           p->flags = EP_Leaf;
    +      ExprClearVVAProperties(p);
           p->iAgg = -1;
           p->pLeft = p->pRight = 0;
           p->x.pList = 0;
    diff --git a/src/sqliteInt.h b/src/sqliteInt.h
    index c338dabca1..a5cf8d141d 100644
    --- a/src/sqliteInt.h
    +++ b/src/sqliteInt.h
    @@ -2594,6 +2594,9 @@ struct Expr {
                              ** TK_COLUMN: the value of p5 for OP_Column
                              ** TK_AGG_FUNCTION: nesting depth
                              ** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */
    +#ifdef SQLITE_DEBUG
    +  u8 vvaFlags;           /* Verification flags. */
    +#endif
       u32 flags;             /* Various flags.  EP_* See below */
       union {
         char *zToken;          /* Token value. Zero terminated and dequoted */
    @@ -2668,7 +2671,7 @@ struct Expr {
     #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 */
    +                  /*  0x020000 // available for reuse */
     #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 */
    @@ -2682,6 +2685,7 @@ struct Expr {
     #define EP_IsTrue   0x10000000 /* Always has boolean value of TRUE */
     #define EP_IsFalse  0x20000000 /* Always has boolean value of FALSE */
     #define EP_FromDDL  0x40000000 /* Originates from sqlite_master */
    +               /*   0x80000000 // Available */
     
     /*
     ** The EP_Propagate mask is a set of properties that automatically propagate
    @@ -2700,14 +2704,24 @@ struct Expr {
     #define ExprAlwaysTrue(E)   (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
     #define ExprAlwaysFalse(E)  (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
     
    +
    +/* Flags for use with Expr.vvaFlags
    +*/
    +#define EP_NoReduce   0x01  /* Cannot EXPRDUP_REDUCE this Expr */
    +#define EP_Immutable  0x02  /* Do not change this Expr node */
    +
     /* The ExprSetVVAProperty() macro is used for Verification, Validation,
     ** and Accreditation only.  It works like ExprSetProperty() during VVA
     ** processes but is a no-op for delivery.
     */
     #ifdef SQLITE_DEBUG
    -# define ExprSetVVAProperty(E,P)  (E)->flags|=(P)
    +# define ExprSetVVAProperty(E,P)   (E)->vvaFlags|=(P)
    +# define ExprHasVVAProperty(E,P)   (((E)->vvaFlags&(P))!=0)
    +# define ExprClearVVAProperties(E) (E)->vvaFlags = 0
     #else
     # define ExprSetVVAProperty(E,P)
    +# define ExprHasVVAProperty(E,P)   0
    +# define ExprClearVVAProperties(E)
     #endif
     
     /*
    @@ -4439,10 +4453,10 @@ int sqlite3VarintLen(u64 v);
     
     const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
     void sqlite3TableAffinity(Vdbe*, Table*, int);
    -char sqlite3CompareAffinity(Expr *pExpr, char aff2);
    -int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
    +char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
    +int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
     char sqlite3TableColumnAffinity(Table*,int);
    -char sqlite3ExprAffinity(Expr *pExpr);
    +char sqlite3ExprAffinity(const Expr *pExpr);
     int sqlite3Atoi64(const char*, i64*, int, u8);
     int sqlite3DecOrHexToI64(const char*, i64*);
     void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
    @@ -4466,9 +4480,9 @@ CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
     int sqlite3IsBinary(const CollSeq*);
     CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
     void sqlite3SetTextEncoding(sqlite3 *db, u8);
    -CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
    -CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
    -int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
    +CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr);
    +CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr);
    +int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*);
     Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
     Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
     Expr *sqlite3ExprSkipCollate(Expr*);
    @@ -4699,8 +4713,8 @@ char *sqlite3Normalize(Vdbe*, const char*);
     #endif
     int sqlite3Reprepare(Vdbe*);
     void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
    -CollSeq *sqlite3ExprCompareCollSeq(Parse*,Expr*);
    -CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
    +CollSeq *sqlite3ExprCompareCollSeq(Parse*,const Expr*);
    +CollSeq *sqlite3BinaryCompareCollSeq(Parse *, const Expr*, const Expr*);
     int sqlite3TempInMemory(const sqlite3*);
     const char *sqlite3JournalModename(int);
     #ifndef SQLITE_OMIT_WAL
    diff --git a/src/treeview.c b/src/treeview.c
    index 90a1d2dcc9..2d9da55077 100644
    --- a/src/treeview.c
    +++ b/src/treeview.c
    @@ -398,14 +398,14 @@ void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
     void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
       const char *zBinOp = 0;   /* Binary operator */
       const char *zUniOp = 0;   /* Unary operator */
    -  char zFlgs[60];
    +  char zFlgs[200];
       pView = sqlite3TreeViewPush(pView, moreToFollow);
       if( pExpr==0 ){
         sqlite3TreeViewLine(pView, "nil");
         sqlite3TreeViewPop(pView);
         return;
       }
    -  if( pExpr->flags || pExpr->affExpr ){
    +  if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
         StrAccum x;
         sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
         sqlite3_str_appendf(&x, " fg.af=%x.%c",
    @@ -416,6 +416,9 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
         if( ExprHasProperty(pExpr, EP_FromDDL) ){
           sqlite3_str_appendf(&x, " DDL");
         }
    +    if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
    +      sqlite3_str_appendf(&x, " IMMUTABLE");
    +    }
         sqlite3StrAccumFinish(&x);
       }else{
         zFlgs[0] = 0;
    @@ -522,6 +525,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
         case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
         case TK_CONCAT:  zBinOp = "CONCAT"; break;
         case TK_DOT:     zBinOp = "DOT";    break;
    +    case TK_LIMIT:   zBinOp = "LIMIT";  break;
     
         case TK_UMINUS:  zUniOp = "UMINUS"; break;
         case TK_UPLUS:   zUniOp = "UPLUS";  break;
    
    From 8d5cea6b61c30dd839a32e253bf7ae241b5662f4 Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Wed, 11 Mar 2020 02:04:15 +0000
    Subject: [PATCH 061/102] This variant to the fix for ticket [e0c2ad1aa8a9c691]
     uses fewer CPU cycles.
    
    FossilOrigin-Name: fb5a8a9edd0a4f979d6c30278d4ddc73c651f56ae989b4e5983fca36887c5ceb
    ---
     manifest      | 12 ++++++------
     manifest.uuid |  2 +-
     src/expr.c    |  9 +++++++--
     3 files changed, 14 insertions(+), 9 deletions(-)
    
    diff --git a/manifest b/manifest
    index 06cd979aa0..9ee146f83d 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Enhanced\sdetection\slogic\sfor\spreventing\sthe\suse\sof\sstatic\sschema\sexpressions\nby\scode\sgenerating\sroutines.
    -D 2020-03-10T19:24:38.960
    +C This\svariant\sto\sthe\sfix\sfor\sticket\s[e0c2ad1aa8a9c691]\suses\sfewer\sCPU\scycles.
    +D 2020-03-11T02:04:15.678
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
     F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
     F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
     F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
    -F src/expr.c 117997508b41b1d02b4c376bdca16da04e813c0f36d0811e3ea13d1c786f53f4
    +F src/expr.c cddb6c7ccdb856338c189c8cc15bd95dd60e596e4bb5a1c8ba86726b49857581
     F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
     F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
     F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
    @@ -1860,7 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P f45f5de000834da5b23cdcf12c3f0e3073287756afe06bdb77b95fb65b250258
    -R f078265eb0d8f8487aa3c2a1c341660a
    +P 5f60b527b938c0778e8f725c635ce0dc5ed7a4e01fd6252aa2cdb64da2f625bc
    +R 37bce3d92e4cf86464a6bfb5a7dc2299
     U drh
    -Z 1d0ba7c8bbe7247314d90dba25e45a8e
    +Z 0b4099ba8ff5f2f0e887def300e748c2
    diff --git a/manifest.uuid b/manifest.uuid
    index c22469d699..0b01cdc6f0 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -5f60b527b938c0778e8f725c635ce0dc5ed7a4e01fd6252aa2cdb64da2f625bc
    \ No newline at end of file
    +fb5a8a9edd0a4f979d6c30278d4ddc73c651f56ae989b4e5983fca36887c5ceb
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index 03d58df32e..cf52c5c754 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -3805,8 +3805,13 @@ expr_code_doover:
             Table *pTab = pCol->pTab;
             sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
                                   pCol->iSorterColumn, target);
    -        if( ALWAYS(pTab) && pCol->iColumn>=0 ){
    -          sqlite3ColumnDefault(v, pTab, pCol->iColumn, target);
    +        if( pCol->iColumn<0 ){
    +          VdbeComment((v,"%s.rowid",pTab->zName));
    +        }else{
    +          VdbeComment((v,"%s.%s",pTab->zName,pTab->aCol[pCol->iColumn].zName));
    +          if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
    +            sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
    +          }
             }
             return target;
           }
    
    From 38dfbdae8a61dd16987d93a6a4bfe0001eab7b3d Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Wed, 11 Mar 2020 17:58:27 +0000
    Subject: [PATCH 062/102] Do not factor out constant functions into the
     initialization section at the end of the prepared statement, be cause if they
     throw an exception, it will abort the statement even if the function is never
     called.  Better to put constant functions in an OP_Once block.
    
    FossilOrigin-Name: 97a18a5cd701848a9660385e31bffe2c397e3cfe57ccdb876f44d08c00d1d39a
    ---
     manifest        | 19 +++++++++++--------
     manifest.uuid   |  2 +-
     src/expr.c      | 28 +++++++++++++++++++++-------
     src/vtab.c      |  2 +-
     test/func5.test |  3 ++-
     5 files changed, 36 insertions(+), 18 deletions(-)
    
    diff --git a/manifest b/manifest
    index 9ee146f83d..11b5b9c942 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C This\svariant\sto\sthe\sfix\sfor\sticket\s[e0c2ad1aa8a9c691]\suses\sfewer\sCPU\scycles.
    -D 2020-03-11T02:04:15.678
    +C Do\snot\sfactor\sout\sconstant\sfunctions\sinto\sthe\sinitialization\ssection\sat\sthe\nend\sof\sthe\sprepared\sstatement,\sbe\scause\sif\sthey\sthrow\san\sexception,\sit\swill\nabort\sthe\sstatement\seven\sif\sthe\sfunction\sis\snever\scalled.\s\sBetter\sto\sput\nconstant\sfunctions\sin\san\sOP_Once\sblock.
    +D 2020-03-11T17:58:27.142
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
     F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
     F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
     F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
    -F src/expr.c cddb6c7ccdb856338c189c8cc15bd95dd60e596e4bb5a1c8ba86726b49857581
    +F src/expr.c 137db48827025f68792824eaf8e4c66612dbd160cf5cafe6ae93b27eed101e12
     F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
     F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
     F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
    @@ -612,7 +612,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b
     F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22
     F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
     F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
    -F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515
    +F src/vtab.c ad810f9b771cf66eee2762e18eb2b704c97c18ca4b4bf25af7f88ab1fb254d14
     F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
     F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc
     F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
    @@ -1007,7 +1007,7 @@ F test/func.test b7f1a706d1bb8de103a24bd0c30c9e3dc3eedf0df24aabc54b0a4f6e0874262
     F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
     F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
     F test/func4.test a94858a8c1f10a408b0b3db439c990b59dbb2349411d503de011ac4e2b5f27a6
    -F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4
    +F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a
     F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c
     F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa
     F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1
    @@ -1860,7 +1860,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 5f60b527b938c0778e8f725c635ce0dc5ed7a4e01fd6252aa2cdb64da2f625bc
    -R 37bce3d92e4cf86464a6bfb5a7dc2299
    +P fb5a8a9edd0a4f979d6c30278d4ddc73c651f56ae989b4e5983fca36887c5ceb
    +R cf3e121998a086e24f73b7daa3777948
    +T *branch * do-not-factor-functions
    +T *sym-do-not-factor-functions *
    +T -sym-trunk *
     U drh
    -Z 0b4099ba8ff5f2f0e887def300e748c2
    +Z 4a780ea0d068b9c3f4aeae83f545f604
    diff --git a/manifest.uuid b/manifest.uuid
    index 0b01cdc6f0..3625ef547a 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -fb5a8a9edd0a4f979d6c30278d4ddc73c651f56ae989b4e5983fca36887c5ceb
    \ No newline at end of file
    +97a18a5cd701848a9660385e31bffe2c397e3cfe57ccdb876f44d08c00d1d39a
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index cf52c5c754..8c0768bb7e 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -4532,15 +4532,29 @@ int sqlite3ExprCodeAtInit(
           }
         }
       }
    +  if( regDest<0 ) regDest = ++pParse->nMem;
       pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
    -  p = sqlite3ExprListAppend(pParse, p, pExpr);
    -  if( p ){
    -     struct ExprList_item *pItem = &p->a[p->nExpr-1];
    -     pItem->reusable = regDest<0;
    -     if( regDest<0 ) regDest = ++pParse->nMem;
    -     pItem->u.iConstExprReg = regDest;
    +  if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
    +    Vdbe *v = pParse->pVdbe;
    +    int addr;
    +    assert( v );
    +    addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
    +    pParse->okConstFactor = 0;
    +    if( !pParse->db->mallocFailed ){
    +      sqlite3ExprCode(pParse, pExpr, regDest);
    +    }
    +    pParse->okConstFactor = 1;
    +    sqlite3ExprDelete(pParse->db, pExpr);
    +    sqlite3VdbeJumpHere(v, addr);
    +  }else{
    +    p = sqlite3ExprListAppend(pParse, p, pExpr);
    +    if( p ){
    +       struct ExprList_item *pItem = &p->a[p->nExpr-1];
    +       pItem->reusable = regDest<0;
    +       pItem->u.iConstExprReg = regDest;
    +    }
    +    pParse->pConstExpr = p;
       }
    -  pParse->pConstExpr = p;
       return regDest;
     }
     
    diff --git a/src/vtab.c b/src/vtab.c
    index 013511cfb4..6a30f83a91 100644
    --- a/src/vtab.c
    +++ b/src/vtab.c
    @@ -1113,7 +1113,7 @@ FuncDef *sqlite3VtabOverloadFunction(
       int rc = 0;
     
       /* Check to see the left operand is a column in a virtual table */
    -  if( NEVER(pExpr==0) ) return pDef;
    +  if( pExpr==0 ) return pDef;
       if( pExpr->op!=TK_COLUMN ) return pDef;
       pTab = pExpr->y.pTab;
       if( pTab==0 ) return pDef;
    diff --git a/test/func5.test b/test/func5.test
    index bfd545b4e3..8c3dd05c60 100644
    --- a/test/func5.test
    +++ b/test/func5.test
    @@ -53,9 +53,10 @@ do_execsql_test func5-2.2 {
        WHERE x+counter1('hello')=counter1('hello')+x
        ORDER BY +x;
     } {}
    +set cvalue [db one {SELECT counter2('hello')+1}]
     do_execsql_test func5-2.3 {
       SELECT x, y FROM t2
    -   WHERE x+counter2('hello')=counter2('hello')+x
    +   WHERE x+counter2('hello')=$cvalue+x
        ORDER BY +x;
     } {1 2 3 4 5 6 7 8}
     
    
    From 9b258c54e453edb5c8c81c3d28b2cb6e2b76a13e Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Wed, 11 Mar 2020 19:41:49 +0000
    Subject: [PATCH 063/102] Rename sqlite3ExprCodeAtInit() to
     sqlite3ExprCodeRunJustOnce(). Other changes to make the new code cleaner. 
     Test cases added.
    
    FossilOrigin-Name: d7f18489978fdbbe3ab317485518cac91a75416ccef55898301afdd76d3b415b
    ---
     manifest        | 23 ++++++++++-------------
     manifest.uuid   |  2 +-
     src/expr.c      | 49 ++++++++++++++++++++++---------------------------
     src/sqliteInt.h |  2 +-
     src/vdbe.c      |  1 -
     src/vtab.c      |  2 +-
     test/func.test  | 20 ++++++++++++++++++++
     7 files changed, 55 insertions(+), 44 deletions(-)
    
    diff --git a/manifest b/manifest
    index 11b5b9c942..b990d901bd 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Do\snot\sfactor\sout\sconstant\sfunctions\sinto\sthe\sinitialization\ssection\sat\sthe\nend\sof\sthe\sprepared\sstatement,\sbe\scause\sif\sthey\sthrow\san\sexception,\sit\swill\nabort\sthe\sstatement\seven\sif\sthe\sfunction\sis\snever\scalled.\s\sBetter\sto\sput\nconstant\sfunctions\sin\san\sOP_Once\sblock.
    -D 2020-03-11T17:58:27.142
    +C Rename\ssqlite3ExprCodeAtInit()\sto\ssqlite3ExprCodeRunJustOnce().\nOther\schanges\sto\smake\sthe\snew\scode\scleaner.\s\sTest\scases\sadded.
    +D 2020-03-11T19:41:49.390
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -483,7 +483,7 @@ F src/date.c 6c408fdd2e9ddf6e8431aba76315a2d061bea2cec8fbb75e25d7c1ba08274712
     F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
     F src/dbstat.c 0f55297469d4244ab7df395849e1af98eb5e95816af7c661e7d2d8402dea23da
     F src/delete.c 11000121c4281c0bce4e41db29addfaea0038eaa127ece02557c9207bc3e541d
    -F src/expr.c 137db48827025f68792824eaf8e4c66612dbd160cf5cafe6ae93b27eed101e12
    +F src/expr.c ed718ee2206166c9c2fc4fe89eadb1f369318aeb8645e06033566b387970fb9a
     F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
     F src/fkey.c 4b575423b0a5d4898b1a7868ce985cf1a8ad91c741c9abbb108ff02536d20f41
     F src/func.c 108577cebe8a50c86d849a93b99493a54e348dd0b846f00d13b52ca973d5baf4
    @@ -536,7 +536,7 @@ F src/shell.c.in f76590931c0cbbfef347f44f81ade6b335f80c46bc6e59b8b6114383a8df30e
     F src/sqlite.h.in 802957feeb249ede54f8dfe99b72aa19e70a0b7737969c46e625dc2f9f2d42b0
     F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
     F src/sqlite3ext.h 9c5269260409eb3275324ccace6a13a96f4ad330c708415f70ca6097901ff4ee
    -F src/sqliteInt.h ed6885bb0ec82db2503c931fd96c795fc7a4b474dc075c3442a45c3a8523c797
    +F src/sqliteInt.h 5f74c1c52b152259ee07f241821620f11736e4f590936cfaf1cbbff9a2f563d3
     F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
     F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
     F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
    @@ -603,7 +603,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
     F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
     F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a
     F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9
    -F src/vdbe.c 8ad7906cf9aca841b97064fbf62323f53aaf8e4f8251ffa5e152abc5bda806d3
    +F src/vdbe.c 6d0cf7ac2d54f78ff2fb55cbef970199695319c0a95bf862c6561d7d2c9f7134
     F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9
     F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051
     F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
    @@ -612,7 +612,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b
     F src/vdbemem.c 39b942ecca179f4f30a32b54579a85d74ccaefa5af2a0ad2700abe5ef0768b22
     F src/vdbesort.c 2be76d26998ce2b3324cdcc9f6443728e54b6c7677c553ad909c7d7cfab587df
     F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0
    -F src/vtab.c ad810f9b771cf66eee2762e18eb2b704c97c18ca4b4bf25af7f88ab1fb254d14
    +F src/vtab.c 7b704a90515a239c6cdba6a66b1bb3a385e62326cceb5ecb05ec7a091d6b8515
     F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
     F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc
     F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
    @@ -1003,7 +1003,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 b7f1a706d1bb8de103a24bd0c30c9e3dc3eedf0df24aabc54b0a4f6e08742622
    +F test/func.test f673822636fb8ed618dd2b80230d16e495d19c8f2e2e7d6c22e93e2b3de097ad
     F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
     F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6
     F test/func4.test a94858a8c1f10a408b0b3db439c990b59dbb2349411d503de011ac4e2b5f27a6
    @@ -1860,10 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P fb5a8a9edd0a4f979d6c30278d4ddc73c651f56ae989b4e5983fca36887c5ceb
    -R cf3e121998a086e24f73b7daa3777948
    -T *branch * do-not-factor-functions
    -T *sym-do-not-factor-functions *
    -T -sym-trunk *
    +P 97a18a5cd701848a9660385e31bffe2c397e3cfe57ccdb876f44d08c00d1d39a
    +R bb18f5b4c4c1d8067c8d33e0ad339acb
     U drh
    -Z 4a780ea0d068b9c3f4aeae83f545f604
    +Z 791b16818e473b4676673e9f9494706b
    diff --git a/manifest.uuid b/manifest.uuid
    index 3625ef547a..9e7309105a 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -97a18a5cd701848a9660385e31bffe2c397e3cfe57ccdb876f44d08c00d1d39a
    \ No newline at end of file
    +d7f18489978fdbbe3ab317485518cac91a75416ccef55898301afdd76d3b415b
    \ No newline at end of file
    diff --git a/src/expr.c b/src/expr.c
    index 8c0768bb7e..8587f5ec78 100644
    --- a/src/expr.c
    +++ b/src/expr.c
    @@ -2096,7 +2096,7 @@ int sqlite3ExprIsConstant(Expr *p){
     **
     ** When this routine returns true, it indicates that the expression
     ** can be added to the pParse->pConstExpr list and evaluated once when
    -** the prepared statement starts up.  See sqlite3ExprCodeAtInit().
    +** the prepared statement starts up.  See sqlite3ExprCodeRunJustOnce().
     */
     int sqlite3ExprIsConstantNotJoin(Expr *p){
       return exprIsConst(p, 2, 0);
    @@ -4127,9 +4127,9 @@ expr_code_doover:
     #endif
     
           if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
    -        /* SQL functions can be expensive. So try to move constant functions
    -        ** out of the inner loop, even if that means an extra OP_Copy. */
    -        return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
    +        /* SQL functions can be expensive. So try to avoid running them
    +        ** multiple times if we know they always give the same result */
    +        return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
           }
           assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
           assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
    @@ -4507,15 +4507,23 @@ expr_code_doover:
     }
     
     /*
    -** Factor out the code of the given expression to initialization time.
    +** Generate code that will evaluate expression pExpr just one time
    +** per prepared statement execution.
    +**
    +** If the expression uses functions (that might throw an exception) then
    +** guard them with an OP_Once opcode to ensure that the code is only executed
    +** once. If no functions are involved, then factor the code out and put it at
    +** the end of the prepared statement in the initialization section.
     **
     ** If regDest>=0 then the result is always stored in that register and the
     ** result is not reusable.  If regDest<0 then this routine is free to 
     ** store the value whereever it wants.  The register where the expression 
    -** is stored is returned.  When regDest<0, two identical expressions will
    -** code to the same register.
    +** is stored is returned.  When regDest<0, two identical expressions might
    +** code to the same register, if they do not contain function calls and hence
    +** are factored out into the initialization section at the end of the
    +** prepared statement.
     */
    -int sqlite3ExprCodeAtInit(
    +int sqlite3ExprCodeRunJustOnce(
       Parse *pParse,    /* Parsing context */
       Expr *pExpr,      /* The expression to code when the VDBE initializes */
       int regDest       /* Store the value in this register */
    @@ -4532,7 +4540,6 @@ int sqlite3ExprCodeAtInit(
           }
         }
       }
    -  if( regDest<0 ) regDest = ++pParse->nMem;
       pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
       if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
         Vdbe *v = pParse->pVdbe;
    @@ -4541,6 +4548,7 @@ int sqlite3ExprCodeAtInit(
         addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
         pParse->okConstFactor = 0;
         if( !pParse->db->mallocFailed ){
    +      if( regDest<0 ) regDest = ++pParse->nMem;
           sqlite3ExprCode(pParse, pExpr, regDest);
         }
         pParse->okConstFactor = 1;
    @@ -4551,6 +4559,7 @@ int sqlite3ExprCodeAtInit(
         if( p ){
            struct ExprList_item *pItem = &p->a[p->nExpr-1];
            pItem->reusable = regDest<0;
    +       if( regDest<0 ) regDest = ++pParse->nMem;
            pItem->u.iConstExprReg = regDest;
         }
         pParse->pConstExpr = p;
    @@ -4579,7 +4588,7 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
        && sqlite3ExprIsConstantNotJoin(pExpr)
       ){
         *pReg  = 0;
    -    r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
    +    r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
       }else{
         int r1 = sqlite3GetTempReg(pParse);
         r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
    @@ -4636,7 +4645,7 @@ void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
     */
     void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
       if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
    -    sqlite3ExprCodeAtInit(pParse, pExpr, target);
    +    sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
       }else{
         sqlite3ExprCodeCopy(pParse, pExpr, target);
       }
    @@ -4696,7 +4705,7 @@ int sqlite3ExprCodeExprList(
         }else if( (flags & SQLITE_ECEL_FACTOR)!=0
                && sqlite3ExprIsConstantNotJoin(pExpr)
         ){
    -      sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
    +      sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
         }else{
           int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
           if( inReg!=target+i ){
    @@ -5256,21 +5265,7 @@ int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){
          && ALWAYS((combinedFlags & EP_Reduced)==0)
         ){
           if( pA->iColumn!=pB->iColumn ) return 2;
    -      if( pA->op2!=pB->op2 ){
    -        if( pA->op==TK_TRUTH ) return 2;
    -        if( pA->op==TK_FUNCTION && iTab<0 ){
    -          /* Ex: CREATE TABLE t1(a CHECK( aop2!=pB->op2 && pA->op==TK_TRUTH ) return 2;
           if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
             return 2;
           }
    diff --git a/src/sqliteInt.h b/src/sqliteInt.h
    index a5cf8d141d..7a00b576a0 100644
    --- a/src/sqliteInt.h
    +++ b/src/sqliteInt.h
    @@ -4239,7 +4239,7 @@ void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int);
     #endif
     void sqlite3ExprCodeCopy(Parse*, Expr*, int);
     void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
    -int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
    +int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int);
     int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
     int sqlite3ExprCodeTarget(Parse*, Expr*, int);
     int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
    diff --git a/src/vdbe.c b/src/vdbe.c
    index 8501e7319e..a69c35d83a 100644
    --- a/src/vdbe.c
    +++ b/src/vdbe.c
    @@ -1544,7 +1544,6 @@ case OP_Concat: {           /* same as TK_CONCAT, in1, in2, out3 */
       pIn1 = &aMem[pOp->p1];
       pIn2 = &aMem[pOp->p2];
       pOut = &aMem[pOp->p3];
    -  testcase( pIn1==pIn2 );
       testcase( pOut==pIn2 );
       assert( pIn1!=pOut );
       flags1 = pIn1->flags;
    diff --git a/src/vtab.c b/src/vtab.c
    index 6a30f83a91..013511cfb4 100644
    --- a/src/vtab.c
    +++ b/src/vtab.c
    @@ -1113,7 +1113,7 @@ FuncDef *sqlite3VtabOverloadFunction(
       int rc = 0;
     
       /* Check to see the left operand is a column in a virtual table */
    -  if( pExpr==0 ) return pDef;
    +  if( NEVER(pExpr==0) ) return pDef;
       if( pExpr->op!=TK_COLUMN ) return pDef;
       pTab = pExpr->y.pTab;
       if( pTab==0 ) return pDef;
    diff --git a/test/func.test b/test/func.test
    index 34a6f18bcf..4b235bedb4 100644
    --- a/test/func.test
    +++ b/test/func.test
    @@ -1477,4 +1477,24 @@ do_execsql_test func-34.10 {
       SELECT * FROM t1;
     } {1 2}
     
    +# 2020-03-11 COALESCE() should short-circuit
    +# See also ticket 3c9eadd2a6ba0aa5
    +# Both issues stem from the fact that functions that could
    +# throw exceptions were being factored out into initialization
    +# code.  The fix was to put those function calls inside of
    +# OP_Once instead.
    +#
    +reset_db
    +do_execsql_test func-35.100 {
    +  CREATE TABLE t1(x);
    +  SELECT coalesce(x, abs(-9223372036854775808)) FROM t1;
    +} {}
    +do_execsql_test func-35.110 {
    +  SELECT coalesce(x, 'xyz' LIKE printf('%.1000000c','y')) FROM t1;
    +} {}
    +do_execsql_test func-35.200 {
    +  CREATE TABLE t0(c0 CHECK(ABS(-9223372036854775808)));
    +  PRAGMA integrity_check;
    +} {ok}
    +
     finish_test
    
    From 576d0a9fd9d43d602d9d9a57ade48a5187f4d96c Mon Sep 17 00:00:00 2001
    From: drh 
    Date: Thu, 12 Mar 2020 17:28:27 +0000
    Subject: [PATCH 064/102] Fix comments and strengthen assert() statements
     associated with the OPFLAG_SEEKEQ and BTREE_SEEK_EQ flags.
    
    FossilOrigin-Name: 231749213854756b599b33413b17b35186f17889b0c73f109fa9db726b415558
    ---
     manifest      | 15 +++++++--------
     manifest.uuid |  2 +-
     src/vdbe.c    | 43 ++++++++++++++++++++++++-------------------
     src/where.c   |  4 ++--
     4 files changed, 34 insertions(+), 30 deletions(-)
    
    diff --git a/manifest b/manifest
    index dd6de47492..f3531e60ad 100644
    --- a/manifest
    +++ b/manifest
    @@ -1,5 +1,5 @@
    -C Do\snot\sfactor\sout\sconstant\sfunctions\sinto\sthe\sinitialization\ssection\sof\sa\nprepared\sstatement,\sbecause\seven\sthough\sthey\sare\sconstant,\sthey\scan\sstill\nthrow\sexceptions.\s\sInstead,\sput\ssuch\sfunctions\sin\san\sOP_Once\sblock.\s\sThis\nfixes\sticket\s[3c9eadd2a6ba0aa5]\sand\scauses\sCOALESCE()\sand\sCASE...END\sto\nbe\sshort-circuit.
    -D 2020-03-11T19:56:26.290
    +C Fix\scomments\sand\sstrengthen\sassert()\sstatements\sassociated\swith\sthe\nOPFLAG_SEEKEQ\sand\sBTREE_SEEK_EQ\sflags.
    +D 2020-03-12T17:28:27.168
     F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
     F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
     F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
    @@ -603,7 +603,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
     F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
     F src/util.c a285c1e026907b69fa2592bd05047a565a1d8a1aef2b73c924b6a8ffe772871a
     F src/vacuum.c 813b510ba887fee6492bcb11f2bf77d7eb58b232b83649136372e0a2fc17f4b9
    -F src/vdbe.c 6d0cf7ac2d54f78ff2fb55cbef970199695319c0a95bf862c6561d7d2c9f7134
    +F src/vdbe.c c1c123c6248fa88940b932a00bcc75056921b6d046d45a82566cb97415d2299c
     F src/vdbe.h 51282fbe819ee0e8eeeaab176240860d334c20a12b14f3b363e7f1a4e05d60b9
     F src/vdbeInt.h a17146053a1aa438474012998fe07e314f3df274a61491ad838ad85d848ac051
     F src/vdbeapi.c 1252d80c548711e47a6d84dae88ed4e95d3fbb4e7bd0eaa1347299af7efddf02
    @@ -617,7 +617,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
     F src/wal.c 697424314e40d99f93f548c7bfa526c10e87f4bdf64d5a76a96b999dd7133ebc
     F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a
     F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d
    -F src/where.c 3b8c9bd013eb0736e16f60bdc109e83337ef99513a3aff5f16ddac036e6c277e
    +F src/where.c 8e4283542574f7586d84673692d36c2d6f4bc323f7427c21d791946737842dbf
     F src/whereInt.h 6b874aa15f94e43a2cec1080be64d955b04deeafeac90ffb5d6975c0d511be3c
     F src/wherecode.c 7b939de85d65cc4b4bfa197513136b9e0ae03167e3b82842ca5a0ba1055ba65d
     F src/whereexpr.c 264d58971eaf8256eb5b0917bcd7fc7a1f1109fdda183a8382308a1b18a2dce7
    @@ -1860,8 +1860,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
     F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
     F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
     F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
    -P fb5a8a9edd0a4f979d6c30278d4ddc73c651f56ae989b4e5983fca36887c5ceb d7f18489978fdbbe3ab317485518cac91a75416ccef55898301afdd76d3b415b
    -R bb18f5b4c4c1d8067c8d33e0ad339acb
    -T +closed d7f18489978fdbbe3ab317485518cac91a75416ccef55898301afdd76d3b415b
    +P c5f96a085db9688a09793f52ce1ecf033c2e6e2e5873a19fe0fb374b242b317f
    +R b4d34578c5e19c108e63249f3f407b58
     U drh
    -Z 0612eee0f98137a25a8377c8a68a78fc
    +Z 3512687e2725ca4d1f170ef6f945b212
    diff --git a/manifest.uuid b/manifest.uuid
    index 0b3dd1b4d9..8b72fe2d1b 100644
    --- a/manifest.uuid
    +++ b/manifest.uuid
    @@ -1 +1 @@
    -c5f96a085db9688a09793f52ce1ecf033c2e6e2e5873a19fe0fb374b242b317f
    \ No newline at end of file
    +231749213854756b599b33413b17b35186f17889b0c73f109fa9db726b415558
    \ No newline at end of file
    diff --git a/src/vdbe.c b/src/vdbe.c
    index a69c35d83a..7f05328660 100644
    --- a/src/vdbe.c
    +++ b/src/vdbe.c
    @@ -3664,7 +3664,7 @@ case OP_SetCookie: {
     ** 
      **
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for ** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT -** of OP_SeekLE/OP_IdxGT) +** of OP_SeekLE/OP_IdxLT) **
    ** ** The P4 value may be either an integer (P4_INT32) or a pointer to @@ -3694,7 +3694,7 @@ case OP_SetCookie: { **
      **
    • 0x02 OPFLAG_SEEKEQ: This cursor will only be used for ** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT -** of OP_SeekLE/OP_IdxGT) +** of OP_SeekLE/OP_IdxLT) **
    ** ** See also: OP_OpenRead, OP_OpenWrite @@ -3718,7 +3718,7 @@ case OP_SetCookie: { **