From 8abc80b2945b7133eee896092643d259410c048c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Aug 2017 01:09:06 +0000 Subject: [PATCH 01/53] Size and performance micro-optimization on sqlite3SrcListIndexedBy(). FossilOrigin-Name: 28a5aec118f9d078c9e7225f85cd48a91920b13908c540771e309557c3f15f84 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 8 +++++--- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e3348517c5..10e55ba5d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompiler\swarnings\sthat\sarise\sif\sthe\sPAGERTRACE\smacro\sis\sturned\son.\nThis\schanges\sdoes\snot\saffect\sproduction\sbuilds. -D 2017-08-11T18:59:00.035 +C Size\sand\sperformance\smicro-optimization\son\ssqlite3SrcListIndexedBy(). +D 2017-08-12T01:09:06.103 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -399,7 +399,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 1a17ba1a765d80c3ca39ce33ff55f92e1f51eb84bbbdab5377f11d36b1515fa1 F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 -F src/build.c 33b0f6055bd990ed052b96e71368acefcd98daa21ccf21f91aa90e8b769c2219 +F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc F src/callback.c 930648a084a3adc741c6471adfbdc50ba47ba3542421cb80a26f259f467de65e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 @@ -1646,7 +1646,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 aa49926dbffaae4f7c486be72ad814f381cca65c549f9d2605f47540a5f4be84 -R d8063074df6e7dea7a8298073c2e62a5 +P 831156a4bd7c4408085f7c5584cdeebd1953c539972f80c5ef29bc147008630e +R 34a870a8db0fd3ad276f368e06b50630 U drh -Z 445b2c6d99e984c3a2a0aca154b718db +Z 3aa22be27e86e8143572e422fdd4e2d3 diff --git a/manifest.uuid b/manifest.uuid index ddc6bd32ec..e16faf1fed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -831156a4bd7c4408085f7c5584cdeebd1953c539972f80c5ef29bc147008630e \ No newline at end of file +28a5aec118f9d078c9e7225f85cd48a91920b13908c540771e309557c3f15f84 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 074041b3f0..cb3172e076 100644 --- a/src/build.c +++ b/src/build.c @@ -3883,8 +3883,10 @@ SrcList *sqlite3SrcListAppendFromTerm( */ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ assert( pIndexedBy!=0 ); - if( p && ALWAYS(p->nSrc>0) ){ - struct SrcList_item *pItem = &p->a[p->nSrc-1]; + if( p && pIndexedBy->n>0 ){ + struct SrcList_item *pItem; + assert( p->nSrc>0 ); + pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); assert( pItem->fg.isTabFunc==0 ); @@ -3894,7 +3896,7 @@ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ pItem->fg.notIndexed = 1; }else{ pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); - pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0); + pItem->fg.isIndexedBy = 1; } } } From 3f18e6d7a93d36ec7a3b29054f0bd7c1d85d64e9 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Aug 2017 02:01:55 +0000 Subject: [PATCH 02/53] Remove the zBase field from the StrAccum object. Resulting code is slightly smaller and faster. FossilOrigin-Name: 6e52fa5fd79988a433bae0152ceae036edab4bb18d2b48ed04c1f53f141728b0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/printf.c | 19 ++++++++----------- src/sqliteInt.h | 3 +-- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 10e55ba5d4..126340c6aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\sand\sperformance\smicro-optimization\son\ssqlite3SrcListIndexedBy(). -D 2017-08-12T01:09:06.103 +C Remove\sthe\szBase\sfield\sfrom\sthe\sStrAccum\sobject.\s\sResulting\scode\sis\sslightly\nsmaller\sand\sfaster. +D 2017-08-12T02:01:55.477 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -449,7 +449,7 @@ F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/prepare.c 3cbb99757d7295997674972f9dd2331c5c544368854ca08954c9beb1e9b6145a -F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 +F src/printf.c 439c145d71ff9e0328ec26b7db23a45f995f742d3207dd546e034cdc1667ac9c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -459,7 +459,7 @@ F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c17 F src/sqlite.h.in 72f1775c7a134f9e358eedafe1ebc703c28b0d705d976464ddbf6a9219448952 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 -F src/sqliteInt.h 07e4d3c8021aea80e3bbafab4dd52833cfcfa4f000210af0d15c7fdaed2f09fc +F src/sqliteInt.h 5e3c160c1e97568d72a5b2b755cd899d32a96f43a2a58eb18ad83da33b77a0cb F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1646,7 +1646,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 831156a4bd7c4408085f7c5584cdeebd1953c539972f80c5ef29bc147008630e -R 34a870a8db0fd3ad276f368e06b50630 +P 28a5aec118f9d078c9e7225f85cd48a91920b13908c540771e309557c3f15f84 +R c12bc93088f8c532a7cb23532de2f4c4 U drh -Z 3aa22be27e86e8143572e422fdd4e2d3 +Z fd24d8fda45b9e8f917fec0b522deb6b diff --git a/manifest.uuid b/manifest.uuid index e16faf1fed..887a009764 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -28a5aec118f9d078c9e7225f85cd48a91920b13908c540771e309557c3f15f84 \ No newline at end of file +6e52fa5fd79988a433bae0152ceae036edab4bb18d2b48ed04c1f53f141728b0 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index a14e658875..49b13cc4f5 100644 --- a/src/printf.c +++ b/src/printf.c @@ -782,7 +782,6 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ }else{ char *zOld = isMalloced(p) ? p->zText : 0; i64 szNew = p->nChar; - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); szNew += N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, @@ -824,7 +823,6 @@ void sqlite3AppendChar(StrAccum *p, int N, char c){ if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ return; } - assert( (p->zText==p->zBase)==!isMalloced(p) ); while( (N--)>0 ) p->zText[p->nChar++] = c; } @@ -842,7 +840,6 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ memcpy(&p->zText[p->nChar], z, N); p->nChar += N; } - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); } /* @@ -877,19 +874,20 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ ** pointer if any kind of error was encountered. */ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ + char *zText; assert( p->mxAlloc>0 && !isMalloced(p) ); - p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); - if( p->zText ){ - memcpy(p->zText, p->zBase, p->nChar+1); + zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); + if( zText ){ + memcpy(zText, p->zText, p->nChar+1); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ setStrAccumError(p, STRACCUM_NOMEM); } - return p->zText; + p->zText = zText; + return zText; } char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ - assert( (p->zText==p->zBase)==!isMalloced(p) ); p->zText[p->nChar] = 0; if( p->mxAlloc>0 && !isMalloced(p) ){ return strAccumFinishRealloc(p); @@ -902,7 +900,6 @@ char *sqlite3StrAccumFinish(StrAccum *p){ ** Reset an StrAccum string. Reclaim all malloced memory. */ void sqlite3StrAccumReset(StrAccum *p){ - assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); if( isMalloced(p) ){ sqlite3DbFree(p->db, p->zText); p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; @@ -925,11 +922,11 @@ void sqlite3StrAccumReset(StrAccum *p){ ** allocations will ever occur. */ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ - p->zText = p->zBase = zBase; + p->zText = zBase; p->db = db; - p->nChar = 0; p->nAlloc = n; p->mxAlloc = mx; + p->nChar = 0; p->accError = 0; p->printfFlags = 0; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7222fcda94..522ab96517 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3227,11 +3227,10 @@ struct DbFixer { */ struct StrAccum { sqlite3 *db; /* Optional database for lookaside. Can be NULL */ - char *zBase; /* A base allocation. Not from malloc. */ char *zText; /* The string collected so far */ - u32 nChar; /* Length of the string so far */ u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ + u32 nChar; /* Length of the string so far */ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ u8 printfFlags; /* SQLITE_PRINTF flags below */ }; From dccf4f2b15061cb84bee3c6c3c874edba563be58 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 12 Aug 2017 02:16:34 +0000 Subject: [PATCH 03/53] Update the speed-check.sh test script to append log output to the end of the cout-NAME.txt file. FossilOrigin-Name: 14d262d6aa4e281dfe0490988f0c1965c4babf98038a1a96b9bb5772a61521a3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/speed-check.sh | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 126340c6aa..9a39ea574b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\szBase\sfield\sfrom\sthe\sStrAccum\sobject.\s\sResulting\scode\sis\sslightly\nsmaller\sand\sfaster. -D 2017-08-12T02:01:55.477 +C Update\sthe\sspeed-check.sh\stest\sscript\sto\sappend\slog\soutput\sto\sthe\send\sof\sthe\ncout-NAME.txt\sfile. +D 2017-08-12T02:16:34.150 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -1606,7 +1606,7 @@ F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c F tool/showwal.c ad9d768f96ca6199ad3a8c9562d679680bd032dd01204ea3e5ea6fb931d81847 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/spaceanal.tcl f40dc82b4d5e39d040a02a3ec38268e324068815e4292a15ffa30ee93208bbfd -F tool/speed-check.sh fd24151fd66465f01886c3f75faf8fa46d19f068c69d16514ca73887adcdafe4 +F tool/speed-check.sh 9eccb9ade8806238a4e9d6cb6511e7be2f64aff6873c41ea70d322219ea28adf F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -1646,7 +1646,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 28a5aec118f9d078c9e7225f85cd48a91920b13908c540771e309557c3f15f84 -R c12bc93088f8c532a7cb23532de2f4c4 +P 6e52fa5fd79988a433bae0152ceae036edab4bb18d2b48ed04c1f53f141728b0 +R 772c60eb3b2c75ff30436857fe8c0a95 U drh -Z fd24d8fda45b9e8f917fec0b522deb6b +Z 259464aafd26637749328aadb6f43b1b diff --git a/manifest.uuid b/manifest.uuid index 887a009764..5c0e0690f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e52fa5fd79988a433bae0152ceae036edab4bb18d2b48ed04c1f53f141728b0 \ No newline at end of file +14d262d6aa4e281dfe0490988f0c1965c4babf98038a1a96b9bb5772a61521a3 \ No newline at end of file diff --git a/tool/speed-check.sh b/tool/speed-check.sh index 5de218748a..f9efb7c13d 100644 --- a/tool/speed-check.sh +++ b/tool/speed-check.sh @@ -147,6 +147,8 @@ size sqlite3.o | tee -a summary-$NAME.txt wc sqlite3.c if test $doCachegrind -eq 1; then cg_anno.tcl cachegrind.out.* >cout-$NAME.txt + echo '*****************************************************' >>cout-$NAME.txt + sed 's/^[0-9=-]\{9\}/==00000==/' summary-$NAME.txt >>cout-$NAME.txt fi if test $doExplain -eq 1; then ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt From 3c77a1e9f161aaf9fce41269ea4293fa890d0b45 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 12 Aug 2017 18:31:31 +0000 Subject: [PATCH 04/53] Add new test file fts5vocab2.test. FossilOrigin-Name: 02174842c353bfaa747019cb3dcdee5bca6551d0a06d83fc1ac6d4569e16bc34 --- ext/fts5/test/fts5vocab2.test | 209 ++++++++++++++++++++++++++++++++++ manifest | 13 ++- manifest.uuid | 2 +- 3 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 ext/fts5/test/fts5vocab2.test diff --git a/ext/fts5/test/fts5vocab2.test b/ext/fts5/test/fts5vocab2.test new file mode 100644 index 0000000000..4a0a1f4e3d --- /dev/null +++ b/ext/fts5/test/fts5vocab2.test @@ -0,0 +1,209 @@ +# 2017 August 10 +# +# 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. +# +#*********************************************************************** +# +# The tests in this file focus on testing the fts5vocab module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5vocab + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b); + CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance); + + INSERT INTO t1 VALUES('one two', 'two three'); + INSERT INTO t1 VALUES('three four', 'four five five five'); +} + +do_execsql_test 1.1 { + SELECT * FROM v1; +} { + five 2 b 1 + five 2 b 2 + five 2 b 3 + four 2 a 1 + four 2 b 0 + one 1 a 0 + three 1 b 1 + three 2 a 0 + two 1 a 1 + two 1 b 0 +} + +do_execsql_test 1.2 { + SELECT * FROM v1 WHERE term='three'; +} { + three 1 b 1 + three 2 a 0 +} + +do_execsql_test 1.3 { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + SELECT * FROM v1; + ROLLBACK; +} { + one 1 a 0 + three 1 b 1 + two 1 a 1 + two 1 b 0 +} + +do_execsql_test 1.4 { + BEGIN; + DELETE FROM t1 WHERE rowid=1; + SELECT * FROM v1; + ROLLBACK; +} { + five 2 b 1 + five 2 b 2 + five 2 b 3 + four 2 a 1 + four 2 b 0 + three 2 a 0 +} + +do_execsql_test 1.5 { + DELETE FROM t1; + SELECT * FROM v1; +} { +} + +#------------------------------------------------------------------------- +# +do_execsql_test 2.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS v1; + + CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=column); + CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance); + + INSERT INTO t1 VALUES('one two', 'two three'); + INSERT INTO t1 VALUES('three four', 'four five five five'); +} + +do_execsql_test 2.1 { + SELECT * FROM v1; +} { + five 2 b {} + four 2 a {} + four 2 b {} + one 1 a {} + three 1 b {} + three 2 a {} + two 1 a {} + two 1 b {} +} + +do_execsql_test 2.2 { + SELECT * FROM v1 WHERE term='three'; +} { + three 1 b {} + three 2 a {} +} + +do_execsql_test 2.3 { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + SELECT * FROM v1; + ROLLBACK; +} { + one 1 a {} + three 1 b {} + two 1 a {} + two 1 b {} +} + +do_execsql_test 2.4 { + BEGIN; + DELETE FROM t1 WHERE rowid=1; + SELECT * FROM v1; + ROLLBACK; +} { + five 2 b {} + four 2 a {} + four 2 b {} + three 2 a {} +} + +do_execsql_test 2.5 { + DELETE FROM t1; + SELECT * FROM v1; +} { +} + +#------------------------------------------------------------------------- +# +do_execsql_test 3.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS v1; + + CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=none); + CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance); + + INSERT INTO t1 VALUES('one two', 'two three'); + INSERT INTO t1 VALUES('three four', 'four five five five'); +} + +do_execsql_test 3.1 { + SELECT * FROM v1; +} { + five 2 {} {} + four 2 {} {} + one 1 {} {} + three 1 {} {} + three 2 {} {} + two 1 {} {} +} + +do_execsql_test 3.2 { + SELECT * FROM v1 WHERE term='three'; +} { + three 1 {} {} + three 2 {} {} +} + +do_execsql_test 3.3 { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + SELECT * FROM v1; + ROLLBACK; +} { + one 1 {} {} + three 1 {} {} + two 1 {} {} +} + +do_execsql_test 3.4 { + BEGIN; + DELETE FROM t1 WHERE rowid=1; + SELECT * FROM v1; + ROLLBACK; +} { + five 2 {} {} + four 2 {} {} + three 2 {} {} +} + +do_execsql_test 3.5 { + DELETE FROM t1; + SELECT * FROM v1; +} { +} + +finish_test + diff --git a/manifest b/manifest index 9a39ea574b..8fbd0a2dcd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sspeed-check.sh\stest\sscript\sto\sappend\slog\soutput\sto\sthe\send\sof\sthe\ncout-NAME.txt\sfile. -D 2017-08-12T02:16:34.150 +C Add\snew\stest\sfile\sfts5vocab2.test. +D 2017-08-12T18:31:31.810 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -201,6 +201,7 @@ F ext/fts5/test/fts5unindexed.test 9021af86a0fb9fc616f7a69a996db0116e7936d0db638 F ext/fts5/test/fts5update.test 0737876e20e97a6a6abf45de19fc99315727bcee6a83fadcada1cc080b9aa8f0 F ext/fts5/test/fts5version.test 99b81372630fbf359107c96580fa761e41cdfb1dafc9966e148629ca72efee71 F ext/fts5/test/fts5vocab.test 2ba98bcef0fcab3e5fead8eaabd6c0efb7e57bfe707a5cfcc18572ca9b277360 +F ext/fts5/test/fts5vocab2.test 2beeec974a305a1d79b91426622cc922c87065874437d22b400de7438979959e F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl 526a9979c963f1c54fd50976a05a502e533a4c59 F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 @@ -1646,7 +1647,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 6e52fa5fd79988a433bae0152ceae036edab4bb18d2b48ed04c1f53f141728b0 -R 772c60eb3b2c75ff30436857fe8c0a95 -U drh -Z 259464aafd26637749328aadb6f43b1b +P 14d262d6aa4e281dfe0490988f0c1965c4babf98038a1a96b9bb5772a61521a3 +R 458c6571aa20c315f2d6b3e7fbde0c5a +U dan +Z d58fa1886079f8c44974d3b28910f9ac diff --git a/manifest.uuid b/manifest.uuid index 5c0e0690f9..ab91f374e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14d262d6aa4e281dfe0490988f0c1965c4babf98038a1a96b9bb5772a61521a3 \ No newline at end of file +02174842c353bfaa747019cb3dcdee5bca6551d0a06d83fc1ac6d4569e16bc34 \ No newline at end of file From 1112cc797b2b588287e32aaee537343a9d3dc02e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Aug 2017 01:33:07 +0000 Subject: [PATCH 05/53] Properly dequote column names in tables constructed by an aggregate SELECT. FossilOrigin-Name: 7e0d3e9cb071873564b7916c022aba5cd9f3b8ebab9dba787ecd7113c5b7816a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 4 +++- test/colname.test | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8fbd0a2dcd..1caf0479d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\stest\sfile\sfts5vocab2.test. -D 2017-08-12T18:31:31.810 +C Properly\sdequote\scolumn\snames\sin\stables\sconstructed\sby\san\saggregate\sSELECT. +D 2017-08-14T01:33:07.818 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -454,7 +454,7 @@ F src/printf.c 439c145d71ff9e0328ec26b7db23a45f995f742d3207dd546e034cdc1667ac9c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 3fd19c98c5223d411b883502d1ac928ddb762a1ea8f031d910210316545fc67c +F src/select.c ea8921065512650a9df3f5bf9a9b531c6ef4fb193c0d57e09d7a479ef9b13992 F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 F src/sqlite.h.in 72f1775c7a134f9e358eedafe1ebc703c28b0d705d976464ddbf6a9219448952 @@ -656,7 +656,7 @@ F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 -F test/colname.test b111edd2a84f558567320904bb94c779d7eec47254265b5f0a3d1f3e52cc28e0 +F test/colname.test c47639d26cbeba6977457e5ef2c2c55c5b6c889478dd7eb0ed858ba894e7fa93 F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9 @@ -1647,7 +1647,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 14d262d6aa4e281dfe0490988f0c1965c4babf98038a1a96b9bb5772a61521a3 -R 458c6571aa20c315f2d6b3e7fbde0c5a -U dan -Z d58fa1886079f8c44974d3b28910f9ac +P 02174842c353bfaa747019cb3dcdee5bca6551d0a06d83fc1ac6d4569e16bc34 +R 81f3b44c4693553d4feb0c8d49d70bc5 +U drh +Z d0554a39e56793c8309c789eafde6181 diff --git a/manifest.uuid b/manifest.uuid index ab91f374e9..11e97f4b39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02174842c353bfaa747019cb3dcdee5bca6551d0a06d83fc1ac6d4569e16bc34 \ No newline at end of file +7e0d3e9cb071873564b7916c022aba5cd9f3b8ebab9dba787ecd7113c5b7816a \ No newline at end of file diff --git a/src/select.c b/src/select.c index 255d729223..98a64b6f42 100644 --- a/src/select.c +++ b/src/select.c @@ -1710,7 +1710,9 @@ int sqlite3ColumnsFromExprList( pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } - if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){ + if( (pColExpr->op==TK_COLUMN || pColExpr->op==TK_AGG_COLUMN) + && pColExpr->pTab!=0 + ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; Table *pTab = pColExpr->pTab; diff --git a/test/colname.test b/test/colname.test index 1497fc275c..2e4ae89008 100644 --- a/test/colname.test +++ b/test/colname.test @@ -378,5 +378,22 @@ do_test colname-9.210 { execsql2 {SELECT t1.a, v3.a AS n FROM t1 JOIN v3} } {a 1 n 3} +# Make sure the quotation marks get removed from the column names +# when constructing a new table from an aggregate SELECT. +# Email from Juergen Palm on 2017-07-11. +# +do_execsql_test colname-10.100 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1("with space" TEXT); + DROP TABLE IF EXISTS t2; + CREATE TABLE t2 AS SELECT "with space" FROM t1; + PRAGMA table_info(t2); +} {0 {with space} TEXT 0 {} 0} +do_execsql_test colname-10.110 { + DROP TABLE IF EXISTS t3; + CREATE TABLE t3 AS SELECT "with space" FROM t1 GROUP BY 1; + PRAGMA table_info(t3); +} {0 {with space} TEXT 0 {} 0} + finish_test From 4dd89d5a249e93cec34d4396f27b1e9c1eb9a296 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Aug 2017 14:53:24 +0000 Subject: [PATCH 06/53] Sometimes a TK_COLUMN Expr node can have Expr.pTab==0 if it is a reference to an expression column in an index on and expression. Fix for ticket [aa98619ad08ddcab]. FossilOrigin-Name: d0da791ba0edfb65186459345e43500d8364a086a5a1651d828fecc1a1dd1edb --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 2 +- src/select.c | 2 ++ src/sqliteInt.h | 3 ++- test/indexexpr1.test | 22 ++++++++++++++++++++++ 6 files changed, 37 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 1caf0479d4..0e89152592 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Properly\sdequote\scolumn\snames\sin\stables\sconstructed\sby\san\saggregate\sSELECT. -D 2017-08-14T01:33:07.818 +C Sometimes\sa\sTK_COLUMN\sExpr\snode\scan\shave\sExpr.pTab==0\sif\sit\sis\sa\sreference\nto\san\sexpression\scolumn\sin\san\sindex\son\sand\sexpression.\s\sFix\sfor\sticket\n[aa98619ad08ddcab]. +D 2017-08-14T14:53:24.546 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -407,7 +407,7 @@ F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74 F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720 F src/delete.c 21a5f1812fdb599e9f7afb9f650bdabab60a3afd51d7e94e539c982f647b0023 -F src/expr.c fdb2fc465cabbf372fecad1fc2b291758bec74150b4db0fb945332e09df28a0e +F src/expr.c dc436431dc50a0256b9dcd3daaa06aac0df21834f91068525f2eb3c10b9a7a9a F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333 F src/func.c ed8888ae80b39f5a5d403954e4a05e0a38303523dff8143161439c142d31dec1 @@ -454,13 +454,13 @@ F src/printf.c 439c145d71ff9e0328ec26b7db23a45f995f742d3207dd546e034cdc1667ac9c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c ea8921065512650a9df3f5bf9a9b531c6ef4fb193c0d57e09d7a479ef9b13992 +F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 F src/sqlite.h.in 72f1775c7a134f9e358eedafe1ebc703c28b0d705d976464ddbf6a9219448952 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 -F src/sqliteInt.h 5e3c160c1e97568d72a5b2b755cd899d32a96f43a2a58eb18ad83da33b77a0cb +F src/sqliteInt.h 854a122ff0ebde410a66d4f967e9923de9002f73965c6c9fa0db544bf7e657d1 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -940,7 +940,7 @@ F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 -F test/indexexpr1.test f348668daf7f533f1e5578dd4f31e4b9a3875da1ee2a60a8d2d50b938a7699c9 +F test/indexexpr1.test 84100e880154a4b645db9f4fc7642756d9a2b6011b68f73c8efda4d244816de9 F test/indexexpr2.test 3ddd7f23bc381b9f2b7a15f2d083b1a4078e7733dce8295602ecfa3c74a34cf9 F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1647,7 +1647,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 02174842c353bfaa747019cb3dcdee5bca6551d0a06d83fc1ac6d4569e16bc34 -R 81f3b44c4693553d4feb0c8d49d70bc5 +P 7e0d3e9cb071873564b7916c022aba5cd9f3b8ebab9dba787ecd7113c5b7816a +R fd85cb2e90a98ca349ba60eafe5856e3 U drh -Z d0554a39e56793c8309c789eafde6181 +Z 01f8f49b6a69b50c9cc82fb68a921316 diff --git a/manifest.uuid b/manifest.uuid index 11e97f4b39..3f3bef9058 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e0d3e9cb071873564b7916c022aba5cd9f3b8ebab9dba787ecd7113c5b7816a \ No newline at end of file +d0da791ba0edfb65186459345e43500d8364a086a5a1651d828fecc1a1dd1edb \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6a3ccd833e..d090aab3b7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1973,8 +1973,8 @@ int sqlite3ExprCanBeNull(const Expr *p){ case TK_BLOB: return 0; case TK_COLUMN: - assert( p->pTab!=0 ); return ExprHasProperty(p, EP_CanBeNull) || + p->pTab==0 || /* Reference to column of index on expression */ (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0); default: return 1; diff --git a/src/select.c b/src/select.c index 98a64b6f42..aedbcc4b3a 100644 --- a/src/select.c +++ b/src/select.c @@ -1617,6 +1617,8 @@ static void generateColumnNames( Expr *p = pEList->a[i].pExpr; assert( p!=0 ); + assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ + assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering indexes not yet coded */ if( pEList->a[i].zName ){ /* An AS clause always takes first priority */ char *zName = pEList->a[i].zName; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 522ab96517..c457b5401b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2385,7 +2385,8 @@ struct Expr { ** TK_COLUMN: the value of p5 for OP_Column ** TK_AGG_FUNCTION: nesting depth */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ - Table *pTab; /* Table for TK_COLUMN expressions. */ + Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL + ** for a column of an index on an expression */ }; /* diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 85ec0df1f0..0e24c8066f 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -380,4 +380,26 @@ do_execsql_test indexexpr1-1300.1 { SELECT a FROM t1300 WHERE substr(b,4)='ess' COLLATE nocase ORDER BY +a; } {3 4} +# Ticket https://sqlite.org/src/tktview/aa98619a +# Assertion fault using an index on a constant +# +do_execsql_test indexexpr1-1400 { + CREATE TABLE t1400(x TEXT); + CREATE INDEX t1400x ON t1400(1); -- Index on a constant + SELECT 1 IN (SELECT 2) FROM t1400; +} {} +do_execsql_test indexexpr1-1410 { + INSERT INTO t1400 VALUES('a'),('b'); + SELECT 1 IN (SELECT 2) FROM t1400; +} {0 0} +do_execsql_test indexexpr1-1420 { + SELECT 1 IN (SELECT 2 UNION ALL SELECT 1) FROM t1400; +} {1 1} +do_execsql_test indexexpr1-1430 { + DROP INDEX t1400x; + CREATE INDEX t1400x ON t1400(abs(15+3)); + SELECT abs(15+3) IN (SELECT 17 UNION ALL SELECT 18) FROM t1; +} {1 1} + + finish_test From f0357d8b2c5eada815416cc0de607e572cf2f8b6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Aug 2017 17:03:58 +0000 Subject: [PATCH 07/53] Fix harmless indentation error. FossilOrigin-Name: 25e92baaaeb9e8a2650b3083d3febf3661ecf1e05d9d24b26fe9f87a03bdd8fa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0e89152592..79eb7f408e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Sometimes\sa\sTK_COLUMN\sExpr\snode\scan\shave\sExpr.pTab==0\sif\sit\sis\sa\sreference\nto\san\sexpression\scolumn\sin\san\sindex\son\sand\sexpression.\s\sFix\sfor\sticket\n[aa98619ad08ddcab]. -D 2017-08-14T14:53:24.546 +C Fix\sharmless\sindentation\serror. +D 2017-08-14T17:03:58.073 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -397,7 +397,7 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 1a17ba1a765d80c3ca39ce33ff55f92e1f51eb84bbbdab5377f11d36b1515fa1 +F src/btree.c 5a6efa29cc6b78f3151a64424bd2f3c28e0158019c45786635ef5ff79d94e850 F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc @@ -1647,7 +1647,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 7e0d3e9cb071873564b7916c022aba5cd9f3b8ebab9dba787ecd7113c5b7816a -R fd85cb2e90a98ca349ba60eafe5856e3 +P d0da791ba0edfb65186459345e43500d8364a086a5a1651d828fecc1a1dd1edb +R 94ae43f22349d16aa74bde77a321d195 U drh -Z 01f8f49b6a69b50c9cc82fb68a921316 +Z ebdb69ac8faf71033c2cac4a21de62a6 diff --git a/manifest.uuid b/manifest.uuid index 3f3bef9058..a86a3b6943 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d0da791ba0edfb65186459345e43500d8364a086a5a1651d828fecc1a1dd1edb \ No newline at end of file +25e92baaaeb9e8a2650b3083d3febf3661ecf1e05d9d24b26fe9f87a03bdd8fa \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 71e7769c1a..6602b3395b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4960,7 +4960,7 @@ static int moveToRoot(BtCursor *pCur){ 0, pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; - return rc; + return rc; } pCur->iPage = 0; pCur->curIntKey = pCur->apPage[0]->intKey; From 44548e7218faf4fdffa8ec4943895f169bdeab23 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Aug 2017 18:13:52 +0000 Subject: [PATCH 08/53] Change the internal btree routine moveToRoot() to return SQLITE_EMPTY if the table is empty or if it has pgnoRoot==0. This simplifies the callers, making them smaller and faster. The SQLITE_EMPTY result code is intercepted and changed into SQLITE_OK before surfacing in an API. FossilOrigin-Name: 240d57143d943eaddd5f7c2d473f47a1d29417e61d28142f70f3d960bb9b30df --- manifest | 14 +++++----- manifest.uuid | 2 +- src/btree.c | 69 +++++++++++++++++++++++++------------------------ src/sqlite.h.in | 2 +- 4 files changed, 44 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index 79eb7f408e..df3d92278a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\sindentation\serror. -D 2017-08-14T17:03:58.073 +C Change\sthe\sinternal\sbtree\sroutine\smoveToRoot()\sto\sreturn\sSQLITE_EMPTY\sif\nthe\stable\sis\sempty\sor\sif\sit\shas\spgnoRoot==0.\s\sThis\ssimplifies\sthe\scallers,\nmaking\sthem\ssmaller\sand\sfaster.\s\sThe\sSQLITE_EMPTY\sresult\scode\sis\sintercepted\nand\schanged\sinto\sSQLITE_OK\sbefore\ssurfacing\sin\san\sAPI. +D 2017-08-14T18:13:52.027 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -397,7 +397,7 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 5a6efa29cc6b78f3151a64424bd2f3c28e0158019c45786635ef5ff79d94e850 +F src/btree.c 43d1c5b335984abd3f9d38e87305bb0da63a638d29ea35744aabad2ddbf9fa4d F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc @@ -457,7 +457,7 @@ F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 -F src/sqlite.h.in 72f1775c7a134f9e358eedafe1ebc703c28b0d705d976464ddbf6a9219448952 +F src/sqlite.h.in f0bd1abf5e27bd22b3bcaae2a861c1efc4ab7e752bf7eb102355135617eb8199 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 F src/sqliteInt.h 854a122ff0ebde410a66d4f967e9923de9002f73965c6c9fa0db544bf7e657d1 @@ -1647,7 +1647,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 d0da791ba0edfb65186459345e43500d8364a086a5a1651d828fecc1a1dd1edb -R 94ae43f22349d16aa74bde77a321d195 +P 25e92baaaeb9e8a2650b3083d3febf3661ecf1e05d9d24b26fe9f87a03bdd8fa +R 842146c033a5d3f4b14318bddfc60ebc U drh -Z ebdb69ac8faf71033c2cac4a21de62a6 +Z 43daddc7888a0248763a7ce6f2befced diff --git a/manifest.uuid b/manifest.uuid index a86a3b6943..2c60456962 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25e92baaaeb9e8a2650b3083d3febf3661ecf1e05d9d24b26fe9f87a03bdd8fa \ No newline at end of file +240d57143d943eaddd5f7c2d473f47a1d29417e61d28142f70f3d960bb9b30df \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 6602b3395b..c1f8cd9364 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4914,9 +4914,9 @@ static void moveToParent(BtCursor *pCur){ ** single child page. This can only happen with the table rooted at page 1. ** ** If the b-tree structure is empty, the cursor state is set to -** CURSOR_INVALID. Otherwise, the cursor is set to point to the first -** cell located on the root (or virtual root) page and the cursor state -** is set to CURSOR_VALID. +** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise, +** the cursor is set to point to the first cell located on the root +** (or virtual root) page and the cursor state is set to CURSOR_VALID. ** ** If this function returns successfully, it may be assumed that the ** page-header flags indicate that the [virtual] root-page is the expected @@ -4935,6 +4935,7 @@ static int moveToRoot(BtCursor *pCur){ assert( CURSOR_VALID < CURSOR_REQUIRESEEK ); assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 ); + assert( pCur->pgnoRoot>0 || pCur->iPage<0 ); if( pCur->iPage>=0 ){ if( pCur->iPage ){ @@ -4946,7 +4947,7 @@ static int moveToRoot(BtCursor *pCur){ } }else if( pCur->pgnoRoot==0 ){ pCur->eState = CURSOR_INVALID; - return SQLITE_OK; + return SQLITE_EMPTY; }else{ assert( pCur->iPage==(-1) ); if( pCur->eState>=CURSOR_REQUIRESEEK ){ @@ -4999,6 +5000,7 @@ skip_init: rc = moveToChild(pCur, subpage); }else{ pCur->eState = CURSOR_INVALID; + rc = SQLITE_EMPTY; } return rc; } @@ -5065,14 +5067,13 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ - if( pCur->eState==CURSOR_INVALID ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - *pRes = 1; - }else{ - assert( pCur->apPage[pCur->iPage]->nCell>0 ); - *pRes = 0; - rc = moveToLeftmost(pCur); - } + assert( pCur->apPage[pCur->iPage]->nCell>0 ); + *pRes = 0; + rc = moveToLeftmost(pCur); + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; } return rc; } @@ -5104,20 +5105,18 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ - if( CURSOR_INVALID==pCur->eState ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - *pRes = 1; + assert( pCur->eState==CURSOR_VALID ); + *pRes = 0; + rc = moveToRightmost(pCur); + if( rc==SQLITE_OK ){ + pCur->curFlags |= BTCF_AtLast; }else{ - assert( pCur->eState==CURSOR_VALID ); - *pRes = 0; - rc = moveToRightmost(pCur); - if( rc==SQLITE_OK ){ - pCur->curFlags |= BTCF_AtLast; - }else{ - pCur->curFlags &= ~BTCF_AtLast; - } - + pCur->curFlags &= ~BTCF_AtLast; } + }else if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + *pRes = 1; + rc = SQLITE_OK; } return rc; } @@ -5216,16 +5215,17 @@ int sqlite3BtreeMovetoUnpacked( rc = moveToRoot(pCur); if( rc ){ + if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + *pRes = -1; + return SQLITE_OK; + } return rc; } - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] ); - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit ); - assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 ); - if( pCur->eState==CURSOR_INVALID ){ - *pRes = -1; - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); - return SQLITE_OK; - } + assert( pCur->apPage[pCur->iPage] ); + assert( pCur->apPage[pCur->iPage]->isInit ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->apPage[pCur->iPage]->nCell > 0 ); assert( pCur->apPage[0]->intKey==pCur->curIntKey ); assert( pCur->curIntKey || pIdxKey ); for(;;){ @@ -8439,6 +8439,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ btreeReleaseAllCursorPages(pCur); pCur->eState = CURSOR_REQUIRESEEK; } + if( rc==SQLITE_EMPTY ) rc = SQLITE_OK; } } return rc; @@ -8903,11 +8904,11 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ i64 nEntry = 0; /* Value to return in *pnEntry */ int rc; /* Return code */ - if( pCur->pgnoRoot==0 ){ + rc = moveToRoot(pCur); + if( rc==SQLITE_EMPTY ){ *pnEntry = 0; return SQLITE_OK; } - rc = moveToRoot(pCur); /* Unless an error occurs, the following loop runs one iteration for each ** page in the B-Tree structure (not including overflow pages). diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ad97b9a0de..1020e5f3d6 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -432,7 +432,7 @@ int sqlite3_exec( #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define SQLITE_EMPTY 16 /* Not used */ +#define SQLITE_EMPTY 16 /* Internal use only */ #define SQLITE_SCHEMA 17 /* The database schema changed */ #define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */ #define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */ From f38dd3b68fd90a1e8d913c242bb50d3d9c42298a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 14 Aug 2017 23:53:02 +0000 Subject: [PATCH 09/53] Minor size and performance optimization to sqlite3BtreeCloseCursor(). FossilOrigin-Name: 16969338841734d00ab906a94b82480c7e1e426eb0ddf7b9e6aed722aee5d91f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index df3d92278a..d114803f0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sinternal\sbtree\sroutine\smoveToRoot()\sto\sreturn\sSQLITE_EMPTY\sif\nthe\stable\sis\sempty\sor\sif\sit\shas\spgnoRoot==0.\s\sThis\ssimplifies\sthe\scallers,\nmaking\sthem\ssmaller\sand\sfaster.\s\sThe\sSQLITE_EMPTY\sresult\scode\sis\sintercepted\nand\schanged\sinto\sSQLITE_OK\sbefore\ssurfacing\sin\san\sAPI. -D 2017-08-14T18:13:52.027 +C Minor\ssize\sand\sperformance\soptimization\sto\ssqlite3BtreeCloseCursor(). +D 2017-08-14T23:53:02.259 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -397,7 +397,7 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 43d1c5b335984abd3f9d38e87305bb0da63a638d29ea35744aabad2ddbf9fa4d +F src/btree.c 05781141fe24e9e24719a1d9c9b6ce38480af115f85a8a26f389a089888060d7 F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc @@ -1647,7 +1647,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 25e92baaaeb9e8a2650b3083d3febf3661ecf1e05d9d24b26fe9f87a03bdd8fa -R 842146c033a5d3f4b14318bddfc60ebc +P 240d57143d943eaddd5f7c2d473f47a1d29417e61d28142f70f3d960bb9b30df +R a7c4eab7d8d2ce1f319f583d46cbd640 U drh -Z 43daddc7888a0248763a7ce6f2befced +Z e48f5e9e2a338851fd6ede62f6ca96de diff --git a/manifest.uuid b/manifest.uuid index 2c60456962..d88c8647b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -240d57143d943eaddd5f7c2d473f47a1d29417e61d28142f70f3d960bb9b30df \ No newline at end of file +16969338841734d00ab906a94b82480c7e1e426eb0ddf7b9e6aed722aee5d91f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index c1f8cd9364..dcd70b9283 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4296,7 +4296,6 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ int i; BtShared *pBt = pCur->pBt; sqlite3BtreeEnter(pBtree); - sqlite3BtreeClearCursor(pCur); assert( pBt->pCursor!=0 ); if( pBt->pCursor==pCur ){ pBt->pCursor = pCur->pNext; @@ -4315,7 +4314,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ } unlockBtreeIfUnused(pBt); sqlite3_free(pCur->aOverflow); - /* sqlite3_free(pCur); */ + sqlite3_free(pCur->pKey); sqlite3BtreeLeave(pBtree); } return SQLITE_OK; From 352a35abf5bdd40b50d7344f34e57ad616352d80 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Aug 2017 03:46:47 +0000 Subject: [PATCH 10/53] Btree optimization: New field BtCursor.pPage that points to the current page, saving a single pointer dereference on each access. FossilOrigin-Name: 373b71d19cad785922d5a80828f2fee0cbe7dff6594743e625bbdfa31b1ca131 --- manifest | 14 ++--- manifest.uuid | 2 +- src/btree.c | 168 +++++++++++++++++++++++++++---------------------- src/btreeInt.h | 3 +- 4 files changed, 103 insertions(+), 84 deletions(-) diff --git a/manifest b/manifest index d114803f0f..3ee6a346e3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssize\sand\sperformance\soptimization\sto\ssqlite3BtreeCloseCursor(). -D 2017-08-14T23:53:02.259 +C Btree\soptimization:\s\sNew\sfield\sBtCursor.pPage\sthat\spoints\sto\sthe\scurrent\spage,\nsaving\sa\ssingle\spointer\sdereference\son\seach\saccess. +D 2017-08-15T03:46:47.011 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -397,9 +397,9 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 05781141fe24e9e24719a1d9c9b6ce38480af115f85a8a26f389a089888060d7 +F src/btree.c d2f5f347e56f8b7ed1bb798087045a3b98cd63f45fde7675fd24b9e88b61304d F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca -F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1 +F src/btreeInt.h f78671f594dafd88cf9a81253da04db81272b382d2dc074bb983d348b95d9d2d F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc F src/callback.c 930648a084a3adc741c6471adfbdc50ba47ba3542421cb80a26f259f467de65e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -1647,7 +1647,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 240d57143d943eaddd5f7c2d473f47a1d29417e61d28142f70f3d960bb9b30df -R a7c4eab7d8d2ce1f319f583d46cbd640 +P 16969338841734d00ab906a94b82480c7e1e426eb0ddf7b9e6aed722aee5d91f +R 3d6cdbe8a873abb5b839027115a07163 U drh -Z e48f5e9e2a338851fd6ede62f6ca96de +Z 53459ac0c08285b40b84acbd692920bc diff --git a/manifest.uuid b/manifest.uuid index d88c8647b6..d331463c6a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -16969338841734d00ab906a94b82480c7e1e426eb0ddf7b9e6aed722aee5d91f \ No newline at end of file +373b71d19cad785922d5a80828f2fee0cbe7dff6594743e625bbdfa31b1ca131 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index dcd70b9283..50981b0575 100644 --- a/src/btree.c +++ b/src/btree.c @@ -439,7 +439,8 @@ static void downgradeAllSharedCacheTableLocks(Btree *p){ #endif /* SQLITE_OMIT_SHARED_CACHE */ -static void releasePage(MemPage *pPage); /* Forward reference */ +static void releasePage(MemPage *pPage); +static void releasePageNotNull(MemPage *pPage); /* Forward reference */ /* ***** This routine is used inside of assert() only **** @@ -598,11 +599,13 @@ static void btreeClearHasContent(BtShared *pBt){ */ static void btreeReleaseAllCursorPages(BtCursor *pCur){ int i; - for(i=0; i<=pCur->iPage; i++){ - releasePage(pCur->apPage[i]); - pCur->apPage[i] = 0; + if( pCur->iPage>=0 ){ + for(i=0; iiPage; i++){ + releasePageNotNull(pCur->apPage[i]); + } + releasePageNotNull(pCur->pPage); + pCur->iPage = -1; } - pCur->iPage = -1; } /* @@ -771,7 +774,7 @@ static int btreeMoveto( if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey); if( pIdxKey->nField==0 ){ - rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno); + rc = SQLITE_CORRUPT; goto moveto_done; } }else{ @@ -2049,7 +2052,7 @@ static int getAndInitPage( int rc; DbPage *pDbPage; assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] ); + assert( pCur==0 || ppPage==&pCur->pPage ); assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); assert( pCur==0 || pCur->iPage>0 ); @@ -2083,7 +2086,10 @@ static int getAndInitPage( return SQLITE_OK; getAndInitPage_error: - if( pCur ) pCur->iPage--; + if( pCur ){ + pCur->iPage--; + pCur->pPage = pCur->apPage[pCur->iPage]; + } testcase( pgno==0 ); assert( pgno!=0 || rc==SQLITE_CORRUPT ); return rc; @@ -4293,7 +4299,6 @@ void sqlite3BtreeCursorZero(BtCursor *p){ int sqlite3BtreeCloseCursor(BtCursor *pCur){ Btree *pBtree = pCur->pBtree; if( pBtree ){ - int i; BtShared *pBt = pCur->pBt; sqlite3BtreeEnter(pBtree); assert( pBt->pCursor!=0 ); @@ -4309,9 +4314,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ pPrev = pPrev->pNext; }while( ALWAYS(pPrev) ); } - for(i=0; i<=pCur->iPage; i++){ - releasePageNotNull(pCur->apPage[i]); - } + btreeReleaseAllCursorPages(pCur); unlockBtreeIfUnused(pBt); sqlite3_free(pCur->aOverflow); sqlite3_free(pCur->pKey); @@ -4331,9 +4334,8 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ #ifndef NDEBUG static void assertCellInfo(BtCursor *pCur){ CellInfo info; - int iPage = pCur->iPage; memset(&info, 0, sizeof(info)); - btreeParseCell(pCur->apPage[iPage], pCur->ix, &info); + btreeParseCell(pCur->pPage, pCur->ix, &info); assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 ); } #else @@ -4341,9 +4343,8 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){ #endif static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ if( pCur->info.nSize==0 ){ - int iPage = pCur->iPage; pCur->curFlags |= BTCF_ValidNKey; - btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info); + btreeParseCell(pCur->pPage,pCur->ix,&pCur->info); }else{ assertCellInfo(pCur); } @@ -4541,7 +4542,7 @@ static int accessPayload( unsigned char *aPayload; int rc = SQLITE_OK; int iIdx = 0; - MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */ + MemPage *pPage = pCur->pPage; /* Btree page of current entry */ BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */ #ifdef SQLITE_DIRECT_OVERFLOW_READ unsigned char * const pBufStart = pBuf; /* Start of original out buffer */ @@ -4737,8 +4738,8 @@ static int accessPayload( int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->iPage>=0 && pCur->pPage ); + assert( pCur->ixpPage->nCell ); return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } @@ -4796,15 +4797,15 @@ static const void *fetchPayload( u32 *pAmt /* Write the number of available bytes here */ ){ u32 amt; - assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); + assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage); assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorOwnsBtShared(pCur) ); - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->ixpPage->nCell ); assert( pCur->info.nSize>0 ); - assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB ); - assert( pCur->info.pPayloadapPage[pCur->iPage]->aDataEnd ||CORRUPT_DB); - amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload); + assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB ); + assert( pCur->info.pPayloadpPage->aDataEnd ||CORRUPT_DB); + amt = (int)(pCur->pPage->aDataEnd - pCur->info.pPayload); if( pCur->info.nLocalinfo.nLocal; *pAmt = amt; return (void*)pCur->info.pPayload; @@ -4851,10 +4852,11 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ } pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); - pCur->aiIdx[pCur->iPage++] = pCur->ix; + pCur->aiIdx[pCur->iPage] = pCur->ix; + pCur->apPage[pCur->iPage] = pCur->pPage; pCur->ix = 0; - return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage], - pCur, pCur->curPagerFlags); + pCur->iPage++; + return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags); } #ifdef SQLITE_DEBUG @@ -4888,20 +4890,23 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ ** the largest cell index. */ static void moveToParent(BtCursor *pCur){ + MemPage *pLeaf; assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>0 ); - assert( pCur->apPage[pCur->iPage] ); + assert( pCur->pPage ); assertParentIndex( pCur->apPage[pCur->iPage-1], pCur->aiIdx[pCur->iPage-1], - pCur->apPage[pCur->iPage]->pgno + pCur->pPage->pgno ); testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); pCur->ix = pCur->aiIdx[pCur->iPage-1]; - releasePageNotNull(pCur->apPage[pCur->iPage--]); + pLeaf = pCur->pPage; + pCur->pPage = pCur->apPage[--pCur->iPage]; + releasePageNotNull(pLeaf); } /* @@ -4938,10 +4943,11 @@ static int moveToRoot(BtCursor *pCur){ if( pCur->iPage>=0 ){ if( pCur->iPage ){ - do{ - assert( pCur->apPage[pCur->iPage]!=0 ); - releasePageNotNull(pCur->apPage[pCur->iPage--]); - }while( pCur->iPage); + releasePageNotNull(pCur->pPage); + while( --pCur->iPage ){ + releasePageNotNull(pCur->apPage[pCur->iPage]); + } + pCur->pPage = pCur->apPage[0]; goto skip_init; } }else if( pCur->pgnoRoot==0 ){ @@ -4956,16 +4962,16 @@ static int moveToRoot(BtCursor *pCur){ } sqlite3BtreeClearCursor(pCur); } - rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0], + rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, 0, pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; return rc; } pCur->iPage = 0; - pCur->curIntKey = pCur->apPage[0]->intKey; + pCur->curIntKey = pCur->pPage->intKey; } - pRoot = pCur->apPage[0]; + pRoot = pCur->pPage; assert( pRoot->pgno==pCur->pgnoRoot ); /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor @@ -4980,7 +4986,7 @@ static int moveToRoot(BtCursor *pCur){ ** (or the freelist). */ assert( pRoot->intKey==1 || pRoot->intKey==0 ); if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ - return SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno); + return SQLITE_CORRUPT_PGNO(pCur->pPage->pgno); } skip_init: @@ -4988,7 +4994,7 @@ skip_init: pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); - pRoot = pCur->apPage[0]; + pRoot = pCur->pPage; if( pRoot->nCell>0 ){ pCur->eState = CURSOR_VALID; }else if( !pRoot->leaf ){ @@ -5018,7 +5024,7 @@ static int moveToLeftmost(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); - while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){ assert( pCur->ixnCell ); pgno = get4byte(findCell(pPage, pCur->ix)); rc = moveToChild(pCur, pgno); @@ -5043,7 +5049,7 @@ static int moveToRightmost(BtCursor *pCur){ assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); - while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){ + while( !(pPage = pCur->pPage)->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); pCur->ix = pPage->nCell; rc = moveToChild(pCur, pgno); @@ -5066,11 +5072,11 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ - assert( pCur->apPage[pCur->iPage]->nCell>0 ); + assert( pCur->pPage->nCell>0 ); *pRes = 0; rc = moveToLeftmost(pCur); }else if( rc==SQLITE_EMPTY ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); *pRes = 1; rc = SQLITE_OK; } @@ -5096,8 +5102,8 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ for(ii=0; iiiPage; ii++){ assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); } - assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 ); - assert( pCur->apPage[pCur->iPage]->leaf ); + assert( pCur->ix==pCur->pPage->nCell-1 ); + assert( pCur->pPage->leaf ); #endif return SQLITE_OK; } @@ -5113,7 +5119,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ pCur->curFlags &= ~BTCF_AtLast; } }else if( rc==SQLITE_EMPTY ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); *pRes = 1; rc = SQLITE_OK; } @@ -5215,22 +5221,22 @@ int sqlite3BtreeMovetoUnpacked( rc = moveToRoot(pCur); if( rc ){ if( rc==SQLITE_EMPTY ){ - assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 ); + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); *pRes = -1; return SQLITE_OK; } return rc; } - assert( pCur->apPage[pCur->iPage] ); - assert( pCur->apPage[pCur->iPage]->isInit ); + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); assert( pCur->eState==CURSOR_VALID ); - assert( pCur->apPage[pCur->iPage]->nCell > 0 ); - assert( pCur->apPage[0]->intKey==pCur->curIntKey ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); assert( pCur->curIntKey || pIdxKey ); for(;;){ int lwr, upr, idx, c; Pgno chldPg; - MemPage *pPage = pCur->apPage[pCur->iPage]; + MemPage *pPage = pCur->pPage; u8 *pCell; /* Pointer to current cell in pPage */ /* pPage->nCell must be greater than zero. If this is the root-page @@ -5369,7 +5375,7 @@ int sqlite3BtreeMovetoUnpacked( assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->ixpPage->nCell ); pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; @@ -5423,9 +5429,10 @@ i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ ** opcode, and it that case the cursor will always be valid and ** will always point to a leaf node. */ if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1; - if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1; + if( NEVER(pCur->pPage->leaf==0) ) return -1; - for(n=1, i=0; i<=pCur->iPage; i++){ + n = pCur->pPage->nCell; + for(i=0; iiPage; i++){ n *= pCur->apPage[i]->nCell; } return n; @@ -5478,7 +5485,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ } } - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; idx = ++pCur->ix; assert( pPage->isInit ); @@ -5501,7 +5508,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ return SQLITE_DONE; } moveToParent(pCur); - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; }while( pCur->ix>=pPage->nCell ); if( pPage->intKey ){ return sqlite3BtreeNext(pCur, 0); @@ -5524,7 +5531,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int flags){ pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur); - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; if( (++pCur->ix)>=pPage->nCell ){ pCur->ix--; return btreeNext(pCur); @@ -5583,7 +5590,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ } } - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; assert( pPage->isInit ); if( !pPage->leaf ){ int idx = pCur->ix; @@ -5602,7 +5609,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 ); pCur->ix--; - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; if( pPage->intKey && !pPage->leaf ){ rc = sqlite3BtreePrevious(pCur, 0); }else{ @@ -5620,7 +5627,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int flags){ pCur->info.nSize = 0; if( pCur->eState!=CURSOR_VALID || pCur->ix==0 - || pCur->apPage[pCur->iPage]->leaf==0 + || pCur->pPage->leaf==0 ){ return btreePrevious(pCur); } @@ -7934,7 +7941,7 @@ static int balance(BtCursor *pCur){ do { int iPage = pCur->iPage; - MemPage *pPage = pCur->apPage[iPage]; + MemPage *pPage = pCur->pPage; if( iPage==0 ){ if( pPage->nOverflow ){ @@ -7950,7 +7957,9 @@ static int balance(BtCursor *pCur){ pCur->iPage = 1; pCur->ix = 0; pCur->aiIdx[0] = 0; - assert( pCur->apPage[1]->nOverflow ); + pCur->apPage[0] = pPage; + pCur->pPage = pCur->apPage[1]; + assert( pCur->pPage->nOverflow ); } }else{ break; @@ -8030,6 +8039,7 @@ static int balance(BtCursor *pCur){ releasePage(pPage); pCur->iPage--; assert( pCur->iPage>=0 ); + pCur->pPage = pCur->apPage[pCur->iPage]; } }while( rc==SQLITE_OK ); @@ -8161,7 +8171,7 @@ int sqlite3BtreeInsert( } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); @@ -8248,7 +8258,7 @@ int sqlite3BtreeInsert( ** fails. Internal data structure corruption will result otherwise. ** Also, set the cursor state to invalid. This stops saveCursorPosition() ** from trying to save the current position of the cursor. */ - pCur->apPage[pCur->iPage]->nOverflow = 0; + pCur->pPage->nOverflow = 0; pCur->eState = CURSOR_INVALID; if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){ btreeReleaseAllCursorPages(pCur); @@ -8265,7 +8275,7 @@ int sqlite3BtreeInsert( pCur->nKey = pX->nKey; } } - assert( pCur->iPage<0 || pCur->apPage[pCur->iPage]->nOverflow==0 ); + assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 ); end_insert: return rc; @@ -8306,13 +8316,13 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( pCur->curFlags & BTCF_WriteFlag ); assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); - assert( pCur->ixapPage[pCur->iPage]->nCell ); + assert( pCur->ixpPage->nCell ); assert( pCur->eState==CURSOR_VALID ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); iCellDepth = pCur->iPage; iCellIdx = pCur->ix; - pPage = pCur->apPage[iCellDepth]; + pPage = pCur->pPage; pCell = findCell(pPage, iCellIdx); /* If the bPreserve flag is set to true, then the cursor position must @@ -8378,11 +8388,16 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** node. The cell from the leaf node needs to be moved to the internal ** node to replace the deleted cell. */ if( !pPage->leaf ){ - MemPage *pLeaf = pCur->apPage[pCur->iPage]; + MemPage *pLeaf = pCur->pPage; int nCell; - Pgno n = pCur->apPage[iCellDepth+1]->pgno; + Pgno n; unsigned char *pTmp; + if( iCellDepthiPage-1 ){ + n = pCur->apPage[iCellDepth+1]->pgno; + }else{ + n = pCur->pPage->pgno; + } pCell = findCell(pLeaf, pLeaf->nCell-1); if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT; nCell = pLeaf->xCellSize(pLeaf, pCell); @@ -8414,16 +8429,19 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** well. */ rc = balance(pCur); if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + releasePageNotNull(pCur->pPage); + pCur->iPage--; while( pCur->iPage>iCellDepth ){ releasePage(pCur->apPage[pCur->iPage--]); } + pCur->pPage = pCur->apPage[pCur->iPage]; rc = balance(pCur); } if( rc==SQLITE_OK ){ if( bSkipnext ){ assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); - assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB ); + assert( pPage==pCur->pPage || CORRUPT_DB ); assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); pCur->eState = CURSOR_SKIPNEXT; if( iCellIdx>=pPage->nCell ){ @@ -8920,7 +8938,7 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ ** this page contains countable entries. Increment the entry counter ** accordingly. */ - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; if( pPage->leaf || !pPage->intKey ){ nEntry += pPage->nCell; } @@ -8943,10 +8961,10 @@ int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ return moveToRoot(pCur); } moveToParent(pCur); - }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell ); + }while ( pCur->ix>=pCur->pPage->nCell ); pCur->ix++; - pPage = pCur->apPage[pCur->iPage]; + pPage = pCur->pPage; } /* Descend to the child node of the cell that the cursor currently @@ -9787,7 +9805,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ && pCsr->pBt->inTransaction==TRANS_WRITE ); assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); - assert( pCsr->apPage[pCsr->iPage]->intKey ); + assert( pCsr->pPage->intKey ); return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); } diff --git a/src/btreeInt.h b/src/btreeInt.h index 77069783c7..f4e5f45fec 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -522,7 +522,8 @@ struct BtCursor { u16 ix; /* Current index for apPage[iPage] */ u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */ struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */ - MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ + MemPage *pPage; /* Current page */ + MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */ }; /* From 6cd8c8c57a249feac637ea97f21a8d3de7670de3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 15 Aug 2017 14:14:36 +0000 Subject: [PATCH 11/53] Small size and performance in the OP_Column opcode. FossilOrigin-Name: 2cf3f3de8a48465bd6b0af7763bfe905f3bb0151488f63c9ecc3147bcb345094 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 16 ++++++---------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 3ee6a346e3..43be9dbc63 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Btree\soptimization:\s\sNew\sfield\sBtCursor.pPage\sthat\spoints\sto\sthe\scurrent\spage,\nsaving\sa\ssingle\spointer\sdereference\son\seach\saccess. -D 2017-08-15T03:46:47.011 +C Small\ssize\sand\sperformance\sin\sthe\sOP_Column\sopcode. +D 2017-08-15T14:14:36.511 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -522,7 +522,7 @@ F src/update.c 5404be9e840717323a69209190cdbc9d0d34adaedaaf1d1a1069babf2c4171c0 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 -F src/vdbe.c 821b3edde2d17ec60da0617db1018a88f38634c359d22f3c8f7be10336c82636 +F src/vdbe.c ebfc41ca25465888b2dc2969a0059d0d563c2a36e31696352573198cdec51fad F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911 F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc @@ -1647,7 +1647,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 16969338841734d00ab906a94b82480c7e1e426eb0ddf7b9e6aed722aee5d91f -R 3d6cdbe8a873abb5b839027115a07163 +P 373b71d19cad785922d5a80828f2fee0cbe7dff6594743e625bbdfa31b1ca131 +R 36da37536a24b366658dfab60814a38c U drh -Z 53459ac0c08285b40b84acbd692920bc +Z 16cc8098bdc3d63f9bef627e24ebd270 diff --git a/manifest.uuid b/manifest.uuid index d331463c6a..f58cbd3506 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -373b71d19cad785922d5a80828f2fee0cbe7dff6594743e625bbdfa31b1ca131 \ No newline at end of file +2cf3f3de8a48465bd6b0af7763bfe905f3bb0151488f63c9ecc3147bcb345094 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index d04a4f2c91..e44f06f3c9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2388,7 +2388,6 @@ case OP_Column: { const u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset */ - u32 avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ @@ -2419,7 +2418,7 @@ case OP_Column: { pReg = &aMem[pC->uc.pseudoTableReg]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); - pC->payloadSize = pC->szRow = avail = pReg->n; + pC->payloadSize = pC->szRow = pReg->n; pC->aRow = (u8*)pReg->z; }else{ sqlite3VdbeMemSetNull(pDest); @@ -2431,14 +2430,11 @@ case OP_Column: { assert( pCrsr ); assert( sqlite3BtreeCursorIsValid(pCrsr) ); pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); - pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail); - assert( avail<=65536 ); /* Maximum page size is 64KiB */ - if( pC->payloadSize <= (u32)avail ){ - pC->szRow = pC->payloadSize; - }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); + assert( pC->szRow<=pC->payloadSize ); + assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ + if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; - }else{ - pC->szRow = avail; } } pC->cacheStatus = p->cacheCtr; @@ -2447,7 +2443,7 @@ case OP_Column: { aOffset[0] = offset; - if( availszRowaRow does not have to hold the entire row, but it does at least ** need to cover the header of the record. If pC->aRow does not contain ** the complete header, then set it to zero, forcing the header to be From 95b225a46d53ab790ec88eff9ade14403c8fe3eb Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Aug 2017 11:04:22 +0000 Subject: [PATCH 12/53] Performance improvement in the OP_Column opcode. FossilOrigin-Name: dc98a92f32511ee322b0207bd286e967248a8e59b418f11168eb31e34b0fa0fa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 30 +++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 43be9dbc63..251d1e672d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sand\sperformance\sin\sthe\sOP_Column\sopcode. -D 2017-08-15T14:14:36.511 +C Performance\simprovement\sin\sthe\sOP_Column\sopcode. +D 2017-08-16T11:04:22.469 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -522,7 +522,7 @@ F src/update.c 5404be9e840717323a69209190cdbc9d0d34adaedaaf1d1a1069babf2c4171c0 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 -F src/vdbe.c ebfc41ca25465888b2dc2969a0059d0d563c2a36e31696352573198cdec51fad +F src/vdbe.c 8530c38ffc19400cf9634d2e55b9c6141d276350e6ea6d99a003cd6963fbf20a F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911 F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc @@ -1647,7 +1647,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 373b71d19cad785922d5a80828f2fee0cbe7dff6594743e625bbdfa31b1ca131 -R 36da37536a24b366658dfab60814a38c +P 2cf3f3de8a48465bd6b0af7763bfe905f3bb0151488f63c9ecc3147bcb345094 +R 1db09713c9077dbfc76327c90333340a U drh -Z 16cc8098bdc3d63f9bef627e24ebd270 +Z 65fa1f244e3ef6aef2172aa886d1ccda diff --git a/manifest.uuid b/manifest.uuid index f58cbd3506..5e9b037d44 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2cf3f3de8a48465bd6b0af7763bfe905f3bb0151488f63c9ecc3147bcb345094 \ No newline at end of file +dc98a92f32511ee322b0207bd286e967248a8e59b418f11168eb31e34b0fa0fa \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e44f06f3c9..c7ef2ef6a1 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2464,13 +2464,23 @@ case OP_Column: { rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } - }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/ - /* The following goto is an optimization. It can be omitted and - ** everything will still work. But OP_Column is measurably faster - ** by skipping the subsequent conditional, which is always true. + }else{ + /* This is an optimization. By skipping over the first few tests + ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a + ** measurable performance gain. + ** + ** This branch is taken even if offset==0. Such a record is never + ** generated by SQLite, and could be considered corruption, but we + ** accept it for historical reasons. When offset==0, the code this + ** branch jumps to reads past the end of the record, but never more + ** than a few bytes. Even if the record occurs at the end of the page + ** content area, the "page header" comes after the page content and so + ** this overread is harmless. Similar overreads can occur for a corrupt + ** database file. */ zData = pC->aRow; assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ + testcase( offset==0 ); goto op_column_read_header; } } @@ -2499,6 +2509,7 @@ case OP_Column: { offset64 = aOffset[i]; zHdr = zData + pC->iHdrOffset; zEndHdr = zData + aOffset[0]; + testcase( zHdr>=zEndHdr ); do{ if( (t = zHdr[0])<0x80 ){ zHdr++; @@ -2519,9 +2530,14 @@ case OP_Column: { if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize)) || (offset64 > pC->payloadSize) ){ - if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; + if( aOffset[0]==0 ){ + i = 0; + zHdr = zEndHdr; + }else{ + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } } pC->nHdrParsed = i; From 1f613c4df389356a3a679cca0066e9381e39467e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Aug 2017 14:16:19 +0000 Subject: [PATCH 13/53] Remove an unnecessary local variable from OP_Column, for a small size reduction and performance increase. FossilOrigin-Name: 39543903282409ad3f139f8a0bb376661e7595a33af4f647945b1513a028ccb4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 14 ++++++-------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 251d1e672d..514232a7c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sin\sthe\sOP_Column\sopcode. -D 2017-08-16T11:04:22.469 +C Remove\san\sunnecessary\slocal\svariable\sfrom\sOP_Column,\sfor\sa\ssmall\ssize\nreduction\sand\sperformance\sincrease. +D 2017-08-16T14:16:19.879 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -522,7 +522,7 @@ F src/update.c 5404be9e840717323a69209190cdbc9d0d34adaedaaf1d1a1069babf2c4171c0 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 -F src/vdbe.c 8530c38ffc19400cf9634d2e55b9c6141d276350e6ea6d99a003cd6963fbf20a +F src/vdbe.c c8e7bec8764b26b8e80fadffab2b9c18e8ed5ab2e92d1be5a7aebeed18ca8be5 F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911 F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc @@ -1647,7 +1647,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 2cf3f3de8a48465bd6b0af7763bfe905f3bb0151488f63c9ecc3147bcb345094 -R 1db09713c9077dbfc76327c90333340a +P dc98a92f32511ee322b0207bd286e967248a8e59b418f11168eb31e34b0fa0fa +R 8dc9658e95fe266a68d077704d4afe1a U drh -Z 65fa1f244e3ef6aef2172aa886d1ccda +Z 4fdaa02107e5a271b3b6d501790c7a7c diff --git a/manifest.uuid b/manifest.uuid index 5e9b037d44..e7180c4267 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc98a92f32511ee322b0207bd286e967248a8e59b418f11168eb31e34b0fa0fa \ No newline at end of file +39543903282409ad3f139f8a0bb376661e7595a33af4f647945b1513a028ccb4 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c7ef2ef6a1..a4665ce79c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2386,7 +2386,6 @@ case OP_Column: { const u8 *zData; /* Part of the record being decoded */ const u8 *zHdr; /* Next unparsed byte of the header */ const u8 *zEndHdr; /* Pointer to first byte after the header */ - u32 offset; /* Offset into the data */ u64 offset64; /* 64-bit offset */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ @@ -2438,12 +2437,11 @@ case OP_Column: { } } pC->cacheStatus = p->cacheCtr; - pC->iHdrOffset = getVarint32(pC->aRow, offset); + pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]); pC->nHdrParsed = 0; - aOffset[0] = offset; - if( pC->szRowszRowaRow does not have to hold the entire row, but it does at least ** need to cover the header of the record. If pC->aRow does not contain ** the complete header, then set it to zero, forcing the header to be @@ -2460,7 +2458,7 @@ case OP_Column: { ** 3-byte type for each of the maximum of 32768 columns plus three ** extra bytes for the header length itself. 32768*3 + 3 = 98307. */ - if( offset > 98307 || offset > pC->payloadSize ){ + if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){ rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } @@ -2469,9 +2467,9 @@ case OP_Column: { ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a ** measurable performance gain. ** - ** This branch is taken even if offset==0. Such a record is never + ** This branch is taken even if aOffset[0]==0. Such a record is never ** generated by SQLite, and could be considered corruption, but we - ** accept it for historical reasons. When offset==0, the code this + ** accept it for historical reasons. When aOffset[0]==0, the code this ** branch jumps to reads past the end of the record, but never more ** than a few bytes. Even if the record occurs at the end of the page ** content area, the "page header" comes after the page content and so @@ -2480,7 +2478,7 @@ case OP_Column: { */ zData = pC->aRow; assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */ - testcase( offset==0 ); + testcase( aOffset[0]==0 ); goto op_column_read_header; } } From fe0cf7a18c665b991a87e8329788563b750f9d9d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 16 Aug 2017 19:20:20 +0000 Subject: [PATCH 14/53] Avoid a test for CURTYPE_BTREE in sqlite3VdbeCursorMoveto() in order to reduce the size and improve the performance of OP_Column. FossilOrigin-Name: f078deb25149b7b1881b7f3374b343d0677e82336d8fdd7f1cdd06d926b5dd57 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/btree.c | 11 +++++++++++ src/btree.h | 1 + src/btreeInt.h | 10 +++++----- src/vdbe.c | 13 ++++++++++--- src/vdbeInt.h | 12 ++++++------ src/vdbeaux.c | 23 +++++++++++------------ 8 files changed, 56 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 514232a7c7..5543cf3302 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\slocal\svariable\sfrom\sOP_Column,\sfor\sa\ssmall\ssize\nreduction\sand\sperformance\sincrease. -D 2017-08-16T14:16:19.879 +C Avoid\sa\stest\sfor\sCURTYPE_BTREE\sin\ssqlite3VdbeCursorMoveto()\sin\sorder\sto\sreduce\nthe\ssize\sand\simprove\sthe\sperformance\sof\sOP_Column. +D 2017-08-16T19:20:20.392 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -397,9 +397,9 @@ F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c d2f5f347e56f8b7ed1bb798087045a3b98cd63f45fde7675fd24b9e88b61304d -F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca -F src/btreeInt.h f78671f594dafd88cf9a81253da04db81272b382d2dc074bb983d348b95d9d2d +F src/btree.c e1a98bef27d6189df5c5b8b3c9b5e53d6b74bf9a936af97757c21e9ea6a5c6b2 +F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 +F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc F src/callback.c 930648a084a3adc741c6471adfbdc50ba47ba3542421cb80a26f259f467de65e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e @@ -522,11 +522,11 @@ F src/update.c 5404be9e840717323a69209190cdbc9d0d34adaedaaf1d1a1069babf2c4171c0 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 -F src/vdbe.c c8e7bec8764b26b8e80fadffab2b9c18e8ed5ab2e92d1be5a7aebeed18ca8be5 +F src/vdbe.c 711a1b2c0a6046483ebf4ac43c4c0ea5bef3e50534a4ab9e1d7e3542635cd009 F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 -F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911 +F src/vdbeInt.h 1fe00770144c12c4913128f35262d11527ef3284561baaab59b947a41c08d0d9 F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc -F src/vdbeaux.c 1bef372f59f9e1dba5ead70cc5c24bf978bab0b9fdc2f69692afaa3a2d4dd8f3 +F src/vdbeaux.c 1f15018ef7abe22669967f70b02bfe6709be403f126f713dabb091b9d631859a F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b F src/vdbemem.c b7fac20534c79b7554dab2e8a180c585a8bc1b9c85149d1b2d9746cf314d06ed F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e3 @@ -1647,7 +1647,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 dc98a92f32511ee322b0207bd286e967248a8e59b418f11168eb31e34b0fa0fa -R 8dc9658e95fe266a68d077704d4afe1a +P 39543903282409ad3f139f8a0bb376661e7595a33af4f647945b1513a028ccb4 +R 6446f3c323d2c08f3899473bfc8c1574 U drh -Z 4fdaa02107e5a271b3b6d501790c7a7c +Z 68326b6d5ed2188a1ee820e19559d5ac diff --git a/manifest.uuid b/manifest.uuid index e7180c4267..eb2dc719d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39543903282409ad3f139f8a0bb376661e7595a33af4f647945b1513a028ccb4 \ No newline at end of file +f078deb25149b7b1881b7f3374b343d0677e82336d8fdd7f1cdd06d926b5dd57 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 50981b0575..ecdbb6d0a3 100644 --- a/src/btree.c +++ b/src/btree.c @@ -838,6 +838,17 @@ int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ return pCur->eState!=CURSOR_VALID; } +/* +** Return a pointer to a fake BtCursor object that will always answer +** false to the sqlite3BtreeCursorHasMoved() routine above. The fake +** cursor returned must not be used with any other Btree interface. +*/ +BtCursor *sqlite3BtreeFakeValidCursor(void){ + static u8 fakeCursor = CURSOR_VALID; + assert( offsetof(BtCursor, eState)==0 ); + return (BtCursor*)&fakeCursor; +} + /* ** This routine restores a cursor back to its original position after it ** has been moved by some outside activity (such as a btree rebalance or diff --git a/src/btree.h b/src/btree.h index b56eb85e68..e2c271cdc5 100644 --- a/src/btree.h +++ b/src/btree.h @@ -230,6 +230,7 @@ int sqlite3BtreeCursor( struct KeyInfo*, /* First argument to compare function */ BtCursor *pCursor /* Space to write cursor structure */ ); +BtCursor *sqlite3BtreeFakeValidCursor(void); int sqlite3BtreeCursorSize(void); void sqlite3BtreeCursorZero(BtCursor*); void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); diff --git a/src/btreeInt.h b/src/btreeInt.h index f4e5f45fec..ac7a3c0a26 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -499,6 +499,11 @@ struct CellInfo { ** eState==FAULT: Cursor fault with skipNext as error code. */ struct BtCursor { + u8 eState; /* One of the CURSOR_XXX constants (see below) */ + u8 curFlags; /* zero or more BTCF_* flags defined below */ + u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ + u8 hints; /* As configured by CursorSetHints() */ + int nOvflAlloc; /* Allocated size of aOverflow[] array */ Btree *pBtree; /* The Btree to which this cursor belongs */ BtShared *pBt; /* The BtShared this cursor points to */ BtCursor *pNext; /* Forms a linked list of all cursors */ @@ -507,13 +512,8 @@ struct BtCursor { i64 nKey; /* Size of pKey, or last integer key */ void *pKey; /* Saved key that was cursor last known position */ Pgno pgnoRoot; /* The root page of this tree */ - int nOvflAlloc; /* Allocated size of aOverflow[] array */ int skipNext; /* Prev() is noop if negative. Next() is noop if positive. ** Error code if eState==CURSOR_FAULT */ - u8 curFlags; /* zero or more BTCF_* flags defined below */ - u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ - u8 eState; /* One of the CURSOR_XXX constants (see below) */ - u8 hints; /* As configured by CursorSetHints() */ /* All fields above are zeroed when the cursor is allocated. See ** sqlite3BtreeCursorZero(). Fields that follow must be manually ** initialized. */ diff --git a/src/vdbe.c b/src/vdbe.c index a4665ce79c..3f5d967d2d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2413,8 +2413,10 @@ case OP_Column: { if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ if( pC->eCurType==CURTYPE_PSEUDO ){ - assert( pC->uc.pseudoTableReg>0 ); - pReg = &aMem[pC->uc.pseudoTableReg]; + /* For the special case of as pseudo-cursor, the seekResult field + ** identifies the register that holds the record */ + assert( pC->seekResult>0 ); + pReg = &aMem[pC->seekResult]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); pC->payloadSize = pC->szRow = pReg->n; @@ -3628,8 +3630,13 @@ case OP_OpenPseudo: { pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; - pCx->uc.pseudoTableReg = pOp->p2; + pCx->seekResult = pOp->p2; pCx->isTable = 1; + /* Give this pseudo-cursor a fake BtCursor pointer so that pCx + ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test + ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto() + ** which is a performance optimization */ + pCx->uc.pCursor = sqlite3BtreeFakeValidCursor(); assert( pOp->p5==0 ); break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index d8e47be500..cb783653c0 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -96,18 +96,18 @@ struct VdbeCursor { u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 ** if there have been no prior seeks on the cursor. */ - /* NB: seekResult does not distinguish between "no seeks have ever occurred - ** on this cursor" and "the most recent seek was an exact match". */ + /* seekResult does not distinguish between "no seeks have ever occurred + ** on this cursor" and "the most recent seek was an exact match". + ** For CURTYPE_PSEUDO, seekResult is the register holding the record */ /* When a new VdbeCursor is allocated, only the fields above are zeroed. ** The fields that follow are uninitialized, and must be individually ** initialized prior to first use. */ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ union { - BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */ - sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ - int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */ - VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ + BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */ + sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ + VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ u32 iHdrOffset; /* Offset to next unparsed byte of the header */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 226b2152ed..7f6632bfa4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3139,19 +3139,18 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){ */ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ VdbeCursor *p = *pp; - if( p->eCurType==CURTYPE_BTREE ){ - if( p->deferredMoveto ){ - int iMap; - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ - *pp = p->pAltCursor; - *piCol = iMap - 1; - return SQLITE_OK; - } - return handleDeferredMoveto(p); - } - if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ - return handleMovedCursor(p); + assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); + if( p->deferredMoveto ){ + int iMap; + if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ + *pp = p->pAltCursor; + *piCol = iMap - 1; + return SQLITE_OK; } + return handleDeferredMoveto(p); + } + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + return handleMovedCursor(p); } return SQLITE_OK; } From dc6b41ed4791d3ccfb2a311df03d32b09220a690 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Aug 2017 02:26:35 +0000 Subject: [PATCH 15/53] Defer schema resets when the query planner is running. Proposed fix for ticket [be436a7f4587ce517]. FossilOrigin-Name: a7bc7752ba0266684f5317e424a4ee9add4af002272082183519e708ab9ffc79 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 41 +++++++++++++++++++++++------------------ src/callback.c | 2 +- src/prepare.c | 3 ++- src/sqliteInt.h | 2 ++ 6 files changed, 38 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index 5543cf3302..e83548519d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\stest\sfor\sCURTYPE_BTREE\sin\ssqlite3VdbeCursorMoveto()\sin\sorder\sto\sreduce\nthe\ssize\sand\simprove\sthe\sperformance\sof\sOP_Column. -D 2017-08-16T19:20:20.392 +C Defer\sschema\sresets\swhen\sthe\squery\splanner\sis\srunning.\nProposed\sfix\sfor\sticket\s[be436a7f4587ce517]. +D 2017-08-17T02:26:35.841 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -400,8 +400,8 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c e1a98bef27d6189df5c5b8b3c9b5e53d6b74bf9a936af97757c21e9ea6a5c6b2 F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc -F src/build.c f8a85d2ad14c2201e10c2fe7185e1cb3f1db8b0c90d40d1fb99c20b135ab71bc -F src/callback.c 930648a084a3adc741c6471adfbdc50ba47ba3542421cb80a26f259f467de65e +F src/build.c 559bce114d59bb6dd795a7985a9eaac781d374ff31422d134dc147f9667a4d21 +F src/callback.c 28a8ede982fde4129b828350f78f2c01fe7d12c74d1a0a05d7108ab36f308688 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74 @@ -449,7 +449,7 @@ F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 -F src/prepare.c 3cbb99757d7295997674972f9dd2331c5c544368854ca08954c9beb1e9b6145a +F src/prepare.c 5da8a0563eff02e23584ec32863273eb3b1ac30bc736e1084efbcbf7379d1a56 F src/printf.c 439c145d71ff9e0328ec26b7db23a45f995f742d3207dd546e034cdc1667ac9c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 @@ -460,7 +460,7 @@ F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c17 F src/sqlite.h.in f0bd1abf5e27bd22b3bcaae2a861c1efc4ab7e752bf7eb102355135617eb8199 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 -F src/sqliteInt.h 854a122ff0ebde410a66d4f967e9923de9002f73965c6c9fa0db544bf7e657d1 +F src/sqliteInt.h 6dddca4e215f4088aeaf60aebaa6d913397d61422733e160f25ab9dc53605a36 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1647,7 +1647,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 39543903282409ad3f139f8a0bb376661e7595a33af4f647945b1513a028ccb4 -R 6446f3c323d2c08f3899473bfc8c1574 +P f078deb25149b7b1881b7f3374b343d0677e82336d8fdd7f1cdd06d926b5dd57 +R 1aca6a5cd400a792803d04295cde6ca8 U drh -Z 68326b6d5ed2188a1ee820e19559d5ac +Z ee696b9e27abcfab805d4537aa8e005a diff --git a/manifest.uuid b/manifest.uuid index eb2dc719d5..3c1067b3fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f078deb25149b7b1881b7f3374b343d0677e82336d8fdd7f1cdd06d926b5dd57 \ No newline at end of file +a7bc7752ba0266684f5317e424a4ee9add4af002272082183519e708ab9ffc79 \ No newline at end of file diff --git a/src/build.c b/src/build.c index cb3172e076..d64eac009e 100644 --- a/src/build.c +++ b/src/build.c @@ -514,28 +514,26 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){ /* ** Reset the schema for the database at index iDb. Also reset the -** TEMP schema. +** TEMP schema. The reset is deferred if db->nSchemaLock is not zero. +** Deferred resets may be run by calling with iDb<0. */ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ - Db *pDb; + int i; assert( iDbnDb ); - /* Case 1: Reset the single schema identified by iDb */ - pDb = &db->aDb[iDb]; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - assert( pDb->pSchema!=0 ); - sqlite3SchemaClear(pDb->pSchema); - - /* If any database other than TEMP is reset, then also reset TEMP - ** since TEMP might be holding triggers that reference tables in the - ** other database. - */ - if( iDb!=1 ){ - pDb = &db->aDb[1]; - assert( pDb->pSchema!=0 ); - sqlite3SchemaClear(pDb->pSchema); + if( iDb>=0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + DbSetProperty(db, iDb, DB_ResetWanted); + DbSetProperty(db, 1, DB_ResetWanted); + } + + if( db->nSchemaLock==0 ){ + for(i=0; inDb; i++){ + if( DbHasProperty(db, i, DB_ResetWanted) ){ + sqlite3SchemaClear(db->aDb[i].pSchema); + } + } } - return; } /* @@ -545,6 +543,7 @@ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ int i; sqlite3BtreeEnterAll(db); + assert( db->nSchemaLock==0 ); for(i=0; inDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ @@ -2155,6 +2154,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int rc; +#endif #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth; /* Saved xAuth pointer */ #endif @@ -2162,7 +2164,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3VtabCallConnect(pParse, pTable) ){ + db->nSchemaLock++; + rc = sqlite3VtabCallConnect(pParse, pTable); + db->nSchemaLock--; + if( rc ){ return SQLITE_ERROR; } if( IsVirtual(pTable) ) return 0; diff --git a/src/callback.c b/src/callback.c index 10505414c1..e08924b2c2 100644 --- a/src/callback.c +++ b/src/callback.c @@ -457,8 +457,8 @@ void sqlite3SchemaClear(void *p){ pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ pSchema->iGeneration++; - pSchema->schemaFlags &= ~DB_SchemaLoaded; } + pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); } /* diff --git a/src/prepare.c b/src/prepare.c index 4fa59e5bef..c31b810820 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -686,7 +686,8 @@ static int sqlite3LockAndPrepare( sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); - if( rc==SQLITE_SCHEMA ){ + if( rc==SQLITE_SCHEMA && db->nSchemaLock==0 ){ + sqlite3ResetOneSchema(db, -1); sqlite3_finalize(*ppStmt); rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c457b5401b..8aa9832e8a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1213,6 +1213,7 @@ 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 */ /* ** The number of different kinds of things that can be limited @@ -1329,6 +1330,7 @@ struct sqlite3 { u32 flags; /* flags settable by pragmas. See below */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 szMmap; /* Default mmap_size setting */ + u32 nSchemaLock; /* Do not reset the schema when non-zero */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ From 865c3c58ab14ff1b520e709a49232f9d48e79aea Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 17 Aug 2017 14:12:16 +0000 Subject: [PATCH 16/53] Add test cases for ticket [be436a7f4587ce517] using virtual table modules fts5 and rtree. FossilOrigin-Name: 2101b4208787d297788e05f2bd82d4a9aff26e2237a7016ac857a52fb5252ce0 --- ext/fts5/test/fts5connect.test | 247 +++++++++++++++++++++++++++++++++ ext/rtree/rtreeconnect.test | 56 ++++++++ manifest | 14 +- manifest.uuid | 2 +- 4 files changed, 312 insertions(+), 7 deletions(-) create mode 100644 ext/fts5/test/fts5connect.test create mode 100644 ext/rtree/rtreeconnect.test diff --git a/ext/fts5/test/fts5connect.test b/ext/fts5/test/fts5connect.test new file mode 100644 index 0000000000..c615d4c734 --- /dev/null +++ b/ext/fts5/test/fts5connect.test @@ -0,0 +1,247 @@ +# 2017 August 17 +# +# 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. +# +#************************************************************************* +# + + + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5connect + +ifcapable !fts5 { + finish_test + return +} + +#------------------------------------------------------------------------- +# The tests in this file test the outcome of a schema-reset happening +# within the xConnect() method of an FTS5 table. At one point this +# was causing a problem in SQLite. Each test proceeds as follows: +# +# 1. Connection [db] opens the db and reads from some unrelated, non-FTS5 +# table causing SQLite to load the db schema into memory. +# +# 2. Connection [db2] opens the db and modifies the db schema. +# +# 3. Connection [db] reads or writes an existing fts5 table. That the +# schema has been modified is detected inside the fts5 xConnect() +# callback that is invoked by sqlite3_prepare(). +# +# 4. Verify that the statement in 3 has worked. SQLite should detect +# that the schema has changed and successfully prepare the +# statement against the new schema. +# +# Test plan: +# +# 1.*: Trigger the xConnect()/schema-reset using statements executed +# directly against an FTS5 table. +# +# 2.*: Using various statements executed by various BEFORE triggers. +# +# 3.*: Using various statements executed by various AFTER triggers. +# +# 4.*: Using various statements executed by various INSTEAD OF triggers. +# + + + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft1 USING fts5(a, b); + CREATE TABLE abc(x INTEGER PRIMARY KEY); + CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b); + + INSERT INTO ft1 VALUES('one', 'two'); + INSERT INTO ft1 VALUES('three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM ft1" {one two three four} + 2 "REPLACE INTO ft1(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft1" {five six three four} + 4 "INSERT INTO ft1 VALUES('seven', 'eight')" {} + 5 "SELECT * FROM ft1" {five six three four seven eight} + 6 "DELETE FROM ft1 WHERE rowid=2" {} + 7 "UPDATE ft1 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft1" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 1.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 1.$tn.2 $sql $res + + do_execsql_test 1.$tn.3 { + INSERT INTO ft1(ft1) VALUES('integrity-check'); + } +} + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft2 USING fts5(a, b); + CREATE TABLE t2(a, b); + CREATE TABLE log(txt); + + CREATE TRIGGER t2_ai AFTER INSERT ON t2 BEGIN + INSERT INTO ft2(rowid, a, b) VALUES(new.rowid, new.a, new.b); + INSERT INTO log VALUES('insert'); + END; + + CREATE TRIGGER t2_ad AFTER DELETE ON t2 BEGIN + DELETE FROM ft2 WHERE rowid = old.rowid; + INSERT INTO log VALUES('delete'); + END; + + CREATE TRIGGER t2_au AFTER UPDATE ON t2 BEGIN + UPDATE ft2 SET a=new.a, b=new.b WHERE rowid=new.rowid; + INSERT INTO log VALUES('update'); + END; + + INSERT INTO t2 VALUES('one', 'two'); + INSERT INTO t2 VALUES('three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM t2" {one two three four} + 2 "REPLACE INTO t2(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft2" {five six three four} + 4 "INSERT INTO t2 VALUES('seven', 'eight')" {} + 5 "SELECT * FROM ft2" {five six three four seven eight} + 6 "DELETE FROM t2 WHERE rowid=2" {} + 7 "UPDATE t2 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft2" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 2.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 2.$tn.2 $sql $res + + do_execsql_test 2.$tn.3 { + INSERT INTO ft2(ft2) VALUES('integrity-check'); + } +} + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE ft3 USING fts5(a, b); + CREATE TABLE t3(a, b); + + CREATE TRIGGER t3_ai BEFORE INSERT ON t3 BEGIN + INSERT INTO ft3(rowid, a, b) VALUES(new.rowid, new.a, new.b); + INSERT INTO log VALUES('insert'); + END; + + CREATE TRIGGER t3_ad BEFORE DELETE ON t3 BEGIN + DELETE FROM ft3 WHERE rowid = old.rowid; + INSERT INTO log VALUES('delete'); + END; + + CREATE TRIGGER t3_au BEFORE UPDATE ON t3 BEGIN + UPDATE ft3 SET a=new.a, b=new.b WHERE rowid=new.rowid; + INSERT INTO log VALUES('update'); + END; + + INSERT INTO t3(rowid, a, b) VALUES(1, 'one', 'two'); + INSERT INTO t3(rowid, a, b) VALUES(2, 'three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM t3" {one two three four} + 2 "REPLACE INTO t3(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft3" {five six three four} + 4 "INSERT INTO t3(rowid, a, b) VALUES(3, 'seven', 'eight')" {} + 5 "SELECT * FROM ft3" {five six three four seven eight} + 6 "DELETE FROM t3 WHERE rowid=2" {} + 7 "UPDATE t3 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft3" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 3.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 3.$tn.2 $sql $res + + do_execsql_test 3.$tn.3 { + INSERT INTO ft3(ft3) VALUES('integrity-check'); + } +} + +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE ft4 USING fts5(a, b); + CREATE VIEW v4 AS SELECT rowid, * FROM ft4; + + CREATE TRIGGER t4_ai INSTEAD OF INSERT ON v4 BEGIN + INSERT INTO ft4(rowid, a, b) VALUES(new.rowid, new.a, new.b); + INSERT INTO log VALUES('insert'); + END; + + CREATE TRIGGER t4_ad INSTEAD OF DELETE ON v4 BEGIN + DELETE FROM ft4 WHERE rowid = old.rowid; + INSERT INTO log VALUES('delete'); + END; + + CREATE TRIGGER t4_au INSTEAD OF UPDATE ON v4 BEGIN + UPDATE ft4 SET a=new.a, b=new.b WHERE rowid=new.rowid; + INSERT INTO log VALUES('update'); + END; + + INSERT INTO ft4(rowid, a, b) VALUES(1, 'one', 'two'); + INSERT INTO ft4(rowid, a, b) VALUES(2, 'three', 'four'); +} + +foreach {tn sql res} { + 1 "SELECT * FROM ft4" {one two three four} + 2 "REPLACE INTO v4(rowid, a, b) VALUES(1, 'five', 'six')" {} + 3 "SELECT * FROM ft4" {five six three four} + 4 "INSERT INTO v4(rowid, a, b) VALUES(3, 'seven', 'eight')" {} + 5 "SELECT * FROM ft4" {five six three four seven eight} + 6 "DELETE FROM v4 WHERE rowid=2" {} + 7 "UPDATE v4 SET b='nine' WHERE rowid=1" {} + 8 "SELECT * FROM ft4" {five nine seven eight} +} { + + catch { db close } + catch { db2 close } + sqlite3 db test.db + sqlite3 db2 test.db + + do_test 4.$tn.1 { + db eval { INSERT INTO abc DEFAULT VALUES } + db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable } + } {} + + do_execsql_test 4.$tn.2 $sql $res + + do_execsql_test 4.$tn.3 { + INSERT INTO ft3(ft3) VALUES('integrity-check'); + } +} + +finish_test + diff --git a/ext/rtree/rtreeconnect.test b/ext/rtree/rtreeconnect.test new file mode 100644 index 0000000000..16d04d9a04 --- /dev/null +++ b/ext/rtree/rtreeconnect.test @@ -0,0 +1,56 @@ +# 2017 August 17 +# +# 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. +# +#*********************************************************************** +# +# The focus of this file is testing the r-tree extension. Specifically, +# the impact of an SQLITE_SCHEMA error within the rtree module xConnect +# callback. +# + + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source $testdir/tester.tcl +set testprefix rtreeconnect + +ifcapable !rtree { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE r1 USING rtree(id, x1, x2, y1, y2); + CREATE TABLE t1(id, x1, x2, y1, y2); + CREATE TABLE log(l); + + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO r1 VALUES(new.id, new.x1, new.x2, new.y1, new.y2); + INSERT INTO log VALUES('r1: ' || new.id); + END; +} + +db close +sqlite3 db test.db +sqlite3 db2 test.db + +do_test 1.1 { + db eval { INSERT INTO log VALUES('startup'); } + db2 eval { CREATE TABLE newtable(x,y); } +} {} + +do_execsql_test 1.2 { + INSERT INTO t1 VALUES(1, 2, 3, 4, 5); +} + +db2 close +db close + +finish_test diff --git a/manifest b/manifest index e83548519d..0c8553907a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Defer\sschema\sresets\swhen\sthe\squery\splanner\sis\srunning.\nProposed\sfix\sfor\sticket\s[be436a7f4587ce517]. -D 2017-08-17T02:26:35.841 +C Add\stest\scases\sfor\sticket\s[be436a7f4587ce517]\susing\svirtual\stable\smodules\sfts5\nand\srtree. +D 2017-08-17T14:12:16.980 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -140,6 +140,7 @@ F ext/fts5/test/fts5colset.test a30473451321bbf0b6218af62e96b4ae5fa99931cfdb210b F ext/fts5/test/fts5columnsize.test 45459ce4dd9fd853b6044cdc9674921bff89e3d840f348ca8c1630f9edbf5482 F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825ce437d26afe0817f F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d +F ext/fts5/test/fts5connect.test b12a2a8b02af3c31c18abbc33aa8100d364de19a888a44457484d21dbccb18a7 F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116 F ext/fts5/test/fts5corrupt.test 8957f0f7e57e0f8a102c5b6e1a7326d6a1966b28e1d99c5883822af1e6038e9e F ext/fts5/test/fts5corrupt2.test 6deaf9f9606b3c957529db9881622bb3a7829b19bb3cdf8f276f074d684ede56 @@ -343,6 +344,7 @@ F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4 F ext/rtree/rtreeG.test 3b185719630795f38594f64cd7d1de86a33f91f1 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea +F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d F ext/rtree/sqlite3rtree.h 9c5777af3d2921c7b4ae4954e8e5697502289d28 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 @@ -1647,7 +1649,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 f078deb25149b7b1881b7f3374b343d0677e82336d8fdd7f1cdd06d926b5dd57 -R 1aca6a5cd400a792803d04295cde6ca8 -U drh -Z ee696b9e27abcfab805d4537aa8e005a +P a7bc7752ba0266684f5317e424a4ee9add4af002272082183519e708ab9ffc79 +R c613de5ae36b19d57fec37de442df285 +U dan +Z ec0c29a7c81c6674b289e2e6cbe8b9e8 diff --git a/manifest.uuid b/manifest.uuid index 3c1067b3fc..fd647ce99e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7bc7752ba0266684f5317e424a4ee9add4af002272082183519e708ab9ffc79 \ No newline at end of file +2101b4208787d297788e05f2bd82d4a9aff26e2237a7016ac857a52fb5252ce0 \ No newline at end of file From 967f8f9e0717de8c8127755a3ca770d8b26858dc Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Aug 2017 14:47:56 +0000 Subject: [PATCH 17/53] Remove an unnecessary branch from the [be436a7f4587ce517ddc] fix. FossilOrigin-Name: fb6ca99b88c67414eab425e2b4ddb6a5e2fd48a6b2cd96a34627c86a5b568c9b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/prepare.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0c8553907a..427ca49809 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\sticket\s[be436a7f4587ce517]\susing\svirtual\stable\smodules\sfts5\nand\srtree. -D 2017-08-17T14:12:16.980 +C Remove\san\sunnecessary\sbranch\sfrom\sthe\s[be436a7f4587ce517ddc]\sfix. +D 2017-08-17T14:47:56.368 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -451,7 +451,7 @@ F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 -F src/prepare.c 5da8a0563eff02e23584ec32863273eb3b1ac30bc736e1084efbcbf7379d1a56 +F src/prepare.c 9e880c0efb5d7f9101bb34c0a87daf6e1e5284c34024fdb811e67bb02fdd299b F src/printf.c 439c145d71ff9e0328ec26b7db23a45f995f742d3207dd546e034cdc1667ac9c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 @@ -1649,7 +1649,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 a7bc7752ba0266684f5317e424a4ee9add4af002272082183519e708ab9ffc79 -R c613de5ae36b19d57fec37de442df285 -U dan -Z ec0c29a7c81c6674b289e2e6cbe8b9e8 +P 2101b4208787d297788e05f2bd82d4a9aff26e2237a7016ac857a52fb5252ce0 +R a88a9175d0467a8bcee3d90b3070177c +U drh +Z f282ee329c3784824fa5652eca8490b4 diff --git a/manifest.uuid b/manifest.uuid index fd647ce99e..9e80a745e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2101b4208787d297788e05f2bd82d4a9aff26e2237a7016ac857a52fb5252ce0 \ No newline at end of file +fb6ca99b88c67414eab425e2b4ddb6a5e2fd48a6b2cd96a34627c86a5b568c9b \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index c31b810820..9f0704c947 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -686,7 +686,7 @@ static int sqlite3LockAndPrepare( sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); - if( rc==SQLITE_SCHEMA && db->nSchemaLock==0 ){ + if( rc==SQLITE_SCHEMA ){ sqlite3ResetOneSchema(db, -1); sqlite3_finalize(*ppStmt); rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); From 6362bbe68d26560660e017c0ed0c420f99fdb052 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Aug 2017 18:17:24 +0000 Subject: [PATCH 18/53] The RTREE extension should return SQLITE_CORRUPT_VTAB, not just SQLITE_CORRUPT when it encounters incorrectly formatted shadow tables. FossilOrigin-Name: 0712f057ef3dcd907984dda30f6d961a29b61c1d2b25627028c4e227ec85dbba --- ext/rtree/rtree.c | 2 +- ext/rtree/rtreeA.test | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index d97cb45491..40a8676d7b 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -3414,7 +3414,7 @@ static int getNodeSize( if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); }else if( pRtree->iNodeSize<(512-64) ){ - rc = SQLITE_CORRUPT; + rc = SQLITE_CORRUPT_VTAB; *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", pRtree->zName); } diff --git a/ext/rtree/rtreeA.test b/ext/rtree/rtreeA.test index 0a718a6f92..d583a15264 100644 --- a/ext/rtree/rtreeA.test +++ b/ext/rtree/rtreeA.test @@ -230,7 +230,7 @@ do_catchsql_test rtreeA-7.110 { } {1 {undersize RTree blobs in "t1_node"}} do_test rtreeA-7.120 { sqlite3_extended_errcode db -} {SQLITE_CORRUPT} +} {SQLITE_CORRUPT_VTAB} diff --git a/manifest b/manifest index 427ca49809..b2ab03eb02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sbranch\sfrom\sthe\s[be436a7f4587ce517ddc]\sfix. -D 2017-08-17T14:47:56.368 +C The\sRTREE\sextension\sshould\sreturn\sSQLITE_CORRUPT_VTAB,\snot\sjust\sSQLITE_CORRUPT\nwhen\sit\sencounters\sincorrectly\sformatted\sshadow\stables. +D 2017-08-17T18:17:24.544 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -324,7 +324,7 @@ F ext/rbu/sqlite3rbu.c 920941a6ff7dbbea0970717c43662878fda5c37e43752de329f0fdd76 F ext/rbu/sqlite3rbu.h 82c102e5ae41025e3b245d3d5944315f82811da85e2cd363a75caa97cbd0cd3e F ext/rbu/test_rbu.c ec18cfc69a104309df23c359e3c80306c9a6bdd1d2c53c8b70ae158e9832dcd6 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 4f1804b80ae06ddf7ff69192aacdceee283646dc6a328acb951f116147445212 +F ext/rtree/rtree.c cf84d52958a7ec6a506f1711e119db847ed6bb5dedde78a58e97503287afcda1 F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree1.test 4fdd60ae034e43f2fefc26492032d02e742e8b14d468b7c51d95a1e2fa47cf00 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba @@ -335,7 +335,7 @@ F ext/rtree/rtree6.test 773a90db2dce6a8353dd0d5b64bca69b29761196 F ext/rtree/rtree7.test 1fa710b9e6bf997a0c1a537b81be7bb6fded1971 F ext/rtree/rtree8.test 076d9d5b783b61b7a23a5ab45fc899551dfffd821974f36ee599ff29f4de7a61 F ext/rtree/rtree9.test 8bfa84dfaba1c897468a2448c28db0a00ad12d464225b5993c7814e907f3776f -F ext/rtree/rtreeA.test abb1e2434defc8cdc5e3195a18ead3681cae04565c06069251d1998796e77d55 +F ext/rtree/rtreeA.test c09ad3f76c08feac00770685ff50ca12966dc0c641bf19a982b26a80643b46d1 F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e F ext/rtree/rtreeC.test c0a9c67f2efa98b6fae12acb8a28348d231a481d F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc @@ -1649,7 +1649,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 2101b4208787d297788e05f2bd82d4a9aff26e2237a7016ac857a52fb5252ce0 -R a88a9175d0467a8bcee3d90b3070177c +P fb6ca99b88c67414eab425e2b4ddb6a5e2fd48a6b2cd96a34627c86a5b568c9b +R 44adf3aab86d2f98e7899082e69a019f U drh -Z f282ee329c3784824fa5652eca8490b4 +Z f778c72442b5a965c1d6d29d9b5a7947 diff --git a/manifest.uuid b/manifest.uuid index 9e80a745e0..01e27acd7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb6ca99b88c67414eab425e2b4ddb6a5e2fd48a6b2cd96a34627c86a5b568c9b \ No newline at end of file +0712f057ef3dcd907984dda30f6d961a29b61c1d2b25627028c4e227ec85dbba \ No newline at end of file From efaffb64fdbc2e00701ac73d3e5481e8f6d04724 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Aug 2017 18:23:46 +0000 Subject: [PATCH 19/53] In sqlite3ViewGetColumnNames(), return the number of errors, not an error code. FossilOrigin-Name: f13682ea2350ba366026a4a58e59591af378c496b92da60803c4c642c3bfc8de --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b2ab03eb02..0dd29b18ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sRTREE\sextension\sshould\sreturn\sSQLITE_CORRUPT_VTAB,\snot\sjust\sSQLITE_CORRUPT\nwhen\sit\sencounters\sincorrectly\sformatted\sshadow\stables. -D 2017-08-17T18:17:24.544 +C In\ssqlite3ViewGetColumnNames(),\sreturn\sthe\snumber\sof\serrors,\snot\san\serror\scode. +D 2017-08-17T18:23:46.704 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -402,7 +402,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c e1a98bef27d6189df5c5b8b3c9b5e53d6b74bf9a936af97757c21e9ea6a5c6b2 F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc -F src/build.c 559bce114d59bb6dd795a7985a9eaac781d374ff31422d134dc147f9667a4d21 +F src/build.c 5b81049a4cea3f547ddb4efc6f56345894524248816dc1ca1511b99be3f7d3ad F src/callback.c 28a8ede982fde4129b828350f78f2c01fe7d12c74d1a0a05d7108ab36f308688 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 @@ -1649,7 +1649,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 fb6ca99b88c67414eab425e2b4ddb6a5e2fd48a6b2cd96a34627c86a5b568c9b -R 44adf3aab86d2f98e7899082e69a019f +P 0712f057ef3dcd907984dda30f6d961a29b61c1d2b25627028c4e227ec85dbba +R f75e24aaa696ff01027f9a4363031c06 U drh -Z f778c72442b5a965c1d6d29d9b5a7947 +Z 9049600ac1caae144c300dc50a09a71b diff --git a/manifest.uuid b/manifest.uuid index 01e27acd7c..2289dcd507 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0712f057ef3dcd907984dda30f6d961a29b61c1d2b25627028c4e227ec85dbba \ No newline at end of file +f13682ea2350ba366026a4a58e59591af378c496b92da60803c4c642c3bfc8de \ No newline at end of file diff --git a/src/build.c b/src/build.c index d64eac009e..55407e77d9 100644 --- a/src/build.c +++ b/src/build.c @@ -2168,7 +2168,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ rc = sqlite3VtabCallConnect(pParse, pTable); db->nSchemaLock--; if( rc ){ - return SQLITE_ERROR; + return 1; } if( IsVirtual(pTable) ) return 0; #endif From 6f7fbcf0bb90adbbf988bd2fbda7fa78a0baf89e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Aug 2017 18:54:27 +0000 Subject: [PATCH 20/53] Size optimization in the authorizer error message generation logic. FossilOrigin-Name: 0367a4d58682a64d7ed4c5a4b4377899e22432851587c649d419efb6d7bac250 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/auth.c | 8 +++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 0dd29b18ac..c2037b0fb1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssqlite3ViewGetColumnNames(),\sreturn\sthe\snumber\sof\serrors,\snot\san\serror\scode. -D 2017-08-17T18:23:46.704 +C Size\soptimization\sin\sthe\sauthorizer\serror\smessage\sgeneration\slogic. +D 2017-08-17T18:54:27.587 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -395,7 +395,7 @@ F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c cf7a8af45cb0ace672f47a1b29ab24092a9e8cd8d945a9974e3b5d925f548594 F src/analyze.c 0d0ccf7520a201d8747ea2f02c92c26e26f801bc161f714f27b9f7630dde0421 F src/attach.c 07b706e336fd3cedbd855e1f8266d10e82fecae07daf86717b5760cd7784c584 -F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c +F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca @@ -1649,7 +1649,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 0712f057ef3dcd907984dda30f6d961a29b61c1d2b25627028c4e227ec85dbba -R f75e24aaa696ff01027f9a4363031c06 +P f13682ea2350ba366026a4a58e59591af378c496b92da60803c4c642c3bfc8de +R 40661ee0bd8f99ce6a0763a7096049ca U drh -Z 9049600ac1caae144c300dc50a09a71b +Z 4b024de8a532f345dd700cff7b7b4750 diff --git a/manifest.uuid b/manifest.uuid index 2289dcd507..684f646ad4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f13682ea2350ba366026a4a58e59591af378c496b92da60803c4c642c3bfc8de \ No newline at end of file +0367a4d58682a64d7ed4c5a4b4377899e22432851587c649d419efb6d7bac250 \ No newline at end of file diff --git a/src/auth.c b/src/auth.c index dabc435b4a..7d6f851d89 100644 --- a/src/auth.c +++ b/src/auth.c @@ -118,11 +118,9 @@ int sqlite3AuthReadCol( #endif ); if( rc==SQLITE_DENY ){ - if( db->nDb>2 || iDb!=0 ){ - sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); - }else{ - sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); - } + char *z = sqlite3_mprintf("%s.%s", zTab, zCol); + if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); + sqlite3ErrorMsg(pParse, "access to %z is prohibited", z); pParse->rc = SQLITE_AUTH; }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ sqliteAuthBadReturnCode(pParse); From dceed86d07146bedbe8b54a613601d2db0d937f8 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Aug 2017 19:23:16 +0000 Subject: [PATCH 21/53] Small optimization in the Expr tree walker. FossilOrigin-Name: 264a5e1b75ee073bd019483e289c3d8d79abcf5a765435be23ac3c21b1db8246 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/walker.c | 26 +++++++++++++++----------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c2037b0fb1..92d8e3f282 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\soptimization\sin\sthe\sauthorizer\serror\smessage\sgeneration\slogic. -D 2017-08-17T18:54:27.587 +C Small\soptimization\sin\sthe\sExpr\stree\swalker. +D 2017-08-17T19:23:16.310 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -537,7 +537,7 @@ F src/vtab.c f1d5c23132fb0247af3e86146404112283ddedb6c518de0d4edc91cfb36970ef F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 -F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a +F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6 F src/where.c cbe8ddffbcec7ce86f7a800fe8fd10aee412c76c87e0dd3732a1682e68d74cd9 F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d F src/wherecode.c e7be3b7f4c11908500cdf02b299d190d3742659533f58e0f4047962fdb5a48da @@ -1649,7 +1649,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 f13682ea2350ba366026a4a58e59591af378c496b92da60803c4c642c3bfc8de -R 40661ee0bd8f99ce6a0763a7096049ca +P 0367a4d58682a64d7ed4c5a4b4377899e22432851587c649d419efb6d7bac250 +R ff1cbce154569f3d7cb9695eac015fa5 U drh -Z 4b024de8a532f345dd700cff7b7b4750 +Z 24e86d635456e5a8dccd5aa790210fdc diff --git a/manifest.uuid b/manifest.uuid index 684f646ad4..fb45173c1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0367a4d58682a64d7ed4c5a4b4377899e22432851587c649d419efb6d7bac250 \ No newline at end of file +264a5e1b75ee073bd019483e289c3d8d79abcf5a765435be23ac3c21b1db8246 \ No newline at end of file diff --git a/src/walker.c b/src/walker.c index 2e292295de..49f9fa1897 100644 --- a/src/walker.c +++ b/src/walker.c @@ -40,18 +40,22 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ int rc; testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_Reduced) ); - rc = pWalker->xExprCallback(pWalker, pExpr); - if( rc ) return rc & WRC_Abort; - if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ - if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; - assert( pExpr->x.pList==0 || pExpr->pRight==0 ); - if( pExpr->pRight ){ - if( walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort; - }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; - }else if( pExpr->x.pList ){ - if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + while(1){ + rc = pWalker->xExprCallback(pWalker, pExpr); + if( rc ) return rc & WRC_Abort; + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; + assert( pExpr->x.pList==0 || pExpr->pRight==0 ); + if( pExpr->pRight ){ + pExpr = pExpr->pRight; + continue; + }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; + }else if( pExpr->x.pList ){ + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + } } + break; } return WRC_Continue; } From ceb4b1dbdde735e851b3bf0d8656cfbe3c29b11a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 17 Aug 2017 20:53:07 +0000 Subject: [PATCH 22/53] Use the __builtin_clzll() function of gcc to improve the performance and reduce the size of the sqlite3LogEst() routine. FossilOrigin-Name: a42a438cbbd721765ca55e71c464552dbaa494050cf472593599b8c7f0249516 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 92d8e3f282..bb8ae26a38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\soptimization\sin\sthe\sExpr\stree\swalker. -D 2017-08-17T19:23:16.310 +C Use\sthe\s__builtin_clzll()\sfunction\sof\sgcc\sto\simprove\sthe\sperformance\sand\nreduce\sthe\ssize\sof\sthe\ssqlite3LogEst()\sroutine. +D 2017-08-17T20:53:07.912 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -522,7 +522,7 @@ F src/treeview.c 2ee4a5dada213d5ab08a742af5c876cee6f1aaae65f10a61923f3fb63846afe F src/trigger.c 48e0f7ed6749ce4d50a695e09e20ce9cf84ecabf2691852c965a51e0b620eccc F src/update.c 5404be9e840717323a69209190cdbc9d0d34adaedaaf1d1a1069babf2c4171c0 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 -F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23 +F src/util.c 773843506ce694714bc96fe67c30c37015f90ef515d0e70f1f8d5c9c24088152 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 F src/vdbe.c 711a1b2c0a6046483ebf4ac43c4c0ea5bef3e50534a4ab9e1d7e3542635cd009 F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 @@ -1649,7 +1649,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 0367a4d58682a64d7ed4c5a4b4377899e22432851587c649d419efb6d7bac250 -R ff1cbce154569f3d7cb9695eac015fa5 +P 264a5e1b75ee073bd019483e289c3d8d79abcf5a765435be23ac3c21b1db8246 +R 08353d9c0ca9dacc46ddab1c0e437979 U drh -Z 24e86d635456e5a8dccd5aa790210fdc +Z 35417eeee14d21861c3f9ed9415c7596 diff --git a/manifest.uuid b/manifest.uuid index fb45173c1a..04447e26d5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -264a5e1b75ee073bd019483e289c3d8d79abcf5a765435be23ac3c21b1db8246 \ No newline at end of file +a42a438cbbd721765ca55e71c464552dbaa494050cf472593599b8c7f0249516 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 7c9c5f54b7..a6d349296f 100644 --- a/src/util.c +++ b/src/util.c @@ -1413,8 +1413,14 @@ LogEst sqlite3LogEst(u64 x){ if( x<2 ) return 0; while( x<8 ){ y -= 10; x <<= 1; } }else{ +#if GCC_VERSION>=5004000 + int i = 60 - __builtin_clzll(x); + y += i*10; + x >>= i; +#else while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/ while( x>15 ){ y += 10; x >>= 1; } +#endif } return a[x&7] + y - 10; } From 62f6f51ae142112c8354460fc70f5c3471d329c4 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 18 Aug 2017 08:29:37 +0000 Subject: [PATCH 23/53] Only use indexes on expressions to optimize ORDER BY and GROUP BY if the collation sequence matches. Possible fix for [e20dd54a]. FossilOrigin-Name: 37e1900880b70be6802eaf43b0e568fda709a1dd6083d8be11e5a7a7d1fda41a --- manifest | 16 ++++---- manifest.uuid | 2 +- src/where.c | 2 +- test/indexexpr2.test | 97 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index bb8ae26a38..dad7e502b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sthe\s__builtin_clzll()\sfunction\sof\sgcc\sto\simprove\sthe\sperformance\sand\nreduce\sthe\ssize\sof\sthe\ssqlite3LogEst()\sroutine. -D 2017-08-17T20:53:07.912 +C Only\suse\sindexes\son\sexpressions\sto\soptimize\sORDER\sBY\sand\sGROUP\sBY\sif\sthe\ncollation\ssequence\smatches.\sPossible\sfix\sfor\s[e20dd54a]. +D 2017-08-18T08:29:37.727 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -538,7 +538,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6 -F src/where.c cbe8ddffbcec7ce86f7a800fe8fd10aee412c76c87e0dd3732a1682e68d74cd9 +F src/where.c ad558533d6fe6578857635218633aa241e2428835763c46801be9e68d6ec0701 F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d F src/wherecode.c e7be3b7f4c11908500cdf02b299d190d3742659533f58e0f4047962fdb5a48da F src/whereexpr.c fe1fe600d7334e91f3d9d487021362d543fba8ab2f1be5e0d68063d619379c05 @@ -943,7 +943,7 @@ F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 F test/indexexpr1.test 84100e880154a4b645db9f4fc7642756d9a2b6011b68f73c8efda4d244816de9 -F test/indexexpr2.test 3ddd7f23bc381b9f2b7a15f2d083b1a4078e7733dce8295602ecfa3c74a34cf9 +F test/indexexpr2.test 2237f1408efa921bd66d0a09ebf0208cb0c228c1bc3b3a18e9fb8fc87d6ed90b F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1649,7 +1649,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 264a5e1b75ee073bd019483e289c3d8d79abcf5a765435be23ac3c21b1db8246 -R 08353d9c0ca9dacc46ddab1c0e437979 -U drh -Z 35417eeee14d21861c3f9ed9415c7596 +P a42a438cbbd721765ca55e71c464552dbaa494050cf472593599b8c7f0249516 +R 01b1b734d02df776d0a6e39431469431 +U dan +Z 25c783941cfeb73ae08636afb42efa7c diff --git a/manifest.uuid b/manifest.uuid index 04447e26d5..eae0feb8f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a42a438cbbd721765ca55e71c464552dbaa494050cf472593599b8c7f0249516 \ No newline at end of file +37e1900880b70be6802eaf43b0e568fda709a1dd6083d8be11e5a7a7d1fda41a \ No newline at end of file diff --git a/src/where.c b/src/where.c index 0e82e471f4..5402977c30 100644 --- a/src/where.c +++ b/src/where.c @@ -3689,7 +3689,7 @@ static i8 wherePathSatisfiesOrderBy( continue; } } - if( iColumn>=0 ){ + if( iColumn!=XN_ROWID ){ pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); if( !pColl ) pColl = db->pDfltColl; if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; diff --git a/test/indexexpr2.test b/test/indexexpr2.test index c72561f347..7fa226cf8f 100644 --- a/test/indexexpr2.test +++ b/test/indexexpr2.test @@ -40,4 +40,101 @@ do_execsql_test 2.1 { SELECT a+1, quote(a+1) FROM t1 ORDER BY 1; } {2 2 3 3 4 4} +#------------------------------------------------------------------------- +# At one point SQLite was incorrectly using indexes on expressions to +# optimize ORDER BY and GROUP BY clauses even when the collation +# sequences of the query and index did not match (ticket [e20dd54ab0e4]). +# The following tests - 3.* - attempt to verify that this has been fixed. +# + +reset_db +do_execsql_test 3.1.0 { + CREATE TABLE t1(a, b); + CREATE INDEX i1 ON t1(a, b); +} {} + +do_eqp_test 3.1.1 { + SELECT b FROM t1 WHERE b IS NOT NULL AND a IS NULL + GROUP BY b COLLATE nocase + ORDER BY b COLLATE nocase; +} { + 0 0 0 {SEARCH TABLE t1 USING COVERING INDEX i1 (a=? AND b>?)} + 0 0 0 {USE TEMP B-TREE FOR GROUP BY} +} + +do_execsql_test 3.2.0 { + CREATE TABLE t2(x); + + INSERT INTO t2 VALUES('.ABC'); + INSERT INTO t2 VALUES('.abcd'); + INSERT INTO t2 VALUES('.defg'); + INSERT INTO t2 VALUES('.DEF'); +} {} + +do_execsql_test 3.2.1 { + SELECT x FROM t2 ORDER BY substr(x, 2) COLLATE nocase; +} { + .ABC .abcd .DEF .defg +} + +do_execsql_test 3.2.2 { + CREATE INDEX i2 ON t2( substr(x, 2) ); + SELECT x FROM t2 ORDER BY substr(x, 2) COLLATE nocase; +} { + .ABC .abcd .DEF .defg +} + +do_execsql_test 3.3.0 { + CREATE TABLE t3(x); +} + +do_eqp_test 3.3.1 { + SELECT json_extract(x, '$.b') FROM t2 + WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL + GROUP BY json_extract(x, '$.b') COLLATE nocase + ORDER BY json_extract(x, '$.b') COLLATE nocase; +} { + 0 0 0 {SCAN TABLE t2} + 0 0 0 {USE TEMP B-TREE FOR GROUP BY} +} + +do_execsql_test 3.3.2 { + CREATE INDEX i3 ON t3(json_extract(x, '$.a'), json_extract(x, '$.b')); +} {} + +do_eqp_test 3.3.3 { + SELECT json_extract(x, '$.b') FROM t3 + WHERE json_extract(x, '$.b') IS NOT NULL AND json_extract(x, '$.a') IS NULL + GROUP BY json_extract(x, '$.b') COLLATE nocase + ORDER BY json_extract(x, '$.b') COLLATE nocase; +} { + 0 0 0 {SEARCH TABLE t3 USING INDEX i3 (=?)} + 0 0 0 {USE TEMP B-TREE FOR GROUP BY} +} + +do_execsql_test 3.4.0 { + CREATE TABLE t4(a, b); + INSERT INTO t4 VALUES('.ABC', 1); + INSERT INTO t4 VALUES('.abc', 2); + INSERT INTO t4 VALUES('.ABC', 3); + INSERT INTO t4 VALUES('.abc', 4); +} + +do_execsql_test 3.4.1 { + SELECT * FROM t4 + WHERE substr(a, 2) = 'abc' COLLATE NOCASE + ORDER BY substr(a, 2), b; +} { + .ABC 1 .ABC 3 .abc 2 .abc 4 +} + +do_execsql_test 3.4.2 { + CREATE INDEX i4 ON t4( substr(a, 2) COLLATE NOCASE, b ); + SELECT * FROM t4 + WHERE substr(a, 2) = 'abc' COLLATE NOCASE + ORDER BY substr(a, 2), b; +} { + .ABC 1 .ABC 3 .abc 2 .abc 4 +} + finish_test From 0f3f7664f01bb9fdaa45c4c71c53fbff7f0f09c4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Aug 2017 14:34:28 +0000 Subject: [PATCH 24/53] Combine the OP_CreateTable and OP_CreateIndex opcodes of the bytecode engine into a single OP_CreateBtree opcode. This simplifies the implementation and makes the bytecode programs clearer. FossilOrigin-Name: eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 17 ++++++++--------- src/sqliteInt.h | 2 +- src/vdbe.c | 44 +++++++++++--------------------------------- src/vdbeaux.c | 5 +++-- 6 files changed, 34 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index dad7e502b8..4fa7a63002 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\suse\sindexes\son\sexpressions\sto\soptimize\sORDER\sBY\sand\sGROUP\sBY\sif\sthe\ncollation\ssequence\smatches.\sPossible\sfix\sfor\s[e20dd54a]. -D 2017-08-18T08:29:37.727 +C Combine\sthe\sOP_CreateTable\sand\sOP_CreateIndex\sopcodes\sof\sthe\sbytecode\sengine\ninto\sa\ssingle\sOP_CreateBtree\sopcode.\s\sThis\ssimplifies\sthe\simplementation\sand\nmakes\sthe\sbytecode\sprograms\sclearer. +D 2017-08-18T14:34:28.967 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -402,7 +402,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c e1a98bef27d6189df5c5b8b3c9b5e53d6b74bf9a936af97757c21e9ea6a5c6b2 F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc -F src/build.c 5b81049a4cea3f547ddb4efc6f56345894524248816dc1ca1511b99be3f7d3ad +F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 F src/callback.c 28a8ede982fde4129b828350f78f2c01fe7d12c74d1a0a05d7108ab36f308688 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 @@ -462,7 +462,7 @@ F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c17 F src/sqlite.h.in f0bd1abf5e27bd22b3bcaae2a861c1efc4ab7e752bf7eb102355135617eb8199 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 -F src/sqliteInt.h 6dddca4e215f4088aeaf60aebaa6d913397d61422733e160f25ab9dc53605a36 +F src/sqliteInt.h bc0792db4ff887e4884d386188527e1cd7c16d496c8f3ba23333e68cee3e4f78 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -524,11 +524,11 @@ F src/update.c 5404be9e840717323a69209190cdbc9d0d34adaedaaf1d1a1069babf2c4171c0 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/util.c 773843506ce694714bc96fe67c30c37015f90ef515d0e70f1f8d5c9c24088152 F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 -F src/vdbe.c 711a1b2c0a6046483ebf4ac43c4c0ea5bef3e50534a4ab9e1d7e3542635cd009 +F src/vdbe.c 82fc4553a0986a06bdd0d2b03a424e159bba5c74802fabb2841aa6cd27ccd962 F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 F src/vdbeInt.h 1fe00770144c12c4913128f35262d11527ef3284561baaab59b947a41c08d0d9 F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc -F src/vdbeaux.c 1f15018ef7abe22669967f70b02bfe6709be403f126f713dabb091b9d631859a +F src/vdbeaux.c 2dff8186d34e0e525838f77b2fac70bd480f0273a77015bf21b6a08f2792da82 F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b F src/vdbemem.c b7fac20534c79b7554dab2e8a180c585a8bc1b9c85149d1b2d9746cf314d06ed F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e3 @@ -1649,7 +1649,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 a42a438cbbd721765ca55e71c464552dbaa494050cf472593599b8c7f0249516 -R 01b1b734d02df776d0a6e39431469431 -U dan -Z 25c783941cfeb73ae08636afb42efa7c +P 37e1900880b70be6802eaf43b0e568fda709a1dd6083d8be11e5a7a7d1fda41a +R 590c7fe86e3ddb105e4572bf5c63dff2 +U drh +Z 553a5b087246c1036f2341d36a71efe3 diff --git a/manifest.uuid b/manifest.uuid index eae0feb8f2..e99f037cf1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -37e1900880b70be6802eaf43b0e568fda709a1dd6083d8be11e5a7a7d1fda41a \ No newline at end of file +eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 55407e77d9..05126f6260 100644 --- a/src/build.c +++ b/src/build.c @@ -1010,7 +1010,8 @@ void sqlite3StartTable( }else #endif { - pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2); + pParse->addrCrTab = + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } sqlite3OpenMasterTable(pParse, iDb); sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); @@ -1670,9 +1671,8 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ ** Changes include: ** ** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. -** (2) Convert the OP_CreateTable into an OP_CreateIndex. There is -** no rowid btree for a WITHOUT ROWID. Instead, the canonical -** data storage is a covering index btree. +** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY +** into BTREE_BLOBKEY. ** (3) Bypass the creation of the sqlite_master table entry ** for the PRIMARY KEY as the primary key index is now ** identified by the sqlite_master table entry of the table itself. @@ -1709,13 +1709,12 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** virtual tables */ if( IN_DECLARE_VTAB ) return; - /* Convert the OP_CreateTable opcode that would normally create the - ** root-page for the table into an OP_CreateIndex opcode. The index - ** created will become the PRIMARY KEY index. + /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY + ** into BTREE_BLOBKEY. */ if( pParse->addrCrTab ){ assert( v ); - sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex); + sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); } /* Locate the PRIMARY KEY index. Or, if this table was originally @@ -3366,7 +3365,7 @@ void sqlite3CreateIndex( ** that case the convertToWithoutRowidTable() routine will replace ** the Noop with a Goto to jump over the VDBE code generated below. */ pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop); - sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem); + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); /* Gather the complete text of the CREATE INDEX statement into ** the zStmt variable diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8aa9832e8a..3689689403 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3001,7 +3001,7 @@ struct Parse { AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ - int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */ + int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */ u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ diff --git a/src/vdbe.c b/src/vdbe.c index 3f5d967d2d..70e745afe0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3409,7 +3409,7 @@ case OP_OpenWrite: assert( (pIn2->flags & MEM_Int)!=0 ); sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; - /* The p2 value always comes from a prior OP_CreateTable opcode and + /* The p2 value always comes from a prior OP_CreateBtree opcode and ** that opcode will always set the p2 value to 2 or more or else fail. ** If there were a failure, the prepared statement would have halted ** before reaching this instruction. */ @@ -5483,50 +5483,28 @@ case OP_ResetSorter: { break; } -/* Opcode: CreateTable P1 P2 * * * -** Synopsis: r[P2]=root iDb=P1 +/* Opcode: CreateBtree P1 P2 P3 * * +** Synopsis: r[P2]=root iDb=P1 flags=P3 ** -** Allocate a new table in the main database file if P1==0 or in the -** auxiliary database file if P1==1 or in an attached database if -** P1>1. Write the root page number of the new table into -** register P2 -** -** The difference between a table and an index is this: A table must -** have a 4-byte integer key and can have arbitrary data. An index -** has an arbitrary key but no data. -** -** See also: CreateIndex +** Allocate a new b-tree in the main database file if P1==0 or in the +** TEMP database file if P1==1 or in an attached database if +** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table +** it must be 2 (BTREE_BLOBKEY) for a index or WITHOUT ROWID table. +** The root page number of the new b-tree is stored in register P2. */ -/* Opcode: CreateIndex P1 P2 * * * -** Synopsis: r[P2]=root iDb=P1 -** -** Allocate a new index in the main database file if P1==0 or in the -** auxiliary database file if P1==1 or in an attached database if -** P1>1. Write the root page number of the new table into -** register P2. -** -** See documentation on OP_CreateTable for additional information. -*/ -case OP_CreateIndex: /* out2 */ -case OP_CreateTable: { /* out2 */ +case OP_CreateBtree: { /* out2 */ int pgno; - int flags; Db *pDb; pOut = out2Prerelease(p, pOp); pgno = 0; + assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY ); assert( pOp->p1>=0 && pOp->p1nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); assert( p->readOnly==0 ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); - if( pOp->opcode==OP_CreateTable ){ - /* flags = BTREE_INTKEY; */ - flags = BTREE_INTKEY; - }else{ - flags = BTREE_BLOBKEY; - } - rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags); + rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3); if( rc ) goto abort_due_to_error; pOut->u.i = pgno; break; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7f6632bfa4..6de0efcb9e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -490,7 +490,8 @@ static Op *opIterNext(VdbeOpIter *p){ ** * OP_VUpdate ** * OP_VRename ** * OP_FkCounter with P2==0 (immediate foreign key constraint) -** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...) +** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine +** (for CREATE TABLE AS SELECT ...) ** ** Then check that the value of Parse.mayAbort is true if an ** ABORT may be thrown, or false otherwise. Return true if it does @@ -518,7 +519,7 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ hasAbort = 1; break; } - if( opcode==OP_CreateTable ) hasCreateTable = 1; + if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1; if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1; #ifndef SQLITE_OMIT_FOREIGN_KEY if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){ From c68886bb9e02ff943ffe6481cb0e9097fd57111e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Aug 2017 16:09:52 +0000 Subject: [PATCH 25/53] For the unix VFS, avoid an unnecessary stat() system call prior to opening any file in the common case where there are no unused file descriptors. FossilOrigin-Name: 3075cfa07489eaf13cb9a2760e2391e79dd73181fe1730fae7bdcd6ad66d2a1f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 41 ++++++++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 4fa7a63002..78a97342e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sthe\sOP_CreateTable\sand\sOP_CreateIndex\sopcodes\sof\sthe\sbytecode\sengine\ninto\sa\ssingle\sOP_CreateBtree\sopcode.\s\sThis\ssimplifies\sthe\simplementation\sand\nmakes\sthe\sbytecode\sprograms\sclearer. -D 2017-08-18T14:34:28.967 +C For\sthe\sunix\sVFS,\savoid\san\sunnecessary\sstat()\ssystem\scall\sprior\sto\sopening\nany\sfile\sin\sthe\scommon\scase\swhere\sthere\sare\sno\sunused\sfile\sdescriptors. +D 2017-08-18T16:09:52.797 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -440,7 +440,7 @@ F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c a361273749229755f92c8f0e3e4855054ad39bbc5c65773e8db5d0b79afa632c +F src/os_unix.c 0a7730f6cb797ba1fd12825e4ea751e1325041410c063c258e30089ca71f9a88 F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 6f2ae58c0d4ddf510d324cb2ec38f471b5cff8f3e061afd32717ad790685cc7f @@ -1649,7 +1649,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 37e1900880b70be6802eaf43b0e568fda709a1dd6083d8be11e5a7a7d1fda41a -R 590c7fe86e3ddb105e4572bf5c63dff2 +P eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3 +R 75fd277ce5c40358998ed365a587d991 U drh -Z 553a5b087246c1036f2341d36a71efe3 +Z 8da9bd8ec0af0fa3e80213d960cc13a7 diff --git a/manifest.uuid b/manifest.uuid index e99f037cf1..97cbaa15bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3 \ No newline at end of file +3075cfa07489eaf13cb9a2760e2391e79dd73181fe1730fae7bdcd6ad66d2a1f \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index d1ebd81f68..bd646d6e70 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -210,7 +210,7 @@ struct unixFile { unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ - UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ + UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ @@ -1120,7 +1120,8 @@ struct unixInodeInfo { /* ** A lists of all unixInodeInfo objects. */ -static unixInodeInfo *inodeList = 0; +static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ +static unsigned int nUnusedFd = 0; /* Total unused file descriptors */ /* ** @@ -1230,6 +1231,7 @@ static void closePendingFds(unixFile *pFile){ pNext = p->pNext; robust_close(pFile, p->fd, __LINE__); sqlite3_free(p); + nUnusedFd--; } pInode->pUnused = 0; } @@ -1262,6 +1264,7 @@ static void releaseInodeInfo(unixFile *pFile){ sqlite3_free(pInode); } } + assert( inodeList!=0 || nUnusedFd==0 ); } /* @@ -1331,6 +1334,7 @@ static int findInodeInfo( #else fileId.ino = (u64)statbuf.st_ino; #endif + assert( inodeList!=0 || nUnusedFd==0 ); pInode = inodeList; while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){ pInode = pInode->pNext; @@ -1750,11 +1754,12 @@ end_lock: */ static void setPendingFd(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; - UnixUnusedFd *p = pFile->pUnused; + UnixUnusedFd *p = pFile->pPreallocatedUnused; p->pNext = pInode->pUnused; pInode->pUnused = p; pFile->h = -1; - pFile->pUnused = 0; + pFile->pPreallocatedUnused = 0; + nUnusedFd++; } /* @@ -1979,7 +1984,7 @@ static int closeUnixFile(sqlite3_file *id){ #endif OSTRACE(("CLOSE %-3d\n", pFile->h)); OpenCounter(-1); - sqlite3_free(pFile->pUnused); + sqlite3_free(pFile->pPreallocatedUnused); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } @@ -3200,7 +3205,7 @@ static int unixRead( /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 - assert( pFile->pUnused==0 + assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); @@ -3313,7 +3318,7 @@ static int unixWrite( /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 - assert( pFile->pUnused==0 + assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); @@ -5564,6 +5569,8 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ #if !OS_VXWORKS struct stat sStat; /* Results of stat() call */ + unixEnterMutex(); + /* A stat() call may fail for various reasons. If this happens, it is ** almost certain that an open() call on the same path will also fail. ** For this reason, if an error occurs in the stat() call here, it is @@ -5572,10 +5579,9 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ ** ** Even if a subsequent open() call does succeed, the consequences of ** not searching for a reusable file descriptor are not dire. */ - if( 0==osStat(zPath, &sStat) ){ + if( nUnusedFd>0 && 0==osStat(zPath, &sStat) ){ unixInodeInfo *pInode; - unixEnterMutex(); pInode = inodeList; while( pInode && (pInode->fileId.dev!=sStat.st_dev || pInode->fileId.ino!=(u64)sStat.st_ino) ){ @@ -5586,11 +5592,12 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ + nUnusedFd--; *pp = pUnused->pNext; } } - unixLeaveMutex(); } + unixLeaveMutex(); #endif /* if !OS_VXWORKS */ return pUnused; } @@ -5811,7 +5818,7 @@ static int unixOpen( return SQLITE_NOMEM_BKPT; } } - p->pUnused = pUnused; + p->pPreallocatedUnused = pUnused; /* Database filenames are double-zero terminated if they are not ** URIs with parameters. Hence, they can always be passed into @@ -5848,7 +5855,7 @@ static int unixOpen( gid_t gid; /* Groupid for the file */ rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid); if( rc!=SQLITE_OK ){ - assert( !p->pUnused ); + assert( !p->pPreallocatedUnused ); assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); return rc; } @@ -5882,9 +5889,9 @@ static int unixOpen( *pOutFlags = flags; } - if( p->pUnused ){ - p->pUnused->fd = fd; - p->pUnused->flags = flags; + if( p->pPreallocatedUnused ){ + p->pPreallocatedUnused->fd = fd; + p->pPreallocatedUnused->flags = flags; } if( isDelete ){ @@ -5965,7 +5972,7 @@ static int unixOpen( open_finished: if( rc!=SQLITE_OK ){ - sqlite3_free(p->pUnused); + sqlite3_free(p->pPreallocatedUnused); } return rc; } @@ -6706,7 +6713,7 @@ static int proxyCreateUnixFile( dummyVfs.zName = "dummy"; pUnused->fd = fd; pUnused->flags = openFlags; - pNew->pUnused = pUnused; + pNew->pPreallocatedUnused = pUnused; rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); if( rc==SQLITE_OK ){ From 56520ab8487200bb697911baa864d7a996ab17f1 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Aug 2017 21:14:50 +0000 Subject: [PATCH 26/53] Size and performance optimization the readDbPage() routine in the pager. FossilOrigin-Name: ca9e1875c3a893321d70a131fc4ffc76d169ad05e0b48b7006f53b6b467db4be --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 29 +++++++++++------------------ 3 files changed, 18 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 78a97342e5..1e5d32d66b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sthe\sunix\sVFS,\savoid\san\sunnecessary\sstat()\ssystem\scall\sprior\sto\sopening\nany\sfile\sin\sthe\scommon\scase\swhere\sthere\sare\sno\sunused\sfile\sdescriptors. -D 2017-08-18T16:09:52.797 +C Size\sand\sperformance\soptimization\sthe\sreadDbPage()\sroutine\sin\sthe\spager. +D 2017-08-18T21:14:50.622 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -443,7 +443,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 0a7730f6cb797ba1fd12825e4ea751e1325041410c063c258e30089ca71f9a88 F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 6f2ae58c0d4ddf510d324cb2ec38f471b5cff8f3e061afd32717ad790685cc7f +F src/pager.c fb9a8f40417d6dfbd6b8be91237f2f64d51cc867ab28687420acbc5cab786a3c F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 52ef3cecd0934e9da4a45b585883a03243ad615d338ad94f44501a05891dcdfa F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 @@ -1649,7 +1649,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 eb1202b5e43f1f029ad2bdf845509e7f31361e4dc189943e5e2bd4462e2ef3f3 -R 75fd277ce5c40358998ed365a587d991 +P 3075cfa07489eaf13cb9a2760e2391e79dd73181fe1730fae7bdcd6ad66d2a1f +R 73e91e0689b3737aa34e053426722c6a U drh -Z 8da9bd8ec0af0fa3e80213d960cc13a7 +Z 58f532a67b173dfa15cad7f44c1bc81c diff --git a/manifest.uuid b/manifest.uuid index 97cbaa15bb..59813005d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3075cfa07489eaf13cb9a2760e2391e79dd73181fe1730fae7bdcd6ad66d2a1f \ No newline at end of file +ca9e1875c3a893321d70a131fc4ffc76d169ad05e0b48b7006f53b6b467db4be \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 1677dfcda7..9a430476a1 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2982,7 +2982,8 @@ end_playback: /* -** Read the content for page pPg out of the database file and into +** Read the content for page pPg out of the database file (or out of +** the WAL if that is where the most recent copy if found) into ** pPg->pData. A shared lock or greater must be held on the database ** file before this function is called. ** @@ -2992,22 +2993,23 @@ end_playback: ** If an IO error occurs, then the IO error is returned to the caller. ** Otherwise, SQLITE_OK is returned. */ -static int readDbPage(PgHdr *pPg, u32 iFrame){ +static int readDbPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ Pgno pgno = pPg->pgno; /* Page number to read */ int rc = SQLITE_OK; /* Return code */ int pgsz = pPager->pageSize; /* Number of bytes to read */ + u32 iFrame = 0; /* Frame of WAL containing pgno */ assert( pPager->eState>=PAGER_READER && !MEMDB ); assert( isOpen(pPager->fd) ); -#ifndef SQLITE_OMIT_WAL + if( pagerUseWal(pPager) ){ + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + if( rc ) return rc; + } if( iFrame ){ - /* Try to pull the page from the write-ahead log. */ rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); - }else -#endif - { + }else{ i64 iOffset = (pgno-1)*(i64)pPager->pageSize; rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ @@ -3092,11 +3094,7 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){ if( sqlite3PcachePageRefcount(pPg)==1 ){ sqlite3PcacheDrop(pPg); }else{ - u32 iFrame = 0; - rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); - if( rc==SQLITE_OK ){ - rc = readDbPage(pPg, iFrame); - } + rc = readDbPage(pPg); if( rc==SQLITE_OK ){ pPager->xReiniter(pPg); } @@ -5489,14 +5487,9 @@ static int getPageNormal( memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ - u32 iFrame = 0; /* Frame to read from WAL file */ - if( pagerUseWal(pPager) ){ - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); - if( rc!=SQLITE_OK ) goto pager_acquire_err; - } assert( pPg->pPager==pPager ); pPager->aStat[PAGER_STAT_MISS]++; - rc = readDbPage(pPg, iFrame); + rc = readDbPage(pPg); if( rc!=SQLITE_OK ){ goto pager_acquire_err; } From 251866d07c0b76e4fd0d762febe3f37a559f961a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 18 Aug 2017 22:30:20 +0000 Subject: [PATCH 27/53] Another size and performance optimization to readDbPage(). This time we eliminate some unnecessary local variables. FossilOrigin-Name: 745bc8decd18d4dc00589474fd3928a3a9f4156d09e05e6f5b8623de6491795a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 18 ++++++++---------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 1e5d32d66b..558153cf2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\sand\sperformance\soptimization\sthe\sreadDbPage()\sroutine\sin\sthe\spager. -D 2017-08-18T21:14:50.622 +C Another\ssize\sand\sperformance\soptimization\sto\sreadDbPage().\s\sThis\stime\swe\neliminate\ssome\sunnecessary\slocal\svariables. +D 2017-08-18T22:30:20.164 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -443,7 +443,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 0a7730f6cb797ba1fd12825e4ea751e1325041410c063c258e30089ca71f9a88 F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c fb9a8f40417d6dfbd6b8be91237f2f64d51cc867ab28687420acbc5cab786a3c +F src/pager.c c1dc0609f04a0659519bb2b8ca1440a64b0ad82b6c2afd675f1a50f6c918321a F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 52ef3cecd0934e9da4a45b585883a03243ad615d338ad94f44501a05891dcdfa F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 @@ -1649,7 +1649,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 3075cfa07489eaf13cb9a2760e2391e79dd73181fe1730fae7bdcd6ad66d2a1f -R 73e91e0689b3737aa34e053426722c6a +P ca9e1875c3a893321d70a131fc4ffc76d169ad05e0b48b7006f53b6b467db4be +R 2ae3b6889f1fe566e9272b8874e17865 U drh -Z 58f532a67b173dfa15cad7f44c1bc81c +Z 970c0b65cb119d003a12faf3a1e4e18e diff --git a/manifest.uuid b/manifest.uuid index 59813005d8..6c04ddf6a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca9e1875c3a893321d70a131fc4ffc76d169ad05e0b48b7006f53b6b467db4be \ No newline at end of file +745bc8decd18d4dc00589474fd3928a3a9f4156d09e05e6f5b8623de6491795a \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 9a430476a1..5986afdae1 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2995,29 +2995,27 @@ end_playback: */ static int readDbPage(PgHdr *pPg){ Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */ - Pgno pgno = pPg->pgno; /* Page number to read */ int rc = SQLITE_OK; /* Return code */ - int pgsz = pPager->pageSize; /* Number of bytes to read */ u32 iFrame = 0; /* Frame of WAL containing pgno */ assert( pPager->eState>=PAGER_READER && !MEMDB ); assert( isOpen(pPager->fd) ); if( pagerUseWal(pPager) ){ - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); if( rc ) return rc; } if( iFrame ){ - rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData); + rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); }else{ - i64 iOffset = (pgno-1)*(i64)pPager->pageSize; - rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset); + i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; + rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } } - if( pgno==1 ){ + if( pPg->pgno==1 ){ if( rc ){ /* If the read is unsuccessful, set the dbFileVers[] to something ** that will never be a valid file version. dbFileVers[] is a copy @@ -3037,13 +3035,13 @@ static int readDbPage(PgHdr *pPg){ memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers)); } } - CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT); + 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, pgno)); + IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno)); PAGERTRACE(("FETCH %d page %d hash(%08x)\n", - PAGERID(pPager), pgno, pager_pagehash(pPg))); + PAGERID(pPager), pPg->pgno, pager_pagehash(pPg))); return rc; } From c84ddf14c5c65007b739d4368cdde7fb24eaed78 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 19 Aug 2017 20:38:18 +0000 Subject: [PATCH 28/53] Space and size optimization to the printf implementation. FossilOrigin-Name: d01d2cffefd1cdb52b386e4983599534c0fbbe6aebda186db53200e4b2283f0a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/printf.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 558153cf2f..19ef566777 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\ssize\sand\sperformance\soptimization\sto\sreadDbPage().\s\sThis\stime\swe\neliminate\ssome\sunnecessary\slocal\svariables. -D 2017-08-18T22:30:20.164 +C Space\sand\ssize\soptimization\sto\sthe\sprintf\simplementation. +D 2017-08-19T20:38:18.374 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -452,7 +452,7 @@ F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2 F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/prepare.c 9e880c0efb5d7f9101bb34c0a87daf6e1e5284c34024fdb811e67bb02fdd299b -F src/printf.c 439c145d71ff9e0328ec26b7db23a45f995f742d3207dd546e034cdc1667ac9c +F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac @@ -1649,7 +1649,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 ca9e1875c3a893321d70a131fc4ffc76d169ad05e0b48b7006f53b6b467db4be -R 2ae3b6889f1fe566e9272b8874e17865 +P 745bc8decd18d4dc00589474fd3928a3a9f4156d09e05e6f5b8623de6491795a +R f17a35ca8aefa46f1d59e82e2ca24c65 U drh -Z 970c0b65cb119d003a12faf3a1e4e18e +Z 9e343ccf54a229e4a80d7dbe62c9be25 diff --git a/manifest.uuid b/manifest.uuid index 6c04ddf6a7..467969b46f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -745bc8decd18d4dc00589474fd3928a3a9f4156d09e05e6f5b8623de6491795a \ No newline at end of file +d01d2cffefd1cdb52b386e4983599534c0fbbe6aebda186db53200e4b2283f0a \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 49b13cc4f5..9427844e09 100644 --- a/src/printf.c +++ b/src/printf.c @@ -656,7 +656,7 @@ void sqlite3VXPrintf( if( precision>=0 ){ for(length=0; length Date: Mon, 21 Aug 2017 02:05:22 +0000 Subject: [PATCH 29/53] Minor optimization to sqlite3VdbeMemSetStr(). FossilOrigin-Name: 6538ef7b6b56c7a6629a0bb7418910c64c8b2e73af2296a116c073ecf2e0d429 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 19ef566777..cac92f9d02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Space\sand\ssize\soptimization\sto\sthe\sprintf\simplementation. -D 2017-08-19T20:38:18.374 +C Minor\soptimization\sto\ssqlite3VdbeMemSetStr(). +D 2017-08-21T02:05:22.118 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -530,7 +530,7 @@ F src/vdbeInt.h 1fe00770144c12c4913128f35262d11527ef3284561baaab59b947a41c08d0d9 F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc F src/vdbeaux.c 2dff8186d34e0e525838f77b2fac70bd480f0273a77015bf21b6a08f2792da82 F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b -F src/vdbemem.c b7fac20534c79b7554dab2e8a180c585a8bc1b9c85149d1b2d9746cf314d06ed +F src/vdbemem.c 2f9d672af5260f0145787e1dc2c6985414987cc0dc575133a0dc17dda767d868 F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e3 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c f1d5c23132fb0247af3e86146404112283ddedb6c518de0d4edc91cfb36970ef @@ -1649,7 +1649,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 745bc8decd18d4dc00589474fd3928a3a9f4156d09e05e6f5b8623de6491795a -R f17a35ca8aefa46f1d59e82e2ca24c65 +P d01d2cffefd1cdb52b386e4983599534c0fbbe6aebda186db53200e4b2283f0a +R 4e15eb10124cc2a73cc86451db58097f U drh -Z 9e343ccf54a229e4a80d7dbe62c9be25 +Z cde05a24b81c141b2ecb8ef40de25a03 diff --git a/manifest.uuid b/manifest.uuid index 467969b46f..fc8c38515c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d01d2cffefd1cdb52b386e4983599534c0fbbe6aebda186db53200e4b2283f0a \ No newline at end of file +6538ef7b6b56c7a6629a0bb7418910c64c8b2e73af2296a116c073ecf2e0d429 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 346c1fb10b..345c41a72d 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -931,7 +931,7 @@ int sqlite3VdbeMemSetStr( if( nByte<0 ){ assert( enc!=0 ); if( enc==SQLITE_UTF8 ){ - nByte = sqlite3Strlen30(z); + nByte = 0x7fffffff & (int)strlen(z); if( nByte>iLimit ) nByte = iLimit+1; }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} From b40f06c62dc64e516510b8221950e1d6b687f7ee Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 21 Aug 2017 02:20:57 +0000 Subject: [PATCH 30/53] Remove an unnecessary conditional. FossilOrigin-Name: 56d19f9fd7b01d4ed5c3e7309977b43fedffee168c9760d3e3b7e885790f781e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cac92f9d02..9ae22d4f8e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\soptimization\sto\ssqlite3VdbeMemSetStr(). -D 2017-08-21T02:05:22.118 +C Remove\san\sunnecessary\sconditional. +D 2017-08-21T02:20:57.510 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -409,7 +409,7 @@ F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0 F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74 F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720 F src/delete.c 21a5f1812fdb599e9f7afb9f650bdabab60a3afd51d7e94e539c982f647b0023 -F src/expr.c dc436431dc50a0256b9dcd3daaa06aac0df21834f91068525f2eb3c10b9a7a9a +F src/expr.c 4ca86dc65f5ea478c665a5b4fe79d05f00432c9bd82237a896b45bd376bf1217 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333 F src/func.c ed8888ae80b39f5a5d403954e4a05e0a38303523dff8143161439c142d31dec1 @@ -1649,7 +1649,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 d01d2cffefd1cdb52b386e4983599534c0fbbe6aebda186db53200e4b2283f0a -R 4e15eb10124cc2a73cc86451db58097f +P 6538ef7b6b56c7a6629a0bb7418910c64c8b2e73af2296a116c073ecf2e0d429 +R 44db9cb33f37af7df65ab136e59cd109 U drh -Z cde05a24b81c141b2ecb8ef40de25a03 +Z bcd0fe0605e077fa72b238dc51f819ad diff --git a/manifest.uuid b/manifest.uuid index fc8c38515c..40286a0698 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6538ef7b6b56c7a6629a0bb7418910c64c8b2e73af2296a116c073ecf2e0d429 \ No newline at end of file +56d19f9fd7b01d4ed5c3e7309977b43fedffee168c9760d3e3b7e885790f781e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d090aab3b7..0e1a8781e1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -775,7 +775,7 @@ Expr *sqlite3Expr( ){ Token x; x.z = zToken; - x.n = zToken ? sqlite3Strlen30(zToken) : 0; + x.n = sqlite3Strlen30(zToken); return sqlite3ExprAlloc(db, op, &x, 0); } From 2e2338101a28a647eaa37cf20945087fd96aaf10 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Aug 2017 15:21:54 +0000 Subject: [PATCH 31/53] Fix error tests in seldom-used compile-time branches of the unix backend. FossilOrigin-Name: 885c2b44a44f8d054014e4079b2cac8279c11d13206d5b5215189ef75b9c5254 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9ae22d4f8e..a66cc1c8aa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sconditional. -D 2017-08-21T02:20:57.510 +C Fix\serror\stests\sin\sseldom-used\scompile-time\sbranches\sof\sthe\sunix\sbackend. +D 2017-08-22T15:21:54.760 F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 @@ -440,7 +440,7 @@ F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c 0a7730f6cb797ba1fd12825e4ea751e1325041410c063c258e30089ca71f9a88 +F src/os_unix.c 489aa972ccc34f7b4770b891694b32101c59ddd4be4ef0ddd9a4da58c145c1a6 F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c c1dc0609f04a0659519bb2b8ca1440a64b0ad82b6c2afd675f1a50f6c918321a @@ -1649,7 +1649,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 6538ef7b6b56c7a6629a0bb7418910c64c8b2e73af2296a116c073ecf2e0d429 -R 44db9cb33f37af7df65ab136e59cd109 +P 56d19f9fd7b01d4ed5c3e7309977b43fedffee168c9760d3e3b7e885790f781e +R fadb89000aeb50524d087e05d444ff10 U drh -Z bcd0fe0605e077fa72b238dc51f819ad +Z b11624f2af9f39a4604e682002fd5d5e diff --git a/manifest.uuid b/manifest.uuid index 40286a0698..9cd165bc2c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56d19f9fd7b01d4ed5c3e7309977b43fedffee168c9760d3e3b7e885790f781e \ No newline at end of file +885c2b44a44f8d054014e4079b2cac8279c11d13206d5b5215189ef75b9c5254 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index bd646d6e70..0d7e494147 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2321,7 +2321,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved)); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + if( (rc & 0xff) == SQLITE_IOERR ){ rc = SQLITE_OK; reserved=1; } @@ -2388,7 +2388,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) { OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS - if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){ + if( (rc & 0xff) == SQLITE_IOERR ){ rc = SQLITE_BUSY; } #endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */ @@ -2925,7 +2925,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){ /* Can't reestablish the shared lock. Sqlite can't deal, this is ** a critical I/O error */ - rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 : + rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : SQLITE_IOERR_LOCK; goto afp_end_lock; } From f39e0ed4de8d76c458bc8c3cf758637b6720e30c Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Aug 2017 19:19:00 +0000 Subject: [PATCH 32/53] Add the "mksourceid" program to the build process. That program changes the SQLITE_SOURCE_ID if the source tree has been modified in any way. FossilOrigin-Name: d4c05e04f7e1325a3260808ee17252876f678e78bf0cf6569a18a52ff674bd7a --- Makefile.in | 7 +- Makefile.msc | 8 +- main.mk | 7 +- manifest | 19 +- manifest.uuid | 2 +- tool/mksourceid.c | 852 ++++++++++++++++++++++++++++++++++++++++++++ tool/mksqlite3h.tcl | 21 +- 7 files changed, 885 insertions(+), 31 deletions(-) create mode 100644 tool/mksourceid.c diff --git a/Makefile.in b/Makefile.in index bce57b717b..50cd5e8e23 100644 --- a/Makefile.in +++ b/Makefile.in @@ -693,6 +693,11 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o $@ $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . +# Rules to build the program that generates the source-id +# +mksourceid$(BEXE): $(TOP)/tool/mksourceid.c + $(BCC) -o $@ $(TOP)/tool/mksourceid.c + # Rules to build individual *.o files from generated *.c files. This # applies to: # @@ -958,7 +963,7 @@ parse.c: $(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl mv parse.h parse.h.temp $(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h keywordhash.h: $(TOP)/tool/mkkeywordhash.c diff --git a/Makefile.msc b/Makefile.msc index da94288c85..a1937fe5fa 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1670,6 +1670,12 @@ lemon.exe: $(TOP)\tool\lemon.c lempar.c $(BCC) $(NO_WARN) -Daccess=_access \ -Fe$@ $(TOP)\tool\lemon.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS) +# <> +# Rules to build the source-id generator tool +# +mksourceid.exe: $(TOP)\tool\mksourceid.c + $(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\mksourceid.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS) + # Rules to build individual *.lo files from generated *.c files. This # applies to: # @@ -1948,7 +1954,7 @@ parse.c: $(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl move parse.h parse.h.temp $(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h -$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION +$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION $(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS) sqlite3ext.h: .target_source diff --git a/main.mk b/main.mk index d3450a63cb..054f6518a5 100644 --- a/main.mk +++ b/main.mk @@ -606,6 +606,11 @@ lemon: $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c $(BCC) -o lemon $(TOP)/tool/lemon.c cp $(TOP)/tool/lempar.c . +# A tool to generate the source-id +# +mksourceid: $(TOP)/tool/mksourceid.c + $(BCC) -o mksourceid $(TOP)/tool/mksourceid.c + # Rules to build individual *.o files from generated *.c files. This # applies to: # @@ -645,7 +650,7 @@ parse.c: $(TOP)/src/parse.y lemon $(TOP)/tool/addopcodes.tcl mv parse.h parse.h.temp tclsh $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h keywordhash.h: $(TOP)/tool/mkkeywordhash.c diff --git a/manifest b/manifest index a66cc1c8aa..6f9319811f 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\serror\stests\sin\sseldom-used\scompile-time\sbranches\sof\sthe\sunix\sbackend. -D 2017-08-22T15:21:54.760 -F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8 +C Add\sthe\s"mksourceid"\sprogram\sto\sthe\sbuild\sprocess.\s\sThat\sprogram\schanges\nthe\sSQLITE_SOURCE_ID\sif\sthe\ssource\stree\shas\sbeen\smodified\sin\sany\sway. +D 2017-08-22T19:19:00.280 +F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016 +F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd F VERSION f81232df28e2d3ff049feefad5fbd5489cc33697f6bd2ecf61af7f0dde3b83d0 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -380,7 +380,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 5b7d72ab03dd70aa1401f934d31e85aefd6fc542eb58094d7a95d6921390b2d0 +F main.mk da75a0527a56da0b7f568a976b3cb69756613080f16e4d208b6c6a0495bfb132 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1588,10 +1588,11 @@ F tool/mkopcodeh.tcl 4ee2a30ccbd900dc4d5cdb61bdab87cd2166cd2affcc78c9cc0b8d22a65 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd F tool/mkshellc.tcl 69c38ecd7b74b2b0799a35ce20e1e3998e504d8c99c100ca4b98ae9d8f6279bc +F tool/mksourceid.c 1db4636bf4249ac5d2d56fb06b0b30929bf7446a88c7048bb731a72a1c4767ea F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl a4b36eaa002ed00a0ab2c93d999a14f1acae98ff09a85382e5abc05a91edb82b -F tool/mksqlite3h.tcl 51bd5e7e840a920388a5966c9f2ccc618f434c57bd68c1bab4085b2553e1e237 +F tool/mksqlite3h.tcl e10b7878ca20161594fbc28913027956d7ee35713400534a115d8f139b496478 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1649,7 +1650,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 56d19f9fd7b01d4ed5c3e7309977b43fedffee168c9760d3e3b7e885790f781e -R fadb89000aeb50524d087e05d444ff10 +P 885c2b44a44f8d054014e4079b2cac8279c11d13206d5b5215189ef75b9c5254 +R 48a68cf4cf699ac46128e2797c5425f9 U drh -Z b11624f2af9f39a4604e682002fd5d5e +Z 40e98cab2922888e2c30394283edf487 diff --git a/manifest.uuid b/manifest.uuid index 9cd165bc2c..616786c10c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -885c2b44a44f8d054014e4079b2cac8279c11d13206d5b5215189ef75b9c5254 \ No newline at end of file +d4c05e04f7e1325a3260808ee17252876f678e78bf0cf6569a18a52ff674bd7a \ No newline at end of file diff --git a/tool/mksourceid.c b/tool/mksourceid.c new file mode 100644 index 0000000000..722728be4c --- /dev/null +++ b/tool/mksourceid.c @@ -0,0 +1,852 @@ +/* +** Run this program with a single argument which is the name of the +** Fossil "manifest" file for a project, and this program will emit on +** standard output the "source id" for for the program. +** +** (1) The "source id" is the date of check-in together with the +** SHA3 hash of the manifest file. +** +** (2) All individual file hashes in the manifest are verified. If any +** source file has changed, the SHA3 hash ends with "-modified". +** +*/ +#include +#include +#include +#include +#include + +/* Portable 64-bit unsigned integers */ +#if defined(_MSC_VER) || defined(__BORLANDC__) + typedef unsigned __int64 u64; +#else + typedef unsigned long long int u64; +#endif + + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DBYTEORDER=0 is set, then byte-order is determined +** at run-time. +*/ +#ifndef BYTEORDER +# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) +# define BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) +# define BYTEORDER 4321 +# else +# define BYTEORDER 0 +# endif +#endif + + + +/* +** State structure for a SHA3 hash in progress +*/ +typedef struct SHA3Context SHA3Context; +struct SHA3Context { + union { + u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ + unsigned char x[1600]; /* ... or 1600 bytes */ + } u; + unsigned nRate; /* Bytes of input accepted per Keccak iteration */ + unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ + unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ +}; + +/* +** A single step of the Keccak mixing function for a 1600-bit state +*/ +static void KeccakF1600Step(SHA3Context *p){ + int i; + u64 B0, B1, B2, B3, B4; + u64 C0, C1, C2, C3, C4; + u64 D0, D1, D2, D3, D4; + static const u64 RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, + 0x800000000000808aULL, 0x8000000080008000ULL, + 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008aULL, 0x0000000000000088ULL, + 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, + 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, + 0x0000000080000001ULL, 0x8000000080008008ULL + }; +# define A00 (p->u.s[0]) +# define A01 (p->u.s[1]) +# define A02 (p->u.s[2]) +# define A03 (p->u.s[3]) +# define A04 (p->u.s[4]) +# define A10 (p->u.s[5]) +# define A11 (p->u.s[6]) +# define A12 (p->u.s[7]) +# define A13 (p->u.s[8]) +# define A14 (p->u.s[9]) +# define A20 (p->u.s[10]) +# define A21 (p->u.s[11]) +# define A22 (p->u.s[12]) +# define A23 (p->u.s[13]) +# define A24 (p->u.s[14]) +# define A30 (p->u.s[15]) +# define A31 (p->u.s[16]) +# define A32 (p->u.s[17]) +# define A33 (p->u.s[18]) +# define A34 (p->u.s[19]) +# define A40 (p->u.s[20]) +# define A41 (p->u.s[21]) +# define A42 (p->u.s[22]) +# define A43 (p->u.s[23]) +# define A44 (p->u.s[24]) +# define ROL64(a,x) ((a<>(64-x))) + + for(i=0; i<24; i+=4){ + C0 = A00^A10^A20^A30^A40; + C1 = A01^A11^A21^A31^A41; + C2 = A02^A12^A22^A32^A42; + C3 = A03^A13^A23^A33^A43; + C4 = A04^A14^A24^A34^A44; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A11^D1), 44); + B2 = ROL64((A22^D2), 43); + B3 = ROL64((A33^D3), 21); + B4 = ROL64((A44^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i]; + A11 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A20^D0), 3); + B3 = ROL64((A31^D1), 45); + B4 = ROL64((A42^D2), 61); + B0 = ROL64((A03^D3), 28); + B1 = ROL64((A14^D4), 20); + A20 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A40^D0), 18); + B0 = ROL64((A01^D1), 1); + B1 = ROL64((A12^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A34^D4), 8); + A40 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A10^D0), 36); + B2 = ROL64((A21^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A43^D3), 56); + B0 = ROL64((A04^D4), 27); + A10 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A30^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A02^D2), 62); + B1 = ROL64((A13^D3), 55); + B2 = ROL64((A24^D4), 39); + A30 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + C0 = A00^A20^A40^A10^A30; + C1 = A11^A31^A01^A21^A41; + C2 = A22^A42^A12^A32^A02; + C3 = A33^A03^A23^A43^A13; + C4 = A44^A14^A34^A04^A24; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A31^D1), 44); + B2 = ROL64((A12^D2), 43); + B3 = ROL64((A43^D3), 21); + B4 = ROL64((A24^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+1]; + A31 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A40^D0), 3); + B3 = ROL64((A21^D1), 45); + B4 = ROL64((A02^D2), 61); + B0 = ROL64((A33^D3), 28); + B1 = ROL64((A14^D4), 20); + A40 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A30^D0), 18); + B0 = ROL64((A11^D1), 1); + B1 = ROL64((A42^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A04^D4), 8); + A30 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A20^D0), 36); + B2 = ROL64((A01^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A13^D3), 56); + B0 = ROL64((A44^D4), 27); + A20 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A10^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A22^D2), 62); + B1 = ROL64((A03^D3), 55); + B2 = ROL64((A34^D4), 39); + A10 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + C0 = A00^A40^A30^A20^A10; + C1 = A31^A21^A11^A01^A41; + C2 = A12^A02^A42^A32^A22; + C3 = A43^A33^A23^A13^A03; + C4 = A24^A14^A04^A44^A34; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A21^D1), 44); + B2 = ROL64((A42^D2), 43); + B3 = ROL64((A13^D3), 21); + B4 = ROL64((A34^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+2]; + A21 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A30^D0), 3); + B3 = ROL64((A01^D1), 45); + B4 = ROL64((A22^D2), 61); + B0 = ROL64((A43^D3), 28); + B1 = ROL64((A14^D4), 20); + A30 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A10^D0), 18); + B0 = ROL64((A31^D1), 1); + B1 = ROL64((A02^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A44^D4), 8); + A10 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A40^D0), 36); + B2 = ROL64((A11^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A03^D3), 56); + B0 = ROL64((A24^D4), 27); + A40 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A20^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A12^D2), 62); + B1 = ROL64((A33^D3), 55); + B2 = ROL64((A04^D4), 39); + A20 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + C0 = A00^A30^A10^A40^A20; + C1 = A21^A01^A31^A11^A41; + C2 = A42^A22^A02^A32^A12; + C3 = A13^A43^A23^A03^A33; + C4 = A34^A14^A44^A24^A04; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A01^D1), 44); + B2 = ROL64((A02^D2), 43); + B3 = ROL64((A03^D3), 21); + B4 = ROL64((A04^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+3]; + A01 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A10^D0), 3); + B3 = ROL64((A11^D1), 45); + B4 = ROL64((A12^D2), 61); + B0 = ROL64((A13^D3), 28); + B1 = ROL64((A14^D4), 20); + A10 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A20^D0), 18); + B0 = ROL64((A21^D1), 1); + B1 = ROL64((A22^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A24^D4), 8); + A20 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A30^D0), 36); + B2 = ROL64((A31^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A33^D3), 56); + B0 = ROL64((A34^D4), 27); + A30 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A40^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A42^D2), 62); + B1 = ROL64((A43^D3), 55); + B2 = ROL64((A44^D4), 39); + A40 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + } +} + +/* +** Initialize a new hash. iSize determines the size of the hash +** in bits and should be one of 224, 256, 384, or 512. Or iSize +** can be zero to use the default hash size of 256 bits. +*/ +static void SHA3Init(SHA3Context *p, int iSize){ + memset(p, 0, sizeof(*p)); + if( iSize>=128 && iSize<=512 ){ + p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; + }else{ + p->nRate = (1600 - 2*256)/8; + } +#if BYTEORDER==1234 + /* Known to be little-endian at compile-time. No-op */ +#elif BYTEORDER==4321 + p->ixMask = 7; /* Big-endian */ +#else + { + static unsigned int one = 1; + if( 1==*(unsigned char*)&one ){ + /* Little endian. No byte swapping. */ + p->ixMask = 0; + }else{ + /* Big endian. Byte swap. */ + p->ixMask = 7; + } + } +#endif +} + +/* +** Make consecutive calls to the SHA3Update function to add new content +** to the hash +*/ +static void SHA3Update( + SHA3Context *p, + const unsigned char *aData, + unsigned int nData +){ + unsigned int i = 0; +#if BYTEORDER==1234 + if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ + for(; i+7u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; + p->nLoaded += 8; + if( p->nLoaded>=p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } + } +#endif + for(; iu.x[p->nLoaded] ^= aData[i]; +#elif BYTEORDER==4321 + p->u.x[p->nLoaded^0x07] ^= aData[i]; +#else + p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; +#endif + p->nLoaded++; + if( p->nLoaded==p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } +} + +/* +** After all content has been added, invoke SHA3Final() to compute +** the final hash. The function returns a pointer to the binary +** hash value. +*/ +static unsigned char *SHA3Final(SHA3Context *p){ + unsigned int i; + if( p->nLoaded==p->nRate-1 ){ + const unsigned char c1 = 0x86; + SHA3Update(p, &c1, 1); + }else{ + const unsigned char c2 = 0x06; + const unsigned char c3 = 0x80; + SHA3Update(p, &c2, 1); + p->nLoaded = p->nRate - 1; + SHA3Update(p, &c3, 1); + } + for(i=0; inRate; i++){ + p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; + } + return &p->u.x[p->nRate]; +} + +/* +** Convert a digest into base-16. digest should be declared as +** "unsigned char digest[20]" in the calling function. The SHA3 +** digest is stored in the first 20 bytes. zBuf should +** be "char zBuf[41]". +*/ +static void DigestToBase16(unsigned char *digest, char *zBuf, int nByte){ + static const char zEncode[] = "0123456789abcdef"; + int ix; + + for(ix=0; ix>4)&0xf]; + *zBuf++ = zEncode[*digest++ & 0xf]; + } + *zBuf = '\0'; +} + + +/* +** Compute the SHA3 checksum of a file on disk. Store the resulting +** checksum in the blob pCksum. pCksum is assumed to be initialized. +** +** Return the number of errors. +*/ +static int sha3sum_file(const char *zFilename, int iSize, char *pCksum){ + FILE *in; + SHA3Context ctx; + char zBuf[10240]; + + in = fopen(zFilename,"rb"); + if( in==0 ){ + return 1; + } + SHA3Init(&ctx, iSize); + for(;;){ + int n = (int)fread(zBuf, 1, sizeof(zBuf), in); + if( n<=0 ) break; + SHA3Update(&ctx, (unsigned char*)zBuf, (unsigned)n); + } + fclose(in); + DigestToBase16(SHA3Final(&ctx), pCksum, iSize/8); + return 0; +} + +/* +** The SHA1 implementation below is adapted from: +** +** $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $ +** $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ +** +** SHA-1 in C +** By Steve Reid +** 100% Public Domain +*/ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + * + * blk0le() for little-endian and blk0be() for big-endian. + */ +#if __GNUC__ && (defined(__i386__) || defined(__x86_64__)) +/* + * GCC by itself only generates left rotates. Use right rotates if + * possible to be kinder to dinky implementations with iterative rotate + * instructions. + */ +#define SHA_ROT(op, x, k) \ + ({ unsigned int y; asm(op " %1,%0" : "=r" (y) : "I" (k), "0" (x)); y; }) +#define rol(x,k) SHA_ROT("roll", x, k) +#define ror(x,k) SHA_ROT("rorl", x, k) + +#else +/* Generic C equivalent */ +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) +#endif + + + + + +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + +static void SHA1Transform( + unsigned int state[5], + const unsigned char buffer[64] +){ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + + /* Copy context->state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + + +/* + * SHA1Init - Initialize new context + */ +static void SHA1Init(SHA1Context *context){ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* + * Run your data through this. + */ +static void SHA1Update( + SHA1Context *context, + const unsigned char *data, + unsigned int len +){ + unsigned int i, j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1] += (len>>29)+1; + j = (j >> 3) & 63; + if ((j + len) > 63) { + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1Transform(context->state, &data[i]); + j = 0; + } else { + i = 0; + } + (void)memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* + * Add padding and return the message digest. + */ +static void SHA1Final(unsigned char *digest, SHA1Context *context){ + unsigned int i; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (const unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) + SHA1Update(context, (const unsigned char *)"\0", 1); + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + + if (digest) { + for (i = 0; i < 20; i++) + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } +} + + +/* +** Compute the SHA1 checksum of a file on disk. Store the resulting +** checksum in the blob pCksum. pCksum is assumed to be initialized. +** +** Return the number of errors. +*/ +static int sha1sum_file(const char *zFilename, char *pCksum){ + FILE *in; + SHA1Context ctx; + unsigned char zResult[20]; + char zBuf[10240]; + + in = fopen(zFilename,"rb"); + if( in==0 ){ + return 1; + } + SHA1Init(&ctx); + for(;;){ + int n = (int)fread(zBuf, 1, sizeof(zBuf), in); + if( n<=0 ) break; + SHA1Update(&ctx, (unsigned char*)zBuf, (unsigned)n); + } + fclose(in); + SHA1Final(zResult, &ctx); + DigestToBase16(zResult, pCksum, 20); + return 0; +} + +/* +** Print a usage comment and quit. +*/ +static void usage(const char *argv0){ + fprintf(stderr, + "Usage: %s manifest\n" + "Options:\n" + " -v Diagnostic output\n" + , argv0); + exit(1); +} + +/* +** Find the first whitespace character in a string. Set that whitespace +** to a \000 terminator and return a pointer to the next character. +*/ +static char *nextToken(char *z){ + while( *z && !isspace(*z) ) z++; + if( *z==0 ) return z; + *z = 0; + return &z[1]; +} + + +int main(int argc, char **argv){ + const char *zManifest = 0; + int i; + int bVerbose = 0; + FILE *in; + int allValid = 1; + int rc; + char zDate[50]; + char zHash[100]; + char zLine[1000]; + + for(i=1; i Date: Tue, 22 Aug 2017 19:43:41 +0000 Subject: [PATCH 33/53] Attempting to fix the source-id generator so that it works for out-of-tree builds. FossilOrigin-Name: 5a037ac2da7449be3e26c36910ac5d865d7e74d3c25af0a10578c1f92fe2afea --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/mksqlite3h.tcl | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6f9319811f..75edf80b05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"mksourceid"\sprogram\sto\sthe\sbuild\sprocess.\s\sThat\sprogram\schanges\nthe\sSQLITE_SOURCE_ID\sif\sthe\ssource\stree\shas\sbeen\smodified\sin\sany\sway. -D 2017-08-22T19:19:00.280 +C Attempting\sto\sfix\sthe\ssource-id\sgenerator\sso\sthat\sit\sworks\sfor\sout-of-tree\nbuilds. +D 2017-08-22T19:43:41.092 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -1592,7 +1592,7 @@ F tool/mksourceid.c 1db4636bf4249ac5d2d56fb06b0b30929bf7446a88c7048bb731a72a1c47 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl a4b36eaa002ed00a0ab2c93d999a14f1acae98ff09a85382e5abc05a91edb82b -F tool/mksqlite3h.tcl e10b7878ca20161594fbc28913027956d7ee35713400534a115d8f139b496478 +F tool/mksqlite3h.tcl 5dbb75b1125000907f5b334b7b7a16960c5805a26c7a7475f6dd9bd415709a71 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1650,7 +1650,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 885c2b44a44f8d054014e4079b2cac8279c11d13206d5b5215189ef75b9c5254 -R 48a68cf4cf699ac46128e2797c5425f9 +P d4c05e04f7e1325a3260808ee17252876f678e78bf0cf6569a18a52ff674bd7a +R cac9e20accccd833acf3f1836f6cc4f1 U drh -Z 40e98cab2922888e2c30394283edf487 +Z 8bf43d2286864b6e544f292f098efb98 diff --git a/manifest.uuid b/manifest.uuid index 616786c10c..aa5c13477d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4c05e04f7e1325a3260808ee17252876f678e78bf0cf6569a18a52ff674bd7a \ No newline at end of file +5a037ac2da7449be3e26c36910ac5d865d7e74d3c25af0a10578c1f92fe2afea \ No newline at end of file diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index ca40df8185..174a3333bf 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -53,7 +53,10 @@ set nVersion [eval format "%d%03d%03d" [split $zVersion .]] # Get the source-id # -set zSourceId [exec ./mksourceid $TOP/manifest] +set PWD [pwd] +cd $TOP +set zSourceId [exec ./mksourceid manifest] +cd $PWD # Set up patterns for recognizing API declarations. # From c9aed7f891242dbd3c8d046986368d35bb23f656 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Aug 2017 19:49:34 +0000 Subject: [PATCH 34/53] Trying again to get out-of-tree builds to work correctly. FossilOrigin-Name: a1b3337e949fc431e19a3d977d07a312bb253ab7fec6811c0221abd514985d55 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/mksqlite3h.tcl | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 75edf80b05..231c05503d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempting\sto\sfix\sthe\ssource-id\sgenerator\sso\sthat\sit\sworks\sfor\sout-of-tree\nbuilds. -D 2017-08-22T19:43:41.092 +C Trying\sagain\sto\sget\sout-of-tree\sbuilds\sto\swork\scorrectly. +D 2017-08-22T19:49:34.691 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -1592,7 +1592,7 @@ F tool/mksourceid.c 1db4636bf4249ac5d2d56fb06b0b30929bf7446a88c7048bb731a72a1c47 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb F tool/mksqlite3c.tcl a4b36eaa002ed00a0ab2c93d999a14f1acae98ff09a85382e5abc05a91edb82b -F tool/mksqlite3h.tcl 5dbb75b1125000907f5b334b7b7a16960c5805a26c7a7475f6dd9bd415709a71 +F tool/mksqlite3h.tcl f92f994d9709aeb9e2b6e6f9fc8b069d2f55202c8e23f453edc44390a25982dc F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 @@ -1650,7 +1650,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 d4c05e04f7e1325a3260808ee17252876f678e78bf0cf6569a18a52ff674bd7a -R cac9e20accccd833acf3f1836f6cc4f1 +P 5a037ac2da7449be3e26c36910ac5d865d7e74d3c25af0a10578c1f92fe2afea +R 5f7cd0b5ad89a4d7783875a0ce64d27b U drh -Z 8bf43d2286864b6e544f292f098efb98 +Z ce17968a3f11b573ce5537607e65c92d diff --git a/manifest.uuid b/manifest.uuid index aa5c13477d..cfd5e7f801 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a037ac2da7449be3e26c36910ac5d865d7e74d3c25af0a10578c1f92fe2afea \ No newline at end of file +a1b3337e949fc431e19a3d977d07a312bb253ab7fec6811c0221abd514985d55 \ No newline at end of file diff --git a/tool/mksqlite3h.tcl b/tool/mksqlite3h.tcl index 174a3333bf..5b4c48bb74 100644 --- a/tool/mksqlite3h.tcl +++ b/tool/mksqlite3h.tcl @@ -55,7 +55,7 @@ set nVersion [eval format "%d%03d%03d" [split $zVersion .]] # set PWD [pwd] cd $TOP -set zSourceId [exec ./mksourceid manifest] +set zSourceId [exec $PWD/mksourceid manifest] cd $PWD # Set up patterns for recognizing API declarations. From 0a02c72e7914eb1bcd6d2d930ec28199bd1839ae Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Aug 2017 21:07:03 +0000 Subject: [PATCH 35/53] Less dramatic changes to the source-id following an edit. Modify the way that the amalgamation is constructed to give it the opportunity to detect changes and modify the source-id. FossilOrigin-Name: 564c7340a3368501c3da885afde52123ed7f558801f6190cbe6173dfe9704b70 --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/shell.c | 2 +- tool/mksourceid.c | 4 ++-- tool/mksqlite3c.tcl | 38 +++++++++++++++++++++++++++++++++++++- 5 files changed, 49 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1c80411530..4ce365fa8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sSQLITE_SOURCE_ID\sif\sthe\ssource\scode\shas\schanged\sin\sany\sway\ssince\nthe\sprevious\scheck-in. -D 2017-08-22T19:54:34.821 +C Less\sdramatic\schanges\sto\sthe\ssource-id\sfollowing\san\sedit.\s\sModify\sthe\sway\nthat\sthe\samalgamation\sis\sconstructed\sto\sgive\sit\sthe\sopportunity\sto\sdetect\nchanges\sand\smodify\sthe\ssource-id. +D 2017-08-22T21:07:03.663 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -457,7 +457,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 -F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f +F src/shell.c 8f2a8b9e4ffe4f4596b1690dd628cd355d5605257e14ddba83daf5422e0e39af F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 F src/sqlite.h.in f0bd1abf5e27bd22b3bcaae2a861c1efc4ab7e752bf7eb102355135617eb8199 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1588,10 +1588,10 @@ F tool/mkopcodeh.tcl 4ee2a30ccbd900dc4d5cdb61bdab87cd2166cd2affcc78c9cc0b8d22a65 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd F tool/mkshellc.tcl 69c38ecd7b74b2b0799a35ce20e1e3998e504d8c99c100ca4b98ae9d8f6279bc -F tool/mksourceid.c 1db4636bf4249ac5d2d56fb06b0b30929bf7446a88c7048bb731a72a1c4767ea +F tool/mksourceid.c 30966d568654a4fd962fb324753e49429b7379e1f72d2be489ade963121f5943 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb -F tool/mksqlite3c.tcl a4b36eaa002ed00a0ab2c93d999a14f1acae98ff09a85382e5abc05a91edb82b +F tool/mksqlite3c.tcl b258d679829a9305f5cf107b7d97b9bf23adb3773df42947fed5ef7b180dfbd9 F tool/mksqlite3h.tcl f92f994d9709aeb9e2b6e6f9fc8b069d2f55202c8e23f453edc44390a25982dc F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 @@ -1650,8 +1650,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 885c2b44a44f8d054014e4079b2cac8279c11d13206d5b5215189ef75b9c5254 a1b3337e949fc431e19a3d977d07a312bb253ab7fec6811c0221abd514985d55 -R 5f7cd0b5ad89a4d7783875a0ce64d27b -T +closed a1b3337e949fc431e19a3d977d07a312bb253ab7fec6811c0221abd514985d55 +P 515d6a8377cc1dc76d2e78e242fe256cbeef1c1217ec35367648ddeeb17007ec +R a4db1e4547b3dd92436518e89aa3b90a U drh -Z d2c0063b0c5ab8271ba1b5751cfab094 +Z 98b8ca1d9a43edd06d77198cb0511ee0 diff --git a/manifest.uuid b/manifest.uuid index e1681bb498..92dd519d2e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -515d6a8377cc1dc76d2e78e242fe256cbeef1c1217ec35367648ddeeb17007ec \ No newline at end of file +564c7340a3368501c3da885afde52123ed7f558801f6190cbe6173dfe9704b70 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index eaefe62012..bd7853f65d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -8023,7 +8023,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdout_is_console = isatty(1); #if USE_SYSTEM_SQLITE+0!=1 - if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ + if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); diff --git a/tool/mksourceid.c b/tool/mksourceid.c index 722728be4c..0e20b3c3d3 100644 --- a/tool/mksourceid.c +++ b/tool/mksourceid.c @@ -7,7 +7,7 @@ ** SHA3 hash of the manifest file. ** ** (2) All individual file hashes in the manifest are verified. If any -** source file has changed, the SHA3 hash ends with "-modified". +** source file has changed, the SHA3 hash ends with "modified". ** */ #include @@ -844,7 +844,7 @@ int main(int argc, char **argv){ fclose(in); sha3sum_file(zManifest, 256, zHash); if( !allValid ){ - printf("%s %.55s-modified\n", zDate, zHash); + printf("%s %.60salt1\n", zDate, zHash); }else{ printf("%s %s\n", zDate, zHash); } diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 3c3f2c35a0..933819d12b 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -242,7 +242,13 @@ proc copy_file {filename} { } } append line $funcname $rest - puts $out $line + if {$funcname=="sqlite3_sourceid" && !$linemacros} { + # The sqlite3_sourceid() routine is synthesized at the end of + # the amalgamation + puts $out "/* $line */" + } else { + puts $out $line + } } else { puts $out "SQLITE_PRIVATE $line" } @@ -396,4 +402,34 @@ foreach file { copy_file tsrc/$file } +# Synthesize an alternative sqlite3_sourceid() implementation that +# that tries to detects changes in the amalgamation source text +# and modify returns a modified source-id if changes are detected. +# +# The only detection mechanism we have is the __LINE__ macro. So only +# edits that changes the number of lines of source code are detected. +# +if {!$linemacros} { + flush $out + set in2 [open sqlite3.c] + set cnt 0 + set oldsrcid {} + while {![eof $in2]} { + incr cnt + gets $in2 line + if {[regexp {^#define SQLITE_SOURCE_ID } $line]} {set oldsrcid $line} + } + close $in2 + regsub {[0-9a-flt]{4}"} $oldsrcid {alt2"} oldsrcid + puts $out \ +"#if __LINE__!=[expr {$cnt+0}] +#undef SQLITE_SOURCE_ID +$oldsrcid +#endif +/* Return the source-id for this library */ +SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }" +} +puts $out \ +"/************************** End of sqlite3.c ******************************/" + close $out From 489a224bea393ab9a661d02d693dfea70a97d599 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 22 Aug 2017 21:23:02 +0000 Subject: [PATCH 36/53] Update documentation to make it clear that SQLITE_SOURCE_ID and sqlite3_sourceid() might changes if the source code is edited. FossilOrigin-Name: e69c0c8770d3cc2fcdc779c6290caf1575644d457326caa00327b9070251d620 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 12 ++++++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 4ce365fa8d..55217ab212 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Less\sdramatic\schanges\sto\sthe\ssource-id\sfollowing\san\sedit.\s\sModify\sthe\sway\nthat\sthe\samalgamation\sis\sconstructed\sto\sgive\sit\sthe\sopportunity\sto\sdetect\nchanges\sand\smodify\sthe\ssource-id. -D 2017-08-22T21:07:03.663 +C Update\sdocumentation\sto\smake\sit\sclear\sthat\sSQLITE_SOURCE_ID\sand\nsqlite3_sourceid()\smight\schanges\sif\sthe\ssource\scode\sis\sedited. +D 2017-08-22T21:23:02.258 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -459,7 +459,7 @@ F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 F src/shell.c 8f2a8b9e4ffe4f4596b1690dd628cd355d5605257e14ddba83daf5422e0e39af F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 -F src/sqlite.h.in f0bd1abf5e27bd22b3bcaae2a861c1efc4ab7e752bf7eb102355135617eb8199 +F src/sqlite.h.in 73a75cc53b5017525332ff3db2f74bb2607f1e8c0e8974d4afa3df3786f70aab F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 F src/sqliteInt.h bc0792db4ff887e4884d386188527e1cd7c16d496c8f3ba23333e68cee3e4f78 @@ -1650,7 +1650,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 515d6a8377cc1dc76d2e78e242fe256cbeef1c1217ec35367648ddeeb17007ec -R a4db1e4547b3dd92436518e89aa3b90a +P 564c7340a3368501c3da885afde52123ed7f558801f6190cbe6173dfe9704b70 +R b1a5f4a03931a03b3cf49a93760947b3 U drh -Z 98b8ca1d9a43edd06d77198cb0511ee0 +Z 80eecc829d5290754bef086590571027 diff --git a/manifest.uuid b/manifest.uuid index 92dd519d2e..0e97d0f48f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -564c7340a3368501c3da885afde52123ed7f558801f6190cbe6173dfe9704b70 \ No newline at end of file +e69c0c8770d3cc2fcdc779c6290caf1575644d457326caa00327b9070251d620 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 1020e5f3d6..96d133b41c 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -115,7 +115,9 @@ extern "C" { ** a string which identifies a particular check-in of SQLite ** within its configuration management system. ^The SQLITE_SOURCE_ID ** string contains the date and time of the check-in (UTC) and a SHA1 -** or SHA3-256 hash of the entire source tree. +** or SHA3-256 hash of the entire source tree. If the source code has +** been edited in any way since it was last checked in, then the last +** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], @@ -139,7 +141,7 @@ extern "C" { ** **
 ** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
 ** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
 ** 
)^ ** @@ -149,9 +151,11 @@ extern "C" { ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The ** sqlite3_libversion_number() function returns an integer equal to -** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns +** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the -** [SQLITE_SOURCE_ID] C preprocessor macro. +** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built +** using an edited copy of [the amalgamation], then the last four characters +** of the hash might be different from [SQLITE_SOURCE_ID].)^ ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ From 5e27e1dc499097272615b0591c457b7967aedf24 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Aug 2017 14:45:59 +0000 Subject: [PATCH 37/53] Smaller and faster implementation of the fillInCell() routine. FossilOrigin-Name: 77074990edef6c42bdfe7ccce1affc8ed64a86dde3ad4fa50b60ba0a6d851eea --- manifest | 12 +++---- manifest.uuid | 2 +- src/btree.c | 99 +++++++++++++++++++++++++++++---------------------- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/manifest b/manifest index 55217ab212..79af87c73a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sdocumentation\sto\smake\sit\sclear\sthat\sSQLITE_SOURCE_ID\sand\nsqlite3_sourceid()\smight\schanges\sif\sthe\ssource\scode\sis\sedited. -D 2017-08-22T21:23:02.258 +C Smaller\sand\sfaster\simplementation\sof\sthe\sfillInCell()\sroutine. +D 2017-08-23T14:45:59.667 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -399,7 +399,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c e1a98bef27d6189df5c5b8b3c9b5e53d6b74bf9a936af97757c21e9ea6a5c6b2 +F src/btree.c ea10ca63430533c358da32e5d2b8b22aa3c6a9e84f295139e4e5bb00f635726d F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 @@ -1650,7 +1650,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 564c7340a3368501c3da885afde52123ed7f558801f6190cbe6173dfe9704b70 -R b1a5f4a03931a03b3cf49a93760947b3 +P e69c0c8770d3cc2fcdc779c6290caf1575644d457326caa00327b9070251d620 +R 66591a7ad128e50f7a0c04de7cb52832 U drh -Z 80eecc829d5290754bef086590571027 +Z 50b9a412665b926c36fcdf17b0a625f8 diff --git a/manifest.uuid b/manifest.uuid index 0e97d0f48f..0e5f5791b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e69c0c8770d3cc2fcdc779c6290caf1575644d457326caa00327b9070251d620 \ No newline at end of file +77074990edef6c42bdfe7ccce1affc8ed64a86dde3ad4fa50b60ba0a6d851eea \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index ecdbb6d0a3..b6e5fbc508 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6218,21 +6218,20 @@ static int fillInCell( ){ int nPayload; const u8 *pSrc; - int nSrc, n, rc; + int nSrc, n, rc, mn; int spaceLeft; - MemPage *pOvfl = 0; - MemPage *pToRelease = 0; + MemPage *pToRelease; unsigned char *pPrior; unsigned char *pPayload; - BtShared *pBt = pPage->pBt; - Pgno pgnoOvfl = 0; + BtShared *pBt; + Pgno pgnoOvfl; int nHeader; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); /* pPage is not necessarily writeable since pCell might be auxiliary ** buffer space that is separate from the pPage buffer area */ - assert( pCellaData || pCell>=&pPage->aData[pBt->pageSize] + assert( pCellaData || pCell>=&pPage->aData[pPage->pBt->pageSize] || sqlite3PagerIswriteable(pPage->pDbPage) ); /* Fill in the header. */ @@ -6252,25 +6251,36 @@ static int fillInCell( } /* Fill in the payload */ + pPayload = &pCell[nHeader]; if( nPayload<=pPage->maxLocal ){ + /* This is the common case where everything fits on the btree page + ** and no overflow pages are required. */ n = nHeader + nPayload; testcase( n==3 ); testcase( n==4 ); if( n<4 ) n = 4; *pnSize = n; - spaceLeft = nPayload; - pPrior = pCell; - }else{ - int mn = pPage->minLocal; - n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); - testcase( n==pPage->maxLocal ); - testcase( n==pPage->maxLocal+1 ); - if( n > pPage->maxLocal ) n = mn; - spaceLeft = n; - *pnSize = n + nHeader + 4; - pPrior = &pCell[nHeader+n]; + assert( nSrc<=nPayload ); + testcase( nSrcminLocal; + n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4); + testcase( n==pPage->maxLocal ); + testcase( n==pPage->maxLocal+1 ); + if( n > pPage->maxLocal ) n = mn; + spaceLeft = n; + *pnSize = n + nHeader + 4; + pPrior = &pCell[nHeader+n]; + pToRelease = 0; + pgnoOvfl = 0; + pBt = pPage->pBt; /* At this point variables should be set as follows: ** @@ -6296,8 +6306,35 @@ static int fillInCell( #endif /* Write the payload into the local Cell and any extra into overflow pages */ - while( nPayload>0 ){ + while( 1 ){ + n = nPayload; + if( n>spaceLeft ) n = spaceLeft; + + /* If pToRelease is not zero than pPayload points into the data area + ** of pToRelease. Make sure pToRelease is still writeable. */ + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); + + /* If pPayload is part of the data area of pPage, then make sure pPage + ** is still writeable */ + assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] + || sqlite3PagerIswriteable(pPage->pDbPage) ); + + if( nSrc>=n ){ + memcpy(pPayload, pSrc, n); + }else if( nSrc>0 ){ + n = nSrc; + memcpy(pPayload, pSrc, n); + }else{ + memset(pPayload, 0, n); + } + nPayload -= n; + if( nPayload<=0 ) break; + pPayload += n; + pSrc += n; + nSrc -= n; + spaceLeft -= n; if( spaceLeft==0 ){ + MemPage *pOvfl = 0; #ifndef SQLITE_OMIT_AUTOVACUUM Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ if( pBt->autoVacuum ){ @@ -6350,30 +6387,6 @@ static int fillInCell( pPayload = &pOvfl->aData[4]; spaceLeft = pBt->usableSize - 4; } - n = nPayload; - if( n>spaceLeft ) n = spaceLeft; - - /* If pToRelease is not zero than pPayload points into the data area - ** of pToRelease. Make sure pToRelease is still writeable. */ - assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); - - /* If pPayload is part of the data area of pPage, then make sure pPage - ** is still writeable */ - assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] - || sqlite3PagerIswriteable(pPage->pDbPage) ); - - if( nSrc>0 ){ - if( n>nSrc ) n = nSrc; - assert( pSrc ); - memcpy(pPayload, pSrc, n); - }else{ - memset(pPayload, 0, n); - } - nPayload -= n; - pPayload += n; - pSrc += n; - nSrc -= n; - spaceLeft -= n; } releasePage(pToRelease); return SQLITE_OK; From 5e398e4cbd2d3f05903bbb7606c4bb15d9c122b2 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Aug 2017 20:36:06 +0000 Subject: [PATCH 38/53] Size and performance optimization to dropCell() and freeSpace(). FossilOrigin-Name: bc1ec123ce05c9d16b0942f870381145dc9725764e47806939ff207a73066f4d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 32 +++++++++++++++++--------------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 79af87c73a..80d60559cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Smaller\sand\sfaster\simplementation\sof\sthe\sfillInCell()\sroutine. -D 2017-08-23T14:45:59.667 +C Size\sand\sperformance\soptimization\sto\sdropCell()\sand\sfreeSpace(). +D 2017-08-23T20:36:06.554 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -399,7 +399,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c ea10ca63430533c358da32e5d2b8b22aa3c6a9e84f295139e4e5bb00f635726d +F src/btree.c 45f3b8b3ad112d21afacfdfcbc1c362637bf080abb58c901104a8d3a6207a1bf F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 @@ -1650,7 +1650,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 e69c0c8770d3cc2fcdc779c6290caf1575644d457326caa00327b9070251d620 -R 66591a7ad128e50f7a0c04de7cb52832 +P 77074990edef6c42bdfe7ccce1affc8ed64a86dde3ad4fa50b60ba0a6d851eea +R 522ed57ec99b8b2e95cc60b01e62a8eb U drh -Z 50b9a412665b926c36fcdf17b0a625f8 +Z 185127068afaca8c598b7b9a50979c09 diff --git a/manifest.uuid b/manifest.uuid index 0e5f5791b5..07ad7f8eec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77074990edef6c42bdfe7ccce1affc8ed64a86dde3ad4fa50b60ba0a6d851eea \ No newline at end of file +bc1ec123ce05c9d16b0942f870381145dc9725764e47806939ff207a73066f4d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b6e5fbc508..bd66a77049 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1505,7 +1505,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ if( (x = size - nByte)>=0 ){ testcase( x==4 ); testcase( x==3 ); - if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){ + if( size+pc > usableSize ){ *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno); return 0; }else if( x<4 ){ @@ -1640,7 +1640,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ u8 hdr; /* Page header size. 0 or 100 */ u8 nFrag = 0; /* Reduction in fragmentation */ u16 iOrigSize = iSize; /* Original value of iSize */ - u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */ + u16 x; /* Offset to cell content area */ u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */ unsigned char *data = pPage->aData; /* Page content */ @@ -1650,13 +1650,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ - assert( iStart<=iLast ); - - /* Overwrite deleted information with zeros when the secure_delete - ** option is enabled */ - if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ - memset(&data[iStart], 0, iSize); - } + assert( iStart<=pPage->pBt->usableSize-4 ); /* The list of freeblocks must be in ascending order. Find the ** spot on the list where iStart should be inserted. @@ -1673,7 +1667,9 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ } iPtr = iFreeBlk; } - if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + if( iFreeBlk>pPage->pBt->usableSize-4 ){ + return SQLITE_CORRUPT_PGNO(pPage->pgno); + } assert( iFreeBlk>iPtr || iFreeBlk==0 ); /* At this point: @@ -1709,19 +1705,25 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno); data[hdr+7] -= nFrag; } - if( iStart==get2byte(&data[hdr+5]) ){ + x = get2byte(&data[hdr+5]); + if( iStart<=x ){ /* The new freeblock is at the beginning of the cell content area, ** so just extend the cell content area rather than create another ** freelist entry */ - if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + if( iStartpgno); put2byte(&data[hdr+1], iFreeBlk); put2byte(&data[hdr+5], iEnd); }else{ /* Insert the new freeblock into the freelist */ put2byte(&data[iPtr], iStart); - put2byte(&data[iStart], iFreeBlk); - put2byte(&data[iStart+2], iSize); } + if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){ + /* Overwrite deleted information with zeros when the secure_delete + ** option is enabled */ + memset(&data[iStart], 0, iSize); + } + put2byte(&data[iStart], iFreeBlk); + put2byte(&data[iStart+2], iSize); pPage->nFree += iOrigSize; return SQLITE_OK; } @@ -6418,7 +6420,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ hdr = pPage->hdrOffset; testcase( pc==get2byte(&data[hdr+5]) ); testcase( pc+sz==pPage->pBt->usableSize ); - if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ + if( pc+sz > pPage->pBt->usableSize ){ *pRC = SQLITE_CORRUPT_BKPT; return; } From 87d63c900db707562a0a1fde30eb98e69e33b7a1 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Aug 2017 23:09:03 +0000 Subject: [PATCH 39/53] Performance optimization to pageFindSlot() in the b-tree layer. FossilOrigin-Name: 59560d079fab4b91ec50855cc60349da178209c38fb6dae674ff874ccfc7f5fa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 16 +++++++--------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 80d60559cb..9a9edb7494 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\sand\sperformance\soptimization\sto\sdropCell()\sand\sfreeSpace(). -D 2017-08-23T20:36:06.554 +C Performance\soptimization\sto\spageFindSlot()\sin\sthe\sb-tree\slayer. +D 2017-08-23T23:09:03.990 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -399,7 +399,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 45f3b8b3ad112d21afacfdfcbc1c362637bf080abb58c901104a8d3a6207a1bf +F src/btree.c f93c05dbd60551b322dbcaaf4961e87ea20eb67667ebc3181f15d2b5cb66bbaa F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 @@ -1650,7 +1650,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 77074990edef6c42bdfe7ccce1affc8ed64a86dde3ad4fa50b60ba0a6d851eea -R 522ed57ec99b8b2e95cc60b01e62a8eb +P bc1ec123ce05c9d16b0942f870381145dc9725764e47806939ff207a73066f4d +R f6b2325c9199ea50423580e65f552033 U drh -Z 185127068afaca8c598b7b9a50979c09 +Z 8c1fbb63bd6c44847b2e56eee310d2d1 diff --git a/manifest.uuid b/manifest.uuid index 07ad7f8eec..7fb20a017d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc1ec123ce05c9d16b0942f870381145dc9725764e47806939ff207a73066f4d \ No newline at end of file +59560d079fab4b91ec50855cc60349da178209c38fb6dae674ff874ccfc7f5fa \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index bd66a77049..a4bcaf6c49 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1488,16 +1488,10 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ int pc = get2byte(&aData[iAddr]); int x; int usableSize = pPg->pBt->usableSize; + int size; /* Size of the free slot */ assert( pc>0 ); - do{ - int size; /* Size of the free slot */ - /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of - ** increasing offset. */ - if( pc>usableSize-4 || pcpgno); - return 0; - } + while( pc<=usableSize-4 ){ /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each ** freeblock form a big-endian integer which is the size of the freeblock ** in bytes, including the 4-byte header. */ @@ -1526,7 +1520,11 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ } iAddr = pc; pc = get2byte(&aData[pc]); - }while( pc ); + if( pcpgno); + } return 0; } From 526740b1b91820e4e0944dd9905be91cec281f12 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Aug 2017 13:55:46 +0000 Subject: [PATCH 40/53] Make sure the sqlite3_result_pointer() interface does not leave a VM register in an inconsistent state. Fix for ticket [7486aa54b968e9b5]. Test cases are in TH3. FossilOrigin-Name: d2f9230c5c7ad6166e7d2b649f77960fa58b1cb583e529a43882753ab348413c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeapi.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9a9edb7494..0da8256bdb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sto\spageFindSlot()\sin\sthe\sb-tree\slayer. -D 2017-08-23T23:09:03.990 +C Make\ssure\sthe\ssqlite3_result_pointer()\sinterface\sdoes\snot\sleave\sa\sVM\sregister\nin\san\sinconsistent\sstate.\s\sFix\sfor\sticket\s[7486aa54b968e9b5].\s\sTest\scases\nare\sin\sTH3. +D 2017-08-24T13:55:46.912 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -527,7 +527,7 @@ F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739 F src/vdbe.c 82fc4553a0986a06bdd0d2b03a424e159bba5c74802fabb2841aa6cd27ccd962 F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97 F src/vdbeInt.h 1fe00770144c12c4913128f35262d11527ef3284561baaab59b947a41c08d0d9 -F src/vdbeapi.c 05d6b14ab73952db0d73f6452d6960216997bd966a710266b2fe051f25326abc +F src/vdbeapi.c 9c670ca0dcc1cd86373aa353b747b26fe531ca5cd4331690c611d1f03842e2a1 F src/vdbeaux.c 2dff8186d34e0e525838f77b2fac70bd480f0273a77015bf21b6a08f2792da82 F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b F src/vdbemem.c 2f9d672af5260f0145787e1dc2c6985414987cc0dc575133a0dc17dda767d868 @@ -1650,7 +1650,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 bc1ec123ce05c9d16b0942f870381145dc9725764e47806939ff207a73066f4d -R f6b2325c9199ea50423580e65f552033 +P 59560d079fab4b91ec50855cc60349da178209c38fb6dae674ff874ccfc7f5fa +R f928c1195d839713ee78e6b46c1884f1 U drh -Z 8c1fbb63bd6c44847b2e56eee310d2d1 +Z fae59aff59c16e3b9c2ad1cd0f0e8fa3 diff --git a/manifest.uuid b/manifest.uuid index 7fb20a017d..c161e3d95e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -59560d079fab4b91ec50855cc60349da178209c38fb6dae674ff874ccfc7f5fa \ No newline at end of file +d2f9230c5c7ad6166e7d2b649f77960fa58b1cb583e529a43882753ab348413c \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 3f4ef8f6a9..b9df40b8fd 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -398,7 +398,8 @@ void sqlite3_result_pointer( ){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); - sqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemRelease(pOut); + pOut->flags = MEM_Null; sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ From 09e16491f603e4cdfa277d48a0989ba79ba4e396 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Aug 2017 15:43:26 +0000 Subject: [PATCH 41/53] Fixes to documentation about SQLITE_OPEN_URI. FossilOrigin-Name: 7ec72314d6b66e4969833194fd032f01963bb861a7bb30d060acdb82dc5d62fe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0da8256bdb..a5acff37b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\ssqlite3_result_pointer()\sinterface\sdoes\snot\sleave\sa\sVM\sregister\nin\san\sinconsistent\sstate.\s\sFix\sfor\sticket\s[7486aa54b968e9b5].\s\sTest\scases\nare\sin\sTH3. -D 2017-08-24T13:55:46.912 +C Fixes\sto\sdocumentation\sabout\sSQLITE_OPEN_URI. +D 2017-08-24T15:43:26.350 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -459,7 +459,7 @@ F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 F src/shell.c 8f2a8b9e4ffe4f4596b1690dd628cd355d5605257e14ddba83daf5422e0e39af F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 -F src/sqlite.h.in 73a75cc53b5017525332ff3db2f74bb2607f1e8c0e8974d4afa3df3786f70aab +F src/sqlite.h.in a8e60396a73996a12a153299943f45fe59202c89bb1a46bab203a5e1b99b2493 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 F src/sqliteInt.h bc0792db4ff887e4884d386188527e1cd7c16d496c8f3ba23333e68cee3e4f78 @@ -1650,7 +1650,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 59560d079fab4b91ec50855cc60349da178209c38fb6dae674ff874ccfc7f5fa -R f928c1195d839713ee78e6b46c1884f1 +P d2f9230c5c7ad6166e7d2b649f77960fa58b1cb583e529a43882753ab348413c +R 9289556db20d60c2fec8166d36acfa2c U drh -Z fae59aff59c16e3b9c2ad1cd0f0e8fa3 +Z 14ebde2517e2be2d793887e9fa413aa5 diff --git a/manifest.uuid b/manifest.uuid index c161e3d95e..64bb1d3ded 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2f9230c5c7ad6166e7d2b649f77960fa58b1cb583e529a43882753ab348413c \ No newline at end of file +7ec72314d6b66e4969833194fd032f01963bb861a7bb30d060acdb82dc5d62fe \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 96d133b41c..d794e73eac 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3150,10 +3150,10 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ^If [URI filename] interpretation is enabled, and the filename argument ** begins with "file:", then the filename is interpreted as a URI. ^URI ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is -** set in the fourth argument to sqlite3_open_v2(), or if it has +** set in the third argument to sqlite3_open_v2(), or if it has ** been enabled globally using the [SQLITE_CONFIG_URI] option with the ** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. -** As of SQLite version 3.7.7, URI filename interpretation is turned off +** URI filename interpretation is turned off ** by default, but future releases of SQLite might enable URI filename ** interpretation by default. See "[URI filenames]" for additional ** information. From 9c6e07d2fa6876c20116d8d9c8e486699f992959 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Aug 2017 20:54:42 +0000 Subject: [PATCH 42/53] Fix an incorrect hyperlink in a comment. FossilOrigin-Name: 25292b9a4eb5efc7db551da0b3c9cfd7e79da1594ee14729de44090e188c2b2a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a5acff37b1..e74b367e97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sto\sdocumentation\sabout\sSQLITE_OPEN_URI. -D 2017-08-24T15:43:26.350 +C Fix\san\sincorrect\shyperlink\sin\sa\scomment. +D 2017-08-24T20:54:42.754 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -535,7 +535,7 @@ F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c f1d5c23132fb0247af3e86146404112283ddedb6c518de0d4edc91cfb36970ef F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 +F src/wal.c 4c7c13a3c0d92b0bed157ac234679e4874afcb1990af33510542a0f35f9264b8 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6 F src/where.c ad558533d6fe6578857635218633aa241e2428835763c46801be9e68d6ec0701 @@ -1650,7 +1650,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 d2f9230c5c7ad6166e7d2b649f77960fa58b1cb583e529a43882753ab348413c -R 9289556db20d60c2fec8166d36acfa2c +P 7ec72314d6b66e4969833194fd032f01963bb861a7bb30d060acdb82dc5d62fe +R 0a9008b1e381e229108d828896139715 U drh -Z 14ebde2517e2be2d793887e9fa413aa5 +Z 0f9a691a1b4c4aa8a5eacf3d9e1dd571 diff --git a/manifest.uuid b/manifest.uuid index 64bb1d3ded..404de58199 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ec72314d6b66e4969833194fd032f01963bb861a7bb30d060acdb82dc5d62fe \ No newline at end of file +25292b9a4eb5efc7db551da0b3c9cfd7e79da1594ee14729de44090e188c2b2a \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 09f605fe57..45f1bc8c84 100644 --- a/src/wal.c +++ b/src/wal.c @@ -3119,7 +3119,7 @@ int sqlite3WalFrames( ** an out-of-order write following a WAL restart could result in ** database corruption. See the ticket: ** - ** http://localhost:591/sqlite/info/ff5be73dee + ** https://sqlite.org/src/info/ff5be73dee */ if( pWal->syncHeader && sync_flags ){ rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); From daaae7b9d124961d4c6bae0cfd128aab76671404 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Aug 2017 01:14:43 +0000 Subject: [PATCH 43/53] Update the mechanism used to keep track of what kind of syncing to do for WAL transaction commits and checkpoint operations. Use the checkpoint-style of syncing to sync the header of a new or restarted WAL file. FossilOrigin-Name: bf65dae8d4297c57ac63228ccf0100f9fabf2fb600438c9f2e10a29c4b118168 --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/os.c | 2 +- src/pager.c | 38 ++++++++++++++++++++++---------------- src/wal.c | 20 +++++++++----------- src/wal.h | 8 ++++---- test/wal2.test | 6 +++--- 7 files changed, 53 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index e74b367e97..cfd5eb0e64 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\shyperlink\sin\sa\scomment. -D 2017-08-24T20:54:42.754 +C Update\sthe\smechanism\sused\sto\skeep\strack\sof\swhat\skind\sof\ssyncing\sto\sdo\sfor\nWAL\stransaction\scommits\sand\scheckpoint\soperations.\s\sUse\sthe\scheckpoint-style\nof\ssyncing\sto\ssync\sthe\sheader\sof\sa\snew\sor\srestarted\sWAL\sfile. +D 2017-08-25T01:14:43.498 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -436,14 +436,14 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23 F src/mutex_w32.c a898fa969823b100c0f5fdc57e54c9a1e419ab4d F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7 -F src/os.c add02933b1dce7a39a005b00a2f5364b763e9a24 +F src/os.c 93e0979b9b55df29c0c4923f73b48e9d3fe728f01dd8ed4f6a9d2f1d79779bc8 F src/os.h 8e976e59eb4ca1c0fca6d35ee803e38951cb0343 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 F src/os_unix.c 489aa972ccc34f7b4770b891694b32101c59ddd4be4ef0ddd9a4da58c145c1a6 F src/os_win.c 964165b66cde03abc72fe948198b01be608436894732eadb94c8720d2467f223 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c c1dc0609f04a0659519bb2b8ca1440a64b0ad82b6c2afd675f1a50f6c918321a +F src/pager.c bf51378c57c8e05d7f4d7bb9861f403a2e40cde82e25513401216d1ed30bc3e5 F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 52ef3cecd0934e9da4a45b585883a03243ad615d338ad94f44501a05891dcdfa F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 @@ -535,8 +535,8 @@ F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c f1d5c23132fb0247af3e86146404112283ddedb6c518de0d4edc91cfb36970ef F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 4c7c13a3c0d92b0bed157ac234679e4874afcb1990af33510542a0f35f9264b8 -F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 +F src/wal.c 839db09792fead5052bb35e533fa485e134913d547d05b5f42e537b73e63f07a +F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6 F src/where.c ad558533d6fe6578857635218633aa241e2428835763c46801be9e68d6ec0701 F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d @@ -1486,7 +1486,7 @@ F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c37 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477 -F test/wal2.test 56b0bc95b8693a0be294f8d210c49025dd094bd7 +F test/wal2.test 6ac39b94a284ebac6efb6be93b0cdfe73ee6083f129555e3144d8a615e9900ef F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 @@ -1650,7 +1650,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 7ec72314d6b66e4969833194fd032f01963bb861a7bb30d060acdb82dc5d62fe -R 0a9008b1e381e229108d828896139715 +P 25292b9a4eb5efc7db551da0b3c9cfd7e79da1594ee14729de44090e188c2b2a +R 0c45c0346ff1a3d7a9dbb07f83f4f723 +T *branch * wal-sync-refactor +T *sym-wal-sync-refactor * +T -sym-trunk * U drh -Z 0f9a691a1b4c4aa8a5eacf3d9e1dd571 +Z 5b1634e4e5e7d2e25acb68caf19e0213 diff --git a/manifest.uuid b/manifest.uuid index 404de58199..cfce901f7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25292b9a4eb5efc7db551da0b3c9cfd7e79da1594ee14729de44090e188c2b2a \ No newline at end of file +bf65dae8d4297c57ac63228ccf0100f9fabf2fb600438c9f2e10a29c4b118168 \ No newline at end of file diff --git a/src/os.c b/src/os.c index 5cf0014794..18277df356 100644 --- a/src/os.c +++ b/src/os.c @@ -98,7 +98,7 @@ int sqlite3OsTruncate(sqlite3_file *id, i64 size){ } int sqlite3OsSync(sqlite3_file *id, int flags){ DO_OS_MALLOC_TEST(id); - return id->pMethods->xSync(id, flags); + return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK; } int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ DO_OS_MALLOC_TEST(id); diff --git a/src/pager.c b/src/pager.c index 5986afdae1..2e5977fe43 100644 --- a/src/pager.c +++ b/src/pager.c @@ -616,6 +616,18 @@ struct PagerSavepoint { ** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode ** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX ** sub-codes. +** +** syncFlags, walSyncFlags +** +** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03). +** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode +** and contains the flags used to sync the checkpoint operations in the +** lower two bits, and sync flags used for transaction commits in the WAL +** file in bits 0x04 and 0x08. In other words, to get the correct sync flags +** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct +** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note +** that with synchronous=NORMAL in WAL mode, transaction commit is not synced +** meaning that the 0x04 and 0x08 bits are both zero. */ struct Pager { sqlite3_vfs *pVfs; /* OS functions to use for IO */ @@ -625,9 +637,8 @@ struct Pager { u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ u8 extraSync; /* sync directory after journal delete */ - u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ - u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ + u8 walSyncFlags; /* See description above */ u8 tempFile; /* zFilename is a temporary or immutable file */ u8 noLock; /* Do not lock (except in WAL mode) */ u8 readOnly; /* True for a read-only database */ @@ -3598,20 +3609,17 @@ void sqlite3PagerSetFlags( } if( pPager->noSync ){ pPager->syncFlags = 0; - pPager->ckptSyncFlags = 0; }else if( pgFlags & PAGER_FULLFSYNC ){ pPager->syncFlags = SQLITE_SYNC_FULL; - pPager->ckptSyncFlags = SQLITE_SYNC_FULL; - }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){ - pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = SQLITE_SYNC_FULL; }else{ pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; } - pPager->walSyncFlags = pPager->syncFlags; + pPager->walSyncFlags = (pPager->syncFlags<<2); if( pPager->fullSync ){ - pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS; + pPager->walSyncFlags |= pPager->syncFlags; + } + if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){ + pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2); } if( pgFlags & PAGER_CACHESPILL ){ pPager->doNotSpill &= ~SPILLFLAG_OFF; @@ -4110,7 +4118,7 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ pPager->exclusiveMode = 0; #ifndef SQLITE_OMIT_WAL assert( db || pPager->pWal==0 ); - sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize, + sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize, (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp) ); pPager->pWal = 0; @@ -4918,13 +4926,11 @@ act_like_temp_file: assert( pPager->extraSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); - assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; pPager->extraSync = 0; pPager->syncFlags = SQLITE_SYNC_NORMAL; - pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; - pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; + pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2); } /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ @@ -7372,7 +7378,7 @@ int sqlite3PagerCheckpoint( rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), pPager->pBusyHandlerArg, - pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, + pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, pnLog, pnCkpt ); } @@ -7529,7 +7535,7 @@ int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ if( rc==SQLITE_OK && pPager->pWal ){ rc = pagerExclusiveLock(pPager); if( rc==SQLITE_OK ){ - rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, + rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize, (u8*)pPager->pTmpSpace); pPager->pWal = 0; pagerFixMaplimit(pPager); diff --git a/src/wal.c b/src/wal.c index 45f1bc8c84..9930b84421 100644 --- a/src/wal.c +++ b/src/wal.c @@ -1798,9 +1798,7 @@ static int walCheckpoint( pInfo->nBackfillAttempted = mxSafeFrame; /* Sync the WAL to disk */ - if( sync_flags ){ - rc = sqlite3OsSync(pWal->pWalFd, sync_flags); - } + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); /* If the database may grow as a result of this checkpoint, hint ** about the eventual size of the db file to the VFS layer. @@ -1841,8 +1839,8 @@ static int walCheckpoint( i64 szDb = pWal->hdr.nPage*(i64)szPage; testcase( IS_BIG_INT(szDb) ); rc = sqlite3OsTruncate(pWal->pDbFd, szDb); - if( rc==SQLITE_OK && sync_flags ){ - rc = sqlite3OsSync(pWal->pDbFd, sync_flags); + if( rc==SQLITE_OK ){ + rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); } } if( rc==SQLITE_OK ){ @@ -2948,8 +2946,8 @@ static int walWriteToLog( iOffset += iFirstAmt; iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); - assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) ); - rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK); + assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); + rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); if( iAmt==0 || rc ) return rc; } rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); @@ -3121,8 +3119,8 @@ int sqlite3WalFrames( ** ** https://sqlite.org/src/info/ff5be73dee */ - if( pWal->syncHeader && sync_flags ){ - rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK); + if( pWal->syncHeader ){ + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); if( rc ) return rc; } } @@ -3197,7 +3195,7 @@ int sqlite3WalFrames( ** sector boundary is synced; the part of the last frame that extends ** past the sector boundary is written after the sync. */ - if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){ + if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ int bSync = 1; if( pWal->padToSectorBoundary ){ int sectorSize = sqlite3SectorSize(pWal->pWalFd); @@ -3213,7 +3211,7 @@ int sqlite3WalFrames( } if( bSync ){ assert( rc==SQLITE_OK ); - rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); + rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags)); } } diff --git a/src/wal.h b/src/wal.h index 4f6d01dad6..d97300a684 100644 --- a/src/wal.h +++ b/src/wal.h @@ -19,11 +19,11 @@ #include "sqliteInt.h" -/* Additional values that can be added to the sync_flags argument of -** sqlite3WalFrames(): +/* Macros for extracting appropriate sync flags for either transaction +** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)): */ -#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ -#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ +#define WAL_SYNC_FLAGS(X) ((X)&0x03) +#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) #ifdef SQLITE_OMIT_WAL # define sqlite3WalOpen(x,y,z) 0 diff --git a/test/wal2.test b/test/wal2.test index 0b15b15461..bc170ad3ff 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -1191,7 +1191,7 @@ if {$::tcl_platform(platform) == "unix"} { # foreach {tn sql reslist} { 1 { } {10 0 4 0 6 0} - 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} + 2 { PRAGMA checkpoint_fullfsync = 1 } {10 6 4 3 6 3} 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} } { ifcapable default_ckptfullfsync { @@ -1261,8 +1261,8 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} { 6 {0 1 full} {0 2} {0 1} {0 2} 7 {1 0 off} {0 0} {0 0} {0 0} - 8 {1 0 normal} {1 0} {0 0} {0 2} - 9 {1 0 full} {2 0} {1 0} {0 2} + 8 {1 0 normal} {0 1} {0 0} {0 2} + 9 {1 0 full} {1 1} {1 0} {0 2} 10 {1 1 off} {0 0} {0 0} {0 0} 11 {1 1 normal} {0 1} {0 0} {0 2} From 1c305122a22464711680d8099db22ba6850e85c1 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 25 Aug 2017 09:17:14 +0000 Subject: [PATCH 44/53] Avoid returning duplicate rows in experimental pragmas "pragma_list", "module_list" and "function_list". FossilOrigin-Name: b79cc8dc88c8ae03daff1290fd650b2b0e6f673ec9d83be6a533a57172930190 --- manifest | 15 +++++------ manifest.uuid | 2 +- src/pragma.c | 4 --- test/pragma5.test | 64 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 test/pragma5.test diff --git a/manifest b/manifest index e74b367e97..bfb51fad1c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincorrect\shyperlink\sin\sa\scomment. -D 2017-08-24T20:54:42.754 +C Avoid\sreturning\sduplicate\srows\sin\sexperimental\spragmas\s"pragma_list",\n"module_list"\sand\s"function_list". +D 2017-08-25T09:17:14.786 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -449,7 +449,7 @@ F src/parse.y 52ef3cecd0934e9da4a45b585883a03243ad615d338ad94f44501a05891dcdfa F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa -F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2 +F src/pragma.c a4e5028dfc8af4c5c347cd0e91bd2f0c0f81fcd9b2c6e0acf8da7da51df7f1fe F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/prepare.c 9e880c0efb5d7f9101bb34c0a87daf6e1e5284c34024fdb811e67bb02fdd299b F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c @@ -1098,6 +1098,7 @@ F test/pragma.test f274259d6393b6681eb433beb8dd39a26ec06a4431052a4880b43b84912a3 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed F test/pragma4.test 6e85b6eab8e61ffc9c7db59d842276674e8e3264 +F test/pragma5.test fd517f42ee847e126afbbbd9fd0fb9e5a4a61a962496a350adb8a22583fbdc37 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 9e6db85f81c63f2367c34a9d7db384088bd374ad @@ -1650,7 +1651,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 7ec72314d6b66e4969833194fd032f01963bb861a7bb30d060acdb82dc5d62fe -R 0a9008b1e381e229108d828896139715 -U drh -Z 0f9a691a1b4c4aa8a5eacf3d9e1dd571 +P 25292b9a4eb5efc7db551da0b3c9cfd7e79da1594ee14729de44090e188c2b2a +R 7b2e7d0666727914b868e680cae90457 +U dan +Z 2b958aabca575686d03fef3a95382582 diff --git a/manifest.uuid b/manifest.uuid index 404de58199..98964c88d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25292b9a4eb5efc7db551da0b3c9cfd7e79da1594ee14729de44090e188c2b2a \ No newline at end of file +b79cc8dc88c8ae03daff1290fd650b2b0e6f673ec9d83be6a533a57172930190 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index e640c7ebe5..2619f2944b 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1234,13 +1234,11 @@ void sqlite3Pragma( for(i=0; iu.pHash ){ sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } } for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ p = (FuncDef*)sqliteHashData(j); sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2); } } break; @@ -1252,7 +1250,6 @@ void sqlite3Pragma( for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){ Module *pMod = (Module*)sqliteHashData(j); sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); - sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } } break; @@ -1262,7 +1259,6 @@ void sqlite3Pragma( int i; for(i=0; i Date: Fri, 25 Aug 2017 13:02:48 +0000 Subject: [PATCH 45/53] Convert a branch made unreachable by [59560d07] into an assert(). FossilOrigin-Name: 2738b8db3caa6ce48d27cb5749d27b79241e6f6682b694886f6ef663e5443583 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 154d622e08..5d2eb2a992 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sinternal\smechanism\sused\sto\skeep\strack\sof\swhat\skind\sof\ssyncing\nto\sdo\sfor\sWAL\stransaction\scommits\sand\scheckpoint\soperations.\s\nUse\sthe\scheckpoint-style\sof\ssyncing\sto\ssync\sthe\sheader\sof\sa\snew\nor\srestarted\sWAL\sfile. -D 2017-08-25T11:44:51.174 +C Convert\sa\sbranch\smade\sunreachable\sby\s[59560d07]\sinto\san\sassert(). +D 2017-08-25T13:02:48.882 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -399,7 +399,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c f93c05dbd60551b322dbcaaf4961e87ea20eb67667ebc3181f15d2b5cb66bbaa +F src/btree.c 83933a8d1ec8ebdcd49c6b1c6541e8d32a55ab5f7155b0e90babe26825223abd F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 @@ -1651,8 +1651,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 b79cc8dc88c8ae03daff1290fd650b2b0e6f673ec9d83be6a533a57172930190 bf65dae8d4297c57ac63228ccf0100f9fabf2fb600438c9f2e10a29c4b118168 -R 537f505d2d307d3df7ac5ca0ae8a4ab7 -T +closed bf65dae8d4297c57ac63228ccf0100f9fabf2fb600438c9f2e10a29c4b118168 +P e8d23afe8478e42779ec1dd602ca2d77d4f3c26c4d54f52112c5aaa928536538 +R c47094d13357cf3081b589cea406d444 U drh -Z f4c9090d66a1befc7247247744f54bd9 +Z 0c1347313e1f31701f169aeedc1bd394 diff --git a/manifest.uuid b/manifest.uuid index f317d7cf98..27c4e54395 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8d23afe8478e42779ec1dd602ca2d77d4f3c26c4d54f52112c5aaa928536538 \ No newline at end of file +2738b8db3caa6ce48d27cb5749d27b79241e6f6682b694886f6ef663e5443583 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a4bcaf6c49..9b67ab2887 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1399,7 +1399,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ int sz = get2byte(&data[iFree+2]); int top = get2byte(&data[hdr+5]); if( iFree2 ){ - if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno); + assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */ sz2 = get2byte(&data[iFree2+2]); assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize ); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); From 83e8ca54d1f09db06ecc30687a16cbdcf7b29250 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Aug 2017 13:34:18 +0000 Subject: [PATCH 46/53] Small performance optimization in sqlite3WhereBegin(). FossilOrigin-Name: 39f708d1e286931365a8992dbe7f900108ff1dad146032a284ad1dec09b11e06 --- manifest | 12 +++++------ manifest.uuid | 2 +- src/where.c | 59 ++++++++++++++++++++++++++------------------------- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/manifest b/manifest index 5d2eb2a992..e7c1f7c289 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Convert\sa\sbranch\smade\sunreachable\sby\s[59560d07]\sinto\san\sassert(). -D 2017-08-25T13:02:48.882 +C Small\sperformance\soptimization\sin\ssqlite3WhereBegin(). +D 2017-08-25T13:34:18.937 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -538,7 +538,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 839db09792fead5052bb35e533fa485e134913d547d05b5f42e537b73e63f07a F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6 -F src/where.c ad558533d6fe6578857635218633aa241e2428835763c46801be9e68d6ec0701 +F src/where.c 0aaa1b085a018c1c2e2da367b48491ce2686aea351bd17772c46b7e04eb51e3d F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d F src/wherecode.c e7be3b7f4c11908500cdf02b299d190d3742659533f58e0f4047962fdb5a48da F src/whereexpr.c fe1fe600d7334e91f3d9d487021362d543fba8ab2f1be5e0d68063d619379c05 @@ -1651,7 +1651,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 e8d23afe8478e42779ec1dd602ca2d77d4f3c26c4d54f52112c5aaa928536538 -R c47094d13357cf3081b589cea406d444 +P 2738b8db3caa6ce48d27cb5749d27b79241e6f6682b694886f6ef663e5443583 +R be107142fb32b5eeca2b38bf38398332 U drh -Z 0c1347313e1f31701f169aeedc1bd394 +Z ca59cf9901a72073d38774a5b3f91248 diff --git a/manifest.uuid b/manifest.uuid index 27c4e54395..1cc2968043 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2738b8db3caa6ce48d27cb5749d27b79241e6f6682b694886f6ef663e5443583 \ No newline at end of file +39f708d1e286931365a8992dbe7f900108ff1dad146032a284ad1dec09b11e06 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 5402977c30..d414b936d5 100644 --- a/src/where.c +++ b/src/where.c @@ -4537,37 +4537,38 @@ WhereInfo *sqlite3WhereBegin( if( wctrlFlags & WHERE_WANT_DISTINCT ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } - } - - /* Assign a bit from the bitmask to every term in the FROM clause. - ** - ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in - ** pTabList, not just the first nTabList tables. nTabList is normally - ** equal to pTabList->nSrc but might be shortened to 1 if the - ** WHERE_OR_SUBCLAUSE flag is set. - */ - for(ii=0; iinSrc; ii++){ - createMask(pMaskSet, pTabList->a[ii].iCursor); - sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); - } -#ifdef SQLITE_DEBUG - { - Bitmask mx = 0; - for(ii=0; iinSrc; ii++){ - Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); - assert( m>=mx ); - mx = m; + }else{ + /* Assign a bit from the bitmask to every term in the FROM clause. + ** + ** The N-th term of the FROM clause is assigned a bitmask of 1<nSrc tables in + ** pTabList, not just the first nTabList tables. nTabList is normally + ** equal to pTabList->nSrc but might be shortened to 1 if the + ** WHERE_OR_SUBCLAUSE flag is set. + */ + ii = 0; + do{ + createMask(pMaskSet, pTabList->a[ii].iCursor); + sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); + }while( (++ii)nSrc ); + #ifdef SQLITE_DEBUG + { + Bitmask mx = 0; + for(ii=0; iinSrc; ii++){ + Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); + assert( m>=mx ); + mx = m; + } } + #endif } -#endif - + /* Analyze all of the subexpressions. */ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); if( db->mallocFailed ) goto whereBeginError; From 36494b8bc681cc27b145674da9bb380eeac7a371 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Aug 2017 15:43:34 +0000 Subject: [PATCH 47/53] Size and performance optimization for sqlite3Init(). FossilOrigin-Name: 776d91284a891bec64d6f649ff17de898b6ac6f66dd3d2afccc394a012a40c7d --- manifest | 12 +++++------ manifest.uuid | 2 +- src/prepare.c | 59 +++++++++++++++++++++++---------------------------- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index e7c1f7c289..c65dc5b85f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\soptimization\sin\ssqlite3WhereBegin(). -D 2017-08-25T13:34:18.937 +C Size\sand\sperformance\soptimization\sfor\ssqlite3Init(). +D 2017-08-25T15:43:34.075 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -451,7 +451,7 @@ F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa F src/pragma.c a4e5028dfc8af4c5c347cd0e91bd2f0c0f81fcd9b2c6e0acf8da7da51df7f1fe F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 -F src/prepare.c 9e880c0efb5d7f9101bb34c0a87daf6e1e5284c34024fdb811e67bb02fdd299b +F src/prepare.c 9a141a1b02dca53beaa9771699d390aafcac01f5d1f1c0ae6e23ded8dcdb709a F src/printf.c 40aee47ae9be4bd3dbdc8968bd07fddc027be8edec8daddf24d3391d36698a1c F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 @@ -1651,7 +1651,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 2738b8db3caa6ce48d27cb5749d27b79241e6f6682b694886f6ef663e5443583 -R be107142fb32b5eeca2b38bf38398332 +P 39f708d1e286931365a8992dbe7f900108ff1dad146032a284ad1dec09b11e06 +R fe3e8a19bfb43e621f9a86b9a7564beb U drh -Z ca59cf9901a72073d38774a5b3f91248 +Z 5ffd42d30ddfce1213880dd5c5ac3e27 diff --git a/manifest.uuid b/manifest.uuid index 1cc2968043..bd597aa8ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39f708d1e286931365a8992dbe7f900108ff1dad146032a284ad1dec09b11e06 \ No newline at end of file +776d91284a891bec64d6f649ff17de898b6ac6f66dd3d2afccc394a012a40c7d \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 9f0704c947..8ff27fec6c 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -150,6 +150,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ assert( sqlite3_mutex_held(db->mutex) ); assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + db->init.busy = 1; + /* Construct the in-memory representation schema tables (sqlite_master or ** sqlite_temp_master) by invoking the parser directly. The appropriate ** table name will be inserted automatically by the parser so we can just @@ -158,7 +160,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ azArg[0] = zMasterName = SCHEMA_TABLE(iDb); azArg[1] = "1"; azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text," - "rootpage integer,sql text)"; + "rootpage int,sql text)"; azArg[3] = 0; initData.db = db; initData.iDb = iDb; @@ -174,10 +176,10 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ - DbSetProperty(db, 1, DB_SchemaLoaded); - } - return SQLITE_OK; + assert( iDb==1 ); + DbSetProperty(db, 1, DB_SchemaLoaded); + rc = SQLITE_OK; + goto error_out; } /* If there is not already a read-only (or read-write) transaction opened @@ -336,9 +338,13 @@ initone_error_out: sqlite3BtreeLeave(pDb->pBt); error_out: - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - sqlite3OomFault(db); + if( rc ){ + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomFault(db); + } + sqlite3ResetOneSchema(db, iDb); } + db->init.busy = 0; return rc; } @@ -359,37 +365,24 @@ int sqlite3Init(sqlite3 *db, char **pzErrMsg){ assert( sqlite3_mutex_held(db->mutex) ); assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); assert( db->init.busy==0 ); - rc = SQLITE_OK; - db->init.busy = 1; ENC(db) = SCHEMA_ENC(db); - for(i=0; rc==SQLITE_OK && inDb; i++){ - if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue; - rc = sqlite3InitOne(db, i, pzErrMsg); - if( rc ){ - sqlite3ResetOneSchema(db, i); + assert( db->nDb>0 ); + /* Do the main schema first */ + if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, 0, pzErrMsg); + if( rc ) return rc; + } + /* All other schemas after the main schema. The "temp" schema must be last */ + for(i=db->nDb-1; i>0; i--){ + if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ + rc = sqlite3InitOne(db, i, pzErrMsg); + if( rc ) return rc; } } - - /* Once all the other databases have been initialized, load the schema - ** for the TEMP database. This is loaded last, as the TEMP database - ** schema may contain references to objects in other databases. - */ -#ifndef SQLITE_OMIT_TEMPDB - assert( db->nDb>1 ); - if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ - rc = sqlite3InitOne(db, 1, pzErrMsg); - if( rc ){ - sqlite3ResetOneSchema(db, 1); - } - } -#endif - - db->init.busy = 0; - if( rc==SQLITE_OK && commit_internal ){ + if( commit_internal ){ sqlite3CommitInternalChanges(db); } - - return rc; + return SQLITE_OK; } /* From f49759bf030088bbe2cf35c5c642b6f265bb56f4 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Aug 2017 19:51:51 +0000 Subject: [PATCH 48/53] Fix a few over-length source code lines. No functional changes. FossilOrigin-Name: 1783c54ce9dcb4b2c4f2a66f6d3315e646b71b54a8899fc32a7bf0f935a21f7f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 3 ++- src/vdbetrace.c | 2 +- src/wherecode.c | 6 +++--- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index c65dc5b85f..3fce59b2ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Size\sand\sperformance\soptimization\sfor\ssqlite3Init(). -D 2017-08-25T15:43:34.075 +C Fix\sa\sfew\sover-length\ssource\scode\slines.\s\sNo\sfunctional\schanges. +D 2017-08-25T19:51:51.034 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -412,7 +412,7 @@ F src/delete.c 21a5f1812fdb599e9f7afb9f650bdabab60a3afd51d7e94e539c982f647b0023 F src/expr.c 4ca86dc65f5ea478c665a5b4fe79d05f00432c9bd82237a896b45bd376bf1217 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333 -F src/func.c ed8888ae80b39f5a5d403954e4a05e0a38303523dff8143161439c142d31dec1 +F src/func.c b4d259af627e3cd9510cf08db37f0bcc88b1887c735169c74490c3739d5cf5c6 F src/global.c 8a6ab6b4d91effb96ffa81b39f0d70c862abca157f8aaa194600a4a8b7923344 F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 @@ -532,7 +532,7 @@ F src/vdbeaux.c 2dff8186d34e0e525838f77b2fac70bd480f0273a77015bf21b6a08f2792da82 F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b F src/vdbemem.c 2f9d672af5260f0145787e1dc2c6985414987cc0dc575133a0dc17dda767d868 F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e3 -F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 +F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c F src/vtab.c f1d5c23132fb0247af3e86146404112283ddedb6c518de0d4edc91cfb36970ef F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 839db09792fead5052bb35e533fa485e134913d547d05b5f42e537b73e63f07a @@ -540,7 +540,7 @@ F src/wal.h 8de5d2d3de0956d6f6cb48c83a4012d5f227b8fe940f3a349a4b7e85ebcb492a F src/walker.c 3ccfa8637f95355bff61144e01a615b8ef26f79c312880848da73f03367da1e6 F src/where.c 0aaa1b085a018c1c2e2da367b48491ce2686aea351bd17772c46b7e04eb51e3d F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d -F src/wherecode.c e7be3b7f4c11908500cdf02b299d190d3742659533f58e0f4047962fdb5a48da +F src/wherecode.c d246d19f5453d3f154ed8fcea892ce6d70ae4a5ddaebae34bd49d73f4c913bc7 F src/whereexpr.c fe1fe600d7334e91f3d9d487021362d543fba8ab2f1be5e0d68063d619379c05 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1651,7 +1651,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 39f708d1e286931365a8992dbe7f900108ff1dad146032a284ad1dec09b11e06 -R fe3e8a19bfb43e621f9a86b9a7564beb +P 776d91284a891bec64d6f649ff17de898b6ac6f66dd3d2afccc394a012a40c7d +R 41344988e24701db849a6d76419462a5 U drh -Z 5ffd42d30ddfce1213880dd5c5ac3e27 +Z b62f697e1468d19c3e527d2e161c50d8 diff --git a/manifest.uuid b/manifest.uuid index bd597aa8ea..97e89e6b6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -776d91284a891bec64d6f649ff17de898b6ac6f66dd3d2afccc394a012a40c7d \ No newline at end of file +1783c54ce9dcb4b2c4f2a66f6d3315e646b71b54a8899fc32a7bf0f935a21f7f \ No newline at end of file diff --git a/src/func.c b/src/func.c index 2bb9a91de6..b46578a407 100644 --- a/src/func.c +++ b/src/func.c @@ -865,7 +865,8 @@ static void likeFunc( #ifdef SQLITE_TEST sqlite3_like_count++; #endif - sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); + sqlite3_result_int(context, + patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); } } diff --git a/src/vdbetrace.c b/src/vdbetrace.c index 7b47363991..c993d9a3dd 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -82,7 +82,7 @@ char *sqlite3VdbeExpandSql( Mem *pVar; /* Value of a host parameter */ StrAccum out; /* Accumulate the output here */ #ifndef SQLITE_OMIT_UTF16 - Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */ + Mem utf8; /* Used to convert UTF16 into UTF8 for display */ #endif char zBase[100]; /* Initial working space */ diff --git a/src/wherecode.c b/src/wherecode.c index 528aeec2b0..30ff3f25c4 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1070,9 +1070,9 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ } /* -** For an indexes on expression X, locate every instance of expression X in pExpr -** and change that subexpression into a reference to the appropriate column of -** the index. +** For an indexes on expression X, locate every instance of expression X +** in pExpr and change that subexpression into a reference to the appropriate +** column of the index. */ static void whereIndexExprTrans( Index *pIdx, /* The Index */ From 20554381d9d68a40500ddea1e745573ecebee5ee Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 Aug 2017 11:12:57 +0000 Subject: [PATCH 49/53] Fix the ".dump", ".schema", and ".fullschema" commands of the command-line shell so that they work even if PRAGMA empty_result_callbacks is enabled. Fix for ticket [02f0f4c54f281]. FossilOrigin-Name: cf0d3715caac9149e65bb4802fd179d0952cfaf9add17ac243c6ca87cbd6e6b7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3fce59b2ae..a31b3715e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sfew\sover-length\ssource\scode\slines.\s\sNo\sfunctional\schanges. -D 2017-08-25T19:51:51.034 +C Fix\sthe\s".dump",\s".schema",\sand\s".fullschema"\scommands\sof\sthe\scommand-line\nshell\sso\sthat\sthey\swork\seven\sif\sPRAGMA\sempty_result_callbacks\sis\senabled.\nFix\sfor\sticket\s[02f0f4c54f281]. +D 2017-08-28T11:12:57.851 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -457,7 +457,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 -F src/shell.c 8f2a8b9e4ffe4f4596b1690dd628cd355d5605257e14ddba83daf5422e0e39af +F src/shell.c 117305aab365a0448505d8cfcc27d58b0182ea314f0201bd26c340a5717419a4 F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 F src/sqlite.h.in a8e60396a73996a12a153299943f45fe59202c89bb1a46bab203a5e1b99b2493 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1651,7 +1651,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 776d91284a891bec64d6f649ff17de898b6ac6f66dd3d2afccc394a012a40c7d -R 41344988e24701db849a6d76419462a5 +P 1783c54ce9dcb4b2c4f2a66f6d3315e646b71b54a8899fc32a7bf0f935a21f7f +R 5eea66808a45f5f0657c113630b948a8 U drh -Z b62f697e1468d19c3e527d2e161c50d8 +Z d811ef40d0e65caf3cded0793706c012 diff --git a/manifest.uuid b/manifest.uuid index 97e89e6b6d..78c2eaf7f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1783c54ce9dcb4b2c4f2a66f6d3315e646b71b54a8899fc32a7bf0f935a21f7f \ No newline at end of file +cf0d3715caac9149e65bb4802fd179d0952cfaf9add17ac243c6ca87cbd6e6b7 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index bd7853f65d..b78da38701 100644 --- a/src/shell.c +++ b/src/shell.c @@ -2659,6 +2659,7 @@ static int shell_callback( int i; ShellState *p = (ShellState*)pArg; + if( azArg==0 ) return 0; switch( p->cMode ){ case MODE_Line: { int w = 5; @@ -3009,6 +3010,7 @@ static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ ShellText *p = (ShellText*)pArg; int i; UNUSED_PARAMETER(az); + if( azArg==0 ) return 0; if( p->n ) appendText(p, "|", 0); for(i=0; i Date: Mon, 28 Aug 2017 14:33:27 +0000 Subject: [PATCH 50/53] Backport changes to shell.c into shell.c.in. FossilOrigin-Name: 2348045fbc3fc99e2b46095cc86db99815cd1f9254d30a3b72c2b15c02076a84 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 6 ++++-- tool/mkshellc.tcl | 3 ++- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index a31b3715e7..c9965634fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".dump",\s".schema",\sand\s".fullschema"\scommands\sof\sthe\scommand-line\nshell\sso\sthat\sthey\swork\seven\sif\sPRAGMA\sempty_result_callbacks\sis\senabled.\nFix\sfor\sticket\s[02f0f4c54f281]. -D 2017-08-28T11:12:57.851 +C Backport\schanges\sto\sshell.c\sinto\sshell.c.in. +D 2017-08-28T14:33:27.858 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -458,7 +458,7 @@ F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 F src/shell.c 117305aab365a0448505d8cfcc27d58b0182ea314f0201bd26c340a5717419a4 -F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175 +F src/shell.c.in 31cd78c3f7a1ac5375bd47afd0585b04266e82fe33a3514d788d32d913d6ce5b F src/sqlite.h.in a8e60396a73996a12a153299943f45fe59202c89bb1a46bab203a5e1b99b2493 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 @@ -1588,7 +1588,7 @@ F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 4ee2a30ccbd900dc4d5cdb61bdab87cd2166cd2affcc78c9cc0b8d22a65b2eee F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl 2144bc8550a6471a029db262a132d2df4b9e0db61b90398bf64f5b7b3f8d92cd -F tool/mkshellc.tcl 69c38ecd7b74b2b0799a35ce20e1e3998e504d8c99c100ca4b98ae9d8f6279bc +F tool/mkshellc.tcl 8743a62e12ab67741f63f3e8ea00c482f8fa50ae3d3bca16b38754641777bf13 F tool/mksourceid.c 30966d568654a4fd962fb324753e49429b7379e1f72d2be489ade963121f5943 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb @@ -1651,7 +1651,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 1783c54ce9dcb4b2c4f2a66f6d3315e646b71b54a8899fc32a7bf0f935a21f7f -R 5eea66808a45f5f0657c113630b948a8 +P cf0d3715caac9149e65bb4802fd179d0952cfaf9add17ac243c6ca87cbd6e6b7 +R a662f367e40c894310c1263328998be4 U drh -Z d811ef40d0e65caf3cded0793706c012 +Z f8feda6acc9937dc005c3c1a1cb14725 diff --git a/manifest.uuid b/manifest.uuid index 78c2eaf7f4..4261b01f79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf0d3715caac9149e65bb4802fd179d0952cfaf9add17ac243c6ca87cbd6e6b7 \ No newline at end of file +2348045fbc3fc99e2b46095cc86db99815cd1f9254d30a3b72c2b15c02076a84 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 4dac4a62d5..8686159932 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1299,6 +1299,7 @@ static int shell_callback( int i; ShellState *p = (ShellState*)pArg; + if( azArg==0 ) return 0; switch( p->cMode ){ case MODE_Line: { int w = 5; @@ -1649,6 +1650,7 @@ static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ ShellText *p = (ShellText*)pArg; int i; UNUSED_PARAMETER(az); + if( azArg==0 ) return 0; if( p->n ) appendText(p, "|", 0); for(i=0; i Date: Mon, 28 Aug 2017 15:51:35 +0000 Subject: [PATCH 51/53] Remove the rarely-used scratch memory allocator. This makes the code smaller, faster, and easier to maintain. In place of the scratch allocator, add the SQLITE_CONFIG_SMALL_MALLOC configuration option that provides a hint to SQLite that large memory allocations should be avoided. FossilOrigin-Name: 54b000246cfb5c7b8adb61a17357ef5a49adddde9e48e8937834d5ba0beb8a6b --- manifest | 44 ++++++------- manifest.uuid | 2 +- src/btree.c | 4 +- src/global.c | 4 +- src/main.c | 26 +------- src/malloc.c | 141 +---------------------------------------- src/shell.c.in | 38 ++--------- src/sqlite.h.in | 72 +++++++-------------- src/sqliteInt.h | 9 +-- src/status.c | 1 - src/test_malloc.c | 41 ------------ src/vdbesort.c | 8 +-- test/kvtest.c | 14 ---- test/lookaside.test | 1 - test/memsubsys1.test | 139 +--------------------------------------- test/permutations.test | 12 ++-- test/speedtest1.c | 20 ------ test/tester.tcl | 8 --- test/wordcount.c | 4 -- 19 files changed, 71 insertions(+), 517 deletions(-) diff --git a/manifest b/manifest index c9965634fa..2131ba9ff1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Backport\schanges\sto\sshell.c\sinto\sshell.c.in. -D 2017-08-28T14:33:27.858 +C Remove\sthe\srarely-used\sscratch\smemory\sallocator.\s\sThis\smakes\sthe\scode\ssmaller,\nfaster,\sand\seasier\sto\smaintain.\s\sIn\splace\sof\sthe\sscratch\sallocator,\sadd\sthe\nSQLITE_CONFIG_SMALL_MALLOC\sconfiguration\soption\sthat\sprovides\sa\shint\sto\sSQLite\nthat\slarge\smemory\sallocations\sshould\sbe\savoided. +D 2017-08-28T15:51:35.625 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -399,7 +399,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 83933a8d1ec8ebdcd49c6b1c6541e8d32a55ab5f7155b0e90babe26825223abd +F src/btree.c 1033b88fe50aba7d364b5a19666a9a274caa8d4c25ab7f3914221997b46af44a F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09 F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc F src/build.c b47a0320c6d237718b8f493ac97d37d1071bce12aca668b15219187150c41295 @@ -413,7 +413,7 @@ F src/expr.c 4ca86dc65f5ea478c665a5b4fe79d05f00432c9bd82237a896b45bd376bf1217 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333 F src/func.c b4d259af627e3cd9510cf08db37f0bcc88b1887c735169c74490c3739d5cf5c6 -F src/global.c 8a6ab6b4d91effb96ffa81b39f0d70c862abca157f8aaa194600a4a8b7923344 +F src/global.c ac3094f1dc59fbeb919aef7cc0cc827a8459d1fb1adb7972ef75bd9e0c10b75b F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da @@ -421,8 +421,8 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c d2d1bf12d2b5382450620d7cede84c7ffe57e6a89fa9a908f1aba68df2731cd9 F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2 -F src/main.c 42f6a2660c7a1d643cc7e863d2dcd630c6aa1e8343f5478b0592120ab84c97ba -F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978 +F src/main.c 227a83d3f840d55e40360a1a8370c120f1466ea7d73b1fffb74b8f59ad0f4046 +F src/malloc.c e069cec00407e029d71fbc9440ebbb5833a629416324b592ade8fed93b045c83 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -458,13 +458,13 @@ F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c c9b3d8444bbf6f167d84f41ca6f3672e2521cb163a8c706b19058dc82fffe9b8 F src/shell.c 117305aab365a0448505d8cfcc27d58b0182ea314f0201bd26c340a5717419a4 -F src/shell.c.in 31cd78c3f7a1ac5375bd47afd0585b04266e82fe33a3514d788d32d913d6ce5b -F src/sqlite.h.in a8e60396a73996a12a153299943f45fe59202c89bb1a46bab203a5e1b99b2493 +F src/shell.c.in af3fb9eabdc0a95beace2f760597d213be0988c974eca116208eb220cd24469c +F src/sqlite.h.in f18eef5b101d5f33f98ca43decb1f025c1b629f091ad77fe2190128e93938a5a F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a1fd3aa82f967da436164e0728a7d6841651fd0c6e27b9044e0eb9f6c8462e47 -F src/sqliteInt.h bc0792db4ff887e4884d386188527e1cd7c16d496c8f3ba23333e68cee3e4f78 +F src/sqliteInt.h 9a283ecf57bb81e0040d243d56e91beae76f6d5762b3ac33c7f3ec6076a71d99 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b -F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 +F src/status.c 90450a491f3f59f6978ca9832023c31238f592064e405eeda971f3c0829564eb F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 487951d81f9704800fd9f0ffdaa2f935a83ccb6be3575c2c4ef83e4789b4c828 F src/test1.c 8513b17ca4a7a9ba28748535d178b6e472ec7394ae0eea53907f2d3bcdbab2df @@ -494,7 +494,7 @@ F src/test_intarray.c 988fc61cb0ff539f4172c0d95f15287c92516f64 F src/test_intarray.h f3b7672f5d1056eac563c0d6ea8480a660b1475c F src/test_journal.c 619f2aa10e0d7a5f87c0f06825bc61dfce1c6b9c7f3ad990fb13de6c3b8874a3 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c c05f6c40bd6c8bfe5f1718212f81fd5687f91766 +F src/test_malloc.c 4f06a805de86be5216a127b3777ca2d5a1ff99d1a9238374ce136a47411be36c F src/test_multiplex.c e054459f7633f3ff8ce1245da724f9a8be189e4e F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 F src/test_mutex.c 7f4337ba23ee6b1d2ec81c189653608cb069926a @@ -531,7 +531,7 @@ F src/vdbeapi.c 9c670ca0dcc1cd86373aa353b747b26fe531ca5cd4331690c611d1f03842e2a1 F src/vdbeaux.c 2dff8186d34e0e525838f77b2fac70bd480f0273a77015bf21b6a08f2792da82 F src/vdbeblob.c db3cf91060f6f4b2f1358a4200e844697990752177784c7c95da00b7ac9f1c7b F src/vdbemem.c 2f9d672af5260f0145787e1dc2c6985414987cc0dc575133a0dc17dda767d868 -F src/vdbesort.c fea2bea25f5e9ccd91e0760d7359f0365f9fba1aaeac7216c71cad78765f58e3 +F src/vdbesort.c 731a09e5cb9e96b70c394c1b7cf3860fbe84acca7682e178615eb941a3a0ef2f F src/vdbetrace.c 48e11ebe040c6b41d146abed2602e3d00d621d7ebe4eb29b0a0f1617fd3c2f6c F src/vtab.c f1d5c23132fb0247af3e86146404112283ddedb6c518de0d4edc91cfb36970ef F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -981,7 +981,7 @@ F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb2848 F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c d2b8cfc91047ebf6cac4f3a04f19c3a864e4ecfd683bbb65c395df450b8dc79c +F test/kvtest.c fcb38ffe3db028a3138b4818fc098359c80dc51a0d1278a91c99c554cc1abb92 F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/like.test 67d7431c9b664254febce9e90fd2f47c7c75c8b38444e2a50ef9ec2776b84ca8 @@ -999,7 +999,7 @@ F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38 F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431 F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035 -F test/lookaside.test 90052e87282de256d613fcf8c9cbb845e4001d2f +F test/lookaside.test b17c99ae3aef96a8c9fa6f6be33cc75b93d657cb791d3827302b6835b71941f7 F test/main.test bb75e406c9b64931f3dc7e7f04626633365bb22f F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8 @@ -1029,7 +1029,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 6d268d0ae90f8d61a2356a1838665654d83de518 +F test/memsubsys1.test 9e7555a22173b8f1c96c281ce289b338fcba2abe8b157f8798ca195bbf1d347e F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41 F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc @@ -1093,7 +1093,7 @@ F test/parser1.test 391b9bf9a229547a129c61ac345ed1a6f5eb1854 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 3b94f8fd431d39fac4952eb5dc38e1bb2b4518e1ac967d66f5abc815c104aeb6 +F test/permutations.test d911c9ba49088d22054a05dc73743f677872a92ac89288bcdeafa0ebf3f9c531 F test/pragma.test f274259d6393b6681eb433beb8dd39a26ec06a4431052a4880b43b84912a3f58 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 14c12bc5352b1e100e0b6b44f371053a81ccf8ed @@ -1219,7 +1219,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 7b1ab42b097b484c18d99e1d1c71a6a0c9c87a7a +F test/speedtest1.c 7a6ec22e87f78ef98d523667593f5d818f6be4a1bcf5fe70d933aece058f32df F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1257,7 +1257,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl eb7ec55fe074a909423c1de701f7c545417b8aa96787b8c3e7a79203f2cebec8 +F test/tester.tcl 9948bd856ce8a1c127f2f7900365387a42a917ce0dc87185bdd128fa5b11aff2 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1553,7 +1553,7 @@ F test/without_rowid3.test 2724c787a51a5dce09d078453a758117b4b728f1 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/without_rowid5.test 89b1c587bd92a0590e440da33e7666bf4891572a F test/without_rowid6.test 1f99644e6508447fb050f73697350c7ceca3392e -F test/wordcount.c 06efb84b7c48a4973c2c24ea06c93d00bce24389 +F test/wordcount.c cb589cec469a1d90add05b1f8cee75c7210338d87a5afd65260ed5c0f4bbf8ac F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e @@ -1651,7 +1651,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 cf0d3715caac9149e65bb4802fd179d0952cfaf9add17ac243c6ca87cbd6e6b7 -R a662f367e40c894310c1263328998be4 +P 2348045fbc3fc99e2b46095cc86db99815cd1f9254d30a3b72c2b15c02076a84 +R dbf94ead9bb02368db4853c4bef6223c U drh -Z f8feda6acc9937dc005c3c1a1cb14725 +Z 970c3285dea1ce91571a8f403e94ff33 diff --git a/manifest.uuid b/manifest.uuid index 4261b01f79..f6193d5c82 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2348045fbc3fc99e2b46095cc86db99815cd1f9254d30a3b72c2b15c02076a84 \ No newline at end of file +54b000246cfb5c7b8adb61a17357ef5a49adddde9e48e8937834d5ba0beb8a6b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9b67ab2887..9ec61507cb 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7288,7 +7288,7 @@ static int balance_nonroot( /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer ** that is more than 6 times the database page size. */ assert( szScratch<=6*(int)pBt->pageSize ); - b.apCell = sqlite3ScratchMalloc( szScratch ); + b.apCell = sqlite3StackAllocRaw(0, szScratch ); if( b.apCell==0 ){ rc = SQLITE_NOMEM_BKPT; goto balance_cleanup; @@ -7866,7 +7866,7 @@ static int balance_nonroot( ** Cleanup before returning. */ balance_cleanup: - sqlite3ScratchFree(b.apCell); + sqlite3StackFree(0, b.apCell); for(i=0; i0 then allocate a scratch buffer into pNew. - */ - case SQLITE_TESTCTRL_SCRATCHMALLOC: { - void *pFree, **ppNew; - int sz; - sz = va_arg(ap, int); - ppNew = va_arg(ap, void**); - pFree = va_arg(ap, void*); - if( sz ) *ppNew = sqlite3ScratchMalloc(sz); - sqlite3ScratchFree(pFree); - break; - } - /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); ** ** If parameter onoff is non-zero, configure the wrappers so that all diff --git a/src/malloc.c b/src/malloc.c index 5eb65bf623..78a50b49c5 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -32,14 +32,6 @@ int sqlite3_release_memory(int n){ #endif } -/* -** An instance of the following object records the location of -** each unused scratch buffer. -*/ -typedef struct ScratchFreeslot { - struct ScratchFreeslot *pNext; /* Next unused scratch buffer */ -} ScratchFreeslot; - /* ** State information local to the memory allocation subsystem. */ @@ -47,22 +39,12 @@ static SQLITE_WSD struct Mem0Global { sqlite3_mutex *mutex; /* Mutex to serialize access */ sqlite3_int64 alarmThreshold; /* The soft heap limit */ - /* - ** Pointers to the end of sqlite3GlobalConfig.pScratch memory - ** (so that a range test can be used to determine if an allocation - ** being freed came from pScratch) and a pointer to the list of - ** unused scratch allocations. - */ - void *pScratchEnd; - ScratchFreeslot *pScratchFree; - u32 nScratchFree; - /* ** True if heap is nearly "full" where "full" is defined by the ** sqlite3_soft_heap_limit() setting. */ int nearlyFull; -} mem0 = { 0, 0, 0, 0, 0, 0 }; +} mem0 = { 0, 0, 0 }; #define mem0 GLOBAL(struct Mem0Global, mem0) @@ -132,28 +114,6 @@ int sqlite3MallocInit(void){ } memset(&mem0, 0, sizeof(mem0)); mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); - if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100 - && sqlite3GlobalConfig.nScratch>0 ){ - int i, n, sz; - ScratchFreeslot *pSlot; - sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch); - sqlite3GlobalConfig.szScratch = sz; - pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch; - n = sqlite3GlobalConfig.nScratch; - mem0.pScratchFree = pSlot; - mem0.nScratchFree = n; - for(i=0; ipNext = (ScratchFreeslot*)(sz+(char*)pSlot); - pSlot = pSlot->pNext; - } - pSlot->pNext = 0; - mem0.pScratchEnd = (void*)&pSlot[1]; - }else{ - mem0.pScratchEnd = 0; - sqlite3GlobalConfig.pScratch = 0; - sqlite3GlobalConfig.szScratch = 0; - sqlite3GlobalConfig.nScratch = 0; - } if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 || sqlite3GlobalConfig.nPage<=0 ){ sqlite3GlobalConfig.pPage = 0; @@ -304,105 +264,6 @@ void *sqlite3_malloc64(sqlite3_uint64 n){ return sqlite3Malloc(n); } -/* -** Each thread may only have a single outstanding allocation from -** xScratchMalloc(). We verify this constraint in the single-threaded -** case by setting scratchAllocOut to 1 when an allocation -** is outstanding clearing it when the allocation is freed. -*/ -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) -static int scratchAllocOut = 0; -#endif - - -/* -** Allocate memory that is to be used and released right away. -** This routine is similar to alloca() in that it is not intended -** for situations where the memory might be held long-term. This -** routine is intended to get memory to old large transient data -** structures that would not normally fit on the stack of an -** embedded processor. -*/ -void *sqlite3ScratchMalloc(int n){ - void *p; - assert( n>0 ); - - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n); - if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){ - p = mem0.pScratchFree; - mem0.pScratchFree = mem0.pScratchFree->pNext; - mem0.nScratchFree--; - sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1); - sqlite3_mutex_leave(mem0.mutex); - }else{ - sqlite3_mutex_leave(mem0.mutex); - p = sqlite3Malloc(n); - if( sqlite3GlobalConfig.bMemstat && p ){ - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p)); - sqlite3_mutex_leave(mem0.mutex); - } - sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH); - } - assert( sqlite3_mutex_notheld(mem0.mutex) ); - - -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch - ** buffers per thread. - ** - ** This can only be checked in single-threaded mode. - */ - assert( scratchAllocOut==0 ); - if( p ) scratchAllocOut++; -#endif - - return p; -} -void sqlite3ScratchFree(void *p){ - if( p ){ - -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) - /* Verify that no more than two scratch allocation per thread - ** is outstanding at one time. (This is only checked in the - ** single-threaded case since checking in the multi-threaded case - ** would be much more complicated.) */ - assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); - scratchAllocOut--; -#endif - - if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){ - /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */ - ScratchFreeslot *pSlot; - pSlot = (ScratchFreeslot*)p; - sqlite3_mutex_enter(mem0.mutex); - pSlot->pNext = mem0.pScratchFree; - mem0.pScratchFree = pSlot; - mem0.nScratchFree++; - assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch ); - sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1); - sqlite3_mutex_leave(mem0.mutex); - }else{ - /* Release memory back to the heap */ - assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); - assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) ); - sqlite3MemdebugSetType(p, MEMTYPE_HEAP); - if( sqlite3GlobalConfig.bMemstat ){ - int iSize = sqlite3MallocSize(p); - sqlite3_mutex_enter(mem0.mutex); - sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize); - sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize); - sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); - sqlite3GlobalConfig.m.xFree(p); - sqlite3_mutex_leave(mem0.mutex); - }else{ - sqlite3GlobalConfig.m.xFree(p); - } - } - } -} - /* ** TRUE if p is a lookaside memory allocation from db */ diff --git a/src/shell.c.in b/src/shell.c.in index 8686159932..bf5e335857 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -871,14 +871,13 @@ struct ShellState { /* ** These are the allowed shellFlgs values */ -#define SHFLG_Scratch 0x00000001 /* The --scratch option is used */ -#define SHFLG_Pagecache 0x00000002 /* The --pagecache option is used */ -#define SHFLG_Lookaside 0x00000004 /* Lookaside memory is used */ -#define SHFLG_Backslash 0x00000008 /* The --backslash option is used */ -#define SHFLG_PreserveRowid 0x00000010 /* .dump preserves rowid values */ -#define SHFLG_Newlines 0x00000020 /* .dump --newline flag */ -#define SHFLG_CountChanges 0x00000040 /* .changes setting */ -#define SHFLG_Echo 0x00000080 /* .echo or --echo setting */ +#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */ +#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */ +#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */ +#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */ +#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ +#define SHFLG_CountChanges 0x00000020 /* .changes setting */ +#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ /* ** Macros for testing and setting shellFlgs @@ -1897,18 +1896,10 @@ static int display_stats( } displayStatLine(pArg, "Number of Pcache Overflow Bytes:", "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); - if( pArg->shellFlgs & SHFLG_Scratch ){ - displayStatLine(pArg, "Number of Scratch Allocations Used:", - "%lld (max %lld)", SQLITE_STATUS_SCRATCH_USED, bReset); - } - displayStatLine(pArg, "Number of Scratch Overflow Bytes:", - "%lld (max %lld) bytes", SQLITE_STATUS_SCRATCH_OVERFLOW, bReset); displayStatLine(pArg, "Largest Allocation:", "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); displayStatLine(pArg, "Largest Pcache Allocation:", "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); - displayStatLine(pArg, "Largest Scratch Allocation:", - "%lld bytes", SQLITE_STATUS_SCRATCH_SIZE, bReset); #ifdef YYTRACKMAXSTACKDEPTH displayStatLine(pArg, "Deepest Parser Stack:", "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); @@ -5929,7 +5920,6 @@ static int do_meta_command(char *zLine, ShellState *p){ { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, - { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, { "imposter", SQLITE_TESTCTRL_IMPOSTER }, @@ -6042,7 +6032,6 @@ static int do_meta_command(char *zLine, ShellState *p){ case SQLITE_TESTCTRL_BITVEC_TEST: case SQLITE_TESTCTRL_FAULT_INSTALL: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: - case SQLITE_TESTCTRL_SCRATCHMALLOC: default: utf8_printf(stderr, "Error: CLI support for testctrl %s not implemented\n", @@ -6562,7 +6551,6 @@ static const char zOptions[] = " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" " -quote set output mode to 'quote'\n" - " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n" " -separator SEP set output column separator. Default: '|'\n" " -stats print memory stats before each finalize\n" " -version show SQLite version\n" @@ -6760,16 +6748,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ #else (void)cmdline_option_value(argc, argv, ++i); #endif - }else if( strcmp(z,"-scratch")==0 ){ - int n, sz; - sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( sz>400000 ) sz = 400000; - if( sz<2500 ) sz = 2500; - n = (int)integerValue(cmdline_option_value(argc,argv,++i)); - if( n>10 ) n = 10; - if( n<1 ) n = 1; - sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n); - data.shellFlgs |= SHFLG_Scratch; }else if( strcmp(z,"-pagecache")==0 ){ int n, sz; sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); @@ -6913,8 +6891,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdin_is_interactive = 0; }else if( strcmp(z,"-heap")==0 ){ i++; - }else if( strcmp(z,"-scratch")==0 ){ - i+=2; }else if( strcmp(z,"-pagecache")==0 ){ i+=2; }else if( strcmp(z,"-lookaside")==0 ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d794e73eac..fd30eab9a3 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1664,6 +1664,16 @@ struct sqlite3_mem_methods { ** routines with a wrapper that simulations memory allocation failure or ** tracks memory usage, for example. ** +** [[SQLITE_CONFIG_SMALL_MALLOC]]
SQLITE_CONFIG_SMALL_MALLOC
+**
^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of +** type int, interpreted as a boolean, which if true provides a hint to +** SQLite that it should avoid large memory allocations if possible. +** SQLite will run faster if it is free to make large memory allocations, +** but some application might prefer to run slower in exchange for +** guarantees about memory fragmentation that are possible if large +** allocations are avoided. This hint is normally off. +**
+** ** [[SQLITE_CONFIG_MEMSTATUS]]
SQLITE_CONFIG_MEMSTATUS
**
^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, ** interpreted as a boolean, which enables or disables the collection of @@ -1681,25 +1691,7 @@ struct sqlite3_mem_methods { **
** ** [[SQLITE_CONFIG_SCRATCH]]
SQLITE_CONFIG_SCRATCH
-**
^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer -** that SQLite can use for scratch memory. ^(There are three arguments -** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte -** aligned memory buffer from which the scratch allocations will be -** drawn, the size of each scratch allocation (sz), -** and the maximum number of scratch allocations (N).)^ -** The first argument must be a pointer to an 8-byte aligned buffer -** of at least sz*N bytes of memory. -** ^SQLite will not use more than one scratch buffers per thread. -** ^SQLite will never request a scratch buffer that is more than 6 -** times the database page size. -** ^If SQLite needs needs additional -** scratch memory beyond what is provided by this configuration option, then -** [sqlite3_malloc()] will be used to obtain the memory needed.

-** ^When the application provides any amount of scratch memory using -** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large -** [sqlite3_malloc|heap allocations]. -** This can help [Robson proof|prevent memory allocation failures] due to heap -** fragmentation in low-memory embedded systems. +**

The SQLITE_CONFIG_SCRATCH option is no longer used. **
** ** [[SQLITE_CONFIG_PAGECACHE]]
SQLITE_CONFIG_PAGECACHE
@@ -1735,8 +1727,7 @@ struct sqlite3_mem_methods { ** [[SQLITE_CONFIG_HEAP]]
SQLITE_CONFIG_HEAP
**
^The SQLITE_CONFIG_HEAP option specifies a static memory buffer ** that SQLite will use for all of its dynamic memory allocation needs -** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and -** [SQLITE_CONFIG_PAGECACHE]. +** beyond those provided for by [SQLITE_CONFIG_PAGECACHE]. ** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled ** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns ** [SQLITE_ERROR] if invoked otherwise. @@ -1929,7 +1920,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ #define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ -#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */ +#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ @@ -1950,6 +1941,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ +#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ /* ** CAPI3REF: Database Connection Configuration Options @@ -7014,7 +7006,7 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 -#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 +#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19 @@ -7073,8 +7065,7 @@ int sqlite3_status64( **
This parameter is the current amount of memory checked out ** using [sqlite3_malloc()], either directly or indirectly. The ** figure includes calls made to [sqlite3_malloc()] by the application -** and internal memory usage by the SQLite library. Scratch memory -** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache +** and internal memory usage by the SQLite library. Auxiliary page-cache ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in ** this parameter. The amount returned is the sum of the allocation ** sizes as reported by the xSize method in [sqlite3_mem_methods].
)^ @@ -7112,29 +7103,14 @@ int sqlite3_status64( ** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.)^ ** -** [[SQLITE_STATUS_SCRATCH_USED]] ^(
SQLITE_STATUS_SCRATCH_USED
-**
This parameter returns the number of allocations used out of the -** [scratch memory allocator] configured using -** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not -** in bytes. Since a single thread may only have one scratch allocation -** outstanding at time, this parameter also reports the number of threads -** using scratch memory at the same time.
)^ +** [[SQLITE_STATUS_SCRATCH_USED]]
SQLITE_STATUS_SCRATCH_USED
+**
No longer used.
** ** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(
SQLITE_STATUS_SCRATCH_OVERFLOW
-**
This parameter returns the number of bytes of scratch memory -** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH] -** buffer and where forced to overflow to [sqlite3_malloc()]. The values -** returned include overflows because the requested allocation was too -** larger (that is, because the requested allocation was larger than the -** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer -** slots were available. -**
)^ +**
No longer used.
** -** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(
SQLITE_STATUS_SCRATCH_SIZE
-**
This parameter records the largest memory allocation request -** handed to [scratch memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. -** The value written into the *pCurrent parameter is undefined.
)^ +** [[SQLITE_STATUS_SCRATCH_SIZE]]
SQLITE_STATUS_SCRATCH_SIZE
+**
No longer used.
** ** [[SQLITE_STATUS_PARSER_STACK]] ^(
SQLITE_STATUS_PARSER_STACK
**
The *pHighwater parameter records the deepest parser stack. @@ -7147,12 +7123,12 @@ int sqlite3_status64( #define SQLITE_STATUS_MEMORY_USED 0 #define SQLITE_STATUS_PAGECACHE_USED 1 #define SQLITE_STATUS_PAGECACHE_OVERFLOW 2 -#define SQLITE_STATUS_SCRATCH_USED 3 -#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 +#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */ +#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */ #define SQLITE_STATUS_MALLOC_SIZE 5 #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 -#define SQLITE_STATUS_SCRATCH_SIZE 8 +#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */ #define SQLITE_STATUS_MALLOC_COUNT 9 /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3689689403..55a8efe214 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3268,6 +3268,7 @@ struct Sqlite3Config { int bFullMutex; /* True to enable full mutexing */ int bOpenUri; /* True to interpret filenames as URIs */ int bUseCis; /* Use covering indices for full-scans */ + int bSmallMalloc; /* Avoid large memory allocations if true */ int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ @@ -3281,9 +3282,6 @@ struct Sqlite3Config { int mnReq, mxReq; /* Min and max heap requests sizes */ sqlite3_int64 szMmap; /* mmap() space per open file */ sqlite3_int64 mxMmap; /* Maximum value for szMmap */ - void *pScratch; /* Scratch memory */ - int szScratch; /* Size of each scratch buffer */ - int nScratch; /* Number of scratch buffers */ void *pPage; /* Page cache memory */ int szPage; /* Size of each page in pPage[] */ int nPage; /* Number of pages in pPage[] */ @@ -3522,8 +3520,6 @@ void sqlite3DbFree(sqlite3*, void*); void sqlite3DbFreeNN(sqlite3*, void*); int sqlite3MallocSize(void*); int sqlite3DbMallocSize(sqlite3*, void*); -void *sqlite3ScratchMalloc(int); -void sqlite3ScratchFree(void*); void *sqlite3PageMalloc(int); void sqlite3PageFree(void*); void sqlite3MemSetDefault(void); @@ -4385,8 +4381,7 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ -#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ -#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */ +#define MEMTYPE_PCACHE 0x04 /* Page cache allocations */ /* ** Threading interface diff --git a/src/status.c b/src/status.c index 24dcad4572..b783b395d3 100644 --- a/src/status.c +++ b/src/status.c @@ -122,7 +122,6 @@ void sqlite3StatusHighwater(int op, int X){ : sqlite3MallocMutex()) ); assert( op==SQLITE_STATUS_MALLOC_SIZE || op==SQLITE_STATUS_PAGECACHE_SIZE - || op==SQLITE_STATUS_SCRATCH_SIZE || op==SQLITE_STATUS_PARSER_STACK ); if( newValue>wsdStat.mxValue[op] ){ wsdStat.mxValue[op] = newValue; diff --git a/src/test_malloc.c b/src/test_malloc.c index e8c248f958..b13d9b2b2c 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -887,46 +887,6 @@ static int SQLITE_TCLAPI test_memdebug_log( return TCL_OK; } -/* -** Usage: sqlite3_config_scratch SIZE N -** -** Set the scratch memory buffer using SQLITE_CONFIG_SCRATCH. -** The buffer is static and is of limited size. N might be -** adjusted downward as needed to accommodate the requested size. -** The revised value of N is returned. -** -** A negative SIZE causes the buffer pointer to be NULL. -*/ -static int SQLITE_TCLAPI test_config_scratch( - void * clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - int sz, N, rc; - Tcl_Obj *pResult; - static char *buf = 0; - if( objc!=3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "SIZE N"); - return TCL_ERROR; - } - if( Tcl_GetIntFromObj(interp, objv[1], &sz) ) return TCL_ERROR; - if( Tcl_GetIntFromObj(interp, objv[2], &N) ) return TCL_ERROR; - free(buf); - if( sz<0 ){ - buf = 0; - rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, (void*)0, 0, 0); - }else{ - buf = malloc( sz*N + 1 ); - rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, buf, sz, N); - } - pResult = Tcl_NewObj(); - Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(rc)); - Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(N)); - Tcl_SetObjResult(interp, pResult); - return TCL_OK; -} - /* ** Usage: sqlite3_config_pagecache SIZE N ** @@ -1538,7 +1498,6 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ { "sqlite3_memdebug_settitle", test_memdebug_settitle ,0 }, { "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count ,0 }, { "sqlite3_memdebug_log", test_memdebug_log ,0 }, - { "sqlite3_config_scratch", test_config_scratch ,0 }, { "sqlite3_config_pagecache", test_config_pagecache ,0 }, { "sqlite3_config_alt_pcache", test_alt_pcache ,0 }, { "sqlite3_status", test_status ,0 }, diff --git a/src/vdbesort.c b/src/vdbesort.c index 8ce7415737..ef5715d249 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1000,11 +1000,9 @@ int sqlite3VdbeSorterInit( mxCache = MIN(mxCache, SQLITE_MAX_PMASZ); pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache); - /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of - ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary - ** large heap allocations. - */ - if( sqlite3GlobalConfig.pScratch==0 ){ + /* Avoid large memory allocations if the application has requested + ** SQLITE_CONFIG_SMALL_MALLOC. */ + if( sqlite3GlobalConfig.bSmallMalloc==0 ){ assert( pSorter->iMemory==0 ); pSorter->nMemory = pgsz; pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); diff --git a/test/kvtest.c b/test/kvtest.c index b80adfea09..9193586a1e 100644 --- a/test/kvtest.c +++ b/test/kvtest.c @@ -741,16 +741,6 @@ static int display_stats( "Number of Pcache Overflow Bytes: %d (max %d) bytes\n", iCur, iHiwtr); iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset); - fprintf(out, - "Number of Scratch Allocations Used: %d (max %d)\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset); - fprintf(out, - "Number of Scratch Overflow Bytes: %d (max %d) bytes\n", - iCur, iHiwtr); - iHiwtr = iCur = -1; sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset); fprintf(out, "Largest Allocation: %d bytes\n", iHiwtr); @@ -758,10 +748,6 @@ static int display_stats( sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset); fprintf(out, "Largest Pcache Allocation: %d bytes\n", iHiwtr); - iHiwtr = iCur = -1; - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset); - fprintf(out, "Largest Scratch Allocation: %d bytes\n", - iHiwtr); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); diff --git a/test/lookaside.test b/test/lookaside.test index a89110ee1d..67a502afb2 100644 --- a/test/lookaside.test +++ b/test/lookaside.test @@ -33,7 +33,6 @@ test_set_config_pagecache 0 0 catch {db close} sqlite3_shutdown -sqlite3_config_scratch 0 0 sqlite3_initialize autoinstall_test_functions sqlite3 db test.db diff --git a/test/memsubsys1.test b/test/memsubsys1.test index 36427f9bae..41bc115269 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -16,7 +16,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl sqlite3_reset_auto_extension -# This test assumes that no page-cache or scratch buffers are installed +# This test assumes that no page-cache buffers are installed # by default when a new database connection is opened. As a result, it # will not work with the "memsubsys1" permutation. # @@ -156,12 +156,11 @@ do_test memsubsys1-3.2.5 { set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] } 0 -# Test 4: Activate both PAGECACHE and SCRATCH. +# Test 4: Activate PAGECACHE # db close sqlite3_shutdown sqlite3_config_pagecache [expr 1024+$xtra_size] 50 -sqlite3_config_scratch 6000 2 sqlite3_initialize reset_highwater_marks build_test_db memsubsys1-4 {PRAGMA page_size=1024} @@ -177,144 +176,10 @@ do_test memsubsys1-4.5 { set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] expr {$maxreq<7000} } 1 -do_test memsubsys1-4.6 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 1 - -# Test 5: Activate both PAGECACHE and SCRATCH. But make the page size is -# such that the SCRATCH allocations are too small. -# -db close -sqlite3_shutdown -sqlite3_config_pagecache [expr 4096+$xtra_size] 24 -sqlite3_config_scratch 4000 2 -sqlite3_initialize -reset_highwater_marks -build_test_db memsubsys1-5 {PRAGMA page_size=4096} -#show_memstats -do_test memsubsys1-5.3 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] -} {/^2[34]$/} -do_test memsubsys1-5.4 { - set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] - expr {$maxreq>4096} -} 1 -do_test memsubsys1-5.5 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 0 -do_test memsubsys1-5.6 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] - expr {$s_ovfl>6000} -} 1 - -# Test 6: Activate both PAGECACHE and SCRATCH with a 4k page size. -# Make it so that SCRATCH is large enough -# -db close -sqlite3_shutdown -sqlite3_config_pagecache [expr 4096+$xtra_size] 24 -sqlite3_config_scratch 25300 1 -sqlite3_initialize -reset_highwater_marks -build_test_db memsubsys1-6 {PRAGMA page_size=4096} -#show_memstats -do_test memsubsys1-6.3 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] -} {/^2[34]$/} -#do_test memsubsys1-6.4 { -# set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] -# expr {$maxreq>4096 && $maxreq<=(4096+$xtra_size)} -#} 1 -do_test memsubsys1-6.5 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 1 -do_test memsubsys1-6.6 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] -} 0 - -# Test 7: Activate both PAGECACHE and SCRATCH with a 4k page size. -# Set cache_size small so that no PAGECACHE overflow occurs. Verify -# that maximum allocation size is small. -# -db close -sqlite3_shutdown -sqlite3_config_pagecache [expr 4096+$xtra_size] 24 -sqlite3_config_scratch 25300 1 -sqlite3_initialize -reset_highwater_marks -build_test_db memsubsys1-7 { - PRAGMA page_size=4096; - PRAGMA cache_size=10; - PRAGMA temp_store=memory; -} -#show_memstats -do_test memsubsys1-7.3 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2] - expr {$pg_used<24} -} 1 -do_test memsubsys1-7.4 { - set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] -} 0 -do_test memsubsys1-7.5 { - set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2] - expr {$maxreq<(4100 + 8200*[nonzero_reserved_bytes])} -} 1 -do_test memsubsys1-7.6 { - set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 1 -do_test memsubsys1-7.7 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] -} 0 - -# Test 8: Disable PAGECACHE. Make available SCRATCH zero. Verify that -# the SCRATCH overflow logic works. -# -db close -sqlite3_shutdown -sqlite3_config_pagecache 0 0 -sqlite3_config_scratch 25000 0 -sqlite3_initialize -reset_highwater_marks -do_test memsubsys1-8.1 { - set pg_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] -} 0 -do_test memsubsys1-8.2 { - set s_ovfl [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2] -} 0 -do_test memsubsys1-8.3 { - sqlite3 db :memory: - db eval { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - } - expr {[lindex [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] 2]>0} -} 1 -db close -sqlite3_shutdown -sqlite3_config_memstatus 0 -sqlite3_initialize -do_test memsubsys1-8.4 { - sqlite3 db :memory: - db eval { - CREATE TABLE t1(x); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 VALUES(zeroblob(400)); - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - INSERT INTO t1 SELECT * FROM t1; - SELECT rowid FROM t1; - } -} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16} - db close sqlite3_shutdown sqlite3_config_memstatus 1 -sqlite3_config_scratch 0 0 sqlite3_config_lookaside 100 500 sqlite3_config serialized sqlite3_initialize diff --git a/test/permutations.test b/test/permutations.test index bcd06c14b7..5afc51cb7d 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -455,33 +455,31 @@ lappend ::testsuitelist xxx # Define the permutation test suites: # -# Run some tests using pre-allocated page and scratch blocks. +# Run some tests using pre-allocated page blocks. # # mmap1.test is excluded because a good number of its tests depend on # the page-cache being larger than the database. But this permutation # causes the effective limit on the page-cache to be just 24 pages. # test_suite "memsubsys1" -description { - Tests using pre-allocated page and scratch blocks + Tests using pre-allocated page blocks } -files [ test_set $::allquicktests -exclude ioerr5.test malloc5.test mmap1.test ] -initialize { test_set_config_pagecache 4096 24 catch {db close} sqlite3_shutdown - sqlite3_config_scratch 25000 1 sqlite3_initialize autoinstall_test_functions } -shutdown { test_restore_config_pagecache catch {db close} sqlite3_shutdown - sqlite3_config_scratch 0 0 sqlite3_initialize autoinstall_test_functions } -# Run some tests using pre-allocated page and scratch blocks. This time +# Run some tests using pre-allocated page blocks. This time # the allocations are too small to use in most cases. # # Both ioerr5.test and malloc5.test are excluded because they test the @@ -489,21 +487,19 @@ test_suite "memsubsys1" -description { # This functionality is disabled if a pre-allocated page block is provided. # test_suite "memsubsys2" -description { - Tests using small pre-allocated page and scratch blocks + Tests using small pre-allocated page blocks } -files [ test_set $::allquicktests -exclude ioerr5.test malloc5.test ] -initialize { test_set_config_pagecache 512 5 catch {db close} sqlite3_shutdown - sqlite3_config_scratch 1000 1 sqlite3_initialize autoinstall_test_functions } -shutdown { test_restore_config_pagecache catch {db close} sqlite3_shutdown - sqlite3_config_scratch 0 0 sqlite3_initialize autoinstall_test_functions } diff --git a/test/speedtest1.c b/test/speedtest1.c index db3a558a38..e374c22c1e 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -25,7 +25,6 @@ static const char zHelp[] = " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n" " --repeat N Repeat each SELECT N times (default: 1)\n" " --reprepare Reprepare each statement upon every invocation\n" - " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n" " --serialized Set serialized threading mode\n" " --singlethread Set single-threaded mode - disables all mutexing\n" " --sqlonly No-op. Only show the SQL that would have been run.\n" @@ -1649,7 +1648,6 @@ int main(int argc, char **argv){ int pageSize = 0; /* Desired page size. 0 means default */ int nPCache = 0, szPCache = 0;/* --pcache configuration */ int doPCache = 0; /* True if --pcache is seen */ - int nScratch = 0, szScratch=0;/* --scratch configuration */ int showStats = 0; /* True for --stats */ int nThread = 0; /* --threads value */ int mmapSize = 0; /* How big of a memory map to use */ @@ -1661,7 +1659,6 @@ int main(int argc, char **argv){ void *pHeap = 0; /* Allocated heap space */ void *pLook = 0; /* Allocated lookaside space */ void *pPCache = 0; /* Allocated storage for pcache */ - void *pScratch = 0; /* Allocated storage for scratch */ int iCur, iHi; /* Stats values, current and "highwater" */ int i; /* Loop counter */ int rc; /* API return code */ @@ -1741,11 +1738,6 @@ int main(int argc, char **argv){ i += 1; }else if( strcmp(z,"reprepare")==0 ){ g.bReprepare = 1; - }else if( strcmp(z,"scratch")==0 ){ - if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); - nScratch = integerValue(argv[i+1]); - szScratch = integerValue(argv[i+2]); - i += 2; #if SQLITE_VERSION_NUMBER>=3006000 }else if( strcmp(z,"serialized")==0 ){ sqlite3_config(SQLITE_CONFIG_SERIALIZED); @@ -1816,13 +1808,6 @@ int main(int argc, char **argv){ rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); if( rc ) fatal_error("pcache configuration failed: %d\n", rc); } - if( nScratch>0 && szScratch>0 ){ - pScratch = malloc( nScratch*(sqlite3_int64)szScratch ); - if( pScratch==0 ) fatal_error("cannot allocate %lld-byte scratch\n", - nScratch*(sqlite3_int64)szScratch); - rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch); - if( rc ) fatal_error("scratch configuration failed: %d\n", rc); - } if( nLook>=0 ){ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); } @@ -1939,14 +1924,10 @@ int main(int argc, char **argv){ #endif sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0); printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi); - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHi, 0); - printf("-- Scratch Overflow Bytes: %d (max %d)\n", iCur,iHi); sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0); printf("-- Largest Allocation: %d bytes\n",iHi); sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0); printf("-- Largest Pcache Allocation: %d bytes\n",iHi); - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0); - printf("-- Largest Scratch Allocation: %d bytes\n", iHi); } #endif @@ -1959,7 +1940,6 @@ int main(int argc, char **argv){ /* Release memory */ free( pLook ); free( pPCache ); - free( pScratch ); free( pHeap ); return 0; } diff --git a/test/tester.tcl b/test/tester.tcl index 38c19701c6..10a20a47d6 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1241,14 +1241,6 @@ proc show_memstats {} { set x [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] set val [format {now %10d max %10d} [lindex $x 1] [lindex $x 2]] output1 "Page-cache overflow: $val" - set x [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] - set val [format {now %10d max %10d} [lindex $x 1] [lindex $x 2]] - output1 "Scratch memory used: $val" - set x [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0] - set y [sqlite3_status SQLITE_STATUS_SCRATCH_SIZE 0] - set val [format {now %10d max %10d max-size %10d} \ - [lindex $x 1] [lindex $x 2] [lindex $y 2]] - output1 "Scratch overflow: $val" ifcapable yytrackmaxstackdepth { set x [sqlite3_status SQLITE_STATUS_PARSER_STACK 0] set val [format { max %10d} [lindex $x 2]] diff --git a/test/wordcount.c b/test/wordcount.c index bc1d499f15..27aed72460 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -633,14 +633,10 @@ int main(int argc, char **argv){ printf("%s Outstanding Allocations: %d (max %d)\n",zTag,iCur,iHiwtr); sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, 0); printf("%s Pcache Overflow Bytes: %d (max %d)\n",zTag,iCur,iHiwtr); - sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, 0); - printf("%s Scratch Overflow Bytes: %d (max %d)\n",zTag,iCur,iHiwtr); sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, 0); printf("%s Largest Allocation: %d bytes\n",zTag,iHiwtr); sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, 0); printf("%s Largest Pcache Allocation: %d bytes\n",zTag,iHiwtr); - sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, 0); - printf("%s Largest Scratch Allocation: %d bytes\n",zTag,iHiwtr); } return 0; } From 52df6f5e5cb421150b8ab9ad1ee51c9628e9ee2b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 Aug 2017 16:11:05 +0000 Subject: [PATCH 52/53] Avoid unnecessary mutexes in the pcache1 implementation in the common case where no auxiliary page cache memory is configured. FossilOrigin-Name: 1ba051e34d7512ab5e8fc969c1b5aaaf827b8e6493ba4235895257aca78b500f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pcache1.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2131ba9ff1..3b3666f8f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\srarely-used\sscratch\smemory\sallocator.\s\sThis\smakes\sthe\scode\ssmaller,\nfaster,\sand\seasier\sto\smaintain.\s\sIn\splace\sof\sthe\sscratch\sallocator,\sadd\sthe\nSQLITE_CONFIG_SMALL_MALLOC\sconfiguration\soption\sthat\sprovides\sa\shint\sto\sSQLite\nthat\slarge\smemory\sallocations\sshould\sbe\savoided. -D 2017-08-28T15:51:35.625 +C Avoid\sunnecessary\smutexes\sin\sthe\spcache1\simplementation\sin\sthe\scommon\scase\nwhere\sno\sauxiliary\spage\scache\smemory\sis\sconfigured. +D 2017-08-28T16:11:05.724 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -448,7 +448,7 @@ F src/pager.h f2a99646c5533ffe11afa43e9e0bea74054e4efa F src/parse.y 52ef3cecd0934e9da4a45b585883a03243ad615d338ad94f44501a05891dcdfa F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870 F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11 -F src/pcache1.c 0b793738b5dddaf0a645784835c6b5557b1ecfaee339af9c26810c6ecdb273aa +F src/pcache1.c ad5bc71727c2e825dcbf342413e1b4b09ed8520cd83903671e8bd03bc30b4c98 F src/pragma.c a4e5028dfc8af4c5c347cd0e91bd2f0c0f81fcd9b2c6e0acf8da7da51df7f1fe F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324 F src/prepare.c 9a141a1b02dca53beaa9771699d390aafcac01f5d1f1c0ae6e23ded8dcdb709a @@ -1651,7 +1651,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 2348045fbc3fc99e2b46095cc86db99815cd1f9254d30a3b72c2b15c02076a84 -R dbf94ead9bb02368db4853c4bef6223c +P 54b000246cfb5c7b8adb61a17357ef5a49adddde9e48e8937834d5ba0beb8a6b +R 83da5bfb65f5a08c38f889ed88d6f498 U drh -Z 970c3285dea1ce91571a8f403e94ff33 +Z cc59cd24e10bd66953b2a2efefd623c5 diff --git a/manifest.uuid b/manifest.uuid index f6193d5c82..ceacf0dc17 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54b000246cfb5c7b8adb61a17357ef5a49adddde9e48e8937834d5ba0beb8a6b \ No newline at end of file +1ba051e34d7512ab5e8fc969c1b5aaaf827b8e6493ba4235895257aca78b500f \ No newline at end of file diff --git a/src/pcache1.c b/src/pcache1.c index 9c59574ace..7a19bd9674 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -250,6 +250,7 @@ void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ if( pcache1.isInit ){ PgFreeslot *p; if( pBuf==0 ) sz = n = 0; + if( n==0 ) sz = 0; sz = ROUNDDOWN8(sz); pcache1.szSlot = sz; pcache1.nSlot = pcache1.nFreeSlot = n; From 83bebddbd91ea60568aa4be7c268e25b8a179e82 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 28 Aug 2017 17:00:12 +0000 Subject: [PATCH 53/53] Add the --enable-update-limit option to the ./configure script. FossilOrigin-Name: 64a8ae68381b7fbb29b659901ca7ce8d50510e4753758d5761f7e41539288cef --- configure | 44 ++++++++++++++++++++++++++++++-------------- configure.ac | 10 ++++++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/configure b/configure index 7a81d52156..ed9ed5ffd4 100755 --- a/configure +++ b/configure @@ -909,6 +909,7 @@ enable_fts3 enable_fts4 enable_fts5 enable_json1 +enable_update_limit enable_rtree enable_session enable_gcov @@ -1560,6 +1561,7 @@ Optional Features: --enable-fts4 Enable the FTS4 extension --enable-fts5 Enable the FTS5 extension --enable-json1 Enable the JSON1 extension + --enable-update-limit Enable the UPDATE/DELETE LIMIT clause --enable-rtree Enable the RTREE extension --enable-session Enable the SESSION extension --enable-gcov Enable coverage testing using gcov @@ -3929,13 +3931,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3932: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3934: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3935: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3937: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3938: output\"" >&5) + (eval echo "\"\$as_me:3940: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5141,7 +5143,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5144 "configure"' > conftest.$ac_ext + echo '#line 5146 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6666,11 +6668,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6669: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6671: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6673: \$? = $ac_status" >&5 + echo "$as_me:6675: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7005,11 +7007,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7008: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7010: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7012: \$? = $ac_status" >&5 + echo "$as_me:7014: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7110,11 +7112,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7113: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7115: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7117: \$? = $ac_status" >&5 + echo "$as_me:7119: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7165,11 +7167,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7168: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7170: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7172: \$? = $ac_status" >&5 + echo "$as_me:7174: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9545,7 +9547,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9548 "configure" +#line 9550 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9641,7 +9643,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9644 "configure" +#line 9646 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11539,6 +11541,20 @@ if test "${enable_json1}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" fi +######### +# See whether we should enable the LIMIT clause on UPDATE and DELETE +# statements. +# Check whether --enable-update-limit was given. +if test "${enable_update_limit+set}" = set; then : + enableval=$enable_update_limit; enable_udlimit=yes +else + enable_udlimit=no +fi + +if test "${enable_udlimit}" = "yes" ; then + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" +fi + ######### # See whether we should enable RTREE # Check whether --enable-rtree was given. diff --git a/configure.ac b/configure.ac index 4deee8ddcb..55ab0673ee 100644 --- a/configure.ac +++ b/configure.ac @@ -644,6 +644,16 @@ if test "${enable_json1}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" fi +######### +# See whether we should enable the LIMIT clause on UPDATE and DELETE +# statements. +AC_ARG_ENABLE(update-limit, AC_HELP_STRING([--enable-update-limit], + [Enable the UPDATE/DELETE LIMIT clause]), + [enable_udlimit=yes],[enable_udlimit=no]) +if test "${enable_udlimit}" = "yes" ; then + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" +fi + ######### # See whether we should enable RTREE AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree], diff --git a/manifest b/manifest index 3b3666f8f6..c1fc26d824 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\smutexes\sin\sthe\spcache1\simplementation\sin\sthe\scommon\scase\nwhere\sno\sauxiliary\spage\scache\smemory\sis\sconfigured. -D 2017-08-28T16:11:05.724 +C Add\sthe\s--enable-update-limit\soption\sto\sthe\s./configure\sscript. +D 2017-08-28T17:00:12.028 F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 25b154da7f0b3d4924f27378c1f8d006285b80811f1ccf3ed953dbebf6282136 @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 2500b432572804093c9a2516e2b16dbcec5d797ea1cd654915cfecd1d7a39ee3 x -F configure.ac 13f45f02e6c51dd0e347315b5401c3f047712b7f79b7f35619115c23755afcff +F configure e691ad9b505f1f47bc5d99be9e1d49b1be9037e9cb3821c9b14c63c3d413d055 x +F configure.ac bb85c1c53e952c8c7078a2f147eba613e0128b8b6e7780d64758d8fb29bcc695 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 1f8b8d4c9f5cfe40e679fee279cc9eb2da8e6eb74ad406028538d7864cc4b6cb F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1651,7 +1651,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 54b000246cfb5c7b8adb61a17357ef5a49adddde9e48e8937834d5ba0beb8a6b -R 83da5bfb65f5a08c38f889ed88d6f498 +P 1ba051e34d7512ab5e8fc969c1b5aaaf827b8e6493ba4235895257aca78b500f +R 7e1ed169d6d4a03a64afe06fcba95957 U drh -Z cc59cd24e10bd66953b2a2efefd623c5 +Z 13247c5e6bbeac642354740051347480 diff --git a/manifest.uuid b/manifest.uuid index ceacf0dc17..09eebfb4e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ba051e34d7512ab5e8fc969c1b5aaaf827b8e6493ba4235895257aca78b500f \ No newline at end of file +64a8ae68381b7fbb29b659901ca7ce8d50510e4753758d5761f7e41539288cef \ No newline at end of file