From 70273d0babf9b470539d443e8714a1ad947d197e Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 14 Nov 2014 19:34:20 +0000 Subject: [PATCH 01/24] Consider using an automatic-index for a scan even if there exists a possible skip-scan that uses one or more "=" operators. FossilOrigin-Name: 93642a65ef3d53ece322ffd85233b68fc9a86c9d --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/where.c | 3 ++- test/autoindex3.test | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1b20e13d73..48ea588135 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sautomatically\sremove\sthe\sDISTINCT\skeyword\sfrom\s"a\sIN\s(SELECT\sDISTINCT\s...)"\sexpressions.\sFix\sfor\s[db87229497]. -D 2014-11-14T15:28:33.929 +C Consider\susing\san\sautomatic-index\sfor\sa\sscan\seven\sif\sthere\sexists\sa\spossible\sskip-scan\sthat\suses\sone\sor\smore\s"="\soperators. +D 2014-11-14T19:34:20.967 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -304,7 +304,7 @@ F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 F src/wal.c fa090966140602f03a621f87d82ee69e66ca63b5 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 3862a1173ae2716bde12f1ab3fb649f1d85b05c2 +F src/where.c 4d72a350fd5eec080583f95044f0f394590d13a3 F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -347,7 +347,7 @@ F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7 F test/autoindex2.test 60d2fc6f38364308ce73a9beb01b47ded38697de -F test/autoindex3.test 8254f689c3241081fad52b7bea18ba53e07e14a2 +F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 @@ -1221,7 +1221,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ef03a203351a6002e2b1075139717e4234c816cd -R bb54553354aa14551393c5e5701542c8 +P 55e453aadbb676dda07f0fa537d39ce184ef636c +R 0a82574686b12650ce6ac2a5e463073b +T *branch * experimental-autoindex-fix +T *sym-experimental-autoindex-fix * +T -sym-trunk * U dan -Z f91e19e3f2d1e58cdccd86465c86ab70 +Z 13c044e2b6669432b7a0bb70427e69a9 diff --git a/manifest.uuid b/manifest.uuid index c5dbef8e09..769887276c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55e453aadbb676dda07f0fa537d39ce184ef636c \ No newline at end of file +93642a65ef3d53ece322ffd85233b68fc9a86c9d \ No newline at end of file diff --git a/src/where.c b/src/where.c index c3641c7cc7..2a06e3f479 100644 --- a/src/where.c +++ b/src/where.c @@ -4130,8 +4130,9 @@ static WhereLoop **whereLoopFindLesser( /* Any loop using an appliation-defined index (or PRIMARY KEY or ** UNIQUE constraint) with one or more == constraints is better - ** than an automatic index. */ + ** than an automatic index. Unless it is a skip-scan. */ if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 + && (pTemplate->nSkip)==0 && (pTemplate->wsFlags & WHERE_INDEXED)!=0 && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0 && (p->prereq & pTemplate->prereq)==pTemplate->prereq diff --git a/test/autoindex3.test b/test/autoindex3.test index 33053bba67..c99a175c6d 100644 --- a/test/autoindex3.test +++ b/test/autoindex3.test @@ -17,6 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix autoindex3 # The t1b and t2d indexes are not very selective. It used to be that # the autoindex mechanism would create automatic indexes on t1(b) or @@ -54,5 +55,38 @@ do_execsql_test autoindex3-140 { EXPLAIN QUERY PLAN SELECT * FROM t1, t2 WHERE d IN (5,b) AND x=y; } {/AUTO/} +reset_db +do_execsql_test 210 { + CREATE TABLE v(b, d, e); + CREATE TABLE u(a, b, c); + ANALYZE sqlite_master; + INSERT INTO "sqlite_stat1" VALUES('u','uab','40000 400 1'); + INSERT INTO "sqlite_stat1" VALUES('v','vbde','40000 400 1 1'); + INSERT INTO "sqlite_stat1" VALUES('v','ve','40000 21'); + + CREATE INDEX uab on u(a, b); + CREATE INDEX ve on v(e); + CREATE INDEX vbde on v(b,d,e); + + DROP TABLE IF EXISTS sqlite_stat4; + ANALYZE sqlite_master; +} + +# At one point, SQLite was using the inferior plan: +# +# 0|0|1|SEARCH TABLE v USING INDEX ve (e>?) +# 0|1|0|SEARCH TABLE u USING COVERING INDEX uab (ANY(a) AND b=?) +# +# on the basis that the real index "uab" must be better than the automatic +# index. This is not right - a skip-scan is not necessarily better than an +# automatic index scan. +# +do_eqp_test 220 { + select count(*) from u, v where u.b = v.b and v.e > 34; +} { + 0 0 1 {SEARCH TABLE v USING INDEX ve (e>?)} + 0 1 0 {SEARCH TABLE u USING AUTOMATIC COVERING INDEX (b=?)} +} + finish_test From f9df2fbdcd43eb7f223da88ce8cdcf70766bd945 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 15 Nov 2014 19:08:13 +0000 Subject: [PATCH 02/24] Adding the "noskipscan" token to an sqlite_stat1.stat field prevents an index for being used with the skip-scan algorithm. FossilOrigin-Name: 00fe09505792cd0d104b2da9d040f023e30fa871 --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/analyze.c | 2 ++ src/sqliteInt.h | 1 + src/where.c | 1 + test/skipscan1.test | 19 +++++++++++++++++++ 6 files changed, 37 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1b20e13d73..1c607eedd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sautomatically\sremove\sthe\sDISTINCT\skeyword\sfrom\s"a\sIN\s(SELECT\sDISTINCT\s...)"\sexpressions.\sFix\sfor\s[db87229497]. -D 2014-11-14T15:28:33.929 +C Adding\sthe\s"noskipscan"\stoken\sto\san\ssqlite_stat1.stat\sfield\sprevents\san\nindex\sfor\sbeing\sused\swith\sthe\sskip-scan\salgorithm. +D 2014-11-15T19:08:13.305 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb -F src/analyze.c afbcca663c3f3625340b8e30d440cd7a97ded6bc +F src/analyze.c 951fd859852dfbced4a58b73954f168eeb9d0772 F src/attach.c f4e94df2d1826feda65eb0939f7f6f5f923a0ad9 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea @@ -233,7 +233,7 @@ F src/shell.c bc28d5992109717c87804e2eb1a08a7c8cc7a2fd F src/sqlite.h.in 0c5c0df7e4e436dfc5592511325bf4a96f6a638d F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d -F src/sqliteInt.h 71b0bf1a7fc55b5cb374f7579fd140e730a6e0f4 +F src/sqliteInt.h c9e95b8fa9aee30d46387735c5be73fa58886e38 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc @@ -304,7 +304,7 @@ F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 F src/wal.c fa090966140602f03a621f87d82ee69e66ca63b5 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 3862a1173ae2716bde12f1ab3fb649f1d85b05c2 +F src/where.c cb89128d24ddb5fe3ca290166d66968f2dc0c3c8 F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -855,7 +855,7 @@ F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 -F test/skipscan1.test 7e15e1cc524524e7b2c4595ec85c75501d22f4ff +F test/skipscan1.test 2ddfe5d168462170c4487f534e2a99fb006b2076 F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 @@ -1221,7 +1221,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ef03a203351a6002e2b1075139717e4234c816cd -R bb54553354aa14551393c5e5701542c8 -U dan -Z f91e19e3f2d1e58cdccd86465c86ab70 +P 55e453aadbb676dda07f0fa537d39ce184ef636c +R 59717354988087765927b6c6b6246253 +T *branch * noskipscan-token +T *sym-noskipscan-token * +T -sym-trunk * +U drh +Z 9d226c4fa6bf82a1f1a22a271191f33c diff --git a/manifest.uuid b/manifest.uuid index c5dbef8e09..1ab180da36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55e453aadbb676dda07f0fa537d39ce184ef636c \ No newline at end of file +00fe09505792cd0d104b2da9d040f023e30fa871 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 597885237c..769a16565a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1466,6 +1466,8 @@ static void decodeIntArray( pIndex->bUnordered = 1; }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); + }else if( sqlite3_strglob("noskipscan*", z)==0 ){ + pIndex->noSkipScan = 1; } #ifdef SQLITE_ENABLE_COSTMULT else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4d272b06a1..f3d6ce015e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1795,6 +1795,7 @@ struct Index { unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned isResized:1; /* True if resizeIndexObject() has been called */ unsigned isCovering:1; /* True if this is a covering index */ + unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ diff --git a/src/where.c b/src/where.c index c3641c7cc7..db6cf94dea 100644 --- a/src/where.c +++ b/src/where.c @@ -4587,6 +4587,7 @@ static int whereLoopAddBtreeIndex( assert( 42==sqlite3LogEst(18) ); if( saved_nEq==saved_nSkip && saved_nEq+1nKeyCol + && pProbe->noSkipScan==0 && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK ){ diff --git a/test/skipscan1.test b/test/skipscan1.test index 6b9f1209a5..4f996df972 100644 --- a/test/skipscan1.test +++ b/test/skipscan1.test @@ -273,4 +273,23 @@ do_execsql_test skipscan1-6.3 { EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1; } {~/ANY/} +# If the sqlite_stat1 entry includes the "noskipscan" token, then never use +# skipscan with that index. +# +do_execsql_test skipscan1-7.1 { + UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100'; + ANALYZE sqlite_master; + EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1; +} {/ANY/} +do_execsql_test skipscan1-7.2 { + UPDATE sqlite_stat1 SET stat='500000 125000 1 noskipscan sz=100'; + ANALYZE sqlite_master; + EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1; +} {~/ANY/} +do_execsql_test skipscan1-7.3 { + UPDATE sqlite_stat1 SET stat='500000 125000 1 sz=100 noskipscan'; + ANALYZE sqlite_master; + EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=1; +} {~/ANY/} + finish_test From 664f85dd59c7995b2651ca9de390607dbfadb419 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Nov 2014 14:05:41 +0000 Subject: [PATCH 03/24] Add an ALWAYS on an always-true branch in wal.c. Fix the ANALYZE command so that it resets the "unordered" and "noskipscan" flags on indices when reloading the sqlite_stat1 table. FossilOrigin-Name: 9ed97a85feee6593faefa2b54cc4cf9a60f515f9 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/analyze.c | 2 ++ src/wal.c | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 272d0369e1..5976aae2e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adding\sthe\s"noskipscan"\stoken\sto\san\ssqlite_stat1.stat\sfield\sprevents\nan\sindex\sfor\sbeing\sused\swith\sthe\sskip-scan\salgorithm. -D 2014-11-18T21:54:31.890 +C Add\san\sALWAYS\son\san\salways-true\sbranch\sin\swal.c.\nFix\sthe\sANALYZE\scommand\sso\sthat\sit\sresets\sthe\s"unordered"\sand\s"noskipscan"\nflags\son\sindices\swhen\sreloading\sthe\ssqlite_stat1\stable. +D 2014-11-19T14:05:41.209 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb -F src/analyze.c 951fd859852dfbced4a58b73954f168eeb9d0772 +F src/analyze.c c59f238a39aacece176f8bb7dfece40deb268ee5 F src/attach.c f4e94df2d1826feda65eb0939f7f6f5f923a0ad9 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea @@ -301,7 +301,7 @@ F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f F src/vdbesort.c 87f3923483113d1c95d84640becb4e4946f27d9a F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 -F src/wal.c fa090966140602f03a621f87d82ee69e66ca63b5 +F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c e275cb74731a3351a9da6ba8280bd5054db6192d @@ -1221,8 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c52f7971e90cac1058d6b66c9e334cbc8607def3 00fe09505792cd0d104b2da9d040f023e30fa871 -R 9bae3f4f5e0db167ef1a706a77e76141 -T +closed 00fe09505792cd0d104b2da9d040f023e30fa871 +P 4461bf045d8eecf98478035efcdba3f41c709bc5 +R b83c6fa5464847f6b6472d2244f6f040 U drh -Z fec927bef6596f9a5e5eec2871a731e7 +Z cd93530e8709a199e7d3e18ae995b78d diff --git a/manifest.uuid b/manifest.uuid index fd301fc3c9..5abcc58c68 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4461bf045d8eecf98478035efcdba3f41c709bc5 \ No newline at end of file +9ed97a85feee6593faefa2b54cc4cf9a60f515f9 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 769a16565a..ffb5c22b63 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1438,6 +1438,8 @@ static void decodeIntArray( if( z==0 ) z = ""; #else assert( z!=0 ); + pIndex->bUnordered = 0; + pIndex->noSkipScan = 0; #endif for(i=0; *z && ihdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); for(iFrame=pWal->hdr.mxFrame+1; - rc==SQLITE_OK && iFrame<=iMax; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; iFrame++ ){ /* This call cannot fail. Unless the page for which the page number From 42a7b4bac94983bfde72f3779e6ee15bfe847335 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Nov 2014 14:31:12 +0000 Subject: [PATCH 04/24] Completely remove an assert() that had previously been commented out. FossilOrigin-Name: 89b3c1c4555c98c633089b21cdd2a1a3a1e751eb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5976aae2e5..b9bc7630da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sALWAYS\son\san\salways-true\sbranch\sin\swal.c.\nFix\sthe\sANALYZE\scommand\sso\sthat\sit\sresets\sthe\s"unordered"\sand\s"noskipscan"\nflags\son\sindices\swhen\sreloading\sthe\ssqlite_stat1\stable. -D 2014-11-19T14:05:41.209 +C Completely\sremove\san\sassert()\sthat\shad\spreviously\sbeen\scommented\sout. +D 2014-11-19T14:31:12.601 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,7 +291,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 3b627daa45c7308c1e36e3dbaa3f9ce7e5c7fa73 F src/vacuum.c 9b30ec729337dd012ed88d4c292922c8ef9cf00c -F src/vdbe.c 5563459c06c434bc43131044fcf8164654008ebd +F src/vdbe.c 16914136ea1e8b18366868671ddb019159687f47 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78 F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4461bf045d8eecf98478035efcdba3f41c709bc5 -R b83c6fa5464847f6b6472d2244f6f040 +P 9ed97a85feee6593faefa2b54cc4cf9a60f515f9 +R 612c462b22665e254a8e686035c1cd93 U drh -Z cd93530e8709a199e7d3e18ae995b78d +Z cb045903d6d20b681c939d9aa729532d diff --git a/manifest.uuid b/manifest.uuid index 5abcc58c68..7fd5801d3e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ed97a85feee6593faefa2b54cc4cf9a60f515f9 \ No newline at end of file +89b3c1c4555c98c633089b21cdd2a1a3a1e751eb \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f883412943..31b42a32bf 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3808,7 +3808,6 @@ case OP_Found: { /* jump, in3 */ ); if( pIdxKey==0 ) goto no_mem; assert( pIn3->flags & MEM_Blob ); - /* assert( (pIn3->flags & MEM_Zero)==0 ); // zeroblobs already expanded */ ExpandBlob(pIn3); sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); } From 113762a284699ca55192eec1b482d695fcb281e6 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 19 Nov 2014 16:36:25 +0000 Subject: [PATCH 05/24] Add new requirements marks associated with the file format documentation. No changes to code. FossilOrigin-Name: 6d00bcca6ed1903fb17275752cab71c14392355b --- manifest | 18 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 57 +++++++++++++++++++++++++++++++++++++++++++++---- src/expr.c | 5 ++++- src/pager.c | 2 +- src/sqlite.h.in | 6 +++--- 6 files changed, 71 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index b9bc7630da..a251e14322 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Completely\sremove\san\sassert()\sthat\shad\spreviously\sbeen\scommented\sout. -D 2014-11-19T14:31:12.601 +C Add\snew\srequirements\smarks\sassociated\swith\sthe\sfile\sformat\sdocumentation.\nNo\schanges\sto\scode. +D 2014-11-19T16:36:25.272 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c b562da29eb370aaac8015026827c2e2fb70ae990 +F src/btree.c d0a7cfc8788ad028c86020637df70c789615196e F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21 F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8 @@ -182,7 +182,7 @@ F src/complete.c c4ba6e0626bb94bc77a0861735f3382fcf7cc818 F src/ctime.c df19848891c8a553c80e6f5a035e768280952d1a F src/date.c 93594514aae68de117ca4a2a0d6cc63eddf26744 F src/delete.c 0750b1eb4d96cd3fb2c798599a3a7c85e92f1417 -F src/expr.c a3ff05db5709d628c23890db862e30f3dd9dc428 +F src/expr.c 73de4c0da2eed6b149d40a05c589dfeb2c4a87a1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 F src/func.c ba47c1671ab3cfdafa6e9d6ee490939ea578adee @@ -216,7 +216,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fb587121840f690101336879adfa6d0b2cd0e8c7 F src/os_win.c a9e500dd963fb1f67d7860e58b5772abe6123862 F src/os_win.h 09e751b20bbc107ffbd46e13555dc73576d88e21 -F src/pager.c 8d97b3633f098fef817656dcbf167ca904511d78 +F src/pager.c b8764f90c135482988268eec93d7f5cdb89d687a F src/pager.h d1eee3c3f741be247ce6d82752a178515fc8578b F src/parse.y 5dfead8aed90cb0c7c1115898ee2266804daff45 F src/pcache.c ace1b67632deeaa84859b4c16c27711dfb7db3d4 @@ -230,7 +230,7 @@ F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 428165951748151e87a15295b7357221433e311b F src/shell.c bc28d5992109717c87804e2eb1a08a7c8cc7a2fd -F src/sqlite.h.in 0c5c0df7e4e436dfc5592511325bf4a96f6a638d +F src/sqlite.h.in dfbdcd6e52e7652648d8e7634a7c191fcac8e6ce F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h c9e95b8fa9aee30d46387735c5be73fa58886e38 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9ed97a85feee6593faefa2b54cc4cf9a60f515f9 -R 612c462b22665e254a8e686035c1cd93 +P 89b3c1c4555c98c633089b21cdd2a1a3a1e751eb +R 92805b92bb878e3838f25a4f3bef8761 U drh -Z cb045903d6d20b681c939d9aa729532d +Z 529027073b2f32ceeacba058565c65ab diff --git a/manifest.uuid b/manifest.uuid index 7fd5801d3e..cb62723bc8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -89b3c1c4555c98c633089b21cdd2a1a3a1e751eb \ No newline at end of file +6d00bcca6ed1903fb17275752cab71c14392355b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9587e567a3..f61078cac6 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1247,10 +1247,15 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){ 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 || pc=nByte ){ int x = size - nByte; @@ -1314,6 +1319,11 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ top = get2byte(&data[hdr+5]); if( gap>top ){ if( top==0 ){ + /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size + ** and the reserved space is zero (the usual value for reserved space) + ** then the cell content offset of an empty page wants to be 65536. + ** However, that integer is too large to be stored in a 2-byte unsigned + ** integer, so a value of 0 is used in its place. */ top = 65536; }else{ return SQLITE_CORRUPT_BKPT; @@ -1998,6 +2008,9 @@ int sqlite3BtreeOpen( #ifdef SQLITE_SECURE_DELETE pBt->btsFlags |= BTS_SECURE_DELETE; #endif + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16); if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){ @@ -2016,6 +2029,9 @@ int sqlite3BtreeOpen( #endif nReserve = 0; }else{ + /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ nReserve = zDbHeader[20]; pBt->btsFlags |= BTS_PAGESIZE_FIXED; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -2525,6 +2541,9 @@ static int lockBtree(BtShared *pBt){ u32 usableSize; u8 *page1 = pPage1->aData; rc = SQLITE_NOTADB; + /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins + ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d + ** 61 74 20 33 00. */ if( memcmp(page1, zMagicHeader, 16)!=0 ){ goto page1_init_failed; } @@ -2565,15 +2584,21 @@ static int lockBtree(BtShared *pBt){ } #endif - /* The maximum embedded fraction must be exactly 25%. And the minimum - ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data. + /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload + ** fractions and the leaf payload fraction values must be 64, 32, and 32. + ** ** The original design allowed these amounts to vary, but as of ** version 3.6.0, we require them to be fixed. */ if( memcmp(&page1[21], "\100\040\040",3)!=0 ){ goto page1_init_failed; } + /* EVIDENCE-OF: R-51873-39618 The page size for a database file is + ** determined by the 2-byte integer located at an offset of 16 bytes from + ** the beginning of the database file. */ pageSize = (page1[16]<<8) | (page1[17]<<16); + /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two + ** between 512 and 65536 inclusive. */ if( ((pageSize-1)&pageSize)!=0 || pageSize>SQLITE_MAX_PAGE_SIZE || pageSize<=256 @@ -2581,6 +2606,13 @@ static int lockBtree(BtShared *pBt){ goto page1_init_failed; } assert( (pageSize & 7)==0 ); + /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte + ** integer at offset 20 is the number of bytes of space at the end of + ** each page to reserve for extensions. + ** + ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is + ** determined by the one-byte unsigned integer found at an offset of 20 + ** into the database file header. */ usableSize = pageSize - page1[20]; if( (u32)pageSize!=pBt->pageSize ){ /* After reading the first page of the database assuming a page size @@ -2601,6 +2633,9 @@ static int lockBtree(BtShared *pBt){ rc = SQLITE_CORRUPT_BKPT; goto page1_init_failed; } + /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to + ** be less than 480. In other words, if the page size is 512, then the + ** reserved space size cannot exceed 32. */ if( usableSize<480 ){ goto page1_init_failed; } @@ -5178,6 +5213,8 @@ static int allocateBtreePage( assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); pPage1 = pBt->pPage1; mxPage = btreePagecount(pBt); + /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36 + ** stores stores the total number of pages on the freelist. */ n = get4byte(&pPage1->aData[36]); testcase( n==mxPage-1 ); if( n>=mxPage ){ @@ -5224,8 +5261,14 @@ static int allocateBtreePage( do { pPrevTrunk = pTrunk; if( pPrevTrunk ){ + /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page + ** is the page number of the next freelist trunk page in the list or + ** zero if this is the last freelist trunk page. */ iTrunk = get4byte(&pPrevTrunk->aData[0]); }else{ + /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32 + ** stores the page number of the first page of the freelist, or zero if + ** the freelist is empty. */ iTrunk = get4byte(&pPage1->aData[32]); } testcase( iTrunk==mxPage ); @@ -5240,8 +5283,9 @@ static int allocateBtreePage( } assert( pTrunk!=0 ); assert( pTrunk->aData!=0 ); - - k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */ + /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page + ** is the number of leaf page pointers to follow. */ + k = get4byte(&pTrunk->aData[4]); if( k==0 && !searchList ){ /* The trunk has no leaves and the list is not being searched. ** So extract the trunk page itself and use it as the newly @@ -5559,6 +5603,11 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ ** for now. At some point in the future (once everyone has upgraded ** to 3.6.0 or later) we should consider fixing the conditional above ** to read "usableSize/4-2" instead of "usableSize/4-8". + ** + ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still + ** avoid using the last six entries in the freelist trunk page array in + ** order that database files created by newer versions of SQLite can be + ** read by older versions of SQLite. */ rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc==SQLITE_OK ){ diff --git a/src/expr.c b/src/expr.c index 25f0be400f..c28f196221 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3003,7 +3003,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ #ifndef SQLITE_OMIT_FLOATING_POINT /* If the column has REAL affinity, it may currently be stored as an - ** integer. Use OP_RealAffinity to make sure it is really real. */ + ** integer. Use OP_RealAffinity to make sure it is really real. + ** + ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to + ** floating point when extracting it from the record. */ if( pExpr->iColumn>=0 && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL ){ diff --git a/src/pager.c b/src/pager.c index 997f842d0a..e0ede87f07 100644 --- a/src/pager.c +++ b/src/pager.c @@ -2899,7 +2899,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){ ** ** For an encrypted database, the situation is more complex: bytes ** 24..39 of the database are white noise. But the probability of - ** white noising equaling 16 bytes of 0xff is vanishingly small so + ** white noise equaling 16 bytes of 0xff is vanishingly small so ** we should still be ok. */ memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers)); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4427f39d06..a59599a0c5 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4164,9 +4164,9 @@ int sqlite3_create_function_v2( ** These constant define integer codes that represent the various ** text encodings supported by SQLite. */ -#define SQLITE_UTF8 1 -#define SQLITE_UTF16LE 2 -#define SQLITE_UTF16BE 3 +#define SQLITE_UTF8 1 /* IMP: R-37514-35566 */ +#define SQLITE_UTF16LE 2 /* IMP: R-03371-37637 */ +#define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* Deprecated */ #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ From 654858d7f45254f915f0796431699ecc841fdf06 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Nov 2014 02:18:14 +0000 Subject: [PATCH 06/24] Add some requirements marks to the record formatting logic. Comment changes only - the code is unaltered. FossilOrigin-Name: 9a9627e178a67bbfc85366aaea900e674d22fb53 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 9 ++++++++- src/vdbeaux.c | 25 +++++++++++++++++++++++-- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index a251e14322..065eb19989 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\srequirements\smarks\sassociated\swith\sthe\sfile\sformat\sdocumentation.\nNo\schanges\sto\scode. -D 2014-11-19T16:36:25.272 +C Add\ssome\srequirements\smarks\sto\sthe\srecord\sformatting\slogic.\s\sComment\schanges\nonly\s-\sthe\scode\sis\sunaltered. +D 2014-11-20T02:18:14.206 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -291,11 +291,11 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c 3b627daa45c7308c1e36e3dbaa3f9ce7e5c7fa73 F src/vacuum.c 9b30ec729337dd012ed88d4c292922c8ef9cf00c -F src/vdbe.c 16914136ea1e8b18366868671ddb019159687f47 +F src/vdbe.c ec1f55acef4864520ca2017b9f0d60c2ac1b8b78 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78 F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83 -F src/vdbeaux.c 9b0a251b6dfab349dd6c6efb40062eb7386b26f5 +F src/vdbeaux.c e3ae27459a4eb986d2892de2d7f309d18c9971ef F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f F src/vdbesort.c 87f3923483113d1c95d84640becb4e4946f27d9a @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 89b3c1c4555c98c633089b21cdd2a1a3a1e751eb -R 92805b92bb878e3838f25a4f3bef8761 +P 6d00bcca6ed1903fb17275752cab71c14392355b +R b487443c841a5e8e1bfed86b80cd7f65 U drh -Z 529027073b2f32ceeacba058565c65ab +Z bbc37d068b0ef41277590cc500b3cc54 diff --git a/manifest.uuid b/manifest.uuid index cb62723bc8..a704e79b38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6d00bcca6ed1903fb17275752cab71c14392355b \ No newline at end of file +9a9627e178a67bbfc85366aaea900e674d22fb53 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 31b42a32bf..822bf80bb8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2636,7 +2636,10 @@ case OP_MakeRecord: { nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type); }while( (--pRec)>=pData0 ); - /* Add the initial header varint and total the size */ + /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint + ** which determines the total number of bytes in the header. The varint + ** value is the size of the header in bytes including the size varint + ** itself. */ testcase( nHdr==126 ); testcase( nHdr==127 ); if( nHdr<=126 ){ @@ -2670,7 +2673,11 @@ case OP_MakeRecord: { pRec = pData0; do{ serial_type = pRec->uTemp; + /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more + ** additional varints, one per column. */ i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ + /* EVIDENCE-OF: R-64536-51728 The values for each column in the record + ** immediately follow the header. */ j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ }while( (++pRec)<=pLast ); assert( i==nHdr ); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d8ee5c8e8c..145bf453ad 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3051,10 +3051,14 @@ static u32 SQLITE_NOINLINE serialGet( u32 y = FOUR_BYTE_UINT(buf+4); x = (x<<32) + y; if( serial_type==6 ){ + /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit + ** twos-complement integer. */ pMem->u.i = *(i64*)&x; pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); }else{ + /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit + ** floating point number. */ #if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT) /* Verify that integers and floating point values use the same ** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is @@ -3082,35 +3086,46 @@ u32 sqlite3VdbeSerialGet( switch( serial_type ){ case 10: /* Reserved for future use */ case 11: /* Reserved for future use */ - case 0: { /* NULL */ + case 0: { /* Null */ + /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ pMem->flags = MEM_Null; break; } - case 1: { /* 1-byte signed integer */ + case 1: { + /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement + ** integer. */ pMem->u.i = ONE_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); return 1; } case 2: { /* 2-byte signed integer */ + /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit + ** twos-complement integer. */ pMem->u.i = TWO_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); return 2; } case 3: { /* 3-byte signed integer */ + /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit + ** twos-complement integer. */ pMem->u.i = THREE_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); return 3; } case 4: { /* 4-byte signed integer */ + /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit + ** twos-complement integer. */ pMem->u.i = FOUR_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); return 4; } case 5: { /* 6-byte signed integer */ + /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit + ** twos-complement integer. */ pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); @@ -3124,11 +3139,17 @@ u32 sqlite3VdbeSerialGet( } case 8: /* Integer 0 */ case 9: { /* Integer 1 */ + /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */ + /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */ pMem->u.i = serial_type-8; pMem->flags = MEM_Int; return 0; } default: { + /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in + ** length. + ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and + ** (N-13)/2 bytes in length. */ static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; pMem->z = (char *)buf; pMem->n = (serial_type-12)/2; From 1b40e63f9bdf8f51241a0511a7c9bb663fe419ed Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Nov 2014 02:58:10 +0000 Subject: [PATCH 07/24] Fix the encoding of some integers to use the minimum amount of space: -128, -32768, -8388608, -217483648, and -140737488355328. FossilOrigin-Name: 2d7c8da5f16e64eaa7b0c2d66898682ea3d102a0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 065eb19989..fe5a6d1bb4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\srequirements\smarks\sto\sthe\srecord\sformatting\slogic.\s\sComment\schanges\nonly\s-\sthe\scode\sis\sunaltered. -D 2014-11-20T02:18:14.206 +C Fix\sthe\sencoding\sof\ssome\sintegers\sto\suse\sthe\sminimum\samount\sof\sspace:\n-128,\s-32768,\s-8388608,\s-217483648,\sand\s-140737488355328. +D 2014-11-20T02:58:10.344 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -295,7 +295,7 @@ F src/vdbe.c ec1f55acef4864520ca2017b9f0d60c2ac1b8b78 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78 F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83 -F src/vdbeaux.c e3ae27459a4eb986d2892de2d7f309d18c9971ef +F src/vdbeaux.c 5ce4f414147a3bc3cbcf00ec57f2606c25791629 F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f F src/vdbesort.c 87f3923483113d1c95d84640becb4e4946f27d9a @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6d00bcca6ed1903fb17275752cab71c14392355b -R b487443c841a5e8e1bfed86b80cd7f65 +P 9a9627e178a67bbfc85366aaea900e674d22fb53 +R acb3727f628d804856a9646910d389b3 U drh -Z bbc37d068b0ef41277590cc500b3cc54 +Z ae13a50368fe7d7b53b7e4276c8588bd diff --git a/manifest.uuid b/manifest.uuid index a704e79b38..1ae875991f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a9627e178a67bbfc85366aaea900e674d22fb53 \ No newline at end of file +2d7c8da5f16e64eaa7b0c2d66898682ea3d102a0 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 145bf453ad..b8f5bca2c3 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2883,9 +2883,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ i64 i = pMem->u.i; u64 u; if( i<0 ){ - if( i<(-MAX_6BYTE) ) return 6; - /* Previous test prevents: u = -(-9223372036854775808) */ - u = -i; + u = ~i; }else{ u = i; } From fdab02635c2304acc99b04272235463e1ed1ac51 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Nov 2014 15:30:50 +0000 Subject: [PATCH 08/24] Ensure that when the number of cells on a page drops to zero that the freelist and fragment counter are both cleared. Also add evidence marks corresponding to file-format documentation. FossilOrigin-Name: ef9fbc08b0a047042deeb2d6007d67028fefb9e2 --- manifest | 12 +++--- manifest.uuid | 2 +- src/btree.c | 102 ++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 89 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index fe5a6d1bb4..7541704f57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sencoding\sof\ssome\sintegers\sto\suse\sthe\sminimum\samount\sof\sspace:\n-128,\s-32768,\s-8388608,\s-217483648,\sand\s-140737488355328. -D 2014-11-20T02:58:10.344 +C Ensure\sthat\swhen\sthe\snumber\sof\scells\son\sa\spage\sdrops\sto\szero\sthat\sthe\sfreelist\nand\sfragment\scounter\sare\sboth\scleared.\s\sAlso\sadd\sevidence\smarks\scorresponding\nto\sfile-format\sdocumentation. +D 2014-11-20T15:30:50.141 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c d0a7cfc8788ad028c86020637df70c789615196e +F src/btree.c 4db5e06ca2d1a5437be7075251fa702c76179b0e F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21 F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9a9627e178a67bbfc85366aaea900e674d22fb53 -R acb3727f628d804856a9646910d389b3 +P 2d7c8da5f16e64eaa7b0c2d66898682ea3d102a0 +R aa709859c03f6b1c53283cb1512cbe99 U drh -Z ae13a50368fe7d7b53b7e4276c8588bd +Z 12bf55f57cbfdde86aed8c230487a6ad diff --git a/manifest.uuid b/manifest.uuid index 1ae875991f..e8ed272102 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d7c8da5f16e64eaa7b0c2d66898682ea3d102a0 \ No newline at end of file +ef9fbc08b0a047042deeb2d6007d67028fefb9e2 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index f61078cac6..5ae5986cfa 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1139,6 +1139,11 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ ** end of the page and all free space is collected into one ** big FreeBlk that occurs in between the header and cell ** pointer array and the cell content area. +** +** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a +** b-tree page so that there are no freeblocks or fragment bytes, all +** unused bytes are contained in the unallocated space region, and all +** cells are packed tightly at the end of the page. */ static int defragmentPage(MemPage *pPage){ int i; /* Loop counter */ @@ -1262,6 +1267,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){ testcase( x==4 ); testcase( x==3 ); if( x<4 ){ + /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total + ** number of bytes in fragments may not exceed 60. */ if( aData[hdr+7]>=60 ){ if( pbDefrag ) *pbDefrag = 1; return 0; @@ -1316,19 +1323,13 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); gap = pPage->cellOffset + 2*pPage->nCell; assert( gap<=65536 ); - top = get2byte(&data[hdr+5]); - if( gap>top ){ - if( top==0 ){ - /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size - ** and the reserved space is zero (the usual value for reserved space) - ** then the cell content offset of an empty page wants to be 65536. - ** However, that integer is too large to be stored in a 2-byte unsigned - ** integer, so a value of 0 is used in its place. */ - top = 65536; - }else{ - return SQLITE_CORRUPT_BKPT; - } - } + /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size + ** and the reserved space is zero (the usual value for reserved space) + ** then the cell content offset of an empty page wants to be 65536. + ** However, that integer is too large to be stored in a 2-byte unsigned + ** integer, so a value of 0 is used in its place. */ + top = get2byteNotZero(&data[hdr+5]); + if( gap>top ) return SQLITE_CORRUPT_BKPT; /* If there is enough space between gap and top for one more cell pointer ** array entry offset, and if the freelist is not empty, then search the @@ -1497,18 +1498,32 @@ static int decodeFlags(MemPage *pPage, int flagByte){ pPage->childPtrSize = 4-4*pPage->leaf; pBt = pPage->pBt; if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){ + /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior + ** table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY)==5 ); + /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf + ** table b-tree page. */ + assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 ); pPage->intKey = 1; pPage->intKeyLeaf = pPage->leaf; pPage->noPayload = !pPage->leaf; pPage->maxLocal = pBt->maxLeaf; pPage->minLocal = pBt->minLeaf; }else if( flagByte==PTF_ZERODATA ){ + /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior + ** index b-tree page. */ + assert( (PTF_ZERODATA)==2 ); + /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf + ** index b-tree page. */ + assert( (PTF_ZERODATA|PTF_LEAF)==10 ); pPage->intKey = 0; pPage->intKeyLeaf = 0; pPage->noPayload = 0; pPage->maxLocal = pBt->maxLocal; pPage->minLocal = pBt->minLocal; }else{ + /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is + ** an error. */ return SQLITE_CORRUPT_BKPT; } pPage->max1bytePayload = pBt->max1bytePayload; @@ -1548,21 +1563,33 @@ static int btreeInitPage(MemPage *pPage){ hdr = pPage->hdrOffset; data = pPage->aData; + /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating + ** the b-tree page type. */ if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT; assert( pBt->pageSize>=512 && pBt->pageSize<=65536 ); pPage->maskPage = (u16)(pBt->pageSize - 1); pPage->nOverflow = 0; usableSize = pBt->usableSize; - pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf; + pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize; pPage->aDataEnd = &data[usableSize]; pPage->aCellIdx = &data[cellOffset]; + /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates + ** the start of the cell content area. A zero value for this integer is + ** interpreted as 65536. */ top = get2byteNotZero(&data[hdr+5]); + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ pPage->nCell = get2byte(&data[hdr+3]); if( pPage->nCell>MX_CELL(pBt) ){ /* To many cells for a single page. The page must be corrupt */ return SQLITE_CORRUPT_BKPT; } testcase( pPage->nCell==MX_CELL(pBt) ); + /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only + ** possible for a root page of a table that contains no rows) then the + ** offset to the cell content area will equal the page size minus the + ** bytes of reserved space. */ + assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB ); /* A malformed database page might cause us to read past the end ** of page when parsing a cell. @@ -1596,13 +1623,20 @@ static int btreeInitPage(MemPage *pPage){ } #endif - /* Compute the total free space on the page */ + /* Compute the total free space on the page + ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the + ** start of the first freeblock on the page, or is zero if there are no + ** freeblocks. */ pc = get2byte(&data[hdr+1]); - nFree = data[hdr+7] + top; + nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */ while( pc>0 ){ u16 next, size; if( pciCellLast ){ - /* Start of free block is off the page */ + /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will + ** always be at least one cell before the first freeblock. + ** + ** Or, the freeblock is off the end of the page + */ return SQLITE_CORRUPT_BKPT; } next = get2byte(&data[pc]); @@ -5959,9 +5993,17 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ return; } pPage->nCell--; - memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); - put2byte(&data[hdr+3], pPage->nCell); - pPage->nFree += 2; + if( pPage->nCell==0 ){ + memset(&data[hdr+1], 0, 4); + data[hdr+7] = 0; + put2byte(&data[hdr+5], pPage->pBt->usableSize); + pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset + - pPage->childPtrSize - 8; + }else{ + memmove(ptr, ptr+2, 2*(pPage->nCell - idx)); + put2byte(&data[hdr+3], pPage->nCell); + pPage->nFree += 2; + } } /* @@ -8609,8 +8651,14 @@ static int checkTreePage( assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ memset(hit+contentOffset, 0, usableSize-contentOffset); memset(hit, 1, contentOffset); + /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the + ** number of cells on the page. */ nCell = get2byte(&data[hdr+3]); + /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page + ** immediately follows the b-tree page header. */ cellStart = hdr + 12 - 4*pPage->leaf; + /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte + ** integer offsets to the cell contents. */ for(i=0; i=pc; j--) hit[j]++; } } + /* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header + ** is the offset of the first freeblock, or zero if there are no + ** freeblocks on the page. */ i = get2byte(&data[hdr+1]); while( i>0 ){ int size, j; @@ -8633,7 +8684,13 @@ static int checkTreePage( size = get2byte(&data[i+2]); assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */ for(j=i+size-1; j>=i; j--) hit[j]++; + /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a + ** big-endian integer which is the offset in the b-tree page of the next + ** freeblock in the chain, or zero if the freeblock is the last on the + ** chain. */ j = get2byte(&data[i]); + /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of + ** increasing offset. */ assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */ assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */ i = j; @@ -8647,6 +8704,11 @@ static int checkTreePage( break; } } + /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments + ** is stored in the fifth field of the b-tree page header. + ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the + ** number of fragmented free bytes within the cell content area. + */ if( cnt!=data[hdr+7] ){ checkAppendMsg(pCheck, "Fragmentation of %d bytes reported as %d on page %d", From 5e3b49bc42c1a10222571bf433045bb03c7057e9 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Nov 2014 19:22:26 +0000 Subject: [PATCH 09/24] Add requirements marks on the built-in collating functions. FossilOrigin-Name: 4b608b62ac8d4eafdb76192b3b5db272332a4bfd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 19 +++++++++++++++---- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7541704f57..0e5910fc06 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\swhen\sthe\snumber\sof\scells\son\sa\spage\sdrops\sto\szero\sthat\sthe\sfreelist\nand\sfragment\scounter\sare\sboth\scleared.\s\sAlso\sadd\sevidence\smarks\scorresponding\nto\sfile-format\sdocumentation. -D 2014-11-20T15:30:50.141 +C Add\srequirements\smarks\son\sthe\sbuilt-in\scollating\sfunctions. +D 2014-11-20T19:22:26.830 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -195,7 +195,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c 7274c97d24bb46631e504332ccd3bd1b37841770 F src/loadext.c de741e66e5ddc1598d904d7289239696e40ed994 -F src/main.c d3310d5ed56e246bf1589e47eeaca8be582bd4b8 +F src/main.c 54d0f4896cebc61ae5f831937464953780fe5346 F src/malloc.c 740db54387204c9a2eb67c6d98e68b08e9ef4eab F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c faf615aafd8be74a71494dfa027c113ea5c6615f @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2d7c8da5f16e64eaa7b0c2d66898682ea3d102a0 -R aa709859c03f6b1c53283cb1512cbe99 +P ef9fbc08b0a047042deeb2d6007d67028fefb9e2 +R 87fc16da633f081b9c3d6138857b30da U drh -Z 12bf55f57cbfdde86aed8c230487a6ad +Z 4f4a01f4cbeff0ca684ca414f4595d57 diff --git a/manifest.uuid b/manifest.uuid index e8ed272102..de14eeaf45 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef9fbc08b0a047042deeb2d6007d67028fefb9e2 \ No newline at end of file +4b608b62ac8d4eafdb76192b3b5db272332a4bfd \ No newline at end of file diff --git a/src/main.c b/src/main.c index f223b71f74..1d34b13d6f 100644 --- a/src/main.c +++ b/src/main.c @@ -773,13 +773,20 @@ static int binCollFunc( ){ int rc, n; n = nKey1mallocFailed ){ goto opendb_out; } + /* EVIDENCE-OF: R-08308-17224 The default collating function for all + ** strings is BINARY. + */ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0); assert( db->pDfltColl!=0 ); - /* Also add a UTF-8 case-insensitive collation sequence. */ - createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); - /* Parse the filename/URI argument. */ db->openFlags = flags; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); From 341eca7f68e2ad7a6102c98342c23ddaf65f3c89 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Nov 2014 23:03:42 +0000 Subject: [PATCH 10/24] Updates to requirements tags on the mutex documentation. FossilOrigin-Name: fcf8b7e4c6c3893e2004a28dc9f0f677907b4ba9 --- manifest | 12 ++++---- manifest.uuid | 2 +- src/sqlite.h.in | 80 +++++++++++++++++++++++-------------------------- 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/manifest b/manifest index 0e5910fc06..3b9c283125 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\srequirements\smarks\son\sthe\sbuilt-in\scollating\sfunctions. -D 2014-11-20T19:22:26.830 +C Updates\sto\srequirements\stags\son\sthe\smutex\sdocumentation. +D 2014-11-20T23:03:42.154 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -230,7 +230,7 @@ F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 428165951748151e87a15295b7357221433e311b F src/shell.c bc28d5992109717c87804e2eb1a08a7c8cc7a2fd -F src/sqlite.h.in dfbdcd6e52e7652648d8e7634a7c191fcac8e6ce +F src/sqlite.h.in c63db0117aeb749ca02b6016dbbbccbbbd9a141d F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d F src/sqliteInt.h c9e95b8fa9aee30d46387735c5be73fa58886e38 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ef9fbc08b0a047042deeb2d6007d67028fefb9e2 -R 87fc16da633f081b9c3d6138857b30da +P 4b608b62ac8d4eafdb76192b3b5db272332a4bfd +R b10e3d696841d651117121c42237df0a U drh -Z 4f4a01f4cbeff0ca684ca414f4595d57 +Z 5d29b887364b9011d92605ad266bc7f8 diff --git a/manifest.uuid b/manifest.uuid index de14eeaf45..fb1afe2201 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b608b62ac8d4eafdb76192b3b5db272332a4bfd \ No newline at end of file +fcf8b7e4c6c3893e2004a28dc9f0f677907b4ba9 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index a59599a0c5..f1b917c308 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5900,34 +5900,34 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** The SQLite source code contains multiple implementations ** of these mutex routines. An appropriate implementation -** is selected automatically at compile-time. ^(The following +** is selected automatically at compile-time. The following ** implementations are available in the SQLite core: ** **
    **
  • SQLITE_MUTEX_PTHREADS **
  • SQLITE_MUTEX_W32 **
  • SQLITE_MUTEX_NOOP -**
)^ +** ** -** ^The SQLITE_MUTEX_NOOP implementation is a set of routines +** The SQLITE_MUTEX_NOOP implementation is a set of routines ** that does no real locking and is appropriate for use in -** a single-threaded application. ^The SQLITE_MUTEX_PTHREADS and +** a single-threaded application. The SQLITE_MUTEX_PTHREADS and ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix ** and Windows. ** -** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor +** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex ** implementation is included with the library. In this case the ** application must supply a custom mutex implementation using the ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function ** before calling sqlite3_initialize() or any other public sqlite3_ -** function that calls sqlite3_initialize().)^ +** function that calls sqlite3_initialize(). ** ** ^The sqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. ^If it returns NULL -** that means that a mutex could not be allocated. ^SQLite -** will unwind its stack and return an error. ^(The argument -** to sqlite3_mutex_alloc() is one of these integer constants: +** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() +** routine returns NULL if it is unable to allocate the requested +** mutex. The argument to sqlite3_mutex_alloc() must one of these +** integer constants: ** **
    **
  • SQLITE_MUTEX_FAST @@ -5940,7 +5940,8 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); **
  • SQLITE_MUTEX_STATIC_PMEM **
  • SQLITE_MUTEX_STATIC_APP1 **
  • SQLITE_MUTEX_STATIC_APP2 -**
)^ +**
  • SQLITE_MUTEX_STATIC_APP3 +** ** ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) ** cause sqlite3_mutex_alloc() to create @@ -5948,14 +5949,14 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. ** The mutex implementation does not need to make a distinction ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does -** not want to. ^SQLite will only request a recursive mutex in -** cases where it really needs one. ^If a faster non-recursive mutex +** not want to. SQLite will only request a recursive mutex in +** cases where it really needs one. If a faster non-recursive mutex ** implementation is available on the host platform, the mutex subsystem ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other ** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return -** a pointer to a static preexisting mutex. ^Six static mutexes are +** a pointer to a static preexisting mutex. ^Nine static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal ** use by SQLite only. Applications that use SQLite mutexes should @@ -5964,16 +5965,13 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. ^But for the static +** returns a different mutex on every call. ^For the static ** mutex types, the same mutex is returned on every call that has ** the same type number. ** ** ^The sqlite3_mutex_free() routine deallocates a previously -** allocated dynamic mutex. ^SQLite is careful to deallocate every -** dynamic mutex that it allocates. The dynamic mutexes must not be in -** use when they are deallocated. Attempting to deallocate a static -** mutex results in undefined behavior. ^SQLite never deallocates -** a static mutex. +** allocated dynamic mutex. Attempting to deallocate a static +** mutex results in undefined behavior. ** ** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt ** to enter a mutex. ^If another thread is already within the mutex, @@ -5981,23 +5979,21 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] ** upon successful entry. ^(Mutexes created using ** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. -** In such cases the, +** In such cases, the ** mutex must be exited an equal number of times before another thread -** can enter.)^ ^(If the same thread tries to enter any other -** kind of mutex more than once, the behavior is undefined. -** SQLite will never exhibit -** such behavior in its own use of mutexes.)^ +** can enter.)^ If the same thread tries to enter any mutex other +** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined. ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^ +** will always return SQLITE_BUSY. The SQLite core only ever uses +** sqlite3_mutex_try() as an optimization so this is acceptable +** behavior.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was -** previously entered by the same thread. ^(The behavior +** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered by the -** calling thread or is not currently allocated. SQLite will -** never do either.)^ +** calling thread or is not currently allocated. ** ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or ** sqlite3_mutex_leave() is a NULL pointer, then all three routines @@ -6018,9 +6014,9 @@ void sqlite3_mutex_leave(sqlite3_mutex*); ** used to allocate and use mutexes. ** ** Usually, the default mutex implementations provided by SQLite are -** sufficient, however the user has the option of substituting a custom +** sufficient, however the application has the option of substituting a custom ** implementation for specialized deployments or systems for which SQLite -** does not provide a suitable implementation. In this case, the user +** does not provide a suitable implementation. In this case, the application ** creates and populates an instance of this structure to pass ** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. ** Additionally, an instance of this structure can be used as an @@ -6061,13 +6057,13 @@ void sqlite3_mutex_leave(sqlite3_mutex*); ** (i.e. it is acceptable to provide an implementation that segfaults if ** it is passed a NULL pointer). ** -** The xMutexInit() method must be threadsafe. ^It must be harmless to +** The xMutexInit() method must be threadsafe. It must be harmless to ** invoke xMutexInit() multiple times within the same process and without ** intervening calls to xMutexEnd(). Second and subsequent calls to ** xMutexInit() must be no-ops. ** -** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] -** and its associates). ^Similarly, xMutexAlloc() must not use SQLite memory +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). Similarly, xMutexAlloc() must not use SQLite memory ** allocation for a static mutex. ^However xMutexAlloc() may use SQLite ** memory allocation for a fast or recursive mutex. ** @@ -6093,29 +6089,29 @@ struct sqlite3_mutex_methods { ** CAPI3REF: Mutex Verification Routines ** ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines -** are intended for use inside assert() statements. ^The SQLite core +** are intended for use inside assert() statements. The SQLite core ** never uses these routines except inside an assert() and applications -** are advised to follow the lead of the core. ^The SQLite core only +** are advised to follow the lead of the core. The SQLite core only ** provides implementations for these routines when it is compiled -** with the SQLITE_DEBUG flag. ^External mutex implementations +** with the SQLITE_DEBUG flag. External mutex implementations ** are only required to provide these routines if SQLITE_DEBUG is ** defined and if NDEBUG is not defined. ** -** ^These routines should return true if the mutex in their argument +** These routines should return true if the mutex in their argument ** is held or not held, respectively, by the calling thread. ** -** ^The implementation is not required to provide versions of these +** The implementation is not required to provide versions of these ** routines that actually work. If the implementation does not provide working ** versions of these routines, it should at least provide stubs that always ** return true so that one does not get spurious assertion failures. ** -** ^If the argument to sqlite3_mutex_held() is a NULL pointer then +** If the argument to sqlite3_mutex_held() is a NULL pointer then ** the routine should return 1. This seems counter-intuitive since ** clearly the mutex cannot be held if it does not exist. But ** the reason the mutex does not exist is because the build is not ** using mutexes. And we do not want the assert() containing the ** call to sqlite3_mutex_held() to fail, so a non-zero return is -** the appropriate thing to do. ^The sqlite3_mutex_notheld() +** the appropriate thing to do. The sqlite3_mutex_notheld() ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG From 2d8233157da0be2fa529b14c4f625f3c15ec38af Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Nov 2014 23:11:30 +0000 Subject: [PATCH 11/24] Fix a benign test error on PRAGMA collation_list introduced by a recent checkin. FossilOrigin-Name: 332cc9591d05508ac9cb56fde2b82e20e0342d1f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/pragma.test | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3b9c283125..3641e5837e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\srequirements\stags\son\sthe\smutex\sdocumentation. -D 2014-11-20T23:03:42.154 +C Fix\sa\sbenign\stest\serror\son\sPRAGMA\scollation_list\nintroduced\sby\sa\srecent\scheckin. +D 2014-11-20T23:11:30.405 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -777,7 +777,7 @@ F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54 F test/permutations.test cef25f5e8499a15846eccd06785f17f4180407ab -F test/pragma.test 19d0241a007bcdd77fc2606ec60fc60357e7fc8b +F test/pragma.test 49ac8a73c0daa574824538fed28727d1259fe735 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/printf2.test b4acd4bf8734243257f01ddefa17c4fb090acc8a @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4b608b62ac8d4eafdb76192b3b5db272332a4bfd -R b10e3d696841d651117121c42237df0a +P fcf8b7e4c6c3893e2004a28dc9f0f677907b4ba9 +R 97435df5b02a85b2d9795aaf4e4e7c6e U drh -Z 5d29b887364b9011d92605ad266bc7f8 +Z ee8d2a1291f4df2e216b5b6437eb1599 diff --git a/manifest.uuid b/manifest.uuid index fb1afe2201..aa16af69b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fcf8b7e4c6c3893e2004a28dc9f0f677907b4ba9 \ No newline at end of file +332cc9591d05508ac9cb56fde2b82e20e0342d1f \ No newline at end of file diff --git a/test/pragma.test b/test/pragma.test index 539d867366..e660ab0fe7 100644 --- a/test/pragma.test +++ b/test/pragma.test @@ -1190,13 +1190,13 @@ ifcapable schema_pragmas { execsql2 { pragma collation_list; } - } {seq 0 name NOCASE seq 1 name RTRIM seq 2 name BINARY} + } {seq 0 name RTRIM seq 1 name NOCASE seq 2 name BINARY} do_test pragma-11.2 { db collate New_Collation blah... execsql { pragma collation_list; } - } {0 New_Collation 1 NOCASE 2 RTRIM 3 BINARY} + } {0 New_Collation 1 RTRIM 2 NOCASE 3 BINARY} } ifcapable schema_pragmas&&tempdb { From 643091f07104b3dd2e3793286ddb1f1b5eb99f87 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 20 Nov 2014 23:21:23 +0000 Subject: [PATCH 12/24] Fix a typo in a requirements mark on the abs() SQL function. FossilOrigin-Name: b1e6c02f8b9a2afaa12ac15a33e3f698c3be27d6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3641e5837e..3722a0fbac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbenign\stest\serror\son\sPRAGMA\scollation_list\nintroduced\sby\sa\srecent\scheckin. -D 2014-11-20T23:11:30.405 +C Fix\sa\stypo\sin\sa\srequirements\smark\son\sthe\sabs()\sSQL\sfunction. +D 2014-11-20T23:21:23.554 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -185,7 +185,7 @@ F src/delete.c 0750b1eb4d96cd3fb2c798599a3a7c85e92f1417 F src/expr.c 73de4c0da2eed6b149d40a05c589dfeb2c4a87a1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c da985ae673efef2c712caef825a5d2edb087ead7 -F src/func.c ba47c1671ab3cfdafa6e9d6ee490939ea578adee +F src/func.c 6d3c4ebd72aa7923ce9b110a7dc15f9b8c548430 F src/global.c 6ded36dda9466fc1c9a3c5492ded81d79bf3977d F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fcf8b7e4c6c3893e2004a28dc9f0f677907b4ba9 -R 97435df5b02a85b2d9795aaf4e4e7c6e +P 332cc9591d05508ac9cb56fde2b82e20e0342d1f +R 5693b17271f5aafc5aa0ee222d419f56 U drh -Z ee8d2a1291f4df2e216b5b6437eb1599 +Z 26e3a9a90b782d10bf5cba52cec231a6 diff --git a/manifest.uuid b/manifest.uuid index aa16af69b0..2d35c62379 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -332cc9591d05508ac9cb56fde2b82e20e0342d1f \ No newline at end of file +b1e6c02f8b9a2afaa12ac15a33e3f698c3be27d6 \ No newline at end of file diff --git a/src/func.c b/src/func.c index cf556e2439..a057993413 100644 --- a/src/func.c +++ b/src/func.c @@ -157,8 +157,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ default: { /* Because sqlite3_value_double() returns 0.0 if the argument is not ** something that can be converted into a number, we have: - ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that - ** cannot be converted to a numeric value. + ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob + ** that cannot be converted to a numeric value. */ double rVal = sqlite3_value_double(argv[0]); if( rVal<0 ) rVal = -rVal; From a3898250d4584338fc1f4df6d5af28c2acbd33df Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 22 Nov 2014 12:22:13 +0000 Subject: [PATCH 13/24] Remove a redundant test case (probably a copy/paste error). Add an assert() to where.c to ensure that automatic indexes do not have there output row counts adjusted downward by supplementary constraints. FossilOrigin-Name: eea47933493c85a85247ad383bd148b06f627d04 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 1 + test/autoindex2.test | 44 -------------------------------------------- 4 files changed, 9 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index 3722a0fbac..1536469c11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\srequirements\smark\son\sthe\sabs()\sSQL\sfunction. -D 2014-11-20T23:21:23.554 +C Remove\sa\sredundant\stest\scase\s(probably\sa\scopy/paste\serror).\s\sAdd\san\sassert()\nto\swhere.c\sto\sensure\sthat\sautomatic\sindexes\sdo\snot\shave\sthere\soutput\srow\s\ncounts\sadjusted\sdownward\sby\ssupplementary\sconstraints. +D 2014-11-22T12:22:13.640 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -304,7 +304,7 @@ F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c e275cb74731a3351a9da6ba8280bd5054db6192d +F src/where.c 13a9920431358fc4885b31fe13a893d98f813a74 F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -346,7 +346,7 @@ F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7 F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 F test/autoindex1.test 6ff78b94f43a59616c06c11c55b12935173506d7 -F test/autoindex2.test 60d2fc6f38364308ce73a9beb01b47ded38697de +F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8 F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 F test/autoindex4.test fc807f9efd158bec60f5dfdf34ebe46fb274612d F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 332cc9591d05508ac9cb56fde2b82e20e0342d1f -R 5693b17271f5aafc5aa0ee222d419f56 +P b1e6c02f8b9a2afaa12ac15a33e3f698c3be27d6 +R e5e0eb3b1af9c334c014cb61507da7b4 U drh -Z 26e3a9a90b782d10bf5cba52cec231a6 +Z 8955433275197ef8c0924c06e567755e diff --git a/manifest.uuid b/manifest.uuid index 2d35c62379..070039fabe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1e6c02f8b9a2afaa12ac15a33e3f698c3be27d6 \ No newline at end of file +eea47933493c85a85247ad383bd148b06f627d04 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8c9ce38889..6dd47816c3 100644 --- a/src/where.c +++ b/src/where.c @@ -4306,6 +4306,7 @@ static void whereLoopOutputAdjust( int i, j; int nEq = 0; /* Number of = constraints not within likely()/unlikely() */ + assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; diff --git a/test/autoindex2.test b/test/autoindex2.test index f4da416745..c8abdf410a 100644 --- a/test/autoindex2.test +++ b/test/autoindex2.test @@ -224,48 +224,4 @@ do_execsql_test autoindex2-120 { # on t3 and reordering the tables so that t3 was in the outer loop and # implementing the ORDER BY clause using a B-Tree. -do_execsql_test autoindex2-120 { - EXPLAIN QUERY PLAN - SELECT - t1_id, - t1.did, - param2, - param3, - t1.ptime, - t1.trange, - t1.exmass, - t1.mass, - t1.vstatus, - type, - subtype, - t1.deviation, - t1.formula, - dparam1, - reserve1, - reserve2, - param4, - t1.last_operation, - t1.admin_uuid, - t1.previous_value, - t1.job_id, - client_did, - t1.last_t1, - t1.data_t1, - t1.previous_date, - param5, - param6, - mgr_uuid - FROM - t3, - t2, - t1 - WHERE - t1.ptime > 1393520400 - AND param3<>9001 - AND t3.flg7 = 1 - AND t1.did = t2.did - AND t2.uid = t3.uid - ORDER BY t1.ptime desc LIMIT 500; -} {0 0 2 {SEARCH TABLE t1 USING INDEX t1x1 (ptime>?)} 0 1 1 {SEARCH TABLE t2 USING INDEX t2x0 (did=?)} 0 2 0 {SEARCH TABLE t3 USING INDEX t3x0 (uid=?)}} - finish_test From 7a1bca7e74806e2820ca2f9421e660c191b3a05d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 22 Nov 2014 18:50:44 +0000 Subject: [PATCH 14/24] Deploy heuristics (well-commented) to better estimate how much unindexed terms in the WHERE clause filter the number of output rows from a single table. FossilOrigin-Name: 221659945c3f78d3b6789bfe8fdeb8d3ee1fa038 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/where.c | 52 +++++++++++++++++++++++++++++++++----------- test/scanstatus.test | 2 +- 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 1536469c11..ab39af5891 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sredundant\stest\scase\s(probably\sa\scopy/paste\serror).\s\sAdd\san\sassert()\nto\swhere.c\sto\sensure\sthat\sautomatic\sindexes\sdo\snot\shave\sthere\soutput\srow\s\ncounts\sadjusted\sdownward\sby\ssupplementary\sconstraints. -D 2014-11-22T12:22:13.640 +C Deploy\sheuristics\s(well-commented)\sto\sbetter\sestimate\show\smuch\sunindexed\sterms\nin\sthe\sWHERE\sclause\sfilter\sthe\snumber\sof\soutput\srows\sfrom\sa\ssingle\stable. +D 2014-11-22T18:50:44.269 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -304,7 +304,7 @@ F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 13a9920431358fc4885b31fe13a893d98f813a74 +F src/where.c 33285024c5d96a17901e1beb04798cd8c15d00ae F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -811,7 +811,7 @@ F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3 -F test/scanstatus.test a6dd739bc4d9638e8f5c2493b518057f2b681655 +F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b1e6c02f8b9a2afaa12ac15a33e3f698c3be27d6 -R e5e0eb3b1af9c334c014cb61507da7b4 +P eea47933493c85a85247ad383bd148b06f627d04 +R c99efa7eb98e96584d3723ffcac72bfb U drh -Z 8955433275197ef8c0924c06e567755e +Z ec1ff7ab563a777168df83432a271a84 diff --git a/manifest.uuid b/manifest.uuid index 070039fabe..e47defa2d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eea47933493c85a85247ad383bd148b06f627d04 \ No newline at end of file +221659945c3f78d3b6789bfe8fdeb8d3ee1fa038 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 6dd47816c3..05663ce472 100644 --- a/src/where.c +++ b/src/where.c @@ -4291,10 +4291,30 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** Adjust the WhereLoop.nOut value downward to account for terms of the ** WHERE clause that reference the loop but which are not used by an ** index. +* +** For every WHERE clause term that is not used by the index +** and which has a truth probability assigned by one of the likelihood(), +** likely(), or unlikely() SQL functions, reduce the estimated number +** of output rows by the probability specified. ** -** In the current implementation, the first extra WHERE clause term reduces -** the number of output rows by a factor of 10 and each additional term -** reduces the number of output rows by sqrt(2). +** TUNING: For every WHERE clause term that is not used by the index +** and which does not have an assigned truth probability, heuristics +** described below are used to try to estimate the truth probability. +** TODO --> Perhaps this is something that could be improved by better +** table statistics. +** +** Heuristic 1: Estimate the truth probability as 6.25%. The 6.25% +** value corresponds to 1 in LogEst notation, so this means decrement +** the WhereLoop.nOut field for every such WHERE clause term. +** +** Heuristic 2: If there exists one or more WHERE clause terms of the +** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the +** final output row estimate is no greater than 1/4 of the total number +** of rows in the table. In other words, assume that x==EXPR will filter +** out at least 3 out of 4 rows. If EXPR is -1 or 0 or 1, then maybe the +** "x" column is boolean or else -1 or 0 or 1 is a common default value +** on the "x" column and so in that case only cap the output row estimate +** at 1/2 instead of 1/4. */ static void whereLoopOutputAdjust( WhereClause *pWC, /* The WHERE clause */ @@ -4303,8 +4323,8 @@ static void whereLoopOutputAdjust( ){ WhereTerm *pTerm, *pX; Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf); - int i, j; - int nEq = 0; /* Number of = constraints not within likely()/unlikely() */ + int i, j, k; + LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ @@ -4319,20 +4339,26 @@ static void whereLoopOutputAdjust( } if( j<0 ){ if( pTerm->truthProb<=0 ){ + /* If a truth probability is specified using the likelihood() hints, + ** then use the probability provided by the application. */ pLoop->nOut += pTerm->truthProb; }else{ + /* In the absence of explicit truth probabilities, use heuristics to + ** guess a reasonable truth probability. */ pLoop->nOut--; - if( pTerm->eOperator&WO_EQ ) nEq++; + if( pTerm->eOperator&WO_EQ ){ + Expr *pRight = pTerm->pExpr->pRight; + if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ + k = 10; + }else{ + k = 20; + } + if( iReducenOut>nRow-10 ){ - pLoop->nOut = nRow - 10; - } + if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce; } /* diff --git a/test/scanstatus.test b/test/scanstatus.test index 7713bae5fc..ed24d97437 100644 --- a/test/scanstatus.test +++ b/test/scanstatus.test @@ -268,7 +268,7 @@ do_scanstatus_test 4.2.2 { nLoop 1 nVisit 1 nEst 1.0 zName sqlite_autoindex_p1_1 zExplain {SEARCH TABLE p1 USING INDEX sqlite_autoindex_p1_1 (x=?)} - nLoop 1 nVisit 3 nEst 524288.0 zName c1 zExplain {SCAN TABLE c1} + nLoop 1 nVisit 3 nEst 262144.0 zName c1 zExplain {SCAN TABLE c1} } #------------------------------------------------------------------------- From ab4624d0058253670ffda8429840d5bf1c3d983d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 22 Nov 2014 19:52:10 +0000 Subject: [PATCH 15/24] Fix an error in the comments from the previous check-in. FossilOrigin-Name: 9660ce541837ccd8df415641a922274e093056aa --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ab39af5891..cb3e8bd605 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Deploy\sheuristics\s(well-commented)\sto\sbetter\sestimate\show\smuch\sunindexed\sterms\nin\sthe\sWHERE\sclause\sfilter\sthe\snumber\sof\soutput\srows\sfrom\sa\ssingle\stable. -D 2014-11-22T18:50:44.269 +C Fix\san\serror\sin\sthe\scomments\sfrom\sthe\sprevious\scheck-in. +D 2014-11-22T19:52:10.008 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -304,7 +304,7 @@ F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c 33285024c5d96a17901e1beb04798cd8c15d00ae +F src/where.c a0b16f9d78321cb340a977287d19f826555c7d3b F src/whereInt.h d3633e9b592103241b74b0ec76185f3e5b8b62e0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P eea47933493c85a85247ad383bd148b06f627d04 -R c99efa7eb98e96584d3723ffcac72bfb +P 221659945c3f78d3b6789bfe8fdeb8d3ee1fa038 +R e42483f1b7bc821fcaab0f4c56777390 U drh -Z ec1ff7ab563a777168df83432a271a84 +Z edb3988f151b88d75256a46f70366322 diff --git a/manifest.uuid b/manifest.uuid index e47defa2d3..ba985640bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -221659945c3f78d3b6789bfe8fdeb8d3ee1fa038 \ No newline at end of file +9660ce541837ccd8df415641a922274e093056aa \ No newline at end of file diff --git a/src/where.c b/src/where.c index 05663ce472..277c8833e8 100644 --- a/src/where.c +++ b/src/where.c @@ -4303,8 +4303,8 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** TODO --> Perhaps this is something that could be improved by better ** table statistics. ** -** Heuristic 1: Estimate the truth probability as 6.25%. The 6.25% -** value corresponds to 1 in LogEst notation, so this means decrement +** Heuristic 1: Estimate the truth probability as 93.75%. The 93.75% +** value corresponds to -1 in LogEst notation, so this means decrement ** the WhereLoop.nOut field for every such WHERE clause term. ** ** Heuristic 2: If there exists one or more WHERE clause terms of the From 0da10d32897a5d98ab237cf5efc9dd9ad004600b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 22 Nov 2014 21:37:00 +0000 Subject: [PATCH 16/24] Always reinitialized the Index.bUnordered and Index.noSkipscan flags before rereading the sqlite_stat1 table, even if SQLITE_ENABLE_STAT4 is defined. FossilOrigin-Name: 1e1221fc4823a6bb6fc5d2408732e27aca585de9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 35 ++++++++++++++++++----------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index cb3e8bd605..125cecdf0c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\sin\sthe\scomments\sfrom\sthe\sprevious\scheck-in. -D 2014-11-22T19:52:10.008 +C Always\sreinitialized\sthe\sIndex.bUnordered\sand\sIndex.noSkipscan\sflags\sbefore\nrereading\sthe\ssqlite_stat1\stable,\seven\sif\sSQLITE_ENABLE_STAT4\sis\sdefined. +D 2014-11-22T21:37:00.608 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c ba266a779bc7ce10e52e59e7d3dc79fa342e8fdb -F src/analyze.c c59f238a39aacece176f8bb7dfece40deb268ee5 +F src/analyze.c f7d774356ba5a14e7ad4fb637681af16875ad88f F src/attach.c f4e94df2d1826feda65eb0939f7f6f5f923a0ad9 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea @@ -1221,7 +1221,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 221659945c3f78d3b6789bfe8fdeb8d3ee1fa038 -R e42483f1b7bc821fcaab0f4c56777390 +P 9660ce541837ccd8df415641a922274e093056aa +R b51cb063fe9c06786b358d55d58b3f87 U drh -Z edb3988f151b88d75256a46f70366322 +Z 1318c316d07e28b9d1759e5cafc8a50c diff --git a/manifest.uuid b/manifest.uuid index ba985640bb..47b33e7181 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9660ce541837ccd8df415641a922274e093056aa \ No newline at end of file +1e1221fc4823a6bb6fc5d2408732e27aca585de9 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index ffb5c22b63..01c2f12952 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1438,8 +1438,6 @@ static void decodeIntArray( if( z==0 ) z = ""; #else assert( z!=0 ); - pIndex->bUnordered = 0; - pIndex->noSkipScan = 0; #endif for(i=0; *z && ibUnordered = 1; - }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ - pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); - }else if( sqlite3_strglob("noskipscan*", z)==0 ){ - pIndex->noSkipScan = 1; - } + pIndex->bUnordered = 0; + pIndex->noSkipScan = 0; + while( z[0] ){ + if( sqlite3_strglob("unordered*", z)==0 ){ + pIndex->bUnordered = 1; + }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ + pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); + }else if( sqlite3_strglob("noskipscan*", z)==0 ){ + pIndex->noSkipScan = 1; + } #ifdef SQLITE_ENABLE_COSTMULT - else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ - pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); - } + else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ + pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); + } #endif - while( z[0]!=0 && z[0]!=' ' ) z++; - while( z[0]==' ' ) z++; + while( z[0]!=0 && z[0]!=' ' ) z++; + while( z[0]==' ' ) z++; + } } } From 0a79238b3925a2c94539379d7fe996425d7e589b Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 25 Nov 2014 18:59:55 +0000 Subject: [PATCH 17/24] Fix an integer overflow bug in vdbesort.c. FossilOrigin-Name: 623827192532f08b68bc0eb9ed1449e173361f0c --- manifest | 17 +++++++++-------- manifest.uuid | 2 +- src/vdbesort.c | 9 ++++++++- test/bigsort.test | 43 ++++++++++++++++++++++++++++++++++++++++++ test/permutations.test | 1 + 5 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 test/bigsort.test diff --git a/manifest b/manifest index 125cecdf0c..61c47f746e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\sreinitialized\sthe\sIndex.bUnordered\sand\sIndex.noSkipscan\sflags\sbefore\nrereading\sthe\ssqlite_stat1\stable,\seven\sif\sSQLITE_ENABLE_STAT4\sis\sdefined. -D 2014-11-22T21:37:00.608 +C Fix\san\sinteger\soverflow\sbug\sin\svdbesort.c. +D 2014-11-25T18:59:55.761 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -298,7 +298,7 @@ F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83 F src/vdbeaux.c 5ce4f414147a3bc3cbcf00ec57f2606c25791629 F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f -F src/vdbesort.c 87f3923483113d1c95d84640becb4e4946f27d9a +F src/vdbesort.c 42c166f7ca78cb643c7f4e4bdfa83c59d363d1a6 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405 @@ -366,6 +366,7 @@ F test/between.test 34d375fb5ce1ae283ffe82b6b233e9f38e84fc6c F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 +F test/bigsort.test 835478d0ce83bd1e5b05c90571dedd9871a09196 F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0 F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142 @@ -776,7 +777,7 @@ F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54 -F test/permutations.test cef25f5e8499a15846eccd06785f17f4180407ab +F test/permutations.test 4e12d43f4639ea8a0e366d9c64e0009afe2eb544 F test/pragma.test 49ac8a73c0daa574824538fed28727d1259fe735 F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 @@ -1221,7 +1222,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9660ce541837ccd8df415641a922274e093056aa -R b51cb063fe9c06786b358d55d58b3f87 -U drh -Z 1318c316d07e28b9d1759e5cafc8a50c +P 1e1221fc4823a6bb6fc5d2408732e27aca585de9 +R d9420ee27960cebcc5a5d23852d1a5da +U dan +Z 0b92bbab30b87a9f1cf79fdddb96f8d5 diff --git a/manifest.uuid b/manifest.uuid index 47b33e7181..03036e1aff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e1221fc4823a6bb6fc5d2408732e27aca585de9 \ No newline at end of file +623827192532f08b68bc0eb9ed1449e173361f0c \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index df8357a57e..7c736adefe 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -147,6 +147,13 @@ # define SQLITE_DEBUG_SORTER_THREADS 1 #endif +/* +** Hard-coded maximum amount of data to accumulate in memory before flushing +** to a level 0 PMA. The purpose of this limit is to prevent various integer +** overflows. 512MiB. +*/ +#define SQLITE_MAX_MXPMASIZE (1<<29) + /* ** Private objects used by the sorter */ @@ -845,7 +852,7 @@ int sqlite3VdbeSorterInit( pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz; mxCache = db->aDb[0].pSchema->cache_size; if( mxCachemxPmaSize = mxCache * pgsz; + pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE); /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary diff --git a/test/bigsort.test b/test/bigsort.test new file mode 100644 index 0000000000..259adc3747 --- /dev/null +++ b/test/bigsort.test @@ -0,0 +1,43 @@ +# 2014 November 26 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bigsort + +#-------------------------------------------------------------------- +# At one point there was an overflow problem if the product of the +# cache-size and page-size was larger than 2^31. Causing an infinite +# loop if the product was also an integer multiple of 2^32, or +# inefficiency otherwise. +# +do_execsql_test 1.0 { + PRAGMA page_size = 1024; + CREATE TABLE t1(a, b); + BEGIN; + WITH data(x,y) AS ( + SELECT 1, zeroblob(10000) + UNION ALL + SELECT x+1, y FROM data WHERE x < 300000 + ) + INSERT INTO t1 SELECT * FROM data; + COMMIT; +} +do_execsql_test 1.1 { + PRAGMA cache_size = 4194304; + CREATE INDEX i1 ON t1(a, b); +} + + +finish_test + + diff --git a/test/permutations.test b/test/permutations.test index 54239cc759..ff61bf644b 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -113,6 +113,7 @@ set allquicktests [test_set $alltests -exclude { vtab_err.test walslow.test walcrash.test walcrash3.test walthread.test rtree3.test indexfault.test securedel2.test sort3.test sort4.test fts4growth.test fts4growth2.test + bigsort.test }] if {[info exists ::env(QUICKTEST_INCLUDE)]} { set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)] From 5ab63775ddb052353c3d1c0774865be3f201bf67 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Nov 2014 03:46:04 +0000 Subject: [PATCH 18/24] Fix a problem in the new b-tree balancer that was causing corruption of the fragmentation count. FossilOrigin-Name: f242394e079dd185aad90f2aee902a5edf27e150 --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/btree.c | 13 +++++++++++-- test/btree01.test | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 test/btree01.test diff --git a/manifest b/manifest index 61c47f746e..21c1471b6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sinteger\soverflow\sbug\sin\svdbesort.c. -D 2014-11-25T18:59:55.761 +C Fix\sa\sproblem\sin\sthe\snew\sb-tree\sbalancer\sthat\swas\scausing\scorruption\sof\nthe\sfragmentation\scount. +D 2014-11-27T03:46:04.203 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c 4db5e06ca2d1a5437be7075251fa702c76179b0e +F src/btree.c c82a514c0622e47141cca05617f5fa17ecbc909f F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21 F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8 @@ -379,6 +379,7 @@ F test/boundary3.tcl 23361e108a125dca9c4080c2feb884fe54d69243 F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b +F test/btree01.test 717fcf43f66da534671bef795c993e2f9b3b2e3e F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de @@ -1222,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1e1221fc4823a6bb6fc5d2408732e27aca585de9 -R d9420ee27960cebcc5a5d23852d1a5da -U dan -Z 0b92bbab30b87a9f1cf79fdddb96f8d5 +P 623827192532f08b68bc0eb9ed1449e173361f0c +R 93dc522ced281537ee4ee3dde5b73f25 +U drh +Z 0ffb28de24b6b45b6e628c5a31b22be7 diff --git a/manifest.uuid b/manifest.uuid index 03036e1aff..a6fb19304d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -623827192532f08b68bc0eb9ed1449e173361f0c \ No newline at end of file +f242394e079dd185aad90f2aee902a5edf27e150 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 5ae5986cfa..49ac6208a9 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6257,6 +6257,14 @@ static int pageFreeArray( } /* +** apCell[] and szCell[] contains pointers to and sizes of all cells in the +** pages being balanced. The current page, pPg, has pPg->nCell cells starting +** with apCell[iOld]. After balancing, this page should hold nNew cells +** starting at apCell[iNew]. +** +** This routine makes the necessary adjustments to pPg so that it contains +** the correct cells after being balanced. +** ** The pPg->nFree field is invalid when this function returns. It is the ** responsibility of the caller to set it correctly. */ @@ -6297,12 +6305,13 @@ static void editPage( ); } - pData = &aData[get2byte(&aData[hdr+5])]; + pData = &aData[get2byteNotZero(&aData[hdr+5])]; if( pDataaCellIdx; memmove(&pCellptr[nAdd*2], pCellptr, nCell*2); if( pageInsertArray( diff --git a/test/btree01.test b/test/btree01.test new file mode 100644 index 0000000000..09358ff76f --- /dev/null +++ b/test/btree01.test @@ -0,0 +1,34 @@ +# 2014-11-27 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains test cases for b-tree logic. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix btree01 + +# The refactoring on the b-tree balance() routine in check-in +# http://www.sqlite.org/src/info/face33bea1ba3a (2014-10-27) +# caused the integrity_check on the following SQL to fail. +# +do_execsql_test btree01-1.1 { + PRAGMA page_size=65536; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b BLOB); + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) + INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c; + UPDATE t1 SET b=zeroblob(3000); + UPDATE t1 SET b=zeroblob(64000) WHERE a=2; + PRAGMA integrity_check; +} {ok} + +finish_test From 3f2d22e1a3a8f49a47d131df38b319f3575dffa8 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 Nov 2014 04:23:19 +0000 Subject: [PATCH 19/24] More test cases for the balancer. FossilOrigin-Name: 358ea818f7ea5aa55bafaf4057e9fc7a5fd77c11 --- manifest | 12 +++--- manifest.uuid | 2 +- test/btree01.test | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 21c1471b6b..06e08e13af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\snew\sb-tree\sbalancer\sthat\swas\scausing\scorruption\sof\nthe\sfragmentation\scount. -D 2014-11-27T03:46:04.203 +C More\stest\scases\sfor\sthe\sbalancer. +D 2014-11-27T04:23:19.652 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -379,7 +379,7 @@ F test/boundary3.tcl 23361e108a125dca9c4080c2feb884fe54d69243 F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b -F test/btree01.test 717fcf43f66da534671bef795c993e2f9b3b2e3e +F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de @@ -1223,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 623827192532f08b68bc0eb9ed1449e173361f0c -R 93dc522ced281537ee4ee3dde5b73f25 +P f242394e079dd185aad90f2aee902a5edf27e150 +R dee46347027ae53917346a5c99ff404e U drh -Z 0ffb28de24b6b45b6e628c5a31b22be7 +Z 45538c84f085c10577fd84190398d06f diff --git a/manifest.uuid b/manifest.uuid index a6fb19304d..19339500a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f242394e079dd185aad90f2aee902a5edf27e150 \ No newline at end of file +358ea818f7ea5aa55bafaf4057e9fc7a5fd77c11 \ No newline at end of file diff --git a/test/btree01.test b/test/btree01.test index 09358ff76f..25f2c6897b 100644 --- a/test/btree01.test +++ b/test/btree01.test @@ -31,4 +31,102 @@ do_execsql_test btree01-1.1 { PRAGMA integrity_check; } {ok} +# The previous test is sufficient to prevent a regression. But we +# add a number of additional tests to stress the balancer in similar +# ways, looking for related problems. +# +for {set i 1} {$i<=30} {incr i} { + do_test btree01-1.2.$i { + db eval { + DELETE FROM t1; + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) + INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c; + UPDATE t1 SET b=zeroblob(3000); + UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i; + PRAGMA integrity_check; + } + } {ok} +} +for {set i 1} {$i<=30} {incr i} { + do_test btree01-1.3.$i { + db eval { + DELETE FROM t1; + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) + INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c; + UPDATE t1 SET b=zeroblob(2000); + UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i; + PRAGMA integrity_check; + } + } {ok} +} +for {set i 1} {$i<=30} {incr i} { + do_test btree01-1.4.$i { + db eval { + DELETE FROM t1; + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) + INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c; + UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==0; + UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==1; + UPDATE t1 SET b=zeroblob(6499) WHERE (a%3)==2; + UPDATE t1 SET b=zeroblob(64000) WHERE a=$::i; + PRAGMA integrity_check; + } + } {ok} +} +for {set i 1} {$i<=30} {incr i} { + do_test btree01-1.5.$i { + db eval { + DELETE FROM t1; + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) + INSERT INTO t1(a,b) SELECT i, zeroblob(6542) FROM c; + UPDATE t1 SET b=zeroblob(2331); + UPDATE t1 SET b=zeroblob(65496) WHERE a=$::i; + PRAGMA integrity_check; + } + } {ok} +} +for {set i 1} {$i<=30} {incr i} { + do_test btree01-1.6.$i { + db eval { + DELETE FROM t1; + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) + INSERT INTO t1(a,b) SELECT i, zeroblob(6542) FROM c; + UPDATE t1 SET b=zeroblob(2332); + UPDATE t1 SET b=zeroblob(65496) WHERE a=$::i; + PRAGMA integrity_check; + } + } {ok} +} +for {set i 1} {$i<=30} {incr i} { + do_test btree01-1.7.$i { + db eval { + DELETE FROM t1; + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) + INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c; + UPDATE t1 SET b=zeroblob(1); + UPDATE t1 SET b=zeroblob(65000) WHERE a=$::i; + PRAGMA integrity_check; + } + } {ok} +} +for {set i 1} {$i<=31} {incr i} { + do_test btree01-1.8.$i { + db eval { + DELETE FROM t1; + WITH RECURSIVE + c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<31) + INSERT INTO t1(a,b) SELECT i, zeroblob(6500) FROM c; + UPDATE t1 SET b=zeroblob(4000); + UPDATE t1 SET b=zeroblob(65000) WHERE a=$::i; + PRAGMA integrity_check; + } + } {ok} +} + finish_test From d89b834f54b4026944df0668dbc5fe7803033a8f Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 27 Nov 2014 11:36:36 +0000 Subject: [PATCH 20/24] Fix a buffer overread during compilation of CREATE VIRTUAL TABLE statements that featured an explicit database name but no virtual table arguments. For example, "CREATE VIRTUAL TABLE main.ft USING fts4". FossilOrigin-Name: f095cde579e7417306e11b5c1d2dd90b6bb547d5 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/test1.c | 17 ++++++++++++++++- src/vtab.c | 7 ++++++- test/vtab1.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 06e08e13af..273e715897 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\sfor\sthe\sbalancer. -D 2014-11-27T04:23:19.652 +C Fix\sa\sbuffer\soverread\sduring\scompilation\sof\sCREATE\sVIRTUAL\sTABLE\sstatements\sthat\sfeatured\san\sexplicit\sdatabase\sname\sbut\sno\svirtual\stable\sarguments.\sFor\sexample,\s"CREATE\sVIRTUAL\sTABLE\smain.ft\sUSING\sfts4". +D 2014-11-27T11:36:36.295 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -238,7 +238,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 81712116e826b0089bb221b018929536b2b5406f F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc F src/tclsqlite.c 0a874655dd39a9875e39c5d3c464db662171d228 -F src/test1.c 6b0469b8e06c77b1de1d3e4a3834cf26edea9cc7 +F src/test1.c a0bce4f47da65b76c80e5f8bf9a5ef174603866a F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df @@ -300,7 +300,7 @@ F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f F src/vdbesort.c 42c166f7ca78cb643c7f4e4bdfa83c59d363d1a6 F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010 -F src/vtab.c 2a30791bbd7926b589401bd09c3abb33de563793 +F src/vtab.c c08ec66f45919eaa726bf88aa53eb08379d607f9 F src/wal.c 486e644b3b8aa5ad066f625bc428aa8ff7001405 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 @@ -1091,7 +1091,7 @@ F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test f311691d696a5cc27e3c1b875cec1b0866b4ccd9 -F test/vtab1.test b631d147b198cfd7903ab5fed028eb2a3d321dc6 +F test/vtab1.test 1cef14310144718812351a61c5cfb4ba8494a171 F test/vtab2.test 7bcffc050da5c68f4f312e49e443063e2d391c0d F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 942f8b8280b3ea8a41dae20e7822d065ca1cb275 @@ -1223,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f242394e079dd185aad90f2aee902a5edf27e150 -R dee46347027ae53917346a5c99ff404e -U drh -Z 45538c84f085c10577fd84190398d06f +P 358ea818f7ea5aa55bafaf4057e9fc7a5fd77c11 +R a4b8cae126976a974aa80f7f44ce5b7f +U dan +Z 67582253c41fc622f4b8d67b4605ed6a diff --git a/manifest.uuid b/manifest.uuid index 19339500a5..e316358ddb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -358ea818f7ea5aa55bafaf4057e9fc7a5fd77c11 \ No newline at end of file +f095cde579e7417306e11b5c1d2dd90b6bb547d5 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index ca3b54a513..1c43861547 100644 --- a/src/test1.c +++ b/src/test1.c @@ -3638,6 +3638,7 @@ static int test_prepare_v2( ){ sqlite3 *db; const char *zSql; + char *zCopy = 0; /* malloc() copy of zSql */ int bytes; const char *zTail = 0; sqlite3_stmt *pStmt = 0; @@ -3653,7 +3654,21 @@ static int test_prepare_v2( zSql = Tcl_GetString(objv[2]); if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; - rc = sqlite3_prepare_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0); + /* Instead of using zSql directly, make a copy into a buffer obtained + ** directly from malloc(). The idea is to make it easier for valgrind + ** to spot buffer overreads. */ + if( bytes>=0 ){ + zCopy = malloc(bytes); + memcpy(zCopy, zSql, bytes); + }else{ + int n = strlen(zSql) + 1; + zCopy = malloc(n); + memcpy(zCopy, zSql, n); + } + rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0); + free(zCopy); + zTail = &zSql[(zTail - zCopy)]; + assert(rc==SQLITE_OK || pStmt==0); Tcl_ResetResult(interp); if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; diff --git a/src/vtab.c b/src/vtab.c index 334de9aacb..00d0882b04 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -332,7 +332,12 @@ void sqlite3VtabBeginParse( addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(db, pTable, 0); addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName)); - pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z); + assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) + || (pParse->sNameToken.z==pName1->z && pName2->z==0) + ); + pParse->sNameToken.n = (int)( + &pModuleName->z[pModuleName->n] - pParse->sNameToken.z + ); #ifndef SQLITE_OMIT_AUTHORIZATION /* Creating a virtual table invokes the authorization callback twice. diff --git a/test/vtab1.test b/test/vtab1.test index 0542ee6fdd..2929b1e54d 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1395,4 +1395,46 @@ do_execsql_test 21.3 { SELECT * FROM t9v WHERE a=b; } {2 2 2} +#------------------------------------------------------------------------- +# At one point executing a CREATE VIRTUAL TABLE statement that specified +# a database name but no virtual table arguments was causing an internal +# buffer overread. Valgrind would report errors while running the following +# tests. Specifically: +# +# CREATE VIRTUAL TABLE t1 USING fts4; -- Ok - no db name. +# CREATE VIRTUAL TABLE main.t1 USING fts4(x); -- Ok - has vtab arguments. +# CREATE VIRTUAL TABLE main.t1 USING fts4; -- Had the problem. +# +ifcapable fts3 { + forcedelete test.db2 + set nm [string repeat abcdefghij 100] + do_execsql_test 22.1 { + ATTACH 'test.db2' AS $nm + } + + execsql "SELECT * FROM sqlite_master" + do_execsql_test 22.2 "CREATE VIRTUAL TABLE ${nm}.t1 USING fts4" + + do_test 22.3.1 { + set sql "CREATE VIRTUAL TABLE ${nm}.t2 USING fts4" + set stmt [sqlite3_prepare_v2 db $sql -1 dummy] + sqlite3_step $stmt + } {SQLITE_DONE} + + do_test 22.3.2 { + sqlite3_finalize $stmt + } {SQLITE_OK} + + do_test 22.4.1 { + set sql "CREATE VIRTUAL TABLE ${nm}.t3 USING fts4" + set n [string length $sql] + set stmt [sqlite3_prepare db "${sql}xyz" $n dummy] + sqlite3_step $stmt + } {SQLITE_DONE} + + do_test 22.4.2 { + sqlite3_finalize $stmt + } {SQLITE_OK} +} + finish_test From cb7fe0ab9cab1f902ea2ff32243c266cef078151 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Nov 2014 11:54:44 +0000 Subject: [PATCH 21/24] Add the -end option to the command-line shell, which forces it to exit after reading prior command-line options (presumably including one or more -cmd options) and without reading standard input. FossilOrigin-Name: b59397b1f1e32c478b5fa96659cd4300177d39f7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c | 3 +++ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 273e715897..b2e178bb04 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbuffer\soverread\sduring\scompilation\sof\sCREATE\sVIRTUAL\sTABLE\sstatements\sthat\sfeatured\san\sexplicit\sdatabase\sname\sbut\sno\svirtual\stable\sarguments.\sFor\sexample,\s"CREATE\sVIRTUAL\sTABLE\smain.ft\sUSING\sfts4". -D 2014-11-27T11:36:36.295 +C Add\sthe\s-end\soption\sto\sthe\scommand-line\sshell,\swhich\sforces\sit\sto\sexit\safter\nreading\sprior\scommand-line\soptions\s(presumably\sincluding\sone\sor\smore\s-cmd\noptions)\sand\swithout\sreading\sstandard\sinput. +D 2014-11-28T11:54:44.417 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -229,7 +229,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 428165951748151e87a15295b7357221433e311b -F src/shell.c bc28d5992109717c87804e2eb1a08a7c8cc7a2fd +F src/shell.c f49ecad5afcae4c7fa2754a1446848582b105509 F src/sqlite.h.in c63db0117aeb749ca02b6016dbbbccbbbd9a141d F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d @@ -1223,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 358ea818f7ea5aa55bafaf4057e9fc7a5fd77c11 -R a4b8cae126976a974aa80f7f44ce5b7f -U dan -Z 67582253c41fc622f4b8d67b4605ed6a +P f095cde579e7417306e11b5c1d2dd90b6bb547d5 +R 705c89a250127228fc15e4e2150ad4c0 +U drh +Z ed3d85af1529a8fcb757b6e7459b553e diff --git a/manifest.uuid b/manifest.uuid index e316358ddb..fa03660517 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f095cde579e7417306e11b5c1d2dd90b6bb547d5 \ No newline at end of file +b59397b1f1e32c478b5fa96659cd4300177d39f7 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index bbd37c7a04..46b4c0f10f 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3944,6 +3944,7 @@ static const char zOptions[] = " -cmd COMMAND run \"COMMAND\" before reading stdin\n" " -csv set output mode to 'csv'\n" " -echo print commands before execution\n" + " -end Halt. Useful after one or more -cmd\n" " -init FILENAME read/process named file\n" " -[no]header turn headers on or off\n" #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) @@ -4288,6 +4289,8 @@ int main(int argc, char **argv){ if( bail_on_error ) return rc; } } + }else if( strcmp(z, "-end")==0 ){ + return 0; }else{ fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); fprintf(stderr,"Use -help for a list of options.\n"); From ac5649a98529c751cac09c72a7a03a2c4f8b14a8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 28 Nov 2014 13:35:03 +0000 Subject: [PATCH 22/24] Remove the ill-designed "-end" option from the command-line shell. Instead, allow multiple SQL or dot-commands as command-line arguments. Any -cmd commands are processed first, followed by other command-line arguments, for backwards compatibility. FossilOrigin-Name: 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e --- manifest | 16 +++++----- manifest.uuid | 2 +- src/shell.c | 80 +++++++++++++++++++++++++++++------------------- test/shell1.test | 31 ++++++++++--------- test/shell2.test | 6 ++-- 5 files changed, 77 insertions(+), 58 deletions(-) diff --git a/manifest b/manifest index b2e178bb04..527a5caae6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s-end\soption\sto\sthe\scommand-line\sshell,\swhich\sforces\sit\sto\sexit\safter\nreading\sprior\scommand-line\soptions\s(presumably\sincluding\sone\sor\smore\s-cmd\noptions)\sand\swithout\sreading\sstandard\sinput. -D 2014-11-28T11:54:44.417 +C Remove\sthe\sill-designed\s"-end"\soption\sfrom\sthe\scommand-line\sshell.\s\sInstead,\nallow\smultiple\sSQL\sor\sdot-commands\sas\scommand-line\sarguments.\s\sAny\s-cmd\ncommands\sare\sprocessed\sfirst,\sfollowed\sby\sother\scommand-line\sarguments,\sfor\nbackwards\scompatibility. +D 2014-11-28T13:35:03.566 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -229,7 +229,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 428165951748151e87a15295b7357221433e311b -F src/shell.c f49ecad5afcae4c7fa2754a1446848582b105509 +F src/shell.c 45d9c9bd7cde07845af957f2d849933b990773cf F src/sqlite.h.in c63db0117aeb749ca02b6016dbbbccbbbd9a141d F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d @@ -848,8 +848,8 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5 F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test d60946b5fde4d85fe06db7331dfe89011f564350 -F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3 +F test/shell1.test ab6025d941f9c84c5b83412c6b4d8b57f78dfa3a +F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29 F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5 F test/shell5.test 15a419cc1df21c892ed64f5596ae7a501f2816f2 @@ -1223,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f095cde579e7417306e11b5c1d2dd90b6bb547d5 -R 705c89a250127228fc15e4e2150ad4c0 +P b59397b1f1e32c478b5fa96659cd4300177d39f7 +R 1ff83ec33f372c19416fe00ba6e9161c U drh -Z ed3d85af1529a8fcb757b6e7459b553e +Z 816c9b1778ea4dbed9ea56de4b3769ca diff --git a/manifest.uuid b/manifest.uuid index fa03660517..c82d09b6ab 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b59397b1f1e32c478b5fa96659cd4300177d39f7 \ No newline at end of file +24fa2e9832daaa5d68ee28a00c56c55f97a4da9e \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 46b4c0f10f..94d20d3549 100644 --- a/src/shell.c +++ b/src/shell.c @@ -3944,7 +3944,6 @@ static const char zOptions[] = " -cmd COMMAND run \"COMMAND\" before reading stdin\n" " -csv set output mode to 'csv'\n" " -echo print commands before execution\n" - " -end Halt. Useful after one or more -cmd\n" " -init FILENAME read/process named file\n" " -[no]header turn headers on or off\n" #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) @@ -4039,10 +4038,12 @@ int main(int argc, char **argv){ char *zErrMsg = 0; ShellState data; const char *zInitFile = 0; - char *zFirstCmd = 0; int i; int rc = 0; int warnInmemoryDb = 0; + int readStdin = 1; + int nCmd = 0; + char **azCmd = 0; #if USE_SYSTEM_SQLITE+0!=1 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ @@ -4062,6 +4063,18 @@ int main(int argc, char **argv){ signal(SIGINT, interrupt_handler); #endif +#ifdef SQLITE_SHELL_DBNAME_PROC + { + /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name + ** of a C-function that will provide the name of the database file. Use + ** this compile-time option to embed this shell program in larger + ** applications. */ + extern void SQLITE_SHELL_DBNAME_PROC(const char**); + SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); + warnInmemoryDb = 0; + } +#endif + /* Do an initial pass through the command-line argument to locate ** the name of the database file, the name of the initialization file, ** the size of the alternative malloc heap, @@ -4073,15 +4086,18 @@ int main(int argc, char **argv){ if( z[0]!='-' ){ if( data.zDbFilename==0 ){ data.zDbFilename = z; - continue; + }else{ + /* Excesss arguments are interpreted as SQL (or dot-commands) and + ** mean that nothing is read from stdin */ + readStdin = 0; + nCmd++; + azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd); + if( azCmd==0 ){ + fprintf(stderr, "out of memory\n"); + exit(1); + } + azCmd[nCmd-1] = z; } - if( zFirstCmd==0 ){ - zFirstCmd = z; - continue; - } - fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]); - fprintf(stderr,"Use -help for a list of options.\n"); - return 1; } if( z[1]=='-' ) z++; if( strcmp(z,"-separator")==0 @@ -4171,11 +4187,6 @@ int main(int argc, char **argv){ #else fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); return 1; -#endif -#ifdef SQLITE_SHELL_DBNAME_PROC - { extern void SQLITE_SHELL_DBNAME_PROC(const char**); - SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename); - warnInmemoryDb = 0; } #endif } data.out = stdout; @@ -4273,6 +4284,10 @@ int main(int argc, char **argv){ }else if( strcmp(z,"-help")==0 ){ usage(1); }else if( strcmp(z,"-cmd")==0 ){ + /* Run commands that follow -cmd first and separately from commands + ** that simply appear on the command-line. This seems goofy. It would + ** be better if all commands ran in the order that they appear. But + ** we retain the goofy behavior for historical compatibility. */ if( i==argc-1 ) break; z = cmdline_option_value(argc,argv,++i); if( z[0]=='.' ){ @@ -4289,8 +4304,6 @@ int main(int argc, char **argv){ if( bail_on_error ) return rc; } } - }else if( strcmp(z, "-end")==0 ){ - return 0; }else{ fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); fprintf(stderr,"Use -help for a list of options.\n"); @@ -4298,23 +4311,28 @@ int main(int argc, char **argv){ } } - if( zFirstCmd ){ - /* Run just the command that follows the database name + if( !readStdin ){ + /* Run all arguments that do not begin with '-' as if they were separate + ** command-line inputs, except for the argToSkip argument which contains + ** the database filename. */ - if( zFirstCmd[0]=='.' ){ - rc = do_meta_command(zFirstCmd, &data); - if( rc==2 ) rc = 0; - }else{ - open_db(&data, 0); - rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg); - if( zErrMsg!=0 ){ - fprintf(stderr,"Error: %s\n", zErrMsg); - return rc!=0 ? rc : 1; - }else if( rc!=0 ){ - fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd); - return rc; + for(i=0; i Date: Tue, 2 Dec 2014 13:46:53 +0000 Subject: [PATCH 23/24] Work around overzealous NULL pointer checking in memcpy() and memset() for some systems. FossilOrigin-Name: 0d04f380e1bd17104b3cf76b64d0cfc79a726606 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 527a5caae6..ad4a3aef34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sill-designed\s"-end"\soption\sfrom\sthe\scommand-line\sshell.\s\sInstead,\nallow\smultiple\sSQL\sor\sdot-commands\sas\scommand-line\sarguments.\s\sAny\s-cmd\ncommands\sare\sprocessed\sfirst,\sfollowed\sby\sother\scommand-line\sarguments,\sfor\nbackwards\scompatibility. -D 2014-11-28T13:35:03.566 +C Work\saround\soverzealous\sNULL\spointer\schecking\sin\smemcpy()\sand\smemset()\sfor\nsome\ssystems. +D 2014-12-02T13:46:53.642 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -295,7 +295,7 @@ F src/vdbe.c ec1f55acef4864520ca2017b9f0d60c2ac1b8b78 F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3 F src/vdbeInt.h 9bb69ff2447c34b6ccc58b34ec35b615f86ead78 F src/vdbeapi.c 07acb615d1e4170e71fc1b0d087f3c53a1ad8e83 -F src/vdbeaux.c 5ce4f414147a3bc3cbcf00ec57f2606c25791629 +F src/vdbeaux.c 6f7f39c3fcf0f5923758df8561bb5d843908a553 F src/vdbeblob.c 4af4bfb71f6df7778397b4a0ebc1879793276778 F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f F src/vdbesort.c 42c166f7ca78cb643c7f4e4bdfa83c59d363d1a6 @@ -1223,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b59397b1f1e32c478b5fa96659cd4300177d39f7 -R 1ff83ec33f372c19416fe00ba6e9161c +P 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e +R 2462364d5d687298c5bd05c143924351 U drh -Z 816c9b1778ea4dbed9ea56de4b3769ca +Z 6348ca916079ca99c53e597a8af8c112 diff --git a/manifest.uuid b/manifest.uuid index c82d09b6ab..6af54cb5bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24fa2e9832daaa5d68ee28a00c56c55f97a4da9e \ No newline at end of file +0d04f380e1bd17104b3cf76b64d0cfc79a726606 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index b8f5bca2c3..7900bd52ac 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1742,7 +1742,7 @@ void sqlite3VdbeMakeReady( p->aVar[n].db = db; } } - if( p->azVar ){ + if( p->azVar && pParse->nzVar>0 ){ p->nzVar = pParse->nzVar; memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); From 1fd2d7d4715695d09bf7120c6a335e5806e8418d Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 2 Dec 2014 16:16:47 +0000 Subject: [PATCH 24/24] Convert two unreachable branches into assert() statements. FossilOrigin-Name: 61b31e771430f490fc2c4cef55046debc4a5f4f5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ad4a3aef34..7f9f9524d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Work\saround\soverzealous\sNULL\spointer\schecking\sin\smemcpy()\sand\smemset()\sfor\nsome\ssystems. -D 2014-12-02T13:46:53.642 +C Convert\stwo\sunreachable\sbranches\sinto\sassert()\sstatements. +D 2014-12-02T16:16:47.791 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 7ddee9c7d505e07e959a575b18498f17c71e53ea F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 49ca66250c7dfa844a4d4cb8272b87420d27d3a5 -F src/btree.c c82a514c0622e47141cca05617f5fa17ecbc909f +F src/btree.c 44b58cd798a32579816ce274e415de262df9843d F src/btree.h e31a3a3ebdedb1caf9bda3ad5dbab3db9b780f6e F src/btreeInt.h 3363e18fd76f69a27a870b25221b2345b3fd4d21 F src/build.c 67bb05b1077e0cdaccb2e36bfcbe7a5df9ed31e8 @@ -1223,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e -R 2462364d5d687298c5bd05c143924351 +P 0d04f380e1bd17104b3cf76b64d0cfc79a726606 +R 22214da224af1bd07c2ba4ce527797c4 U drh -Z 6348ca916079ca99c53e597a8af8c112 +Z 4469ca4ec037115204af98a9b9e41068 diff --git a/manifest.uuid b/manifest.uuid index 6af54cb5bb..fe8f0fdad5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0d04f380e1bd17104b3cf76b64d0cfc79a726606 \ No newline at end of file +61b31e771430f490fc2c4cef55046debc4a5f4f5 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 49ac6208a9..796b44403d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1356,7 +1356,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ testcase( gap+2+nByte==top ); if( gap+2+nByte>top ){ defragment_page: - testcase( pPage->nCell==0 ); + assert( pPage->nCell>0 || CORRUPT_DB ); rc = defragmentPage(pPage); if( rc ) return rc; top = get2byteNotZero(&data[hdr+5]); @@ -6416,7 +6416,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ assert( pPage->nOverflow==1 ); /* This error condition is now caught prior to reaching this function */ - if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; + if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT; /* Allocate a new page. This page will become the right-sibling of ** pPage. Make the parent page writable, so that the new divider cell