From faacf17cc1a1d6b062d63a27fca5fa5a87bf3bb9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 12 Aug 2011 01:51:45 +0000 Subject: [PATCH 01/56] Begin a branch that experimentally replaces sqlite_stat2 with a new table called sqlite_stat3 that will hopefully facilitate better query planning decisions. FossilOrigin-Name: 52e1d7e8ddd4bb5ef3a9d00fd2d719a8a784f807 --- manifest | 34 ++-- manifest.uuid | 2 +- src/analyze.c | 501 +++++++++++++++++++++++++++++++--------------- src/build.c | 152 +++++++------- src/ctime.c | 3 + src/sqlite.h.in | 2 +- src/sqliteInt.h | 31 ++- src/test_config.c | 6 + src/utf.c | 2 +- src/vdbemem.c | 6 +- src/where.c | 368 ++++++++++++++++------------------ test/auth.test | 6 +- test/stat3.test | 56 ++++++ 13 files changed, 714 insertions(+), 455 deletions(-) create mode 100644 test/stat3.test diff --git a/manifest b/manifest index 83e86d4850..13b45de240 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sopenDirectory\sroutine\sin\sos_unix.c\soverrideable\sso\sthat\sit\scan\nbe\sturned\sinto\sa\sharmless\sno-op\sfor\sthe\schromium\ssandbox. -D 2011-08-10T01:52:12.736 +C Begin\sa\sbranch\sthat\sexperimentally\sreplaces\ssqlite_stat2\swith\sa\snew\stable\ncalled\ssqlite_stat3\sthat\swill\shopefully\sfacilitate\sbetter\squery\nplanning\sdecisions. +D 2011-08-12T01:51:45.485 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c a425d62e8fa9ebcb4359ab84ff0c62c6563d2e2a +F src/analyze.c da6661dbe12f71d37e81c1138cd7b3175fa60a4f F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -127,10 +127,10 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 8c46f0ab69ad9549c75a3a91fed87abdaa743e2f F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c 19a8957a442d922a0d6ed1a5dd67b63202fc3260 +F src/build.c 4165efa323b4d3678a6b39fddb775627c18e9a80 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac -F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4 +F src/ctime.c 0df87f944b17c17c6b3976a9758d8af2802e1b19 F src/date.c a3c6842bad7ae632281811de112a8ba63ff08ab3 F src/delete.c ff68e5ef23aee08c0ff528f699a19397ed8bbed8 F src/expr.c 4bbdfaf66bc614be9254ce0c26a17429067a3e07 @@ -181,9 +181,9 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d219c4b68d603cc734b6f9b1e2780fee12a1fa0d F src/shell.c bbe7818ff5bc8614105ceb81ad67b8bdc0b671dd -F src/sqlite.h.in 0b3cab7b2ea51f58396e8871fa5f349cfece5330 +F src/sqlite.h.in e8eb090406b9a743befff4c387aa3bd5eeae661e F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 -F src/sqliteInt.h ba4a6d6288efb25b84bc0d7d0aaf80f9b42523ba +F src/sqliteInt.h a4c0124ff6dbbf325002b4a34248cc08453c9739 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -201,7 +201,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c b4648b103586d2ae863056080c657680f6fa4825 +F src/test_config.c baa9cfc6304aa739b32c735378008a0fa846b573 F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -235,7 +235,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c c819d9f72168a035d545a5bdafe9b085b20df705 F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 F src/update.c 74a6cfb34e9732c1e2a86278b229913b4b51eeec -F src/utf.c c53eb7404b3eb5c1cbb5655c6a7a0e0ce6bd50f0 +F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 06302ffd2b80408d4f6c7af71f7090e0cf8d8ff7 F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e F src/vdbe.c 49d834f0fe49d305e07f9c212e94007fda2028e9 @@ -244,13 +244,13 @@ F src/vdbeInt.h ad84226cc0adcb1185c22b70696b235a1678bb45 F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98 F src/vdbeaux.c 4d100407e3c72e163854aff8903d19d5ecdf46c0 F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 -F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b +F src/vdbemem.c 74410d1639869b309d6fe1e8cbc02a557157a7c2 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 7d09f4c1512affb60cc1190a4b33d121d4ce039a +F src/where.c 24d95b218176bad38ae2abe73197c28d3d6ef9a6 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -277,7 +277,7 @@ F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966 F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e F test/attach4.test 31f9eb0ca7bdbc393cc4657b877903a226a83d4b F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 -F test/auth.test b047105c32da7db70b842fd24056723125ecc2ff +F test/auth.test ac996c81ad910148606f5c7e3b3f85d47c29960f F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882 F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf @@ -682,6 +682,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 0997f6a57a35866b14111ed361ed8851ce7978ae +F test/stat3.test 44cec64164a2f5d86960343a118bc0bdac754f61 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 @@ -957,7 +958,10 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P dfa22ed4387f9526b74d5265503c7c8e9d559903 -R bf22196e9aa98f18724e5d2624f7dcbf +P 6b236069e1ea3c99ff0a007a790d4baebda70b13 +R 28c5bf799a1842cffe08b02c7be0270b +T *branch * stat3-enhancement +T *sym-stat3-enhancement * +T -sym-trunk * U drh -Z 2ec35109792cc0dc5d4f7cebd4d85034 +Z 1615a89a47ce6302aa7ba89aa7dcb40d diff --git a/manifest.uuid b/manifest.uuid index ec7b7e54a0..1903efcb65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b236069e1ea3c99ff0a007a790d4baebda70b13 \ No newline at end of file +52e1d7e8ddd4bb5ef3a9d00fd2d719a8a784f807 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 17c1de83a9..7ccddfb115 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -10,6 +10,95 @@ ** ************************************************************************* ** This file contains code associated with the ANALYZE command. +** +** The ANALYZE command gather statistics about the content of tables +** and indices. These statistics are made available to the query planner +** to help it make better decisions about how to perform queries. +** +** The following system tables are or have been supported: +** +** CREATE TABLE sqlite_stat1(tbl, idx, stat); +** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); +** CREATE TABLE sqlite_stat3(tbl, idx, nLt, nEq, sample); +** +** Additional tables might be added in future releases of SQLite. +** The sqlite_stat2 table is not created or used unless the SQLite version +** is between 3.6.18 and 3.7.7, inclusive, and unless SQLite is compiled +** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. +** The sqlite_stat2 table is superceded by sqlite_stat3, which is only +** created and used by SQLite versions after 2011-08-09 with +** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3 +** is a superset of sqlite_stat2. +** +** Format of sqlite_stat1: +** +** There is normally one row per index, with the index identified by the +** name in the idx column. The tbl column is the name of the table to +** which the index belongs. In each such row, the stat column will be +** a string consisting of a list of integers. The first integer in this +** list is the number of rows in the index and in the table. The second +** integer is the average number of rows in the index that have the same +** value in the first column of the index. The third integer is the average +** number of rows in the index that have the same value for the first two +** columns. The N-th integer (for N>1) is the average number of rows in +** the index which have the same value for the first N-1 columns. For +** a K-column index, there will be K+1 integers in the stat column. If +** the index is unique, then the last integer will be 1. +** +** The list of integers in the stat column can optionally be followed +** by the keyword "unordered". The "unordered" keyword, if it is present, +** must be separated from the last integer by a single space. If the +** "unordered" keyword is present, then the query planner assumes that +** the index is unordered and will not use the index for a range query. +** +** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat +** column contains a single integer which is the (estimated) number of +** rows in the table identified by sqlite_stat1.tbl. +** +** Format of sqlite_stat2: +** +** The sqlite_stat2 is only created and is only used if SQLite is compiled +** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between +** 3.6.18 and 3.7.7. The "stat2" table contains additional information +** about the distribution of keys within an index. The index is identified by +** the "idx" column and the "tbl" column is the name of the table to which +** the index belongs. There are usually 10 rows in the sqlite_stat2 +** table for each index. +** +** The sqlite_stat2 entires for an index that have sampleno between 0 and 9 +** inclusive are samples of the left-most key value in the index taken at +** evenly spaced points along the index. Let the number of samples be S +** (10 in the standard build) and let C be the number of rows in the index. +** Then the sampled rows are given by: +** +** rownumber = (i*C*2 + C)/(S*2) +** +** For i between 0 and S-1. Conceptually, the index space is divided into +** S uniform buckets and the samples are the middle row from each bucket. +** +** The format for sqlite_stat2 is recorded here for legacy reference. This +** version of SQLite does not support sqlite_stat2. It neither reads nor +** writes the sqlite_stat2 table. This version of SQLite only supports +** sqlite_stat3. +** +** Format for sqlite_stat3: +** +** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is +** used to avoid compatibility problems. +** +** The format of the sqlite_stat3 table is similar to the format for +** the sqlite_stat2 table, with the following changes: (1) +** The sampleno column is removed. (2) Every sample has nEq and nLt +** columns which hold the approximate number of keys in the table that +** exactly match the sample, and which are less than the sample, +** respectively. (3) The number of samples can very from one table +** to the next; the sample count does not have to be exactly 10 as +** it is with sqlite_stat2. (4) The samples do not have to be evenly spaced. +** +** The ANALYZE command will typically generate sqlite_stat3 tables +** that contain between 10 and 40 samples which are distributed across +** the key space, though not uniformly, and which include samples with +** largest possible nEq values. */ #ifndef SQLITE_OMIT_ANALYZE #include "sqliteInt.h" @@ -42,8 +131,14 @@ static void openStatTable( const char *zCols; } aTable[] = { { "sqlite_stat1", "tbl,idx,stat" }, -#ifdef SQLITE_ENABLE_STAT2 - { "sqlite_stat2", "tbl,idx,sampleno,sample" }, +#ifdef SQLITE_ENABLE_STAT3 + { "sqlite_stat3", "tbl,idx,neq,nlt,sample" }, +#endif + }; + static const char *azToDrop[] = { + "sqlite_stat2", +#ifndef SQLITE_ENABLE_STAT3 + "sqlite_stat3", #endif }; @@ -59,6 +154,17 @@ static void openStatTable( assert( sqlite3VdbeDb(v)==db ); pDb = &db->aDb[iDb]; + /* Drop all statistics tables that this version of SQLite does not + ** understand. + */ + for(i=0; izName); + if( pTab ) sqlite3CodeDropTable(pParse, pTab, iDb, 0); + } + + /* Create new statistic tables if they do not exist, or clear them + ** if they do already exist. + */ for(i=0; i= this */ + int regTemp1 = iMem++; /* Intermediate register */ + int regCount = iMem++; /* Number of rows in the table or index */ + int regGosub = iMem++; /* Register holding subroutine return addr */ + int once = 1; /* One-time initialization */ + int shortJump = 0; /* Instruction address */ + int addrStoreStat3 = 0; /* Address of subroutine to wrote to stat3 */ +#endif + int regCol = iMem++; /* Content of a column in analyzed table */ int regRec = iMem++; /* Register holding completed record */ int regTemp = iMem++; /* Temporary use register */ int regRowid = iMem++; /* Rowid for the inserted record */ -#ifdef SQLITE_ENABLE_STAT2 - int addr = 0; /* Instruction address */ - int regTemp2 = iMem++; /* Temporary use register */ - int regSamplerecno = iMem++; /* Index of next sample to record */ - int regRecno = iMem++; /* Current sample index */ - int regLast = iMem++; /* Index of last sample to record */ - int regFirst = iMem++; /* Index of first sample to record */ -#endif v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) ){ @@ -165,13 +284,18 @@ static void analyzeOneTable( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; KeyInfo *pKey; + int addrIfNot; /* address of OP_IfNot */ + int *aChngAddr; /* Array of jump instruction addresses */ if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; + VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); nCol = pIdx->nColumn; pKey = sqlite3IndexKeyinfo(pParse, pIdx); if( iMem+1+(nCol*2)>pParse->nMem ){ pParse->nMem = iMem+1+(nCol*2); } + aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*pIdx->nColumn); + if( aChngAddr==0 ) continue; /* Open a cursor to the index to be analyzed. */ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); @@ -182,31 +306,43 @@ static void analyzeOneTable( /* Populate the register containing the index name. */ sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 /* If this iteration of the loop is generating code to analyze the ** first index in the pTab->pIndex list, then register regLast has ** not been populated. In this case populate it now. */ - if( pTab->pIndex==pIdx ){ - sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno); - sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp); - sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2); + if( once ){ + once = 0; + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount); + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1); + sqlite3VdbeAddOp3(v, OP_Divide, regTemp1, regCount, regSpacing); + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES/2, regTemp1); + sqlite3VdbeAddOp3(v, OP_Divide, regTemp1, regCount, regBigSize); - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast); - sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst); - addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast); - sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst); - sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast); - sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2); - sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regLast); - sqlite3VdbeJumpHere(v, addr); + /* Generate code for a subroutine that store the most recent sample + ** in the sqlite_stat3 table + */ + shortJump = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 5, regRec, "bbbbb", 0); + VdbeComment((v, "begin stat3 write subroutine")); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid); + sqlite3VdbeAddOp3(v, OP_Add, regNext, regSpacing, regNext); + sqlite3VdbeAddOp1(v, OP_Return, regGosub); + addrStoreStat3 = + sqlite3VdbeAddOp3(v, OP_Ge, regBigSize, shortJump+1, regNumEq); + sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regTemp1); + sqlite3VdbeAddOp3(v, OP_Ge, regNext, shortJump+1, regTemp1); + sqlite3VdbeAddOp1(v, OP_Return, regGosub); + VdbeComment((v, "end stat3 write subroutine")); + sqlite3VdbeJumpHere(v, shortJump); } + /* Reset state registers */ + sqlite3VdbeAddOp2(v, OP_Copy, regSpacing, regNext); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); - /* Zero the regSampleno and regRecno registers. */ - sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno); - sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno); - sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno); -#endif +#endif /* SQLITE_ENABLE_STAT3 */ /* The block of memory cells initialized here is used as follows. ** @@ -236,75 +372,54 @@ static void analyzeOneTable( endOfLoop = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); topOfLoop = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */ for(i=0; iazColl!=0 ); assert( pIdx->azColl[i]!=0 ); pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); - sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1, - (char*)pColl, P4_COLLSEQ); + aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1, + (char*)pColl, P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); - } - if( db->mallocFailed ){ - /* If a malloc failure has occurred, then the result of the expression - ** passed as the second argument to the call to sqlite3VdbeJumpHere() - ** below may be negative. Which causes an assert() to fail (or an - ** out-of-bounds write if SQLITE_DEBUG is not defined). */ - return; + VdbeComment((v, "jump if column %d changed", i)); +#ifdef SQLITE_ENABLE_STAT3 + if( i==0 && addrStoreStat3 ){ + sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1); + VdbeComment((v, "incr repeat count")); + } +#endif } sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); for(i=0; i0 then it is always the case the D>0 so division by zero ** is never possible. */ - sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno); + sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1); if( jZeroRows<0 ){ jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); } for(i=0; ipIndex==0 ){ sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); VdbeComment((v, "%s", pTab->zName)); - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regSampleno); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1); sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); - jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regSampleno); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); }else{ sqlite3VdbeJumpHere(v, jZeroRows); jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto); @@ -365,6 +480,7 @@ static void analyzeOneTable( sqlite3VdbeJumpHere(v, jZeroRows); } + /* ** Generate code that will cause the most recent index analysis to ** be loaded into internal hash tables where is can be used. @@ -518,7 +634,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ Index *pIndex; Table *pTable; int i, c, n; - unsigned int v; + tRowcnt v; const char *z; assert( argc==3 ); @@ -561,36 +677,157 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ ** and its contents. */ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 if( pIdx->aSample ){ int j; - for(j=0; jnSample; j++){ IndexSample *p = &pIdx->aSample[j]; if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ - sqlite3DbFree(db, p->u.z); + sqlite3_free(p->u.z); } } - sqlite3DbFree(db, pIdx->aSample); + sqlite3_free(pIdx->aSample); } + pIdx->nSample = 0; + pIdx->aSample = 0; #else UNUSED_PARAMETER(db); UNUSED_PARAMETER(pIdx); #endif } +#ifdef SQLITE_ENABLE_STAT3 /* -** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The +** Load content from the sqlite_stat3 table into the Index.aSample[] +** arrays of all indices. +*/ +static int loadStat3(sqlite3 *db, const char *zDb){ + int rc; /* Result codes from subroutines */ + sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ + char *zSql; /* Text of the SQL statement */ + Index *pPrevIdx = 0; /* Previous index in the loop */ + int idx; /* slot in pIdx->aSample[] for next sample */ + int eType; /* Datatype of a sample */ + IndexSample *pSample; /* A slot in pIdx->aSample[] */ + + if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){ + return SQLITE_OK; + } + + zSql = sqlite3MPrintf(db, + "SELECT idx,count(*) FROM %Q.sqlite_stat3" + " GROUP BY idx", zDb); + if( !zSql ){ + return SQLITE_NOMEM; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + int nSample; /* Number of samples */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + nSample = sqlite3_column_int(pStmt, 1); + if( nSample>255 ) continue; + pIdx = sqlite3FindIndex(db, zIndex, zDb); + if( pIdx==0 ) continue; + assert( pIdx->nSample==0 ); + pIdx->nSample = (u8)nSample; + pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); + if( pIdx->aSample==0 ){ + db->mallocFailed = 1; + sqlite3_finalize(pStmt); + return SQLITE_NOMEM; + } + } + sqlite3_finalize(pStmt); + + zSql = sqlite3MPrintf(db, + "SELECT idx,nlt,neq,sample FROM %Q.sqlite_stat3" + " ORDER BY idx, nlt", zDb); + if( !zSql ){ + return SQLITE_NOMEM; + } + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); + if( rc ) return rc; + + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex; /* Index name */ + Index *pIdx; /* Pointer to the index object */ + + zIndex = (char *)sqlite3_column_text(pStmt, 0); + if( zIndex==0 ) continue; + pIdx = sqlite3FindIndex(db, zIndex, zDb); + if( pIdx==0 ) continue; + if( pIdx==pPrevIdx ){ + idx++; + }else{ + pPrevIdx = pIdx; + idx = 0; + } + assert( idxnSample ); + pSample = &pIdx->aSample[idx]; + pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 1); + pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 2); + eType = sqlite3_column_type(pStmt, 3); + pSample->eType = (u8)eType; + switch( eType ){ + case SQLITE_INTEGER: { + pSample->u.i = sqlite3_column_int64(pStmt, 3); + break; + } + case SQLITE_FLOAT: { + pSample->u.r = sqlite3_column_double(pStmt, 3); + break; + } + case SQLITE_NULL: { + break; + } + default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); { + const char *z = (const char *)( + (eType==SQLITE_BLOB) ? + sqlite3_column_blob(pStmt, 3): + sqlite3_column_text(pStmt, 3) + ); + int n = sqlite3_column_bytes(pStmt, 2); + if( n>0xffff ) n = 0xffff; + pSample->nByte = (u16)n; + if( n < 1){ + pSample->u.z = 0; + }else{ + pSample->u.z = sqlite3Malloc(n); + if( pSample->u.z==0 ){ + db->mallocFailed = 1; + sqlite3_finalize(pStmt); + return SQLITE_NOMEM; + } + memcpy(pSample->u.z, z, n); + } + } + } + } + return sqlite3_finalize(pStmt); +} +#endif /* SQLITE_ENABLE_STAT3 */ + +/* +** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] -** arrays. The contents of sqlite_stat2 are used to populate the +** arrays. The contents of sqlite_stat3 are used to populate the ** Index.aSample[] arrays. ** ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR -** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined -** during compilation and the sqlite_stat2 table is present, no data is +** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined +** during compilation and the sqlite_stat3 table is present, no data is ** read from it. ** -** If SQLITE_ENABLE_STAT2 was defined during compilation and the -** sqlite_stat2 table is not present in the database, SQLITE_ERROR is +** If SQLITE_ENABLE_STAT3 was defined during compilation and the +** sqlite_stat3 table is not present in the database, SQLITE_ERROR is ** returned. However, in this case, data is read from the sqlite_stat1 ** table (if it is present) before returning. ** @@ -612,8 +849,10 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3DefaultRowEst(pIdx); +#ifdef SQLITE_ENABLE_STAT3 sqlite3DeleteIndexSamples(db, pIdx); pIdx->aSample = 0; +#endif } /* Check to make sure the sqlite_stat1 table exists */ @@ -625,7 +864,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load new statistics out of the sqlite_stat1 table */ zSql = sqlite3MPrintf(db, - "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); + "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ @@ -634,78 +873,10 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ } - /* Load the statistics from the sqlite_stat2 table. */ -#ifdef SQLITE_ENABLE_STAT2 - if( rc==SQLITE_OK && !sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase) ){ - rc = SQLITE_ERROR; - } + /* Load the statistics from the sqlite_stat3 table. */ +#ifdef SQLITE_ENABLE_STAT3 if( rc==SQLITE_OK ){ - sqlite3_stmt *pStmt = 0; - - zSql = sqlite3MPrintf(db, - "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase); - if( !zSql ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); - sqlite3DbFree(db, zSql); - } - - if( rc==SQLITE_OK ){ - while( sqlite3_step(pStmt)==SQLITE_ROW ){ - char *zIndex; /* Index name */ - Index *pIdx; /* Pointer to the index object */ - - zIndex = (char *)sqlite3_column_text(pStmt, 0); - pIdx = zIndex ? sqlite3FindIndex(db, zIndex, sInfo.zDatabase) : 0; - if( pIdx ){ - int iSample = sqlite3_column_int(pStmt, 1); - if( iSample=0 ){ - int eType = sqlite3_column_type(pStmt, 2); - - if( pIdx->aSample==0 ){ - static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES; - pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz); - if( pIdx->aSample==0 ){ - db->mallocFailed = 1; - break; - } - memset(pIdx->aSample, 0, sz); - } - - assert( pIdx->aSample ); - { - IndexSample *pSample = &pIdx->aSample[iSample]; - pSample->eType = (u8)eType; - if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - pSample->u.r = sqlite3_column_double(pStmt, 2); - }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ - const char *z = (const char *)( - (eType==SQLITE_BLOB) ? - sqlite3_column_blob(pStmt, 2): - sqlite3_column_text(pStmt, 2) - ); - int n = sqlite3_column_bytes(pStmt, 2); - if( n>24 ){ - n = 24; - } - pSample->nByte = (u8)n; - if( n < 1){ - pSample->u.z = 0; - }else{ - pSample->u.z = sqlite3DbStrNDup(0, z, n); - if( pSample->u.z==0 ){ - db->mallocFailed = 1; - break; - } - } - } - } - } - } - } - rc = sqlite3_finalize(pStmt); - } + rc = loadStat3(db, sInfo.zDatabase); } #endif diff --git a/src/build.c b/src/build.c index f609ed8379..73c51c8550 100644 --- a/src/build.c +++ b/src/build.c @@ -1990,7 +1990,11 @@ static void sqlite3ClearStatTables( const char *zType, /* "idx" or "tbl" */ const char *zName /* Name of index or table */ ){ - static const char *azStatTab[] = { "sqlite_stat1", "sqlite_stat2" }; + static const char *azStatTab[] = { + "sqlite_stat1", + "sqlite_stat2", + "sqlite_stat3", + }; int i; const char *zDbName = pParse->db->aDb[iDb].zName; for(i=0; idb; + Trigger *pTrigger; + Db *pDb = &db->aDb[iDb]; + + v = sqlite3GetVdbe(pParse); + assert( v!=0 ); + sqlite3BeginWriteOperation(pParse, 1, iDb); + +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp0(v, OP_VBegin); + } +#endif + + /* Drop all triggers associated with the table being dropped. Code + ** is generated to remove entries from sqlite_master and/or + ** sqlite_temp_master if required. + */ + pTrigger = sqlite3TriggerList(pParse, pTab); + while( pTrigger ){ + assert( pTrigger->pSchema==pTab->pSchema || + pTrigger->pSchema==db->aDb[1].pSchema ); + sqlite3DropTriggerPtr(pParse, pTrigger); + pTrigger = pTrigger->pNext; + } + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Remove any entries of the sqlite_sequence table associated with + ** the table being dropped. This is done before the table is dropped + ** at the btree level, in case the sqlite_sequence table needs to + ** move as a result of the drop (can happen in auto-vacuum mode). + */ + if( pTab->tabFlags & TF_Autoincrement ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", + pDb->zName, pTab->zName + ); + } +#endif + + /* Drop all SQLITE_MASTER table and index entries that refer to the + ** table. The program name loops through the master table and deletes + ** every row that refers to a table of the same name as the one being + ** dropped. Triggers are handled seperately because a trigger can be + ** created in the temp database that refers to a table in another + ** database. + */ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", + pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + if( !isView && !IsVirtual(pTab) ){ + destroyTable(pParse, pTab); + } + + /* Remove the table entry from SQLite's internal schema and modify + ** the schema cookie. + */ + if( IsVirtual(pTab) ){ + sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); + } + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + sqlite3ChangeCookie(pParse, iDb); + sqliteViewResetAll(db, iDb); + +} + /* ** This routine is called to do the work of a DROP TABLE statement. ** pName is the name of the table to be dropped. @@ -2071,7 +2147,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } } #endif - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( !pParse->nested && sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } @@ -2095,68 +2171,10 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ */ v = sqlite3GetVdbe(pParse); if( v ){ - Trigger *pTrigger; - Db *pDb = &db->aDb[iDb]; sqlite3BeginWriteOperation(pParse, 1, iDb); - -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - sqlite3VdbeAddOp0(v, OP_VBegin); - } -#endif sqlite3FkDropTable(pParse, pName, pTab); - - /* Drop all triggers associated with the table being dropped. Code - ** is generated to remove entries from sqlite_master and/or - ** sqlite_temp_master if required. - */ - pTrigger = sqlite3TriggerList(pParse, pTab); - while( pTrigger ){ - assert( pTrigger->pSchema==pTab->pSchema || - pTrigger->pSchema==db->aDb[1].pSchema ); - sqlite3DropTriggerPtr(pParse, pTrigger); - pTrigger = pTrigger->pNext; - } - -#ifndef SQLITE_OMIT_AUTOINCREMENT - /* Remove any entries of the sqlite_sequence table associated with - ** the table being dropped. This is done before the table is dropped - ** at the btree level, in case the sqlite_sequence table needs to - ** move as a result of the drop (can happen in auto-vacuum mode). - */ - if( pTab->tabFlags & TF_Autoincrement ){ - sqlite3NestedParse(pParse, - "DELETE FROM %s.sqlite_sequence WHERE name=%Q", - pDb->zName, pTab->zName - ); - } -#endif - - /* Drop all SQLITE_MASTER table and index entries that refer to the - ** table. The program name loops through the master table and deletes - ** every row that refers to a table of the same name as the one being - ** dropped. Triggers are handled seperately because a trigger can be - ** created in the temp database that refers to a table in another - ** database. - */ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", - pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); - sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); - if( !isView && !IsVirtual(pTab) ){ - destroyTable(pParse, pTab); - } - - /* Remove the table entry from SQLite's internal schema and modify - ** the schema cookie. - */ - if( IsVirtual(pTab) ){ - sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); - } - sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); - sqlite3ChangeCookie(pParse, iDb); + sqlite3CodeDropTable(pParse, pTab, iDb, isView); } - sqliteViewResetAll(db, iDb); exit_drop_table: sqlite3SrcListDelete(db, pName); @@ -2603,8 +2621,8 @@ Index *sqlite3CreateIndex( nCol = pList->nExpr; pIndex = sqlite3DbMallocZero(db, sizeof(Index) + /* Index structure */ + sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */ sizeof(int)*nCol + /* Index.aiColumn */ - sizeof(int)*(nCol+1) + /* Index.aiRowEst */ sizeof(char *)*nCol + /* Index.azColl */ sizeof(u8)*nCol + /* Index.aSortOrder */ nName + 1 + /* Index.zName */ @@ -2613,10 +2631,10 @@ Index *sqlite3CreateIndex( if( db->mallocFailed ){ goto exit_create_index; } - pIndex->azColl = (char**)(&pIndex[1]); + pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]); + pIndex->azColl = (char**)(&pIndex->aiRowEst[nCol+1]); pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]); - pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]); - pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]); + pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]); pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]); zExtra = (char *)(&pIndex->zName[nName+1]); memcpy(pIndex->zName, zName, nName+1); @@ -2893,9 +2911,9 @@ exit_create_index: ** are based on typical values found in actual indices. */ void sqlite3DefaultRowEst(Index *pIdx){ - unsigned *a = pIdx->aiRowEst; + tRowcnt *a = pIdx->aiRowEst; int i; - unsigned n; + tRowcnt n; assert( a!=0 ); a[0] = pIdx->pTable->nRowEst; if( a[0]<10 ) a[0] = 10; diff --git a/src/ctime.c b/src/ctime.c index a128f61a69..ad028ed2a8 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -117,6 +117,9 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_ENABLE_STAT2 "ENABLE_STAT2", #endif +#ifdef SQLITE_ENABLE_STAT3 + "ENABLE_STAT3", +#endif #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY "ENABLE_UNLOCK_NOTIFY", #endif diff --git a/src/sqlite.h.in b/src/sqlite.h.in index eb5f7a02a0..4471c5d363 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2851,7 +2851,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal); ** ^The specific value of WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column -** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled. +** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. ** the ** ** diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bcf6a591af..6bb14b60b8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -445,6 +445,18 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */ */ #define SQLITE_MAX_U32 ((((u64)1)<<32)-1) +/* +** The datatype used to store estimates of the number of rows in a +** table or index. This is an unsigned integer type. For 99.9% of +** the world, a 32-bit integer is sufficient. But a 64-bit integer +** can be used at compile-time if desired. +*/ +#ifdef SQLITE_64BIT_STATS + typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */ +#else + typedef u32 tRowcnt; /* 32-bit is the default */ +#endif + /* ** Macros to determine whether the machine is big or little endian, ** evaluated at runtime. @@ -1278,7 +1290,7 @@ struct Table { Column *aCol; /* Information about each column */ Index *pIndex; /* List of SQL indexes on this table. */ int tnum; /* Root BTree node for this table (see note above) */ - unsigned nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ + tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */ Select *pSelect; /* NULL for tables. Points to definition if a view. */ u16 nRef; /* Number of pointers to this Table */ u8 tabFlags; /* Mask of TF_* values */ @@ -1477,18 +1489,21 @@ struct Index { char *zName; /* Name of this index */ int nColumn; /* Number of columns in the table used by this index */ int *aiColumn; /* Which columns are used by this index. 1st is 0 */ - unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ + tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ int tnum; /* Page containing root of this index in database file */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ u8 bUnordered; /* Use this index for == or IN queries only */ + u8 nSample; /* Number of elements in aSample[] */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ - IndexSample *aSample; /* Array of SQLITE_INDEX_SAMPLES samples */ +#ifdef SQLITE_ENABLE_STAT3 + IndexSample *aSample; /* Samples of the left-most key */ +#endif }; /* @@ -1498,10 +1513,13 @@ struct Index { struct IndexSample { union { char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ - double r; /* Value if eType is SQLITE_FLOAT or SQLITE_INTEGER */ + double r; /* Value if eType is SQLITE_FLOAT */ + i64 i; /* Value if eType is SQLITE_INTEGER */ } u; u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ - u8 nByte; /* Size in byte of text or blob. */ + u16 nByte; /* Size in byte of text or blob. */ + tRowcnt nEq; /* Est. number of rows where the key equals this sample */ + tRowcnt nLt; /* Est. number of rows where key is less than this sample */ }; /* @@ -2707,6 +2725,7 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int); #endif void sqlite3DropTable(Parse*, SrcList*, int, int); +void sqlite3CodeDropTable(Parse*, Table*, int, int); void sqlite3DeleteTable(sqlite3*, Table*); #ifndef SQLITE_OMIT_AUTOINCREMENT void sqlite3AutoincrementBegin(Parse *pParse); @@ -2963,7 +2982,7 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void sqlite3ValueFree(sqlite3_value*); sqlite3_value *sqlite3ValueNew(sqlite3 *); char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *); #endif int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); diff --git a/src/test_config.c b/src/test_config.c index e8d6f88f62..9a3f3da730 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -418,6 +418,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double", Tcl_SetVar2(interp, "sqlite_options", "stat2", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_STAT3 + Tcl_SetVar2(interp, "sqlite_options", "stat3", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "stat3", "0", TCL_GLOBAL_ONLY); +#endif + #if !defined(SQLITE_ENABLE_LOCKING_STYLE) # if defined(__APPLE__) # define SQLITE_ENABLE_LOCKING_STYLE 1 diff --git a/src/utf.c b/src/utf.c index 17f3a09a4f..e94815b5ab 100644 --- a/src/utf.c +++ b/src/utf.c @@ -464,7 +464,7 @@ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){ ** If a malloc failure occurs, NULL is returned and the db.mallocFailed ** flag set. */ -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){ Mem m; memset(&m, 0, sizeof(m)); diff --git a/src/vdbemem.c b/src/vdbemem.c index 882c686334..9c964a2581 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1032,11 +1032,11 @@ int sqlite3ValueFromExpr( } op = pExpr->op; - /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2. + /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3. ** The ifdef here is to enable us to achieve 100% branch test coverage even - ** when SQLITE_ENABLE_STAT2 is omitted. + ** when SQLITE_ENABLE_STAT3 is omitted. */ -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 if( op==TK_REGISTER ) op = pExpr->op2; #else if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; diff --git a/src/where.c b/src/where.c index 21fb7f45f4..3118a0a0e1 100644 --- a/src/where.c +++ b/src/where.c @@ -118,7 +118,7 @@ struct WhereTerm { #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ #else # define TERM_VNULL 0x00 /* Disabled if not using stat2 */ @@ -1332,7 +1332,7 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 /* When sqlite_stat2 histogram data is available an operator of the ** form "x IS NOT NULL" can sometimes be evaluated more efficiently ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a @@ -1371,7 +1371,7 @@ static void exprAnalyze( pNewTerm->prereqAll = pTerm->prereqAll; } } -#endif /* SQLITE_ENABLE_STAT2 */ +#endif /* SQLITE_ENABLE_STAT */ /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. @@ -2420,67 +2420,70 @@ static void bestVirtualIndex( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ +#ifdef SQLITE_ENABLE_STAT3 /* -** Argument pIdx is a pointer to an index structure that has an array of -** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column -** stored in Index.aSample. These samples divide the domain of values stored -** the index into (SQLITE_INDEX_SAMPLES+1) regions. -** Region 0 contains all values less than the first sample value. Region -** 1 contains values between the first and second samples. Region 2 contains -** values between samples 2 and 3. And so on. Region SQLITE_INDEX_SAMPLES -** contains values larger than the last sample. +** Estimate the location of a particular key among all keys in an +** index. Store the results in aStat as follows: ** -** If the index contains many duplicates of a single value, then it is -** possible that two or more adjacent samples can hold the same value. -** When that is the case, the smallest possible region code is returned -** when roundUp is false and the largest possible region code is returned -** when roundUp is true. +** aStat[0] Est. number of rows less than pVal +** aStat[1] Est. number of rows equal to pVal ** -** If successful, this function determines which of the regions value -** pVal lies in, sets *piRegion to the region index (a value between 0 -** and SQLITE_INDEX_SAMPLES+1, inclusive) and returns SQLITE_OK. -** Or, if an OOM occurs while converting text values between encodings, -** SQLITE_NOMEM is returned and *piRegion is undefined. +** Return SQLITE_OK on success. */ -#ifdef SQLITE_ENABLE_STAT2 -static int whereRangeRegion( +static int whereKeyStats( Parse *pParse, /* Database connection */ Index *pIdx, /* Index to consider domain of */ sqlite3_value *pVal, /* Value to consider */ - int roundUp, /* Return largest valid region if true */ - int *piRegion /* OUT: Region of domain in which value lies */ + int roundUp, /* Round up if true. Round down if false */ + tRowcnt *aStat /* OUT: stats written here */ ){ - assert( roundUp==0 || roundUp==1 ); - if( ALWAYS(pVal) ){ - IndexSample *aSample = pIdx->aSample; - int i = 0; - int eType = sqlite3_value_type(pVal); + tRowcnt n; + IndexSample *aSample; + int i, eType; + int isEq = 0; - if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - double r = sqlite3_value_double(pVal); - for(i=0; i=SQLITE_TEXT ) break; - if( roundUp ){ - if( aSample[i].u.r>r ) break; - }else{ - if( aSample[i].u.r>=r ) break; - } + assert( roundUp==0 || roundUp==1 ); + if( pVal==0 ) return SQLITE_ERROR; + n = pIdx->aiRowEst[0]; + aSample = pIdx->aSample; + i = 0; + eType = sqlite3_value_type(pVal); + + if( eType==SQLITE_INTEGER ){ + i64 v = sqlite3_value_int64(pVal); + for(i=0; inSample; i++){ + if( aSample[i].eType==SQLITE_NULL ) continue; + if( aSample[i].eType>=SQLITE_TEXT ) break; + if( aSample[i].u.i>=v ){ + isEq = aSample[i].u.i==v; + break; } - }else if( eType==SQLITE_NULL ){ - i = 0; - if( roundUp ){ - while( inSample; i++){ + if( aSample[i].eType==SQLITE_NULL ) continue; + if( aSample[i].eType>=SQLITE_TEXT ) break; + if( aSample[i].u.r>=r ){ + isEq = aSample[i].u.r==r; + break; } - }else{ + } + }else if( eType==SQLITE_NULL ){ + i = 0; + if( pIdx->nSample>=1 && aSample[0].eType==SQLITE_NULL ) isEq = 1; + }else{ + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + for(i=0; inSample; i++){ + if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){ + break; + } + } + if( inSample ){ sqlite3 *db = pParse->db; CollSeq *pColl; const u8 *z; int n; - - /* pVal comes from sqlite3ValueFromExpr() so the type cannot be NULL */ - assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); - if( eType==SQLITE_BLOB ){ z = (const u8 *)sqlite3_value_blob(pVal); pColl = db->pDfltColl; @@ -2499,12 +2502,12 @@ static int whereRangeRegion( assert( z && pColl && pColl->xCmp ); } n = sqlite3ValueBytes(pVal, pColl->enc); - - for(i=0; inSample; i++){ int c; int eSampletype = aSample[i].eType; - if( eSampletype==SQLITE_NULL || eSampletypeenc!=SQLITE_UTF8 ){ int nSample; @@ -2522,16 +2525,51 @@ static int whereRangeRegion( { c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); } - if( c-roundUp>=0 ) break; + if( c>=0 ){ + if( c==0 ) isEq = 1; + break; + } } } + } - assert( i>=0 && i<=SQLITE_INDEX_SAMPLES ); - *piRegion = i; + /* At this point, aSample[i] is the first sample that is greater than + ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less + ** than pVal. If aSample[i]==pVal, then isEq==1. + */ + if( isEq ){ + assert( inSample ); + aStat[0] = aSample[i].nLt; + aStat[1] = aSample[i].nEq; + }else{ + tRowcnt iLower, iUpper, iGap; + if( i==0 ){ + iLower = 0; + iUpper = aSample[0].nLt; + }else if( i>=pIdx->nSample ){ + iUpper = n; + iLower = aSample[i].nEq + aSample[i].nLt; + }else{ + iLower = aSample[i-1].nEq + aSample[i-1].nLt; + iUpper = aSample[i].nLt; + } + aStat[1] = pIdx->aiRowEst[1]; + if( iLower>=iUpper ){ + iGap = 0; + }else{ + iGap = iUpper - iLower; + if( iGap>=aStat[1]/2 ) iGap -= aStat[1]/2; + } + if( roundUp ){ + iGap = (iGap*2)/3; + }else{ + iGap = iGap/3; + } + aStat[0] = iLower + iGap; } return SQLITE_OK; } -#endif /* #ifdef SQLITE_ENABLE_STAT2 */ +#endif /* SQLITE_ENABLE_STAT3 */ /* ** If expression pExpr represents a literal value, set *pp to point to @@ -2549,7 +2587,7 @@ static int whereRangeRegion( ** ** If an error occurs, return an error code. Otherwise, SQLITE_OK. */ -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 static int valueFromExpr( Parse *pParse, Expr *pExpr, @@ -2597,17 +2635,15 @@ static int valueFromExpr( ** ** then nEq should be passed 0. ** -** The returned value is an integer between 1 and 100, inclusive. A return -** value of 1 indicates that the proposed range scan is expected to visit -** approximately 1/100th (1%) of the rows selected by the nEq equality -** constraints (if any). A return value of 100 indicates that it is expected -** that the range scan will visit every row (100%) selected by the equality -** constraints. +** The returned value is an integer divisor to reduce the estimated +** search space. A return value of 1 means that range constraints are +** no help at all. A return value of 2 means range constraints are +** expected to reduce the search space by half. And so forth... ** -** In the absence of sqlite_stat2 ANALYZE data, each range inequality -** reduces the search space by 3/4ths. Hence a single constraint (x>?) -** results in a return of 25 and a range constraint (x>? AND x?) +** results in a return of 4 and a range constraint (x>? AND xaCol[] of the range-compared column */ WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ - int *piEst /* OUT: Return value */ + tRowcnt *pRangeDiv /* OUT: Reduce search space by this divisor */ ){ int rc = SQLITE_OK; -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 - if( nEq==0 && p->aSample ){ - sqlite3_value *pLowerVal = 0; - sqlite3_value *pUpperVal = 0; - int iEst; - int iLower = 0; - int iUpper = SQLITE_INDEX_SAMPLES; - int roundUpUpper = 0; - int roundUpLower = 0; + if( nEq==0 && p->nSample ){ + sqlite3_value *pRangeVal; + tRowcnt iLower = 0; + tRowcnt iUpper = p->aiRowEst[0]; + tRowcnt a[2]; u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; if( pLower ){ Expr *pExpr = pLower->pExpr->pRight; - rc = valueFromExpr(pParse, pExpr, aff, &pLowerVal); + rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE ); - roundUpLower = (pLower->eOperator==WO_GT) ?1:0; + if( rc==SQLITE_OK + && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK + ){ + iLower = a[0]; + if( pLower->eOperator==WO_GT ) iLower += a[1]; + } + sqlite3ValueFree(pRangeVal); } if( rc==SQLITE_OK && pUpper ){ Expr *pExpr = pUpper->pExpr->pRight; - rc = valueFromExpr(pParse, pExpr, aff, &pUpperVal); + rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE ); - roundUpUpper = (pUpper->eOperator==WO_LE) ?1:0; - } - - if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){ - sqlite3ValueFree(pLowerVal); - sqlite3ValueFree(pUpperVal); - goto range_est_fallback; - }else if( pLowerVal==0 ){ - rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper); - if( pLower ) iLower = iUpper/2; - }else if( pUpperVal==0 ){ - rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower); - if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2; - }else{ - rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper); - if( rc==SQLITE_OK ){ - rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower); + if( rc==SQLITE_OK + && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK + ){ + iUpper = a[0]; + if( pLower->eOperator==WO_LE ) iUpper += a[1]; } + sqlite3ValueFree(pRangeVal); } - WHERETRACE(("range scan regions: %d..%d\n", iLower, iUpper)); - - iEst = iUpper - iLower; - testcase( iEst==SQLITE_INDEX_SAMPLES ); - assert( iEst<=SQLITE_INDEX_SAMPLES ); - if( iEst<1 ){ - *piEst = 50/SQLITE_INDEX_SAMPLES; - }else{ - *piEst = (iEst*100)/SQLITE_INDEX_SAMPLES; + if( rc==SQLITE_OK ){ + if( iUpper<=iLower ){ + *pRangeDiv = p->aiRowEst[0]; + }else{ + *pRangeDiv = p->aiRowEst[0]/(iUpper - iLower); + } + WHERETRACE(("range scan regions: %u..%u div=%u\n", + (u32)iLower, (u32)iUpper, (u32)*pRangeDiv)); + return SQLITE_OK; } - sqlite3ValueFree(pLowerVal); - sqlite3ValueFree(pUpperVal); - return rc; } -range_est_fallback: #else UNUSED_PARAMETER(pParse); UNUSED_PARAMETER(p); UNUSED_PARAMETER(nEq); #endif assert( pLower || pUpper ); - *piEst = 100; - if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *piEst /= 4; - if( pUpper ) *piEst /= 4; + *pRangeDiv = 1; + if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= 4; + if( pUpper ) *pRangeDiv *= 4; return rc; } -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 /* ** Estimate the number of rows that will be returned based on ** an equality constraint x=VALUE and where that VALUE occurs in ** the histogram data. This only works when x is the left-most -** column of an index and sqlite_stat2 histogram data is available +** column of an index and sqlite_stat3 histogram data is available ** for that index. When pExpr==NULL that means the constraint is ** "x IS NULL" instead of "x=VALUE". ** @@ -2712,10 +2736,9 @@ static int whereEqualScanEst( double *pnRow /* Write the revised row estimate here */ ){ sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ - int iLower, iUpper; /* Range of histogram regions containing pRhs */ u8 aff; /* Column affinity */ int rc; /* Subfunction return code */ - double nRowEst; /* New estimate of the number of rows */ + tRowcnt a[2]; /* Statistics */ assert( p->aSample!=0 ); aff = p->pTable->aCol[p->aiColumn[0]].affinity; @@ -2726,26 +2749,18 @@ static int whereEqualScanEst( pRhs = sqlite3ValueNew(pParse->db); } if( pRhs==0 ) return SQLITE_NOTFOUND; - rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower); - if( rc ) goto whereEqualScanEst_cancel; - rc = whereRangeRegion(pParse, p, pRhs, 1, &iUpper); - if( rc ) goto whereEqualScanEst_cancel; - WHERETRACE(("equality scan regions: %d..%d\n", iLower, iUpper)); - if( iLower>=iUpper ){ - nRowEst = p->aiRowEst[0]/(SQLITE_INDEX_SAMPLES*2); - if( nRowEst<*pnRow ) *pnRow = nRowEst; - }else{ - nRowEst = (iUpper-iLower)*p->aiRowEst[0]/SQLITE_INDEX_SAMPLES; - *pnRow = nRowEst; + rc = whereKeyStats(pParse, p, pRhs, 0, a); + if( rc==SQLITE_OK ){ + WHERETRACE(("equality scan regions: %d\n", (int)a[1])); + *pnRow = a[1]; } - whereEqualScanEst_cancel: sqlite3ValueFree(pRhs); return rc; } -#endif /* defined(SQLITE_ENABLE_STAT2) */ +#endif /* defined(SQLITE_ENABLE_STAT3) */ -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 /* ** Estimate the number of rows that will be returned based on ** an IN constraint where the right-hand side of the IN operator @@ -2768,60 +2783,25 @@ static int whereInScanEst( ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ double *pnRow /* Write the revised row estimate here */ ){ - sqlite3_value *pVal = 0; /* One value from list */ - int iLower, iUpper; /* Range of histogram regions containing pRhs */ - u8 aff; /* Column affinity */ int rc = SQLITE_OK; /* Subfunction return code */ + double nEst; /* Number of rows for a single term */ double nRowEst; /* New estimate of the number of rows */ - int nSpan = 0; /* Number of histogram regions spanned */ - int nSingle = 0; /* Histogram regions hit by a single value */ - int nNotFound = 0; /* Count of values that are not constants */ - int i; /* Loop counter */ - u8 aSpan[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions that are spanned */ - u8 aSingle[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions hit once */ + int i; /* Loop counter */ assert( p->aSample!=0 ); - aff = p->pTable->aCol[p->aiColumn[0]].affinity; - memset(aSpan, 0, sizeof(aSpan)); - memset(aSingle, 0, sizeof(aSingle)); - for(i=0; inExpr; i++){ - sqlite3ValueFree(pVal); - rc = valueFromExpr(pParse, pList->a[i].pExpr, aff, &pVal); - if( rc ) break; - if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ - nNotFound++; - continue; - } - rc = whereRangeRegion(pParse, p, pVal, 0, &iLower); - if( rc ) break; - rc = whereRangeRegion(pParse, p, pVal, 1, &iUpper); - if( rc ) break; - if( iLower>=iUpper ){ - aSingle[iLower] = 1; - }else{ - assert( iLower>=0 && iUpper<=SQLITE_INDEX_SAMPLES ); - while( iLowernExpr; i++){ + nEst = p->aiRowEst[0]; + rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst); + nRowEst += nEst; } if( rc==SQLITE_OK ){ - for(i=nSpan=0; i<=SQLITE_INDEX_SAMPLES; i++){ - if( aSpan[i] ){ - nSpan++; - }else if( aSingle[i] ){ - nSingle++; - } - } - nRowEst = (nSpan*2+nSingle)*p->aiRowEst[0]/(2*SQLITE_INDEX_SAMPLES) - + nNotFound*p->aiRowEst[1]; if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; *pnRow = nRowEst; - WHERETRACE(("IN row estimate: nSpan=%d, nSingle=%d, nNotFound=%d, est=%g\n", - nSpan, nSingle, nNotFound, nRowEst)); + WHERETRACE(("IN row estimate: est=%g\n", nRowEst)); } - sqlite3ValueFree(pVal); return rc; } -#endif /* defined(SQLITE_ENABLE_STAT2) */ +#endif /* defined(SQLITE_ENABLE_STAT3) */ /* @@ -2868,7 +2848,7 @@ static void bestBtreeIndex( int eqTermMask; /* Current mask of valid equality operators */ int idxEqTermMask; /* Index mask of valid equality operators */ Index sPk; /* A fake index object for the primary key */ - unsigned int aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ + tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ int aiColumnPk = -1; /* The aColumn[] value for the sPk index */ int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */ @@ -2923,7 +2903,7 @@ static void bestBtreeIndex( /* Loop over all indices looking for the best one to use */ for(; pProbe; pIdx=pProbe=pProbe->pNext){ - const unsigned int * const aiRowEst = pProbe->aiRowEst; + const tRowcnt * const aiRowEst = pProbe->aiRowEst; double cost; /* Cost of using pProbe */ double nRow; /* Estimated number of rows in result set */ double log10N; /* base-10 logarithm of nRow (inexact) */ @@ -2966,14 +2946,12 @@ static void bestBtreeIndex( ** IN operator must be a SELECT, not a value list, for this variable ** to be true. ** - ** estBound: - ** An estimate on the amount of the table that must be searched. A - ** value of 100 means the entire table is searched. Range constraints - ** might reduce this to a value less than 100 to indicate that only - ** a fraction of the table needs searching. In the absence of - ** sqlite_stat2 ANALYZE data, a single inequality reduces the search - ** space to 1/4rd its original size. So an x>? constraint reduces - ** estBound to 25. Two constraints (x>? AND xeOperator & WO_ISNULL ){ wsFlags |= WHERE_COLUMN_NULL; } -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm; #endif used |= pTerm->prereqRight; } - /* Determine the value of estBound. */ + /* Determine the value of rangeDiv */ if( nEqnColumn && pProbe->bUnordered==0 ){ int j = pProbe->aiColumn[nEq]; if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); - whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound); + whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv); if( pTop ){ nBound = 1; wsFlags |= WHERE_TOP_LIMIT; @@ -3112,7 +3090,7 @@ static void bestBtreeIndex( nInMul = (int)(nRow / aiRowEst[nEq]); } -#ifdef SQLITE_ENABLE_STAT2 +#ifdef SQLITE_ENABLE_STAT3 /* If the constraint is of the form x=VALUE or x IN (E1,E2,...) ** and we do not think that values of x are unique and if histogram ** data is available for column x, then it might be possible @@ -3128,12 +3106,12 @@ static void bestBtreeIndex( whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow); } } -#endif /* SQLITE_ENABLE_STAT2 */ +#endif /* SQLITE_ENABLE_STAT3 */ /* Adjust the number of output rows and downward to reflect rows ** that are excluded by range constraints. */ - nRow = (nRow * (double)estBound) / (double)100; + nRow = nRow/(double)rangeDiv; if( nRow<1 ) nRow = 1; /* Experiments run on real SQLite databases show that the time needed @@ -3262,10 +3240,10 @@ static void bestBtreeIndex( WHERETRACE(( - "%s(%s): nEq=%d nInMul=%d estBound=%d bSort=%d bLookup=%d wsFlags=0x%x\n" + "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n" " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n", pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), - nEq, nInMul, estBound, bSort, bLookup, wsFlags, + nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags, notReady, log10N, nRow, cost, used )); diff --git a/test/auth.test b/test/auth.test index 8d2159ecde..5b97a9d742 100644 --- a/test/auth.test +++ b/test/auth.test @@ -2324,7 +2324,11 @@ ifcapable compound&&subquery { ifcapable stat2 { set stat2 "sqlite_stat2 " } else { - set stat2 "" + ifcapable stat3 { + set stat2 "sqlite_stat3 " + } else { + set stat2 "" + } } do_test auth-5.2 { execsql { diff --git a/test/stat3.test b/test/stat3.test new file mode 100644 index 0000000000..780a69ce67 --- /dev/null +++ b/test/stat3.test @@ -0,0 +1,56 @@ +# 2011 August 08 +# +# 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 implements regression tests for SQLite library. This file +# implements tests for the extra functionality provided by the ANALYZE +# command when the library is compiled with SQLITE_ENABLE_STAT2 defined. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set testprefix stat3 + + +# Verify that if not compiled with SQLITE_ENABLE_STAT2 that the ANALYZE +# command will delete the sqlite_stat2 table. Likewise, if not compiled +# with SQLITE_ENABLE_STAT3, the sqlite_stat3 table is deleted. +# +do_test 1.1 { + db eval { + PRAGMA writable_schema=ON; + CREATE TABLE sqlite_stat2(tbl,idx,sampleno,sample); + CREATE TABLE sqlite_stat3(tbl,idx,sampleno,sample,neq,nlt); + SELECT name FROM sqlite_master ORDER BY 1; + } +} {sqlite_stat2 sqlite_stat3} +do_test 1.2 { + db close + sqlite3 db test.db + db eval {SELECT name FROM sqlite_master ORDER BY 1} +} {sqlite_stat2 sqlite_stat3} + +ifcapable {stat3} { + do_test 1.3 { + db eval {ANALYZE; SELECT name FROM sqlite_master ORDER BY 1} + } {sqlite_stat1 sqlite_stat3} +} else { + do_test 1.4 { + db eval {ANALYZE; SELECT name FROM sqlite_master ORDER BY 1} + } {sqlite_stat1} + finish_test + return +} + + + + +finish_test From ade3addfb541b6db23619af99763732bca468dd6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Aug 2011 00:58:05 +0000 Subject: [PATCH 02/56] The ANALYZE command picks for 15 samples for sqlite_stat3 with the largest nEq fields, plus 5 other evenly spaced samples. FossilOrigin-Name: 8225924ea015a0c331b69134139922ec83f989f8 --- manifest | 15 +-- manifest.uuid | 2 +- src/analyze.c | 304 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 262 insertions(+), 59 deletions(-) diff --git a/manifest b/manifest index 13b45de240..7193488362 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\sa\sbranch\sthat\sexperimentally\sreplaces\ssqlite_stat2\swith\sa\snew\stable\ncalled\ssqlite_stat3\sthat\swill\shopefully\sfacilitate\sbetter\squery\nplanning\sdecisions. -D 2011-08-12T01:51:45.485 +C The\sANALYZE\scommand\spicks\sfor\s15\ssamples\sfor\ssqlite_stat3\swith\sthe\slargest\nnEq\sfields,\splus\s5\sother\sevenly\sspaced\ssamples. +D 2011-08-13T00:58:05.748 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c da6661dbe12f71d37e81c1138cd7b3175fa60a4f +F src/analyze.c 31a1ea5a5a355097aa7a5fce09bbd9ae2a2c7672 F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -958,10 +958,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 6b236069e1ea3c99ff0a007a790d4baebda70b13 -R 28c5bf799a1842cffe08b02c7be0270b -T *branch * stat3-enhancement -T *sym-stat3-enhancement * -T -sym-trunk * +P 52e1d7e8ddd4bb5ef3a9d00fd2d719a8a784f807 +R d14fbf4d209dccbd0b61f66b6e37c6c9 U drh -Z 1615a89a47ce6302aa7ba89aa7dcb40d +Z 59baacb653226a018ea530dc8e60b319 diff --git a/manifest.uuid b/manifest.uuid index 1903efcb65..e910470b5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -52e1d7e8ddd4bb5ef3a9d00fd2d719a8a784f807 \ No newline at end of file +8225924ea015a0c331b69134139922ec83f989f8 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 7ccddfb115..848a939576 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -207,9 +207,214 @@ static void openStatTable( ** Recommended number of samples for sqlite_stat3 */ #ifndef SQLITE_STAT3_SAMPLES -# define SQLITE_STAT3_SAMPLES 16 +# define SQLITE_STAT3_SAMPLES 20 #endif +/* +** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() - +** share an instance of the following structure to hold their state +** information. +*/ +typedef struct Stat3Accum Stat3Accum; +struct Stat3Accum { + tRowcnt nRow; /* Number of rows in the entire table */ + tRowcnt nPSample; /* How often to do a periodic sample */ + int iMin; /* Index of entry with minimum nEq and hash */ + int mxSample; /* Maximum number of samples to accumulate */ + int nSample; /* Current number of samples */ + struct Stat3Sample { + i64 iRowid; /* Rowid in main table of the key */ + tRowcnt nEq; /* sqlite_stat3.nEq */ + tRowcnt nLt; /* sqlite_stat3.nLt */ + u8 isPSample; /* True if a periodic sample */ + u32 iHash; /* Tiebreaker hash */ + } *a; /* An array of samples */ +}; + +#ifdef SQLITE_ENABLE_STAT3 +/* +** Implementation of the stat3_init(C,S) SQL function. The two parameters +** are the number of rows in the table or index (C) and the number of samples +** to accumulate (S). +** +** This routine allocates the Stat3Accum object. +** +** The return value is the Stat3Accum object (P). +*/ +static void stat3Init( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Stat3Accum *p; + tRowcnt nRow; + int mxSample; + int n; + + nRow = (tRowcnt)sqlite3_value_int64(argv[0]); + mxSample = sqlite3_value_int(argv[1]); + n = sizeof(*p) + sizeof(p->a[0])*mxSample; + p = sqlite3_malloc( n ); + if( p==0 ){ + sqlite3_result_error_nomem(context); + return; + } + memset(p, 0, n); + p->a = (struct Stat3Sample*)&p[1]; + p->nRow = nRow; + p->mxSample = mxSample; + p->nPSample = p->nRow/6 + 1; + sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); +} +static const FuncDef stat3InitFuncdef = { + 2, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + stat3Init, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat3_init", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; + + +/* +** Implementation of the stat3_push(nEq,nLt,rowid,P) SQL function. The +** arguments describe a single key instance. This routine makes the +** decision about whether or not to retain this key for the sqlite_stat3 +** table. +** +** The return value is NULL. +*/ +static void stat3Push( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[3]); + tRowcnt nEq = sqlite3_value_int64(argv[0]); + tRowcnt nLt = sqlite3_value_int64(argv[1]); + i64 rowid = sqlite3_value_int64(argv[2]); + u8 isPSample = 0; + u8 doInsert = 0; + int iMin = p->iMin; + struct Stat3Sample *pSample; + int i; + u32 h, h1, h2, h3; + if( nEq==0 ) return; + + h1 = (unsigned)(rowid&0xffff); + h2 = (unsigned)nEq; + h3 = (unsigned)(nLt+1); + h = h1*h2*h3*0x10010001; + + if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){ + doInsert = isPSample = 1; + }else if( p->nSamplemxSample ){ + doInsert = 1; + }else{ + if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){ + doInsert = 1; + } + } + if( !doInsert ) return; + if( p->nSample==p->mxSample ){ + pSample = &p->a[iMin]; + }else{ + pSample = &p->a[p->nSample++]; + } + pSample->iRowid = rowid; + pSample->nEq = nEq; + pSample->nLt = nLt; + pSample->iHash = h; + pSample->isPSample = isPSample; + + /* Find the new minimum */ + if( p->nSample==p->mxSample ){ + pSample = p->a; + i = 0; + while( pSample->isPSample ){ + i++; + pSample++; + assert( inSample ); + } + nEq = pSample->nEq; + h = pSample->iHash; + iMin = i; + for(i++, pSample++; inSample; i++, pSample++){ + if( pSample->isPSample ) continue; + if( pSample->nEqnEq==nEq && pSample->iHashnEq; + h = pSample->iHash; + } + } + p->iMin = iMin; + } +} +static const FuncDef stat3PushFuncdef = { + 3, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + stat3Push, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat3_push", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; + +/* +** Implementation of the stat3_get(P,N,...) SQL function. This routine is +** used to query the results. Content is returned for the Nth sqlite_stat3 +** row where N is between 0 and S-1 and S is the number of samples. The +** value returned depends on the number of arguments. +** +** argc==2 result: rowid +** argc==3 result: nEq +** argc==4 result: nLt +*/ +static void stat3Get( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int n = sqlite3_value_int(argv[1]); + Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]); + + assert( p!=0 ); + if( p->nSample<=n ) return; + switch( argc ){ + case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; + case 3: sqlite3_result_int64(context, p->a[n].nEq); break; + case 4: sqlite3_result_int64(context, p->a[n].nLt); break; + } +} +static const FuncDef stat3GetFuncdef = { + -1, /* nArg */ + SQLITE_UTF8, /* iPrefEnc */ + 0, /* flags */ + 0, /* pUserData */ + 0, /* pNext */ + stat3Get, /* xFunc */ + 0, /* xStep */ + 0, /* xFinalize */ + "stat3_get", /* zName */ + 0, /* pHash */ + 0 /* pDestructor */ +}; +#endif /* SQLITE_ENABLE_STAT3 */ + + + + /* ** Generate code to do an analysis of all indices associated with ** a single table. @@ -234,23 +439,23 @@ static void analyzeOneTable( int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* The stat column of sqlite_stat1 */ #ifdef SQLITE_ENABLE_STAT3 - int regNumEq = iMem-1; /* Number of instances. Same as regStat1 */ + int regNumEq = regStat1; /* Number of instances. Same as regStat1 */ int regNumLt = iMem++; /* Number of keys less than regSample */ int regSample = iMem++; /* The next sample value */ - int regNext = iMem++; /* Index of next sample to record */ - int regSpacing = iMem++; /* Spacing between samples */ - int regBigSize = iMem++; /* Always save entries with nEq >= this */ - int regTemp1 = iMem++; /* Intermediate register */ + int regRowid = regSample; /* Rowid of a sample */ + int regAccum = iMem++; /* Register to hold Stat3Accum object */ + int regLoop = iMem++; /* Loop counter */ int regCount = iMem++; /* Number of rows in the table or index */ - int regGosub = iMem++; /* Register holding subroutine return addr */ + int regTemp1 = iMem++; /* Intermediate register */ + int regTemp2 = iMem++; /* Intermediate register */ int once = 1; /* One-time initialization */ int shortJump = 0; /* Instruction address */ - int addrStoreStat3 = 0; /* Address of subroutine to wrote to stat3 */ + int iTabCur = pParse->nTab++; /* Table cursor */ #endif int regCol = iMem++; /* Content of a column in analyzed table */ int regRec = iMem++; /* Register holding completed record */ int regTemp = iMem++; /* Temporary use register */ - int regRowid = iMem++; /* Rowid for the inserted record */ + int regNewRowid = iMem++; /* Rowid for the inserted record */ v = sqlite3GetVdbe(pParse); @@ -307,41 +512,17 @@ static void analyzeOneTable( sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); #ifdef SQLITE_ENABLE_STAT3 - - /* If this iteration of the loop is generating code to analyze the - ** first index in the pTab->pIndex list, then register regLast has - ** not been populated. In this case populate it now. */ if( once ){ once = 0; - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount); - sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1); - sqlite3VdbeAddOp3(v, OP_Divide, regTemp1, regCount, regSpacing); - sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES/2, regTemp1); - sqlite3VdbeAddOp3(v, OP_Divide, regTemp1, regCount, regBigSize); - - /* Generate code for a subroutine that store the most recent sample - ** in the sqlite_stat3 table - */ - shortJump = sqlite3VdbeAddOp0(v, OP_Goto); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 5, regRec, "bbbbb", 0); - VdbeComment((v, "begin stat3 write subroutine")); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid); - sqlite3VdbeAddOp3(v, OP_Add, regNext, regSpacing, regNext); - sqlite3VdbeAddOp1(v, OP_Return, regGosub); - addrStoreStat3 = - sqlite3VdbeAddOp3(v, OP_Ge, regBigSize, shortJump+1, regNumEq); - sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regTemp1); - sqlite3VdbeAddOp3(v, OP_Ge, regNext, shortJump+1, regTemp1); - sqlite3VdbeAddOp1(v, OP_Return, regGosub); - VdbeComment((v, "end stat3 write subroutine")); - sqlite3VdbeJumpHere(v, shortJump); + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); } - /* Reset state registers */ - sqlite3VdbeAddOp2(v, OP_Copy, regSpacing, regNext); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount); + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1); sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); - + sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum, + (char*)&stat3InitFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 2); #endif /* SQLITE_ENABLE_STAT3 */ /* The block of memory cells initialized here is used as follows. @@ -389,7 +570,7 @@ static void analyzeOneTable( sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); VdbeComment((v, "jump if column %d changed", i)); #ifdef SQLITE_ENABLE_STAT3 - if( i==0 && addrStoreStat3 ){ + if( i==0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1); VdbeComment((v, "incr repeat count")); } @@ -401,8 +582,10 @@ static void analyzeOneTable( if( i==0 ){ sqlite3VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */ #ifdef SQLITE_ENABLE_STAT3 - sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrStoreStat3); - sqlite3VdbeAddOp2(v, OP_Copy, regCol, regSample); + sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, + (char*)&stat3PushFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 4); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid); sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt); sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq); #endif @@ -418,7 +601,30 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop); sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); #ifdef SQLITE_ENABLE_STAT3 - sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrStoreStat3); + sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, + (char*)&stat3PushFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 4); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop); + shortJump = + sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 2); + sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1); + sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1); + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample); + sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 3); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 4); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 5, regRec, "bbbbb", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid); + sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump); + sqlite3VdbeJumpHere(v, shortJump+2); #endif /* Store the results in sqlite_stat1. @@ -453,8 +659,8 @@ static void analyzeOneTable( sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1); } sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); } @@ -473,8 +679,8 @@ static void analyzeOneTable( } sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); if( pParse->nMemnMem = regRec; sqlite3VdbeJumpHere(v, jZeroRows); @@ -504,7 +710,7 @@ static void analyzeDatabase(Parse *pParse, int iDb){ sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab; - pParse->nTab += 2; + pParse->nTab += 3; openStatTable(pParse, iDb, iStatCur, 0, 0); iMem = pParse->nMem+1; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); @@ -529,7 +735,7 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab; - pParse->nTab += 2; + pParse->nTab += 3; if( pOnlyIdx ){ openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); }else{ From f404c86ad7c1cb41954b266f01d6a5b2dac1006e Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Aug 2011 15:25:10 +0000 Subject: [PATCH 03/56] Add the sqlite_stat3.nDLT field. Use an linear congruence PRNG to choose which samples to select from among those with the same nEq field. FossilOrigin-Name: 1dcd24283e6c1cc638eb9ffac434046447f88769 --- manifest | 12 +++++----- manifest.uuid | 2 +- src/analyze.c | 64 ++++++++++++++++++++++++++++++--------------------- 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index 7193488362..1e5050812e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sANALYZE\scommand\spicks\sfor\s15\ssamples\sfor\ssqlite_stat3\swith\sthe\slargest\nnEq\sfields,\splus\s5\sother\sevenly\sspaced\ssamples. -D 2011-08-13T00:58:05.748 +C Add\sthe\ssqlite_stat3.nDLT\sfield.\s\sUse\san\slinear\scongruence\sPRNG\sto\schoose\nwhich\ssamples\sto\sselect\sfrom\samong\sthose\swith\sthe\ssame\snEq\sfield. +D 2011-08-13T15:25:10.607 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 31a1ea5a5a355097aa7a5fce09bbd9ae2a2c7672 +F src/analyze.c 6901cc6e91cc6d4a6b584025f58ec2839783b6c3 F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -958,7 +958,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 52e1d7e8ddd4bb5ef3a9d00fd2d719a8a784f807 -R d14fbf4d209dccbd0b61f66b6e37c6c9 +P 8225924ea015a0c331b69134139922ec83f989f8 +R 26e2ba931d588fb68b0f6f40c6d0c97e U drh -Z 59baacb653226a018ea530dc8e60b319 +Z 3074616e4d36d00fd7fabd4dfdb13fe0 diff --git a/manifest.uuid b/manifest.uuid index e910470b5f..167b946d45 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8225924ea015a0c331b69134139922ec83f989f8 \ No newline at end of file +1dcd24283e6c1cc638eb9ffac434046447f88769 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 848a939576..05512ce3c9 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -19,7 +19,7 @@ ** ** CREATE TABLE sqlite_stat1(tbl, idx, stat); ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); -** CREATE TABLE sqlite_stat3(tbl, idx, nLt, nEq, sample); +** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); ** ** Additional tables might be added in future releases of SQLite. ** The sqlite_stat2 table is not created or used unless the SQLite version @@ -88,12 +88,13 @@ ** ** The format of the sqlite_stat3 table is similar to the format for ** the sqlite_stat2 table, with the following changes: (1) -** The sampleno column is removed. (2) Every sample has nEq and nLt -** columns which hold the approximate number of keys in the table that -** exactly match the sample, and which are less than the sample, -** respectively. (3) The number of samples can very from one table -** to the next; the sample count does not have to be exactly 10 as -** it is with sqlite_stat2. (4) The samples do not have to be evenly spaced. +** The sampleno column is removed. (2) Every sample has nEq, nLt, and nDLt +** columns which hold the approximate number of rows in the table that +** exactly match the sample, the approximate number of rows with values +** less than the sample, and the approximate number of distinct key values +** less than the sample, respectively. (3) The number of samples can very +** from one table to the next; the sample count does not have to be +** exactly 10 as it is with sqlite_stat2. ** ** The ANALYZE command will typically generate sqlite_stat3 tables ** that contain between 10 and 40 samples which are distributed across @@ -132,7 +133,7 @@ static void openStatTable( } aTable[] = { { "sqlite_stat1", "tbl,idx,stat" }, #ifdef SQLITE_ENABLE_STAT3 - { "sqlite_stat3", "tbl,idx,neq,nlt,sample" }, + { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, #endif }; static const char *azToDrop[] = { @@ -207,7 +208,7 @@ static void openStatTable( ** Recommended number of samples for sqlite_stat3 */ #ifndef SQLITE_STAT3_SAMPLES -# define SQLITE_STAT3_SAMPLES 20 +# define SQLITE_STAT3_SAMPLES 24 #endif /* @@ -222,10 +223,12 @@ struct Stat3Accum { int iMin; /* Index of entry with minimum nEq and hash */ int mxSample; /* Maximum number of samples to accumulate */ int nSample; /* Current number of samples */ + u32 iPrn; /* Pseudo-random number used for sampling */ struct Stat3Sample { i64 iRowid; /* Rowid in main table of the key */ tRowcnt nEq; /* sqlite_stat3.nEq */ tRowcnt nLt; /* sqlite_stat3.nLt */ + tRowcnt nDLt; /* sqlite_stat3.nDLt */ u8 isPSample; /* True if a periodic sample */ u32 iHash; /* Tiebreaker hash */ } *a; /* An array of samples */ @@ -263,7 +266,8 @@ static void stat3Init( p->a = (struct Stat3Sample*)&p[1]; p->nRow = nRow; p->mxSample = mxSample; - p->nPSample = p->nRow/6 + 1; + p->nPSample = p->nRow/(mxSample/3+1) + 1; + sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); } static const FuncDef stat3InitFuncdef = { @@ -282,7 +286,7 @@ static const FuncDef stat3InitFuncdef = { /* -** Implementation of the stat3_push(nEq,nLt,rowid,P) SQL function. The +** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The ** arguments describe a single key instance. This routine makes the ** decision about whether or not to retain this key for the sqlite_stat3 ** table. @@ -294,23 +298,20 @@ static void stat3Push( int argc, sqlite3_value **argv ){ - Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[3]); + Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]); tRowcnt nEq = sqlite3_value_int64(argv[0]); tRowcnt nLt = sqlite3_value_int64(argv[1]); - i64 rowid = sqlite3_value_int64(argv[2]); + tRowcnt nDLt = sqlite3_value_int64(argv[2]); + i64 rowid = sqlite3_value_int64(argv[3]); u8 isPSample = 0; u8 doInsert = 0; int iMin = p->iMin; struct Stat3Sample *pSample; int i; - u32 h, h1, h2, h3; + u32 h; if( nEq==0 ) return; - h1 = (unsigned)(rowid&0xffff); - h2 = (unsigned)nEq; - h3 = (unsigned)(nLt+1); - h = h1*h2*h3*0x10010001; - + h = p->iPrn = p->iPrn*1103515245 + 12345; if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){ doInsert = isPSample = 1; }else if( p->nSamplemxSample ){ @@ -322,13 +323,17 @@ static void stat3Push( } if( !doInsert ) return; if( p->nSample==p->mxSample ){ - pSample = &p->a[iMin]; + if( iMinnSample ){ + memcpy(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin)); + } + pSample = &p->a[p->nSample-1]; }else{ pSample = &p->a[p->nSample++]; } pSample->iRowid = rowid; pSample->nEq = nEq; pSample->nLt = nLt; + pSample->nDLt = nDLt; pSample->iHash = h; pSample->isPSample = isPSample; @@ -358,7 +363,7 @@ static void stat3Push( } } static const FuncDef stat3PushFuncdef = { - 3, /* nArg */ + 5, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ 0, /* pUserData */ @@ -380,6 +385,7 @@ static const FuncDef stat3PushFuncdef = { ** argc==2 result: rowid ** argc==3 result: nEq ** argc==4 result: nLt +** argc==5 result: nDLt */ static void stat3Get( sqlite3_context *context, @@ -395,6 +401,7 @@ static void stat3Get( case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; case 3: sqlite3_result_int64(context, p->a[n].nEq); break; case 4: sqlite3_result_int64(context, p->a[n].nLt); break; + case 5: sqlite3_result_int64(context, p->a[n].nDLt); break; } } static const FuncDef stat3GetFuncdef = { @@ -441,6 +448,7 @@ static void analyzeOneTable( #ifdef SQLITE_ENABLE_STAT3 int regNumEq = regStat1; /* Number of instances. Same as regStat1 */ int regNumLt = iMem++; /* Number of keys less than regSample */ + int regNumDLt = iMem++; /* Number of distinct keys less than regSample */ int regSample = iMem++; /* The next sample value */ int regRowid = regSample; /* Rowid of a sample */ int regAccum = iMem++; /* Register to hold Stat3Accum object */ @@ -520,6 +528,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1); sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt); sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum, (char*)&stat3InitFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 2); @@ -584,9 +593,10 @@ static void analyzeOneTable( #ifdef SQLITE_ENABLE_STAT3 sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, (char*)&stat3PushFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 4); + sqlite3VdbeChangeP5(v, 5); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid); sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt); + sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1); sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq); #endif } @@ -603,7 +613,7 @@ static void analyzeOneTable( #ifdef SQLITE_ENABLE_STAT3 sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, (char*)&stat3PushFuncdef, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, 4); + sqlite3VdbeChangeP5(v, 5); sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop); shortJump = sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1); @@ -620,7 +630,10 @@ static void analyzeOneTable( sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt, (char*)&stat3GetFuncdef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, 4); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 5, regRec, "bbbbb", 0); + sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt, + (char*)&stat3GetFuncdef, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, 5); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0); sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid); sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump); @@ -953,8 +966,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){ sqlite3_finalize(pStmt); zSql = sqlite3MPrintf(db, - "SELECT idx,nlt,neq,sample FROM %Q.sqlite_stat3" - " ORDER BY idx, nlt", zDb); + "SELECT idx,nlt,neq,sample FROM %Q.sqlite_stat3", zDb); if( !zSql ){ return SQLITE_NOMEM; } From 4e50c5ec48d11b6bad8b34a99d9829eadd6ddf6a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 13 Aug 2011 19:35:19 +0000 Subject: [PATCH 04/56] Further testing and bug fixing for sqlite_stat3. Added the Index.avgEq field to index statistics. Fixed several problems in the query planner associated with stat3. FossilOrigin-Name: 89b2f70884cad0abdf4c66cb64ecddb2820ded74 --- manifest | 32 +++++----- manifest.uuid | 2 +- src/analyze.c | 29 ++++++--- src/build.c | 2 +- src/sqliteInt.h | 2 + src/where.c | 59 +++++++++++------- test/analyze.test | 20 +++--- test/analyze3.test | 8 +-- test/analyze5.test | 146 +++++++++++++++++++++----------------------- test/analyze7.test | 22 ++++--- test/dbstatus.test | 14 ++++- test/stat3.test | 4 +- test/unordered.test | 6 +- 13 files changed, 188 insertions(+), 158 deletions(-) diff --git a/manifest b/manifest index 1e5050812e..635de7d9bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite_stat3.nDLT\sfield.\s\sUse\san\slinear\scongruence\sPRNG\sto\schoose\nwhich\ssamples\sto\sselect\sfrom\samong\sthose\swith\sthe\ssame\snEq\sfield. -D 2011-08-13T15:25:10.607 +C Further\stesting\sand\sbug\sfixing\sfor\ssqlite_stat3.\s\sAdded\sthe\sIndex.avgEq\nfield\sto\sindex\sstatistics.\s\sFixed\sseveral\sproblems\sin\sthe\squery\splanner\nassociated\swith\sstat3. +D 2011-08-13T19:35:19.088 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 6901cc6e91cc6d4a6b584025f58ec2839783b6c3 +F src/analyze.c c04d95f4dc82b94250c4053ca36cc52b42f257ea F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -127,7 +127,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 8c46f0ab69ad9549c75a3a91fed87abdaa743e2f F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c 4165efa323b4d3678a6b39fddb775627c18e9a80 +F src/build.c cd77ae979219d6363234b506de28c71f217063e1 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 0df87f944b17c17c6b3976a9758d8af2802e1b19 @@ -183,7 +183,7 @@ F src/select.c d219c4b68d603cc734b6f9b1e2780fee12a1fa0d F src/shell.c bbe7818ff5bc8614105ceb81ad67b8bdc0b671dd F src/sqlite.h.in e8eb090406b9a743befff4c387aa3bd5eeae661e F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 -F src/sqliteInt.h a4c0124ff6dbbf325002b4a34248cc08453c9739 +F src/sqliteInt.h f491be51e47267ae1454317fbd3438382e60fdb3 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -250,7 +250,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 24d95b218176bad38ae2abe73197c28d3d6ef9a6 +F src/where.c 118896232fe70b1ac9c2ef2811675d5bef8b9c40 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -260,13 +260,13 @@ F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060 F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d F test/alter4.test b2debc14d8cbe4c1d12ccd6a41eef88a8c1f15d5 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc -F test/analyze.test 68b43c1f9cd6ffc3bbb30d27a23712b38c413eca +F test/analyze.test f8ab7d15858b4093b06caf5e57e2a5ff7104bdae F test/analyze2.test 8f2b1534d43f5547ce9a6b736c021d4192c75be3 -F test/analyze3.test d61f55d8b472fc6e713160b1e577f7a68e63f38b +F test/analyze3.test d5e4da00a37b927d83aead50626c254a785c111f F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045 -F test/analyze5.test 1de8d66b11aae5a1453aa042d62e834a476bac9c +F test/analyze5.test 713354664c5ff1853ab2cbcb740f0cf5cb7c802e F test/analyze6.test c125622a813325bba1b4999040ddc213773c2290 -F test/analyze7.test 5508e7828164ea0b518ed219bed7320a481863d4 +F test/analyze7.test d3587aa5af75c9048d031b94fceca2534fa75d1d F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 @@ -359,7 +359,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff -F test/dbstatus.test a719af0f226bd280748a4bb9054c0a5a9fc1b16c +F test/dbstatus.test 9eb484ba837c6f3f9bbcaecc29e6060a8c3ba6d2 F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa @@ -682,7 +682,7 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 0997f6a57a35866b14111ed361ed8851ce7978ae -F test/stat3.test 44cec64164a2f5d86960343a118bc0bdac754f61 +F test/stat3.test 986d735f70ef62a1daf98e8762f35fa3b062c5c3 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 @@ -851,7 +851,7 @@ F test/types2.test 3555aacf8ed8dc883356e59efc314707e6247a84 F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e -F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced +F test/unordered.test f53095cee37851bf30130fa1bf299a8845e837bb F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 F test/uri.test 53de9a2549cbda9c343223236918ef502f6a9051 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae @@ -958,7 +958,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 8225924ea015a0c331b69134139922ec83f989f8 -R 26e2ba931d588fb68b0f6f40c6d0c97e +P 1dcd24283e6c1cc638eb9ffac434046447f88769 +R d1b65b54090c71db8593e348e48cfb27 U drh -Z 3074616e4d36d00fd7fabd4dfdb13fe0 +Z 11276de2d321825346f710e3928eda70 diff --git a/manifest.uuid b/manifest.uuid index 167b946d45..12a95a47e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dcd24283e6c1cc638eb9ffac434046447f88769 \ No newline at end of file +89b2f70884cad0abdf4c66cb64ecddb2820ded74 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 05512ce3c9..f67e26e8c1 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -957,6 +957,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){ assert( pIdx->nSample==0 ); pIdx->nSample = (u8)nSample; pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); + pIdx->avgEq = pIdx->aiRowEst[1]; if( pIdx->aSample==0 ){ db->mallocFailed = 1; sqlite3_finalize(pStmt); @@ -966,7 +967,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){ sqlite3_finalize(pStmt); zSql = sqlite3MPrintf(db, - "SELECT idx,nlt,neq,sample FROM %Q.sqlite_stat3", zDb); + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb); if( !zSql ){ return SQLITE_NOMEM; } @@ -977,6 +978,8 @@ static int loadStat3(sqlite3 *db, const char *zDb){ while( sqlite3_step(pStmt)==SQLITE_ROW ){ char *zIndex; /* Index name */ Index *pIdx; /* Pointer to the index object */ + int i; /* Loop counter */ + tRowcnt sumEq; /* Sum of the nEq values */ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; @@ -990,17 +993,25 @@ static int loadStat3(sqlite3 *db, const char *zDb){ } assert( idxnSample ); pSample = &pIdx->aSample[idx]; - pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 1); - pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 2); - eType = sqlite3_column_type(pStmt, 3); + pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1); + pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2); + pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3); + if( idx==pIdx->nSample-1 ){ + if( pSample->nDLt>0 ){ + for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq; + pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt; + } + if( pIdx->avgEq<=0 ) pIdx->avgEq = 1; + } + eType = sqlite3_column_type(pStmt, 4); pSample->eType = (u8)eType; switch( eType ){ case SQLITE_INTEGER: { - pSample->u.i = sqlite3_column_int64(pStmt, 3); + pSample->u.i = sqlite3_column_int64(pStmt, 4); break; } case SQLITE_FLOAT: { - pSample->u.r = sqlite3_column_double(pStmt, 3); + pSample->u.r = sqlite3_column_double(pStmt, 4); break; } case SQLITE_NULL: { @@ -1009,10 +1020,10 @@ static int loadStat3(sqlite3 *db, const char *zDb){ default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); { const char *z = (const char *)( (eType==SQLITE_BLOB) ? - sqlite3_column_blob(pStmt, 3): - sqlite3_column_text(pStmt, 3) + sqlite3_column_blob(pStmt, 4): + sqlite3_column_text(pStmt, 4) ); - int n = sqlite3_column_bytes(pStmt, 2); + int n = sqlite3_column_bytes(pStmt, 4); if( n>0xffff ) n = 0xffff; pSample->nByte = (u16)n; if( n < 1){ diff --git a/src/build.c b/src/build.c index 73c51c8550..7277a42d0c 100644 --- a/src/build.c +++ b/src/build.c @@ -2062,7 +2062,6 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); - sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); if( !isView && !IsVirtual(pTab) ){ destroyTable(pParse, pTab); } @@ -2174,6 +2173,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3FkDropTable(pParse, pName, pTab); sqlite3CodeDropTable(pParse, pTab, iDb, isView); + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); } exit_drop_table: diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6bb14b60b8..f437b20370 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1502,6 +1502,7 @@ struct Index { u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ #ifdef SQLITE_ENABLE_STAT3 + tRowcnt avgEq; /* Average nEq value for key values not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ #endif }; @@ -1520,6 +1521,7 @@ struct IndexSample { u16 nByte; /* Size in byte of text or blob. */ tRowcnt nEq; /* Est. number of rows where the key equals this sample */ tRowcnt nLt; /* Est. number of rows where key is less than this sample */ + tRowcnt nDLt; /* Est. number of distinct keys less than this sample */ }; /* diff --git a/src/where.c b/src/where.c index 3118a0a0e1..fe8bd90498 100644 --- a/src/where.c +++ b/src/where.c @@ -2441,6 +2441,8 @@ static int whereKeyStats( IndexSample *aSample; int i, eType; int isEq = 0; + i64 v; + double r, rS; assert( roundUp==0 || roundUp==1 ); if( pVal==0 ) return SQLITE_ERROR; @@ -2450,22 +2452,36 @@ static int whereKeyStats( eType = sqlite3_value_type(pVal); if( eType==SQLITE_INTEGER ){ - i64 v = sqlite3_value_int64(pVal); + v = sqlite3_value_int64(pVal); + r = (i64)v; for(i=0; inSample; i++){ if( aSample[i].eType==SQLITE_NULL ) continue; if( aSample[i].eType>=SQLITE_TEXT ) break; - if( aSample[i].u.i>=v ){ - isEq = aSample[i].u.i==v; - break; + if( aSample[i].eType==SQLITE_INTEGER ){ + if( aSample[i].u.i>=v ){ + isEq = aSample[i].u.i==v; + break; + } + }else{ + assert( aSample[i].eType==SQLITE_FLOAT ); + if( aSample[i].u.r>=r ){ + isEq = aSample[i].u.r==r; + break; + } } } }else if( eType==SQLITE_FLOAT ){ - double r = sqlite3_value_double(pVal); + r = sqlite3_value_double(pVal); for(i=0; inSample; i++){ if( aSample[i].eType==SQLITE_NULL ) continue; if( aSample[i].eType>=SQLITE_TEXT ) break; - if( aSample[i].u.r>=r ){ - isEq = aSample[i].u.r==r; + if( aSample[i].eType==SQLITE_FLOAT ){ + rS = aSample[i].u.r; + }else{ + rS = aSample[i].u.i; + } + if( rS>=r ){ + isEq = rS==r; break; } } @@ -2546,14 +2562,11 @@ static int whereKeyStats( if( i==0 ){ iLower = 0; iUpper = aSample[0].nLt; - }else if( i>=pIdx->nSample ){ - iUpper = n; - iLower = aSample[i].nEq + aSample[i].nLt; }else{ + iUpper = i>=pIdx->nSample ? n : aSample[i].nLt; iLower = aSample[i-1].nEq + aSample[i-1].nLt; - iUpper = aSample[i].nLt; } - aStat[1] = pIdx->aiRowEst[1]; + aStat[1] = pIdx->avgEq; if( iLower>=iUpper ){ iGap = 0; }else{ @@ -2651,7 +2664,7 @@ static int whereRangeScanEst( int nEq, /* index into p->aCol[] of the range-compared column */ WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ - tRowcnt *pRangeDiv /* OUT: Reduce search space by this divisor */ + double *pRangeDiv /* OUT: Reduce search space by this divisor */ ){ int rc = SQLITE_OK; @@ -2684,18 +2697,18 @@ static int whereRangeScanEst( && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK ){ iUpper = a[0]; - if( pLower->eOperator==WO_LE ) iUpper += a[1]; + if( pUpper->eOperator==WO_LE ) iUpper += a[1]; } sqlite3ValueFree(pRangeVal); } if( rc==SQLITE_OK ){ if( iUpper<=iLower ){ - *pRangeDiv = p->aiRowEst[0]; + *pRangeDiv = (double)p->aiRowEst[0]; }else{ - *pRangeDiv = p->aiRowEst[0]/(iUpper - iLower); + *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower); } - WHERETRACE(("range scan regions: %u..%u div=%u\n", - (u32)iLower, (u32)iUpper, (u32)*pRangeDiv)); + WHERETRACE(("range scan regions: %u..%u div=%g\n", + (u32)iLower, (u32)iUpper, *pRangeDiv)); return SQLITE_OK; } } @@ -2705,9 +2718,9 @@ static int whereRangeScanEst( UNUSED_PARAMETER(nEq); #endif assert( pLower || pUpper ); - *pRangeDiv = 1; - if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= 4; - if( pUpper ) *pRangeDiv *= 4; + *pRangeDiv = (double)1; + if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4; + if( pUpper ) *pRangeDiv *= (double)4; return rc; } @@ -2976,7 +2989,7 @@ static void bestBtreeIndex( int nEq; /* Number of == or IN terms matching index */ int bInEst = 0; /* True if "x IN (SELECT...)" seen */ int nInMul = 1; /* Number of distinct equalities to lookup */ - tRowcnt rangeDiv = 1; /* Estimated reduction in search space */ + double rangeDiv = (double)1; /* Estimated reduction in search space */ int nBound = 0; /* Number of range constraints seen */ int bSort = !!pOrderBy; /* True if external sort required */ int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */ @@ -3111,7 +3124,7 @@ static void bestBtreeIndex( /* Adjust the number of output rows and downward to reflect rows ** that are excluded by range constraints. */ - nRow = nRow/(double)rangeDiv; + nRow = nRow/rangeDiv; if( nRow<1 ) nRow = 1; /* Experiments run on real SQLite databases show that the time needed diff --git a/test/analyze.test b/test/analyze.test index 6bb8cc363c..362702a9c2 100644 --- a/test/analyze.test +++ b/test/analyze.test @@ -288,7 +288,7 @@ do_test analyze-4.3 { } {} # Verify that DROP TABLE and DROP INDEX remove entries from the -# sqlite_stat1 and sqlite_stat2 tables. +# sqlite_stat1 and sqlite_stat3 tables. # do_test analyze-5.0 { execsql { @@ -306,11 +306,11 @@ do_test analyze-5.0 { SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1; } } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4} -ifcapable stat2 { +ifcapable stat3 { do_test analyze-5.1 { execsql { - SELECT DISTINCT idx FROM sqlite_stat2 ORDER BY 1; - SELECT DISTINCT tbl FROM sqlite_stat2 ORDER BY 1; + SELECT DISTINCT idx FROM sqlite_stat3 ORDER BY 1; + SELECT DISTINCT tbl FROM sqlite_stat3 ORDER BY 1; } } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4} } @@ -321,11 +321,11 @@ do_test analyze-5.2 { SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1; } } {t3i1 t3i3 t4i1 t4i2 t3 t4} -ifcapable stat2 { +ifcapable stat3 { do_test analyze-5.3 { execsql { - SELECT DISTINCT idx FROM sqlite_stat2 ORDER BY 1; - SELECT DISTINCT tbl FROM sqlite_stat2 ORDER BY 1; + SELECT DISTINCT idx FROM sqlite_stat3 ORDER BY 1; + SELECT DISTINCT tbl FROM sqlite_stat3 ORDER BY 1; } } {t3i1 t3i3 t4i1 t4i2 t3 t4} } @@ -336,11 +336,11 @@ do_test analyze-5.4 { SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1; } } {t4i1 t4i2 t4} -ifcapable stat2 { +ifcapable stat3 { do_test analyze-5.5 { execsql { - SELECT DISTINCT idx FROM sqlite_stat2 ORDER BY 1; - SELECT DISTINCT tbl FROM sqlite_stat2 ORDER BY 1; + SELECT DISTINCT idx FROM sqlite_stat3 ORDER BY 1; + SELECT DISTINCT tbl FROM sqlite_stat3 ORDER BY 1; } } {t4i1 t4i2 t4} } diff --git a/test/analyze3.test b/test/analyze3.test index 2378ffaaba..2c8e42d607 100644 --- a/test/analyze3.test +++ b/test/analyze3.test @@ -97,10 +97,10 @@ do_test analyze3-1.1.1 { do_eqp_test analyze3-1.1.2 { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x? AND x0 AND x<1100 -} {0 0 0 {SCAN TABLE t1 (~111 rows)}} +} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? and x200 AND x<300 } @@ -193,7 +193,7 @@ do_test analyze3-1.3.1 { } {} do_eqp_test analyze3-1.3.2 { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 -} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x? AND x0 AND x<1100 } {0 0 0 {SCAN TABLE t3 (~111 rows)}} @@ -248,7 +248,7 @@ do_test analyze3-2.1 { } {} do_eqp_test analyze3-2.2 { SELECT count(a) FROM t1 WHERE b LIKE 'a%' -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b? AND b=0 AND z<=0} t1z 400 2 {z>=1 AND z<=1} t1z 300 - 3 {z>=2 AND z<=2} t1z 200 - 4 {z>=3 AND z<=3} t1z 100 - 5 {z>=4 AND z<=4} t1z 50 - 6 {z>=-1 AND z<=-1} t1z 50 - 7 {z>1 AND z<3} t1z 200 + 3 {z>=2 AND z<=2} t1z 175 + 4 {z>=3 AND z<=3} t1z 125 + 5 {z>=4 AND z<=4} t1z 1 + 6 {z>=-1 AND z<=-1} t1z 1 + 7 {z>1 AND z<3} t1z 175 8 {z>0 AND z<100} t1z 600 9 {z>=1 AND z<100} t1z 600 10 {z>1 AND z<100} t1z 300 11 {z>=2 AND z<100} t1z 300 - 12 {z>2 AND z<100} t1z 100 - 13 {z>=3 AND z<100} t1z 100 - 14 {z>3 AND z<100} t1z 50 - 15 {z>=4 AND z<100} t1z 50 - 16 {z>=-100 AND z<=-1} t1z 50 + 12 {z>2 AND z<100} t1z 125 + 13 {z>=3 AND z<100} t1z 125 + 14 {z>3 AND z<100} t1z 1 + 15 {z>=4 AND z<100} t1z 1 + 16 {z>=-100 AND z<=-1} t1z 1 17 {z>=-100 AND z<=0} t1z 400 - 18 {z>=-100 AND z<0} t1z 50 + 18 {z>=-100 AND z<0} t1z 1 19 {z>=-100 AND z<=1} t1z 700 20 {z>=-100 AND z<2} t1z 700 - 21 {z>=-100 AND z<=2} t1z 900 - 22 {z>=-100 AND z<3} t1z 900 + 21 {z>=-100 AND z<=2} t1z 875 + 22 {z>=-100 AND z<3} t1z 875 31 {z>=0.0 AND z<=0.0} t1z 400 32 {z>=1.0 AND z<=1.0} t1z 300 - 33 {z>=2.0 AND z<=2.0} t1z 200 - 34 {z>=3.0 AND z<=3.0} t1z 100 - 35 {z>=4.0 AND z<=4.0} t1z 50 - 36 {z>=-1.0 AND z<=-1.0} t1z 50 - 37 {z>1.5 AND z<3.0} t1z 200 - 38 {z>0.5 AND z<100} t1z 600 + 33 {z>=2.0 AND z<=2.0} t1z 175 + 34 {z>=3.0 AND z<=3.0} t1z 125 + 35 {z>=4.0 AND z<=4.0} t1z 1 + 36 {z>=-1.0 AND z<=-1.0} t1z 1 + 37 {z>1.5 AND z<3.0} t1z 174 + 38 {z>0.5 AND z<100} t1z 599 39 {z>=1.0 AND z<100} t1z 600 - 40 {z>1.5 AND z<100} t1z 300 + 40 {z>1.5 AND z<100} t1z 299 41 {z>=2.0 AND z<100} t1z 300 - 42 {z>2.1 AND z<100} t1z 100 - 43 {z>=3.0 AND z<100} t1z 100 - 44 {z>3.2 AND z<100} t1z 50 - 45 {z>=4.0 AND z<100} t1z 50 - 46 {z>=-100 AND z<=-1.0} t1z 50 + 42 {z>2.1 AND z<100} t1z 124 + 43 {z>=3.0 AND z<100} t1z 125 + 44 {z>3.2 AND z<100} t1z 1 + 45 {z>=4.0 AND z<100} t1z 1 + 46 {z>=-100 AND z<=-1.0} t1z 1 47 {z>=-100 AND z<=0.0} t1z 400 - 48 {z>=-100 AND z<0.0} t1z 50 + 48 {z>=-100 AND z<0.0} t1z 1 49 {z>=-100 AND z<=1.0} t1z 700 50 {z>=-100 AND z<2.0} t1z 700 - 51 {z>=-100 AND z<=2.0} t1z 900 - 52 {z>=-100 AND z<3.0} t1z 900 + 51 {z>=-100 AND z<=2.0} t1z 875 + 52 {z>=-100 AND z<3.0} t1z 875 - 101 {z=-1} t1z 50 + 101 {z=-1} t1z 1 102 {z=0} t1z 400 103 {z=1} t1z 300 - 104 {z=2} t1z 200 - 105 {z=3} t1z 100 - 106 {z=4} t1z 50 - 107 {z=-10.0} t1z 50 + 104 {z=2} t1z 175 + 105 {z=3} t1z 125 + 106 {z=4} t1z 1 + 107 {z=-10.0} t1z 1 108 {z=0.0} t1z 400 109 {z=1.0} t1z 300 - 110 {z=2.0} t1z 200 - 111 {z=3.0} t1z 100 - 112 {z=4.0} t1z 50 - 113 {z=1.5} t1z 50 - 114 {z=2.5} t1z 50 + 110 {z=2.0} t1z 175 + 111 {z=3.0} t1z 125 + 112 {z=4.0} t1z 1 + 113 {z=1.5} t1z 1 + 114 {z=2.5} t1z 1 - 201 {z IN (-1)} t1z 50 + 201 {z IN (-1)} t1z 1 202 {z IN (0)} t1z 400 203 {z IN (1)} t1z 300 - 204 {z IN (2)} t1z 200 - 205 {z IN (3)} t1z 100 - 206 {z IN (4)} t1z 50 - 207 {z IN (0.5)} t1z 50 + 204 {z IN (2)} t1z 175 + 205 {z IN (3)} t1z 125 + 206 {z IN (4)} t1z 1 + 207 {z IN (0.5)} t1z 1 208 {z IN (0,1)} t1z 700 - 209 {z IN (0,1,2)} t1z 900 + 209 {z IN (0,1,2)} t1z 875 210 {z IN (0,1,2,3)} {} 100 211 {z IN (0,1,2,3,4,5)} {} 100 - 212 {z IN (1,2)} t1z 500 + 212 {z IN (1,2)} t1z 475 213 {z IN (2,3)} t1z 300 214 {z=3 OR z=2} t1z 300 - 215 {z IN (-1,3)} t1z 150 - 216 {z=-1 OR z=3} t1z 150 + 215 {z IN (-1,3)} t1z 126 + 216 {z=-1 OR z=3} t1z 126 - 300 {y=0} {} 100 - 301 {y=1} t1y 50 - 302 {y=0.1} t1y 50 + 300 {y=0} t1y 974 + 301 {y=1} t1y 26 + 302 {y=0.1} t1y 1 400 {x IS NULL} t1x 400 @@ -204,16 +192,17 @@ db eval { # Verify that range queries generate the correct row count estimates # foreach {testid where index rows} { - 500 {x IS NULL AND u='charlie'} t1u 20 - 501 {x=1 AND u='charlie'} t1x 5 - 502 {x IS NULL} {} 100 - 503 {x=1} t1x 50 - 504 {x IS NOT NULL} t1x 25 + 500 {x IS NULL AND u='charlie'} t1u 17 + 501 {x=1 AND u='charlie'} t1x 1 + 502 {x IS NULL} t1x 995 + 503 {x=1} t1x 1 + 504 {x IS NOT NULL} t1x 2 505 {+x IS NOT NULL} {} 500 506 {upper(x) IS NOT NULL} {} 500 } { # Verify that the expected index is used with the expected row count +if {$testid==50299} {breakpoint; set sqlite_where_trace 1} do_test analyze5-1.${testid}a { set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3] set idx {} @@ -221,6 +210,7 @@ foreach {testid where index rows} { regexp {~([0-9]+) rows} $x all nrow list $idx $nrow } [list $index $rows] +if {$testid==50299} exit # Verify that the same result is achieved regardless of whether or not # the index is used diff --git a/test/analyze7.test b/test/analyze7.test index 4892a2233a..5bdb04d72c 100644 --- a/test/analyze7.test +++ b/test/analyze7.test @@ -82,14 +82,14 @@ do_test analyze7-3.1 { do_test analyze7-3.2.1 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}} -ifcapable stat2 { - # If ENABLE_STAT2 is defined, SQLite comes up with a different estimated +ifcapable stat3 { + # If ENABLE_STAT3 is defined, SQLite comes up with a different estimated # row count for (c=2) than it does for (c=?). do_test analyze7-3.2.2 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} - } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~51 rows)}} + } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~57 rows)}} } else { - # If ENABLE_STAT2 is not defined, the expected row count for (c=2) is the + # If ENABLE_STAT3 is not defined, the expected row count for (c=2) is the # same as that for (c=?). do_test analyze7-3.2.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;} @@ -98,12 +98,14 @@ ifcapable stat2 { do_test analyze7-3.3 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}} -do_test analyze7-3.4 { - execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}} -do_test analyze7-3.5 { - execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123} -} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}} +ifcapable {!stat3} { + do_test analyze7-3.4 { + execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123} + } {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}} + do_test analyze7-3.5 { + execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123} + } {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}} +} do_test analyze7-3.6 { execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123} } {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?) (~1 rows)}} diff --git a/test/dbstatus.test b/test/dbstatus.test index 39522f4857..e1c8f3ebbf 100644 --- a/test/dbstatus.test +++ b/test/dbstatus.test @@ -56,6 +56,12 @@ proc lookaside {db} { } } +ifcapable stat3 { + set STAT3 1 +} else { + set STAT3 0 +} + #--------------------------------------------------------------------------- # Run the dbstatus-2 and dbstatus-3 tests with several of different # lookaside buffer sizes. @@ -118,7 +124,7 @@ foreach ::lookaside_buffer_size {0 64 120} { CREATE TABLE t2(c, d); CREATE VIEW v1 AS SELECT * FROM t1 UNION SELECT * FROM t2; } - 6 { + 6y { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a); CREATE INDEX i2 ON t1(a,b); @@ -198,7 +204,11 @@ foreach ::lookaside_buffer_size {0 64 120} { # much greater than just that reported by DBSTATUS_SCHEMA_USED in this # case. # - if {[string match *x $tn] || $AUTOVACUUM} { + # Some of the memory used for sqlite_stat3 is unaccounted for by + # dbstatus. + # + if {[string match *x $tn] || $AUTOVACUUM + || ([string match *y $tn] && $STAT3)} { do_test dbstatus-2.$tn.ax { expr {($nSchema1-$nSchema2)<=$nFree} } 1 } else { do_test dbstatus-2.$tn.a { expr {$nSchema1-$nSchema2} } $nFree diff --git a/test/stat3.test b/test/stat3.test index 780a69ce67..6c848192c1 100644 --- a/test/stat3.test +++ b/test/stat3.test @@ -11,7 +11,7 @@ # # This file implements regression tests for SQLite library. This file # implements tests for the extra functionality provided by the ANALYZE -# command when the library is compiled with SQLITE_ENABLE_STAT2 defined. +# command when the library is compiled with SQLITE_ENABLE_STAT3 defined. # set testdir [file dirname $argv0] @@ -28,7 +28,7 @@ do_test 1.1 { db eval { PRAGMA writable_schema=ON; CREATE TABLE sqlite_stat2(tbl,idx,sampleno,sample); - CREATE TABLE sqlite_stat3(tbl,idx,sampleno,sample,neq,nlt); + CREATE TABLE sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample); SELECT name FROM sqlite_master ORDER BY 1; } } {sqlite_stat2 sqlite_stat3} diff --git a/test/unordered.test b/test/unordered.test index a9c6253432..6c7c2bb25b 100644 --- a/test/unordered.test +++ b/test/unordered.test @@ -31,11 +31,13 @@ do_execsql_test 1.0 { } {} foreach idxmode {ordered unordered} { + catchsql { DELETE FROM sqlite_stat2 } + catchsql { DELETE FROM sqlite_stat3 } if {$idxmode == "unordered"} { execsql { UPDATE sqlite_stat1 SET stat = stat || ' unordered' } - db close - sqlite3 db test.db } + db close + sqlite3 db test.db foreach {tn sql r(ordered) r(unordered)} { 1 "SELECT * FROM t1 ORDER BY a" {0 0 0 {SCAN TABLE t1 USING INDEX i1 (~128 rows)}} From 23e7c4de7b8d88ca1cc03b3288a52bd2e9af8a14 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 15 Aug 2011 12:02:21 +0000 Subject: [PATCH 05/56] Fix a couple of typos in comments in analyze.c. FossilOrigin-Name: ae31dc67aa0637150f964de31a6da6f5797b462a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 635de7d9bf..4ef9e851b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\stesting\sand\sbug\sfixing\sfor\ssqlite_stat3.\s\sAdded\sthe\sIndex.avgEq\nfield\sto\sindex\sstatistics.\s\sFixed\sseveral\sproblems\sin\sthe\squery\splanner\nassociated\swith\sstat3. -D 2011-08-13T19:35:19.088 +C Fix\sa\scouple\sof\stypos\sin\scomments\sin\sanalyze.c. +D 2011-08-15T12:02:21.660 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c c04d95f4dc82b94250c4053ca36cc52b42f257ea +F src/analyze.c 8a41063db56d2fe4735a1ae4dd556b37df1702e1 F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -958,7 +958,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 1dcd24283e6c1cc638eb9ffac434046447f88769 -R d1b65b54090c71db8593e348e48cfb27 -U drh -Z 11276de2d321825346f710e3928eda70 +P 89b2f70884cad0abdf4c66cb64ecddb2820ded74 +R 9884d3dd8105ab98ebe71de1c72e2a2b +U dan +Z b401be2988daefedc016cbb2d3ab24a6 diff --git a/manifest.uuid b/manifest.uuid index 12a95a47e2..5d52dcb26d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -89b2f70884cad0abdf4c66cb64ecddb2820ded74 \ No newline at end of file +ae31dc67aa0637150f964de31a6da6f5797b462a \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index f67e26e8c1..0ba9b2bfae 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -65,7 +65,7 @@ ** the index belongs. There are usually 10 rows in the sqlite_stat2 ** table for each index. ** -** The sqlite_stat2 entires for an index that have sampleno between 0 and 9 +** The sqlite_stat2 entries for an index that have sampleno between 0 and 9 ** inclusive are samples of the left-most key value in the index taken at ** evenly spaced points along the index. Let the number of samples be S ** (10 in the standard build) and let C be the number of rows in the index. @@ -92,7 +92,7 @@ ** columns which hold the approximate number of rows in the table that ** exactly match the sample, the approximate number of rows with values ** less than the sample, and the approximate number of distinct key values -** less than the sample, respectively. (3) The number of samples can very +** less than the sample, respectively. (3) The number of samples can vary ** from one table to the next; the sample count does not have to be ** exactly 10 as it is with sqlite_stat2. ** From 50a1c56a2e466eb45db9e67510ee193f2fa7ff65 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 15 Aug 2011 12:58:23 +0000 Subject: [PATCH 06/56] Update some test cases to work with sqlite_stat3 instead of sqlite_stat2. FossilOrigin-Name: 2504bcfb0cf14b5ce51db0af1269ac28384714e0 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- test/alter.test | 1 + test/analyze3.test | 30 +++++++++++++++--------------- test/analyze6.test | 2 +- test/tkt-cbd054fa6b.test | 6 +++--- 6 files changed, 31 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index 4ef9e851b5..6e35346e9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sof\stypos\sin\scomments\sin\sanalyze.c. -D 2011-08-15T12:02:21.660 +C Update\ssome\stest\scases\sto\swork\swith\ssqlite_stat3\sinstead\sof\ssqlite_stat2. +D 2011-08-15T12:58:23.538 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -255,17 +255,17 @@ F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 52fc8dee494092031a556911d404ca30a749a30b -F test/alter.test 5314fc01ef51ab8af0b8890725b710ed48d4806b +F test/alter.test 54912d932309df2e4f62aeb47169c2ff740e53ed F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060 F test/alter3.test 49c9d9fba2b8fcdce2dedeca97bbf1f369cc548d F test/alter4.test b2debc14d8cbe4c1d12ccd6a41eef88a8c1f15d5 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/analyze.test f8ab7d15858b4093b06caf5e57e2a5ff7104bdae F test/analyze2.test 8f2b1534d43f5547ce9a6b736c021d4192c75be3 -F test/analyze3.test d5e4da00a37b927d83aead50626c254a785c111f +F test/analyze3.test 7bcadc47589fd730f9a12ffc9b30a520d7f6931b F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045 F test/analyze5.test 713354664c5ff1853ab2cbcb740f0cf5cb7c802e -F test/analyze6.test c125622a813325bba1b4999040ddc213773c2290 +F test/analyze6.test bd3625806a5ee6f7bef72d06295bd319f0290af2 F test/analyze7.test d3587aa5af75c9048d031b94fceca2534fa75d1d F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b @@ -734,7 +734,7 @@ F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 F test/tkt-b72787b1.test e6b62b2b2785c04d0d698d6a603507e384165049 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 -F test/tkt-cbd054fa6b.test f14f97ea43662e6f70c9e63287081e8be5d9d589 +F test/tkt-cbd054fa6b.test bd9fb546f63bc0c79d1776978d059fa51c5b1c63 F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7 F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 F test/tkt-d82e3f3721.test 731359dfdcdb36fea0559cd33fec39dd0ceae8e6 @@ -958,7 +958,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 89b2f70884cad0abdf4c66cb64ecddb2820ded74 -R 9884d3dd8105ab98ebe71de1c72e2a2b -U dan -Z b401be2988daefedc016cbb2d3ab24a6 +P ae31dc67aa0637150f964de31a6da6f5797b462a +R db03066face0c75eaaff8230204f24b2 +U drh +Z 4658be3708d6f87baa530d35bdb7827f diff --git a/manifest.uuid b/manifest.uuid index 5d52dcb26d..fd01eb5171 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae31dc67aa0637150f964de31a6da6f5797b462a \ No newline at end of file +2504bcfb0cf14b5ce51db0af1269ac28384714e0 \ No newline at end of file diff --git a/test/alter.test b/test/alter.test index 4d5a484b2e..e915d26c50 100644 --- a/test/alter.test +++ b/test/alter.test @@ -847,6 +847,7 @@ set system_table_list {1 sqlite_master} catchsql ANALYZE ifcapable analyze { lappend system_table_list 2 sqlite_stat1 } ifcapable stat2 { lappend system_table_list 3 sqlite_stat2 } +ifcapable stat3 { lappend system_table_list 4 sqlite_stat3 } foreach {tn tbl} $system_table_list { do_test alter-15.$tn.1 { diff --git a/test/analyze3.test b/test/analyze3.test index 2c8e42d607..9ac15c4680 100644 --- a/test/analyze3.test +++ b/test/analyze3.test @@ -17,7 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -ifcapable !stat2 { +ifcapable !stat3 { finish_test return } @@ -100,7 +100,7 @@ do_eqp_test analyze3-1.1.2 { } {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x0 AND x<1100 -} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? and x? AND x200 AND x<300 } @@ -117,17 +117,17 @@ do_test analyze3-1.1.6 { } {199 0 14850} do_test analyze3-1.1.7 { sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 } -} {999 999 499500} +} {2000 0 499500} do_test analyze3-1.1.8 { set l [string range "0" 0 end] set u [string range "1100" 0 end] sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u } -} {999 999 499500} +} {2000 0 499500} do_test analyze3-1.1.9 { set l [expr int(0)] set u [expr int(1100)] sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u } -} {999 999 499500} +} {2000 0 499500} # The following tests are similar to the block above. The difference is @@ -146,10 +146,10 @@ do_test analyze3-1.2.1 { } {} do_eqp_test analyze3-1.2.2 { SELECT sum(y) FROM t2 WHERE x>1 AND x<2 -} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x? AND x0 AND x<99 -} {0 0 0 {SCAN TABLE t2 (~111 rows)}} +} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x12 AND x<20 } } {161 0 4760} @@ -165,17 +165,17 @@ do_test analyze3-1.2.6 { } {161 0 integer integer 4760} do_test analyze3-1.2.7 { sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 } -} {999 999 490555} +} {1981 0 490555} do_test analyze3-1.2.8 { set l [string range "0" 0 end] set u [string range "99" 0 end] sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u} -} {999 999 text text 490555} +} {1981 0 text text 490555} do_test analyze3-1.2.9 { set l [expr int(0)] set u [expr int(99)] sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u} -} {999 999 integer integer 490555} +} {1981 0 integer integer 490555} # Same tests a third time. This time, column x has INTEGER affinity and # is not the leftmost column of the table. This triggered a bug causing @@ -193,10 +193,10 @@ do_test analyze3-1.3.1 { } {} do_eqp_test analyze3-1.3.2 { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 -} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x? AND x0 AND x<1100 -} {0 0 0 {SCAN TABLE t3 (~111 rows)}} +} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x200 AND x<300 } @@ -213,17 +213,17 @@ do_test analyze3-1.3.6 { } {199 0 14850} do_test analyze3-1.3.7 { sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 } -} {999 999 499500} +} {2000 0 499500} do_test analyze3-1.3.8 { set l [string range "0" 0 end] set u [string range "1100" 0 end] sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u } -} {999 999 499500} +} {2000 0 499500} do_test analyze3-1.3.9 { set l [expr int(0)] set u [expr int(1100)] sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u } -} {999 999 499500} +} {2000 0 499500} #------------------------------------------------------------------------- # Test that the values of bound SQL variables may be used for the LIKE diff --git a/test/analyze6.test b/test/analyze6.test index b090b5b091..74b7ec7984 100644 --- a/test/analyze6.test +++ b/test/analyze6.test @@ -17,7 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -ifcapable !stat2 { +ifcapable !stat3 { finish_test return } diff --git a/test/tkt-cbd054fa6b.test b/test/tkt-cbd054fa6b.test index 6e7455b3a3..180acf56df 100644 --- a/test/tkt-cbd054fa6b.test +++ b/test/tkt-cbd054fa6b.test @@ -16,7 +16,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -ifcapable !stat2 { +ifcapable !stat3 { finish_test return } @@ -46,7 +46,7 @@ do_test tkt-cbd05-1.2 { do_test tkt-cbd05-1.3 { execsql { SELECT tbl,idx,group_concat(sample,' ') - FROM sqlite_stat2 + FROM sqlite_stat3 WHERE idx = 't1_x' GROUP BY tbl,idx } @@ -78,7 +78,7 @@ do_test tkt-cbd05-2.2 { do_test tkt-cbd05-2.3 { execsql { SELECT tbl,idx,group_concat(sample,' ') - FROM sqlite_stat2 + FROM sqlite_stat3 WHERE idx = 't1_x' GROUP BY tbl,idx } From 461728d3d0097fc8cd17727ee42fef56741b88ea Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Aug 2011 01:15:12 +0000 Subject: [PATCH 07/56] Add the analyze8.test test module for sqlite_stat3. FossilOrigin-Name: 2c83ac89dc5a6017587defb541c9f3731b98892a --- manifest | 11 ++--- manifest.uuid | 2 +- test/analyze8.test | 103 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 test/analyze8.test diff --git a/manifest b/manifest index 6e35346e9a..dfb25817e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\ssome\stest\scases\sto\swork\swith\ssqlite_stat3\sinstead\sof\ssqlite_stat2. -D 2011-08-15T12:58:23.538 +C Add\sthe\sanalyze8.test\stest\smodule\sfor\ssqlite_stat3. +D 2011-08-16T01:15:12.193 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -267,6 +267,7 @@ F test/analyze4.test 757b37875cf9bb528d46f74497bc789c88365045 F test/analyze5.test 713354664c5ff1853ab2cbcb740f0cf5cb7c802e F test/analyze6.test bd3625806a5ee6f7bef72d06295bd319f0290af2 F test/analyze7.test d3587aa5af75c9048d031b94fceca2534fa75d1d +F test/analyze8.test 4ca170de2ba30ccb1af2c0406803db72262f9691 F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 @@ -958,7 +959,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P ae31dc67aa0637150f964de31a6da6f5797b462a -R db03066face0c75eaaff8230204f24b2 +P 2504bcfb0cf14b5ce51db0af1269ac28384714e0 +R 5a73b64fef41c0e56d473c9564281bab U drh -Z 4658be3708d6f87baa530d35bdb7827f +Z db81907234b1038bee781d0d0d68d5d7 diff --git a/manifest.uuid b/manifest.uuid index fd01eb5171..64e6a035d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2504bcfb0cf14b5ce51db0af1269ac28384714e0 \ No newline at end of file +2c83ac89dc5a6017587defb541c9f3731b98892a \ No newline at end of file diff --git a/test/analyze8.test b/test/analyze8.test new file mode 100644 index 0000000000..f3e2710abe --- /dev/null +++ b/test/analyze8.test @@ -0,0 +1,103 @@ +# 2011 August 13 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests for SQLite library. The focus of the tests +# in this file is testing the capabilities of sqlite_stat3. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !stat3 { + finish_test + return +} + +set testprefix analyze8 + +proc eqp {sql {db db}} { + uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db +} + +# Scenario: +# +# Two indices. One has mostly singleton entries, but for a few +# values there are hundreds of entries. The other has 10-20 +# entries per value. +# +# Verify that the query planner chooses the first index for the singleton +# entries and the second index for the others. +# +do_test 1.0 { + db eval { + CREATE TABLE t1(a,b,c,d); + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1b ON t1(b); + CREATE INDEX t1c ON t1(c); + } + for {set i 0} {$i<1000} {incr i} { + if {$i%2==0} {set a $i} {set a [expr {($i%8)*100}]} + set b [expr {$i/10}] + set c [expr {$i/8}] + set c [expr {$c*$c*$c}] + db eval {INSERT INTO t1 VALUES($a,$b,$c,$i)} + } + db eval {ANALYZE} +} {} + +# The a==100 comparison is expensive because there are many rows +# with a==100. And so for those cases, choose the t1b index. +# +# Buf ro a==99 and a==101, there are far fewer rows so choose +# the t1a index. +# +do_test 1.1 { + eqp {SELECT * FROM t1 WHERE a=100 AND b=55} +} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}} +do_test 1.2 { + eqp {SELECT * FROM t1 WHERE a=99 AND b=55} +} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}} +do_test 1.3 { + eqp {SELECT * FROM t1 WHERE a=101 AND b=55} +} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}} +do_test 1.4 { + eqp {SELECT * FROM t1 WHERE a=100 AND b=56} +} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}} +do_test 1.5 { + eqp {SELECT * FROM t1 WHERE a=99 AND b=56} +} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}} +do_test 1.6 { + eqp {SELECT * FROM t1 WHERE a=101 AND b=56} +} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}} +do_test 2.1 { + eqp {SELECT * FROM t1 WHERE a=100 AND b BETWEEN 50 AND 54} +} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b? AND b? AND c? AND c Date: Tue, 16 Aug 2011 02:07:04 +0000 Subject: [PATCH 08/56] Allow the sqlite3VdbeJumpHere() routine to accept a negative or zero address if a prior memory allocation error has occurred. The new sqlite_stat3 logic needs this. FossilOrigin-Name: 9650d7962804d61f56cac944ff9bb2c7bc111957 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index dfb25817e0..b75563c2cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sanalyze8.test\stest\smodule\sfor\ssqlite_stat3. -D 2011-08-16T01:15:12.193 +C Allow\sthe\ssqlite3VdbeJumpHere()\sroutine\sto\saccept\sa\snegative\sor\szero\saddress\nif\sa\sprior\smemory\sallocation\serror\shas\soccurred.\s\sThe\snew\ssqlite_stat3\slogic\nneeds\sthis. +D 2011-08-16T02:07:04.573 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -242,7 +242,7 @@ F src/vdbe.c 49d834f0fe49d305e07f9c212e94007fda2028e9 F src/vdbe.h 5cf09e7ee8a3f7d93bc51f196a96550786afe7a1 F src/vdbeInt.h ad84226cc0adcb1185c22b70696b235a1678bb45 F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98 -F src/vdbeaux.c 4d100407e3c72e163854aff8903d19d5ecdf46c0 +F src/vdbeaux.c 05eb4457899f09c2a2eb0bff26844023cf6544f8 F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3 F src/vdbemem.c 74410d1639869b309d6fe1e8cbc02a557157a7c2 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114 @@ -959,7 +959,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 2504bcfb0cf14b5ce51db0af1269ac28384714e0 -R 5a73b64fef41c0e56d473c9564281bab +P 2c83ac89dc5a6017587defb541c9f3731b98892a +R 1450328cb5bbd53defdba59501aa7ba3 U drh -Z db81907234b1038bee781d0d0d68d5d7 +Z d5f58e0bf7dc218c29e54b5a642cee65 diff --git a/manifest.uuid b/manifest.uuid index 64e6a035d2..fdfada439b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c83ac89dc5a6017587defb541c9f3731b98892a \ No newline at end of file +9650d7962804d61f56cac944ff9bb2c7bc111957 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 989a8003d3..dae366017d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -572,8 +572,8 @@ void sqlite3VdbeChangeP5(Vdbe *p, u8 val){ ** the address of the next instruction to be coded. */ void sqlite3VdbeJumpHere(Vdbe *p, int addr){ - assert( addr>=0 ); - sqlite3VdbeChangeP2(p, addr, p->nOp); + assert( addr>=0 || p->db->mallocFailed ); + if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp); } From 6825719667cd6c7a15f6cc160e01e8d11641f172 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Aug 2011 17:06:21 +0000 Subject: [PATCH 09/56] Fix a few harmless compiler warnings. Add SQLITE_ENABLE_STAT3 to the standard compiler warning script. FossilOrigin-Name: 3d68f9afee02f95103eb1682b8f2362f8d249437 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/analyze.c | 10 +++++++--- src/where.c | 9 ++++----- tool/warnings.sh | 4 ++-- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index b75563c2cb..e28f8e0d61 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sthe\ssqlite3VdbeJumpHere()\sroutine\sto\saccept\sa\snegative\sor\szero\saddress\nif\sa\sprior\smemory\sallocation\serror\shas\soccurred.\s\sThe\snew\ssqlite_stat3\slogic\nneeds\sthis. -D 2011-08-16T02:07:04.573 +C Fix\sa\sfew\sharmless\scompiler\swarnings.\s\sAdd\sSQLITE_ENABLE_STAT3\sto\sthe\nstandard\scompiler\swarning\sscript. +D 2011-08-16T17:06:21.985 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 8a41063db56d2fe4735a1ae4dd556b37df1702e1 +F src/analyze.c f436b0f53be47fbc03c661ec7c2b4c5fec14077e F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -250,7 +250,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 118896232fe70b1ac9c2ef2811675d5bef8b9c40 +F src/where.c 3d9a78a422726c1b3a57188c3099e537cb18e18a F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -958,8 +958,8 @@ F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262 -P 2c83ac89dc5a6017587defb541c9f3731b98892a -R 1450328cb5bbd53defdba59501aa7ba3 +F tool/warnings.sh 682b359e1531c8d4c805e2c1b5656b2d76e481e3 +P 9650d7962804d61f56cac944ff9bb2c7bc111957 +R f1db5c89fee04ee43fcb815b658cde4c U drh -Z d5f58e0bf7dc218c29e54b5a642cee65 +Z 935e4c47860333dc9df37a80ab259764 diff --git a/manifest.uuid b/manifest.uuid index fdfada439b..80c96250c0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9650d7962804d61f56cac944ff9bb2c7bc111957 \ No newline at end of file +3d68f9afee02f95103eb1682b8f2362f8d249437 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 0ba9b2bfae..f7dba4b6b8 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -254,6 +254,7 @@ static void stat3Init( int mxSample; int n; + UNUSED_PARAMETER(argc); nRow = (tRowcnt)sqlite3_value_int64(argv[0]); mxSample = sqlite3_value_int(argv[1]); n = sizeof(*p) + sizeof(p->a[0])*mxSample; @@ -309,8 +310,10 @@ static void stat3Push( struct Stat3Sample *pSample; int i; u32 h; - if( nEq==0 ) return; + UNUSED_PARAMETER(context); + UNUSED_PARAMETER(argc); + if( nEq==0 ) return; h = p->iPrn = p->iPrn*1103515245 + 12345; if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){ doInsert = isPSample = 1; @@ -497,7 +500,7 @@ static void analyzeOneTable( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; KeyInfo *pKey; - int addrIfNot; /* address of OP_IfNot */ + int addrIfNot = 0; /* address of OP_IfNot */ int *aChngAddr; /* Array of jump instruction addresses */ if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; @@ -907,6 +910,7 @@ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ } sqlite3_free(pIdx->aSample); } + UNUSED_PARAMETER(db); pIdx->nSample = 0; pIdx->aSample = 0; #else @@ -925,7 +929,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){ sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ char *zSql; /* Text of the SQL statement */ Index *pPrevIdx = 0; /* Previous index in the loop */ - int idx; /* slot in pIdx->aSample[] for next sample */ + int idx = 0; /* slot in pIdx->aSample[] for next sample */ int eType; /* Datatype of a sample */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ diff --git a/src/where.c b/src/where.c index fe8bd90498..33969c0439 100644 --- a/src/where.c +++ b/src/where.c @@ -2499,7 +2499,6 @@ static int whereKeyStats( sqlite3 *db = pParse->db; CollSeq *pColl; const u8 *z; - int n; if( eType==SQLITE_BLOB ){ z = (const u8 *)sqlite3_value_blob(pVal); pColl = db->pDfltColl; @@ -2796,10 +2795,10 @@ static int whereInScanEst( ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ double *pnRow /* Write the revised row estimate here */ ){ - int rc = SQLITE_OK; /* Subfunction return code */ - double nEst; /* Number of rows for a single term */ - double nRowEst; /* New estimate of the number of rows */ - int i; /* Loop counter */ + int rc = SQLITE_OK; /* Subfunction return code */ + double nEst; /* Number of rows for a single term */ + double nRowEst = (double)0; /* New estimate of the number of rows */ + int i; /* Loop counter */ assert( p->aSample!=0 ); for(i=0; rc==SQLITE_OK && inExpr; i++){ diff --git a/tool/warnings.sh b/tool/warnings.sh index 2eb3992f09..29b54374ef 100644 --- a/tool/warnings.sh +++ b/tool/warnings.sh @@ -8,9 +8,9 @@ echo '********** No optimizations. Includes FTS4 and RTREE *********' gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \ sqlite3.c -echo '********** No optimizations. ENABLE_STAT2. THREADSAFE=0 *******' +echo '********** No optimizations. ENABLE_STAT3. THREADSAFE=0 *******' gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ - -ansi -DSQLITE_ENABLE_STAT2 -DSQLITE_THREADSAFE=0 \ + -ansi -DSQLITE_ENABLE_STAT3 -DSQLITE_THREADSAFE=0 \ sqlite3.c echo '********** Optimized -O3. Includes FTS4 and RTREE ************' gcc -O3 -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \ From 88ab5b08ad1c9a47019072d2232fdea7f7b8b80a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2011 01:10:35 +0000 Subject: [PATCH 10/56] Fix an error with OOM processing in the ANALYZE logic. FossilOrigin-Name: b26ec79c69f44b55bc4bb11e293f11b3afa3b724 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e28f8e0d61..a1306c7652 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sfew\sharmless\scompiler\swarnings.\s\sAdd\sSQLITE_ENABLE_STAT3\sto\sthe\nstandard\scompiler\swarning\sscript. -D 2011-08-16T17:06:21.985 +C Fix\san\serror\swith\sOOM\sprocessing\sin\sthe\sANALYZE\slogic. +D 2011-08-18T01:10:35.659 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c f436b0f53be47fbc03c661ec7c2b4c5fec14077e +F src/analyze.c 6beb1c0a3b44ed0b841a332dea992a6b52422497 F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -959,7 +959,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 682b359e1531c8d4c805e2c1b5656b2d76e481e3 -P 9650d7962804d61f56cac944ff9bb2c7bc111957 -R f1db5c89fee04ee43fcb815b658cde4c +P 3d68f9afee02f95103eb1682b8f2362f8d249437 +R 6062edeb95e40a6916ef4809b7eeeeb7 U drh -Z 935e4c47860333dc9df37a80ab259764 +Z 87a9c9bfca0f09248c3abec58d88b5e3 diff --git a/manifest.uuid b/manifest.uuid index 80c96250c0..28fa0e8ce3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d68f9afee02f95103eb1682b8f2362f8d249437 \ No newline at end of file +b26ec79c69f44b55bc4bb11e293f11b3afa3b724 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index f7dba4b6b8..f812db344a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -506,12 +506,12 @@ static void analyzeOneTable( if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); nCol = pIdx->nColumn; + aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol); + if( aChngAddr==0 ) continue; pKey = sqlite3IndexKeyinfo(pParse, pIdx); if( iMem+1+(nCol*2)>pParse->nMem ){ pParse->nMem = iMem+1+(nCol*2); } - aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*pIdx->nColumn); - if( aChngAddr==0 ) continue; /* Open a cursor to the index to be analyzed. */ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); From fc0ce2a83e90a6d596c09c44f680c167a54212cf Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2011 02:51:21 +0000 Subject: [PATCH 11/56] Fix a bug in the cleanup of stat tables on a DROP TABLE in autovacuum mode. FossilOrigin-Name: 3fe5d54f635f7b27851d256e417f21b91febb871 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a1306c7652..42bf53b67d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\swith\sOOM\sprocessing\sin\sthe\sANALYZE\slogic. -D 2011-08-18T01:10:35.659 +C Fix\sa\sbug\sin\sthe\scleanup\sof\sstat\stables\son\sa\sDROP\sTABLE\sin\sautovacuum\smode. +D 2011-08-18T02:51:21.105 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -127,7 +127,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 8c46f0ab69ad9549c75a3a91fed87abdaa743e2f F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c cd77ae979219d6363234b506de28c71f217063e1 +F src/build.c 4534f8c4b1747e8305b5351100ce24ae3fd2b256 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 0df87f944b17c17c6b3976a9758d8af2802e1b19 @@ -959,7 +959,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 682b359e1531c8d4c805e2c1b5656b2d76e481e3 -P 3d68f9afee02f95103eb1682b8f2362f8d249437 -R 6062edeb95e40a6916ef4809b7eeeeb7 +P b26ec79c69f44b55bc4bb11e293f11b3afa3b724 +R f2393c9ff880d16764503970806408ba U drh -Z 87a9c9bfca0f09248c3abec58d88b5e3 +Z 766e55b80580eb08573c3a4577419339 diff --git a/manifest.uuid b/manifest.uuid index 28fa0e8ce3..d5e295a3e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b26ec79c69f44b55bc4bb11e293f11b3afa3b724 \ No newline at end of file +3fe5d54f635f7b27851d256e417f21b91febb871 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 7277a42d0c..8f1148c198 100644 --- a/src/build.c +++ b/src/build.c @@ -2075,7 +2075,6 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); sqlite3ChangeCookie(pParse, iDb); sqliteViewResetAll(db, iDb); - } /* @@ -2171,9 +2170,9 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ v = sqlite3GetVdbe(pParse); if( v ){ sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); sqlite3FkDropTable(pParse, pName, pTab); sqlite3CodeDropTable(pParse, pTab, iDb, isView); - sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); } exit_drop_table: From 8e3937ff0d2a69ba1fa5d530d214929a603fdf3d Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 18 Aug 2011 13:45:23 +0000 Subject: [PATCH 12/56] Fix the stat3 analysis loader to be compatible with sqlite3_db_status(). Also fix some OOM issues with the stat3 analysis loader. FossilOrigin-Name: eaf447ea87b0ff29ae06283204f522fcd005b284 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 16 +++++++++------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 42bf53b67d..fa38621865 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sthe\scleanup\sof\sstat\stables\son\sa\sDROP\sTABLE\sin\sautovacuum\smode. -D 2011-08-18T02:51:21.105 +C Fix\sthe\sstat3\sanalysis\sloader\sto\sbe\scompatible\swith\ssqlite3_db_status().\nAlso\sfix\ssome\sOOM\sissues\swith\sthe\sstat3\sanalysis\sloader. +D 2011-08-18T13:45:23.575 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 1e6988b3c11dee9bd5edc0c804bd4468d74a9cdc F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 6beb1c0a3b44ed0b841a332dea992a6b52422497 +F src/analyze.c 3fbffcfbc606d73fa996ded1f874eddffbb06d09 F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c @@ -959,7 +959,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh 682b359e1531c8d4c805e2c1b5656b2d76e481e3 -P b26ec79c69f44b55bc4bb11e293f11b3afa3b724 -R f2393c9ff880d16764503970806408ba +P 3fe5d54f635f7b27851d256e417f21b91febb871 +R 9217825cb5191e88bf95b5e4ba6d99d3 U drh -Z 766e55b80580eb08573c3a4577419339 +Z 7bc5368e818d03d3e9a11991cb532d98 diff --git a/manifest.uuid b/manifest.uuid index d5e295a3e5..cf35c9b6a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3fe5d54f635f7b27851d256e417f21b91febb871 \ No newline at end of file +eaf447ea87b0ff29ae06283204f522fcd005b284 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index f812db344a..316f0ecad9 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -905,14 +905,15 @@ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ for(j=0; jnSample; j++){ IndexSample *p = &pIdx->aSample[j]; if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ - sqlite3_free(p->u.z); + sqlite3DbFree(db, p->u.z); } } - sqlite3_free(pIdx->aSample); + sqlite3DbFree(db, pIdx->aSample); + } + if( db && db->pnBytesFreed==0 ){ + pIdx->nSample = 0; + pIdx->aSample = 0; } - UNUSED_PARAMETER(db); - pIdx->nSample = 0; - pIdx->aSample = 0; #else UNUSED_PARAMETER(db); UNUSED_PARAMETER(pIdx); @@ -968,7 +969,8 @@ static int loadStat3(sqlite3 *db, const char *zDb){ return SQLITE_NOMEM; } } - sqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); + if( rc ) return rc; zSql = sqlite3MPrintf(db, "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb); @@ -1027,7 +1029,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){ sqlite3_column_blob(pStmt, 4): sqlite3_column_text(pStmt, 4) ); - int n = sqlite3_column_bytes(pStmt, 4); + int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; if( n>0xffff ) n = 0xffff; pSample->nByte = (u16)n; if( n < 1){ From 9d56acdcfcb3a28240ce3fdf6f54f5c7b145be47 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Sep 2011 20:56:59 +0000 Subject: [PATCH 13/56] Minor comment change in the description of the different memory allocator options. No changes to code. FossilOrigin-Name: 36be31ff0af7f811fe2c6f7e26f058cffb7257e1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4fa7069d09..95538b272e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.7.8\srelease\scandidate -D 2011-09-19T14:49:19.255 +C Minor\scomment\schange\sin\sthe\sdescription\sof\sthe\sdifferent\smemory\sallocator\noptions.\s\sNo\schanges\sto\scode. +D 2011-09-19T20:56:59.410 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c 13fe2aeddc3cc90d6a273831d1f63736d1596f81 F src/sqlite.h.in 0a6c9c23337fd1352c5c75a613ff9533aa7d91cb F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 -F src/sqliteInt.h feb4f2b212fe36bbd951e44d2490c6aacf02f689 +F src/sqliteInt.h 76d81cd9da0618b231398bfcf90556e971972fca F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -963,7 +963,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P db019465036171fcad31181bec7d6ac185f50430 -R 0a2782a80f1b08369498ecce1d7a7aa8 +P 3e0da808d2f5b4d12046e05980ca04578f581177 +R 8185767b36f8ee5089cf1856ba34ec13 U drh -Z 5f8dabab2a44903caad40fc4aceed901 +Z dd5a6c14bafead231702b31c9079bdda diff --git a/manifest.uuid b/manifest.uuid index 6cc03efd83..f3b3da0f66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e0da808d2f5b4d12046e05980ca04578f581177 \ No newline at end of file +36be31ff0af7f811fe2c6f7e26f058cffb7257e1 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 65b0aa1fc6..f0fc6abf2a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -156,7 +156,7 @@ ** assertion will be triggered. ** ** (Historical note: There used to be several other options, but we've -** pared it down to just these two.) +** pared it down to just these three.) ** ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. From 0ae479dff2767e2825745c808dcfa0d69d762a64 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Sep 2011 16:43:07 +0000 Subject: [PATCH 14/56] Change the way the sqlite3_analyzer executable is built. FossilOrigin-Name: 05e3cced8a884e8bca6f208d2f09e335d3929eac --- main.mk | 20 +++++++-------- manifest | 18 ++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 67 ++++++++++++++++++++++++++++--------------------- src/test_stat.c | 9 ++++--- 5 files changed, 65 insertions(+), 51 deletions(-) diff --git a/main.mk b/main.mk index aab3706272..a1f7233140 100644 --- a/main.mk +++ b/main.mk @@ -518,6 +518,16 @@ tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a $(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \ $(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB) +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl + echo "#define TCLSH 2" > $@ + cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@ + echo "static const char *tclsh_main_loop(void){" >> $@ + echo "static const char *zMainloop = " >> $@ + $(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@ + echo "; return zMainloop; }" >> $@ + +sqlite3_analyzer$(EXE): sqlite3_analyzer.c spaceanal_tcl.h + $(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) # Rules to build the 'testfixture' application. # @@ -560,16 +570,6 @@ threadtest3$(EXE): sqlite3.o $(TOP)/test/threadtest3.c $(TOP)/test/tt3_checkpoin threadtest: threadtest3$(EXE) ./threadtest3$(EXE) -sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \ - $(TOP)/tool/spaceanal.tcl - $(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl \ - >spaceanal_tcl.h - $(TCCX) $(TCL_FLAGS) -DTCLSH=2 $(TESTFIXTURE_FLAGS) \ - -DSQLITE_TEST=1 -DSQLITE_PRIVATE="" \ - $(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c \ - -o sqlite3_analyzer$(EXE) \ - $(LIBTCL) $(THREADLIB) - TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO) $(TEST_EXTENSION): $(TOP)/src/test_loadext.c $(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION) diff --git a/manifest b/manifest index 95538b272e..7c20228ef4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scomment\schange\sin\sthe\sdescription\sof\sthe\sdifferent\smemory\sallocator\noptions.\s\sNo\schanges\sto\scode. -D 2011-09-19T20:56:59.410 +C Change\sthe\sway\sthe\ssqlite3_analyzer\sexecutable\sis\sbuilt. +D 2011-09-21T16:43:07.588 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -104,7 +104,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk 8744cb76517817170f7fd2c78fbf0006fabb93c1 +F main.mk e8b1c8b8eac849d90d3ffce9c2365f657446971c F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -187,7 +187,7 @@ F src/sqliteInt.h 76d81cd9da0618b231398bfcf90556e971972fca F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 3ef1dda2f1dc207c792eaadebf9d8adc44648581 +F src/tclsqlite.c 20578e66dda94b4d4db3d4478644a4dd9c6084a6 F src/test1.c 0f41b7c67719207a5de24b009e172c4dcf189827 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432 @@ -223,7 +223,7 @@ F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_stat.c f682704b5d1ba8e1d4e7e882a6d7922e2dcf066c +F src/test_stat.c 5bf0dcd0ffa469b2326d90f4a6e52d83e3f2df07 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa @@ -963,7 +963,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 3e0da808d2f5b4d12046e05980ca04578f581177 -R 8185767b36f8ee5089cf1856ba34ec13 -U drh -Z dd5a6c14bafead231702b31c9079bdda +P 36be31ff0af7f811fe2c6f7e26f058cffb7257e1 +R 8a6deb50b0588867fc20acf473ca1a9e +U dan +Z 506e969eac3211328e94965db47501bb diff --git a/manifest.uuid b/manifest.uuid index f3b3da0f66..53acc37cad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36be31ff0af7f811fe2c6f7e26f058cffb7257e1 \ No newline at end of file +05e3cced8a884e8bca6f208d2f09e335d3929eac \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index d2a0582e47..35dd0ad8ae 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3539,33 +3539,34 @@ int Md5_Register(sqlite3 *db){ ** the TCL interpreter reads and evaluates that file. */ #if TCLSH==1 -static char zMainloop[] = - "set line {}\n" - "while {![eof stdin]} {\n" - "if {$line!=\"\"} {\n" - "puts -nonewline \"> \"\n" - "} else {\n" - "puts -nonewline \"% \"\n" - "}\n" - "flush stdout\n" - "append line [gets stdin]\n" - "if {[info complete $line]} {\n" - "if {[catch {uplevel #0 $line} result]} {\n" - "puts stderr \"Error: $result\"\n" - "} elseif {$result!=\"\"} {\n" - "puts $result\n" +static const char *tclsh_main_loop(void){ + static const char zMainloop[] = + "set line {}\n" + "while {![eof stdin]} {\n" + "if {$line!=\"\"} {\n" + "puts -nonewline \"> \"\n" + "} else {\n" + "puts -nonewline \"% \"\n" + "}\n" + "flush stdout\n" + "append line [gets stdin]\n" + "if {[info complete $line]} {\n" + "if {[catch {uplevel #0 $line} result]} {\n" + "puts stderr \"Error: $result\"\n" + "} elseif {$result!=\"\"} {\n" + "puts $result\n" + "}\n" + "set line {}\n" + "} else {\n" + "append line \\n\n" "}\n" - "set line {}\n" - "} else {\n" - "append line \\n\n" "}\n" - "}\n" -; + ; + return zMainloop; +} #endif #if TCLSH==2 -static char zMainloop[] = -#include "spaceanal_tcl.h" -; +static const char *tclsh_main_loop(void); #endif #ifdef SQLITE_TEST @@ -3649,6 +3650,17 @@ static void init_all(Tcl_Interp *interp){ Md5_Init(interp); #endif + /* Install the [register_dbstat_vtab] command to access the implementation + ** of virtual table dbstat (source file test_stat.c). This command is + ** required for testfixture and sqlite3_analyzer, but not by the production + ** Tcl extension. */ +#if defined(SQLITE_TEST) || TCLSH==2 + { + extern int SqlitetestStat_Init(Tcl_Interp*); + SqlitetestStat_Init(interp); + } +#endif + #ifdef SQLITE_TEST { extern int Sqliteconfig_Init(Tcl_Interp*); @@ -3678,7 +3690,6 @@ static void init_all(Tcl_Interp *interp){ extern int Sqlitetestbackup_Init(Tcl_Interp*); extern int Sqlitetestintarray_Init(Tcl_Interp*); extern int Sqlitetestvfs_Init(Tcl_Interp *); - extern int SqlitetestStat_Init(Tcl_Interp*); extern int Sqlitetestrtree_Init(Tcl_Interp*); extern int Sqlitequota_Init(Tcl_Interp*); extern int Sqlitemultiplex_Init(Tcl_Interp*); @@ -3722,7 +3733,6 @@ static void init_all(Tcl_Interp *interp){ Sqlitetestbackup_Init(interp); Sqlitetestintarray_Init(interp); Sqlitetestvfs_Init(interp); - SqlitetestStat_Init(interp); Sqlitetestrtree_Init(interp); Sqlitequota_Init(interp); Sqlitemultiplex_Init(interp); @@ -3758,12 +3768,13 @@ int TCLSH_MAIN(int argc, char **argv){ ** sqlite3_initialize() is. */ sqlite3_shutdown(); + Tcl_FindExecutable(argv[0]); + interp = Tcl_CreateInterp(); + #if TCLSH==2 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); #endif - Tcl_FindExecutable(argv[0]); - interp = Tcl_CreateInterp(); init_all(interp); if( argc>=2 ){ int i; @@ -3784,7 +3795,7 @@ int TCLSH_MAIN(int argc, char **argv){ } } if( TCLSH==2 || argc<=1 ){ - Tcl_GlobalEval(interp, zMainloop); + Tcl_GlobalEval(interp, tclsh_main_loop()); } return 0; } diff --git a/src/test_stat.c b/src/test_stat.c index c85463e526..6e6accf6da 100644 --- a/src/test_stat.c +++ b/src/test_stat.c @@ -18,7 +18,9 @@ ** for an example implementation. */ -#include "sqliteInt.h" +#ifndef SQLITE_AMALGAMATION +# include "sqliteInt.h" +#endif #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -568,7 +570,7 @@ int sqlite3_dbstat_register(sqlite3 *db){ #endif -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || TCLSH==2 #include static int test_dbstat( @@ -604,4 +606,5 @@ int SqlitetestStat_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, "register_dbstat_vtab", test_dbstat, 0, 0); return TCL_OK; } -#endif +#endif /* if defined(SQLITE_TEST) || TCLSH==2 */ + From c42cdce5e03b191b8909bee0f95c162c9d2853e7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Sep 2011 17:04:21 +0000 Subject: [PATCH 15/56] Fix the sqlite3_analyzer target in the configure-generated Makefile. FossilOrigin-Name: 256cdbdc810cae23388ccf73583c591304294dbb --- Makefile.in | 20 +++++++++----------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/Makefile.in b/Makefile.in index 8f1f65dcd0..c2424b0287 100644 --- a/Makefile.in +++ b/Makefile.in @@ -885,18 +885,16 @@ soaktest: testfixture$(TEXE) sqlite3$(TEXE) test: testfixture$(TEXE) sqlite3$(TEXE) ./testfixture$(TEXE) $(TOP)/test/veryquick.test -sqlite3_analyzer$(TEXE): $(TESTFIXTURE_SRC) $(TOP)/tool/spaceanal.tcl - sed \ - -e '/^#/d' \ - -e 's,\\,\\\\,g' \ - -e 's,",\\",g' \ - -e 's,^,",' \ - -e 's,$$,\\n",' \ - $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h - $(LTLINK) -DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 \ - -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE \ - $(TEMP_STORE) -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl + echo "#define TCLSH 2" > $@ + cat sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c >> $@ + echo "static const char *tclsh_main_loop(void){" >> $@ + echo "static const char *zMainloop = " >> $@ + $(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@ + echo "; return zMainloop; }" >> $@ +sqlite3_analyzer$(TEXE): sqlite3_analyzer.c spaceanal_tcl.h + $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) # Standard install and cleanup targets # diff --git a/manifest b/manifest index 7c20228ef4..70c66ccad8 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,7 @@ -C Change\sthe\sway\sthe\ssqlite3_analyzer\sexecutable\sis\sbuilt. -D 2011-09-21T16:43:07.588 +C Fix\sthe\ssqlite3_analyzer\starget\sin\sthe\sconfigure-generated\sMakefile. +D 2011-09-21T17:04:21.754 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 +F Makefile.in c9d4753bb534cad66d3b46e6923707b865f18ef6 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc b5e917439d5ed42364173d1648aae1d418e323ea F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 @@ -963,7 +963,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 36be31ff0af7f811fe2c6f7e26f058cffb7257e1 -R 8a6deb50b0588867fc20acf473ca1a9e -U dan -Z 506e969eac3211328e94965db47501bb +P 05e3cced8a884e8bca6f208d2f09e335d3929eac +R d2ae1eb53fb99dd2853da3eccd53ad17 +U drh +Z 32d053563fdefa8a387e9c96c97f544b diff --git a/manifest.uuid b/manifest.uuid index 53acc37cad..2da362a9f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -05e3cced8a884e8bca6f208d2f09e335d3929eac \ No newline at end of file +256cdbdc810cae23388ccf73583c591304294dbb \ No newline at end of file From 8d43aa10cb4f750b2148c112ee1e336a0f209d91 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Sep 2011 18:29:49 +0000 Subject: [PATCH 16/56] Remove unnecessary dependencies from the sqlite3_analyzer targets in makefiles. FossilOrigin-Name: 0bd8fd352d290637d8c4d4fb76e8dd28f0149fa0 --- Makefile.in | 2 +- main.mk | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile.in b/Makefile.in index c2424b0287..80dcc83909 100644 --- a/Makefile.in +++ b/Makefile.in @@ -893,7 +893,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TO $(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@ echo "; return zMainloop; }" >> $@ -sqlite3_analyzer$(TEXE): sqlite3_analyzer.c spaceanal_tcl.h +sqlite3_analyzer$(TEXE): sqlite3_analyzer.c $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) # Standard install and cleanup targets diff --git a/main.mk b/main.mk index a1f7233140..70ba4a1cee 100644 --- a/main.mk +++ b/main.mk @@ -526,7 +526,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/test_stat.c $(TOP)/src/tclsqlite.c $(TO $(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@ echo "; return zMainloop; }" >> $@ -sqlite3_analyzer$(EXE): sqlite3_analyzer.c spaceanal_tcl.h +sqlite3_analyzer$(EXE): sqlite3_analyzer.c $(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) # Rules to build the 'testfixture' application. diff --git a/manifest b/manifest index 70c66ccad8..9d24438730 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,7 @@ -C Fix\sthe\ssqlite3_analyzer\starget\sin\sthe\sconfigure-generated\sMakefile. -D 2011-09-21T17:04:21.754 +C Remove\sunnecessary\sdependencies\sfrom\sthe\ssqlite3_analyzer\stargets\sin\nmakefiles. +D 2011-09-21T18:29:49.463 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in c9d4753bb534cad66d3b46e6923707b865f18ef6 +F Makefile.in b6c543a666dbd1eaad06c3705778e75231c0e297 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc b5e917439d5ed42364173d1648aae1d418e323ea F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 @@ -104,7 +104,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk e8b1c8b8eac849d90d3ffce9c2365f657446971c +F main.mk cdd9d05779dedd4e72712286e807e15c4c666e46 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -963,7 +963,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 05e3cced8a884e8bca6f208d2f09e335d3929eac -R d2ae1eb53fb99dd2853da3eccd53ad17 +P 256cdbdc810cae23388ccf73583c591304294dbb +R 9e70a6e80548512d02d33e2ddd01332b U drh -Z 32d053563fdefa8a387e9c96c97f544b +Z 8142f1a978344d0179d691a7e8574898 diff --git a/manifest.uuid b/manifest.uuid index 2da362a9f8..5b0b626668 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -256cdbdc810cae23388ccf73583c591304294dbb \ No newline at end of file +0bd8fd352d290637d8c4d4fb76e8dd28f0149fa0 \ No newline at end of file From 565621a57e596d534806480b42dc25fe2779229e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 21 Sep 2011 20:10:42 +0000 Subject: [PATCH 17/56] Minor tweaks to the TCL code for sqlite3_analyzer. FossilOrigin-Name: 3a261f383f11d839d3a23d454b4422298bef9c88 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/spaceanal.tcl | 12 +++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 9d24438730..0323ff0b9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\sdependencies\sfrom\sthe\ssqlite3_analyzer\stargets\sin\nmakefiles. -D 2011-09-21T18:29:49.463 +C Minor\stweaks\sto\sthe\sTCL\scode\sfor\ssqlite3_analyzer. +D 2011-09-21T20:10:42.584 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in b6c543a666dbd1eaad06c3705778e75231c0e297 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -952,7 +952,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl fe02dede3d29ef0fefcf80a685644fdf4d9a768e +F tool/spaceanal.tcl 537f35d9e432695990ec855314d72eba9b999fe4 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -963,7 +963,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 256cdbdc810cae23388ccf73583c591304294dbb -R 9e70a6e80548512d02d33e2ddd01332b +P 0bd8fd352d290637d8c4d4fb76e8dd28f0149fa0 +R fe88c011dfd8ce1303bfab126d559106 U drh -Z 8142f1a978344d0179d691a7e8574898 +Z f9ab27a8b8af4fdd9533127fd7d4648e diff --git a/manifest.uuid b/manifest.uuid index 5b0b626668..f6dca2ce1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0bd8fd352d290637d8c4d4fb76e8dd28f0149fa0 \ No newline at end of file +3a261f383f11d839d3a23d454b4422298bef9c88 \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index 52e825b798..bb5c1a0c3c 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -35,8 +35,7 @@ sqlite3 db $file_to_analyze register_dbstat_vtab db set pageSize [db one {PRAGMA page_size}] - -#set DB [btree_open $file_to_analyze 1000 0] +db eval {SELECT count(*) FROM sqlite_master} # In-memory database for collecting statistics. This script loops through # the tables and indices in the database being analyzed, adding a row for each @@ -66,11 +65,10 @@ mem eval $tabledef # Create a temporary "dbstat" virtual table. # -db eval { - CREATE VIRTUAL TABLE temp.stat USING dbstat; - CREATE TEMP TABLE dbstat AS SELECT * FROM temp.stat ORDER BY name, path; - DROP TABLE temp.stat; -} +db eval {CREATE VIRTUAL TABLE temp.stat USING dbstat} +db eval {CREATE TEMP TABLE dbstat AS SELECT * FROM temp.stat + ORDER BY name, path} +db eval {DROP TABLE temp.stat} proc isleaf {pagetype is_index} { return [expr {$pagetype == "leaf" || ($pagetype == "internal" && $is_index)}] From 9a55e31f4d95d519734a5ff436a49b2d805facc9 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 22 Sep 2011 00:06:44 +0000 Subject: [PATCH 18/56] Integrate build changes for sqlite3_analyzer into the MSVC makefile. Also, more cleanup of build files, including sqlite3_analyzer, for all makefiles. FossilOrigin-Name: af1c5718292c0326b785416b7109eafefaeb59a7 --- Makefile.in | 4 +++- Makefile.msc | 19 ++++++++++--------- main.mk | 7 ++++++- manifest | 18 +++++++++--------- manifest.uuid | 2 +- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/Makefile.in b/Makefile.in index 80dcc83909..2c08e03b9f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -928,9 +928,11 @@ clean: rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -rf tsrc .target_source + rm -f tclsqlite3$(TEXE) rm -f testfixture$(TEXE) test.db - rm -f sqlite3.dll sqlite3.lib sqlite3.def + rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def rm -f sqlite3.c + rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c distclean: clean rm -f config.log config.status libtool Makefile sqlite3.pc diff --git a/Makefile.msc b/Makefile.msc index 01f490b42b..1521ceb5ae 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -926,15 +926,15 @@ soaktest: testfixture.exe sqlite3.exe test: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\veryquick.test -spaceanal_tcl.h: $(TOP)\tool\spaceanal.tcl - $(NAWK) -f $(TOP)/tool/tostr.awk \ - $(TOP)\tool\spaceanal.tcl > spaceanal_tcl.h +sqlite3_analyzer.c: sqlite3.c $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl + copy sqlite3.c + $(TOP)\src\test_stat.c + $(TOP)\src\tclsqlite.c $@ + echo static const char *tclsh_main_loop(void){ >> $@ + echo static const char *zMainloop = >> $@ + $(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@ + echo ; return zMainloop; } >> $@ -sqlite3_analyzer.exe: $(TESTFIXTURE_SRC) spaceanal_tcl.h - $(LTLINK) -DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 \ - -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE \ - -DBUILD_sqlite -I$(TCLINCDIR) \ - $(TESTFIXTURE_SRC) \ +sqlite3_analyzer.exe: sqlite3_analyzer.c + $(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \ /link $(LTLINKOPTS) /LIBPATH:$(TCLLIBDIR) $(LIBTCL) $(TLIBS) clean: @@ -944,10 +944,11 @@ clean: del /Q mkkeywordhash.exe keywordhash.h -rmdir /Q/S tsrc del /Q .target_source + del /Q tclsqlite3.exe del /Q testfixture.exe testfixture.exp test.db del /Q sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def del /Q sqlite3.c - del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp spaceanal_tcl.h + del /Q sqlite3_analyzer.exe sqlite3_analyzer.exp sqlite3_analyzer.c # # Windows section diff --git a/main.mk b/main.mk index 70ba4a1cee..2668b854e1 100644 --- a/main.mk +++ b/main.mk @@ -593,10 +593,15 @@ install: sqlite3 libsqlite3.a sqlite3.h mv sqlite3.h /usr/include clean: - rm -f *.o sqlite3 libsqlite3.a sqlite3.h opcodes.* + rm -f *.o sqlite3 sqlite3.exe libsqlite3.a sqlite3.h opcodes.* rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h rm -f $(PUBLISH) rm -f *.da *.bb *.bbg gmon.out rm -rf tsrc target_source rm -f testloadext.dll libtestloadext.so + rm -f amalgamation-testfixture amalgamation-testfixture.exe + rm -f fts3-testfixture fts3-testfixture.exe + rm -f testfixture testfixture.exe + rm -f threadtest3 threadtest3.exe rm -f sqlite3.c fts?amal.c tclsqlite3.c + rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c diff --git a/manifest b/manifest index 0323ff0b9a..ec378965ef 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Minor\stweaks\sto\sthe\sTCL\scode\sfor\ssqlite3_analyzer. -D 2011-09-21T20:10:42.584 +C Integrate\sbuild\schanges\sfor\ssqlite3_analyzer\sinto\sthe\sMSVC\smakefile.\s\sAlso,\smore\scleanup\sof\sbuild\sfiles,\sincluding\ssqlite3_analyzer,\sfor\sall\smakefiles. +D 2011-09-22T00:06:44.751 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in b6c543a666dbd1eaad06c3705778e75231c0e297 +F Makefile.in 8de00a4e52f308ef6d564834c0973e53646e0d4c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc b5e917439d5ed42364173d1648aae1d418e323ea +F Makefile.msc 6676bcfe711f621a0b1916ecfa5d0927f8084517 F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION f724de7326e87b7f3b0a55f16ef4b4d993680d54 @@ -104,7 +104,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk cdd9d05779dedd4e72712286e807e15c4c666e46 +F main.mk aa43670ca62ce7a3f4d80a5f8980c9a9ad076903 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -963,7 +963,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 0bd8fd352d290637d8c4d4fb76e8dd28f0149fa0 -R fe88c011dfd8ce1303bfab126d559106 -U drh -Z f9ab27a8b8af4fdd9533127fd7d4648e +P 3a261f383f11d839d3a23d454b4422298bef9c88 +R 333437cf067e53e389b09715ac478b4b +U mistachkin +Z 0999590e6e1cd2394f226d9ff7df4c00 diff --git a/manifest.uuid b/manifest.uuid index f6dca2ce1a..e0738b2bdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a261f383f11d839d3a23d454b4422298bef9c88 \ No newline at end of file +af1c5718292c0326b785416b7109eafefaeb59a7 \ No newline at end of file From 93c6384ca6db28d2b501d818d30ef1af163b386b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Sep 2011 00:28:55 +0000 Subject: [PATCH 19/56] Fix an uninitialized variable and a misuse of memcpy(). FossilOrigin-Name: ee110d5a4a6f29400bb632a9a18c7dcd04638657 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 2 +- src/where.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7f7797b145..0e783c5618 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Pull\sin\sthe\slatest\schanges\sfrom\strunk.\s\sUpdate\sthe\sSTAT3\sdocumentation. -D 2011-09-21T00:09:41.245 +C Fix\san\suninitialized\svariable\sand\sa\smisuse\sof\smemcpy(). +D 2011-09-22T00:28:55.958 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 002e085428c9b2dda5b25f43539178d31c124525 +F src/analyze.c 78a513d6229689c40252aa5d820565bcba90634c F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 28a4fe55327ff708bfaf9d4326d02686f7a553c3 @@ -251,7 +251,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c da04df6f003024bd217da9afb369e751417e07da +F src/where.c bd9ca1bb5ab909b04bdba6da2fffdfe07207c655 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 9607600b6ca9b546dd248982fd8e8d64f708be5c 36be31ff0af7f811fe2c6f7e26f058cffb7257e1 -R bd162fa2b501bed3d79b1607f9710e81 +P 63fc3e4bea6a7f5dc34b2af83f30458eb10b8fe0 +R 21208cbb3e90ead0385f6f34c9d78ada U drh -Z 642a2c81deaec7b7de912d100473111b +Z 173e771ada64f444efa1679d0416f2ab diff --git a/manifest.uuid b/manifest.uuid index d79b87d27f..bcbf1257fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63fc3e4bea6a7f5dc34b2af83f30458eb10b8fe0 \ No newline at end of file +ee110d5a4a6f29400bb632a9a18c7dcd04638657 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 6e33db8c9b..251560f14e 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -339,7 +339,7 @@ static void stat3Push( if( !doInsert ) return; if( p->nSample==p->mxSample ){ if( iMinnSample ){ - memcpy(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin)); + memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1)); } pSample = &p->a[p->nSample-1]; }else{ diff --git a/src/where.c b/src/where.c index 962a9dbf7e..db076ebaf0 100644 --- a/src/where.c +++ b/src/where.c @@ -2925,7 +2925,7 @@ static void bestBtreeIndex( const tRowcnt * const aiRowEst = pProbe->aiRowEst; double cost; /* Cost of using pProbe */ double nRow; /* Estimated number of rows in result set */ - double log10N; /* base-10 logarithm of nRow (inexact) */ + double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */ int rev; /* True to scan in reverse order */ int wsFlags = 0; Bitmask used = 0; From 0fe0c466cafc174a8f14dbaf1d7cab8dcdc25773 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Sep 2011 00:56:38 +0000 Subject: [PATCH 20/56] Update the version number to 3.7.9. FossilOrigin-Name: 14e28eb9546906b33eb03e596ad104c8ca049d6c --- VERSION | 2 +- configure | 374 ++++++++++++++++++++++++++------------------------ manifest | 16 +-- manifest.uuid | 2 +- 4 files changed, 206 insertions(+), 188 deletions(-) diff --git a/VERSION b/VERSION index a0fc9e07cb..c77a7de85c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.7.8 +3.7.9 diff --git a/configure b/configure index 6b30db6167..79cd72de34 100755 --- a/configure +++ b/configure @@ -1,11 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for sqlite 3.7.8. +# Generated by GNU Autoconf 2.67 for sqlite 3.7.9. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -316,7 +316,7 @@ $as_echo X"$as_dir" | test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -356,19 +356,19 @@ else fi # as_fn_arith -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -679,7 +679,7 @@ test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` @@ -698,8 +698,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.7.8' -PACKAGE_STRING='sqlite 3.7.8' +PACKAGE_VERSION='3.7.9' +PACKAGE_STRING='sqlite 3.7.9' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -952,8 +952,9 @@ do fi case $ac_option in - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *) ac_optarg=yes ;; + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. @@ -998,7 +999,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1024,7 +1025,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1228,7 +1229,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1244,7 +1245,7 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1274,8 +1275,8 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information." + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" ;; *=*) @@ -1283,7 +1284,7 @@ Try \`$0 --help' for more information." # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error "invalid variable name: \`$ac_envvar'" ;; + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1301,13 +1302,13 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error "missing argument to $ac_option" + as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; - fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1330,7 +1331,7 @@ do [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -1344,8 +1345,8 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1360,9 +1361,9 @@ test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error "working directory cannot be determined" + as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error "pwd does not report name of working directory" + as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. @@ -1401,11 +1402,11 @@ else fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then @@ -1431,7 +1432,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.7.8 to adapt to many kinds of systems. +\`configure' configures sqlite 3.7.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1445,7 +1446,7 @@ Configuration: --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages + -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files @@ -1496,7 +1497,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.7.8:";; + short | recursive ) echo "Configuration of sqlite 3.7.9:";; esac cat <<\_ACEOF @@ -1613,10 +1614,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.7.8 -generated by GNU Autoconf 2.65 +sqlite configure 3.7.9 +generated by GNU Autoconf 2.67 -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1720,7 +1721,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1763,7 +1764,7 @@ $as_echo "$ac_try_echo"; } >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } >/dev/null && { + test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : @@ -1829,7 +1830,7 @@ ac_fn_c_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1897,7 +1898,7 @@ ac_fn_c_check_type () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1950,10 +1951,10 @@ $as_echo "$ac_res" >&6; } ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : + if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -1989,7 +1990,7 @@ if ac_fn_c_try_cpp "$LINENO"; then : else ac_header_preproc=no fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } @@ -2016,7 +2017,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -2032,8 +2033,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.7.8, which was -generated by GNU Autoconf 2.65. Invocation command line was +It was created by sqlite $as_me 3.7.9, which was +generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2143,11 +2144,9 @@ trap 'exit_status=$? { echo - cat <<\_ASBOX -## ---------------- ## + $as_echo "## ---------------- ## ## Cache variables. ## -## ---------------- ## -_ASBOX +## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( @@ -2181,11 +2180,9 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ) echo - cat <<\_ASBOX -## ----------------- ## + $as_echo "## ----------------- ## ## Output variables. ## -## ----------------- ## -_ASBOX +## ----------------- ##" echo for ac_var in $ac_subst_vars do @@ -2198,11 +2195,9 @@ _ASBOX echo if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------------- ## + $as_echo "## ------------------- ## ## File substitutions. ## -## ------------------- ## -_ASBOX +## ------------------- ##" echo for ac_var in $ac_subst_files do @@ -2216,11 +2211,9 @@ _ASBOX fi if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## + $as_echo "## ----------- ## ## confdefs.h. ## -## ----------- ## -_ASBOX +## ----------- ##" echo cat confdefs.h echo @@ -2275,7 +2268,12 @@ _ACEOF ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - ac_site_file1=$CONFIG_SITE + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site @@ -2290,7 +2288,11 @@ do { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5 ; } fi done @@ -2366,7 +2368,7 @@ if $ac_cache_corrupted; then $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2382,7 +2384,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'` if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then -as_fn_error "configure script is out of date: +as_fn_error $? "configure script is out of date: configure \$PACKAGE_VERSION = $PACKAGE_VERSION top level VERSION file = $sqlite_version_sanity_check please regen with autoconf" "$LINENO" 5 @@ -2421,16 +2423,22 @@ ltmain="$ac_aux_dir/ltmain.sh" ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - for ac_t in install-sh install.sh shtool; do - if test -f "$ac_dir/$ac_t"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/$ac_t -c" - break 2 - fi - done + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi done if test -z "$ac_aux_dir"; then - as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -2444,7 +2452,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } @@ -2455,16 +2463,16 @@ else test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && - as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5 + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; -*) as_fn_error "invalid value of canonical build" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' @@ -2489,7 +2497,7 @@ else ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi @@ -2497,7 +2505,7 @@ fi $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; -*) as_fn_error "invalid value of canonical host" "$LINENO" 5;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' @@ -2813,8 +2821,8 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "no acceptable C compiler found in \$PATH -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -2928,9 +2936,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -{ as_fn_set_status 77 -as_fn_error "C compiler cannot create executables -See \`config.log' for more details." "$LINENO" 5; }; } +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -2972,8 +2979,8 @@ done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3030,9 +3037,9 @@ $as_echo "$ac_try_echo"; } >&5 else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot run C compiled programs. +as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details." "$LINENO" 5; } +See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi @@ -3083,8 +3090,8 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "cannot compute suffix of object files: cannot compile -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -3361,7 +3368,7 @@ esac done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then - as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5 + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED @@ -3437,7 +3444,7 @@ esac done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then - as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP @@ -3503,7 +3510,7 @@ esac done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then - as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP @@ -3570,7 +3577,7 @@ esac done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then - as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP @@ -3686,7 +3693,7 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi -test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5 +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then : @@ -3888,13 +3895,13 @@ if test "${lt_cv_nm_interface+set}" = set; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3891: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3898: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3894: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3901: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3897: output\"" >&5) + (eval echo "\"\$as_me:3904: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5100,7 +5107,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5103 "configure"' > conftest.$ac_ext + echo '#line 5110 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -5889,7 +5896,7 @@ else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -5905,11 +5912,11 @@ else ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi @@ -5948,7 +5955,7 @@ else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. @@ -5964,18 +5971,18 @@ else ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext +rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." "$LINENO" 5; } +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=c @@ -6104,8 +6111,7 @@ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -6626,11 +6632,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6629: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6635: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6633: \$? = $ac_status" >&5 + echo "$as_me:6639: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6965,11 +6971,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6968: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6974: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6972: \$? = $ac_status" >&5 + echo "$as_me:6978: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7070,11 +7076,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7073: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7079: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7077: \$? = $ac_status" >&5 + echo "$as_me:7083: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7125,11 +7131,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7128: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7134: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7132: \$? = $ac_status" >&5 + echo "$as_me:7138: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9505,7 +9511,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9508 "configure" +#line 9514 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9601,7 +9607,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9604 "configure" +#line 9610 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10266,8 +10272,7 @@ for ac_header in sys/types.h stdlib.h stdint.h inttypes.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -eval as_val=\$$as_ac_Header - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF @@ -10284,8 +10289,7 @@ for ac_func in usleep fdatasync localtime_r gmtime_r localtime_s utime do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -eval as_val=\$$as_ac_var - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF @@ -10750,7 +10754,7 @@ else if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` else - as_fn_error "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 + as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 fi fi @@ -11050,11 +11054,11 @@ else as_ac_File=`$as_echo "ac_cv_file_$dir/$subdir/readline.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dir/$subdir/readline.h" >&5 $as_echo_n "checking for $dir/$subdir/readline.h... " >&6; } -if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then : +if eval "test \"\${$as_ac_File+set}\"" = set; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && - as_fn_error "cannot check for file existence when cross compiling" "$LINENO" 5 + as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$dir/$subdir/readline.h"; then eval "$as_ac_File=yes" else @@ -11064,8 +11068,7 @@ fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } -eval as_val=\$$as_ac_File - if test "x$as_val" = x""yes; then : +if eval test \"x\$"$as_ac_File"\" = x"yes"; then : found=yes fi @@ -11422,6 +11425,7 @@ DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= +U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' @@ -11583,19 +11587,19 @@ export LANGUAGE (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# as_fn_error ERROR [LINENO LOG_FD] -# --------------------------------- +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with status $?, using 1 if that was 0. +# script with STATUS, using 1 if that was 0. as_fn_error () { - as_status=$?; test $as_status -eq 0 && as_status=1 - if test "$3"; then - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $1" >&2 + $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -11791,7 +11795,7 @@ $as_echo X"$as_dir" | test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p @@ -11844,8 +11848,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.7.8, which was -generated by GNU Autoconf 2.65. Invocation command line was +This file was extended by sqlite $as_me 3.7.9, which was +generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -11910,11 +11914,11 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.7.8 -configured by $0, generated by GNU Autoconf 2.65, +sqlite config.status 3.7.9 +configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" -Copyright (C) 2009 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -11931,11 +11935,16 @@ ac_need_defaults=: while test $# != 0 do case $1 in - --*=*) + --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; *) ac_option=$1 ac_optarg=$2 @@ -11957,6 +11966,7 @@ do $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; @@ -11969,7 +11979,7 @@ do ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error "ambiguous option: \`$1' + as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; @@ -11978,7 +11988,7 @@ Try \`$0 --help' for more information.";; ac_cs_silent=: ;; # This is an error. - -*) as_fn_error "unrecognized option: \`$1' + -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" @@ -12291,7 +12301,7 @@ do "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "sqlite3.pc") CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;; - *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done @@ -12329,7 +12339,7 @@ $debug || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") -} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5 +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -12346,7 +12356,7 @@ if test "x$ac_cr" = x; then fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\r' + ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi @@ -12360,18 +12370,18 @@ _ACEOF echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -12460,20 +12470,28 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ - || as_fn_error "could not setup config files machinery" "$LINENO" 5 + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/ -s/:*\${srcdir}:*/:/ -s/:*@srcdir@:*/:/ -s/^\([^=]*=[ ]*\):*/\1/ + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// s/^[^=]*=[ ]*$// }' fi @@ -12501,7 +12519,7 @@ for ac_last_try in false false :; do if test -z "$ac_t"; then break elif $ac_last_try; then - as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5 + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi @@ -12586,7 +12604,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error "could not setup config headers machinery" "$LINENO" 5 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" @@ -12599,7 +12617,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -12627,7 +12645,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -12654,7 +12672,7 @@ $as_echo "$as_me: creating $ac_file" >&6;} case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 ;; + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -12785,22 +12803,22 @@ s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&5 +which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined." >&2;} +which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # @@ -12811,19 +12829,19 @@ which seems to be undefined. Please make sure it is defined." >&2;} $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ - || as_fn_error "could not create $ac_file" "$LINENO" 5 + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error "could not create -" "$LINENO" 5 + || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; @@ -13479,7 +13497,7 @@ _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || - as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5 + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. @@ -13500,7 +13518,7 @@ if test "$no_create" != yes; then exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit $? + $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 diff --git a/manifest b/manifest index ec378965ef..29b8515f55 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Integrate\sbuild\schanges\sfor\ssqlite3_analyzer\sinto\sthe\sMSVC\smakefile.\s\sAlso,\smore\scleanup\sof\sbuild\sfiles,\sincluding\ssqlite3_analyzer,\sfor\sall\smakefiles. -D 2011-09-22T00:06:44.751 +C Update\sthe\sversion\snumber\sto\s3.7.9. +D 2011-09-22T00:56:38.282 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8de00a4e52f308ef6d564834c0973e53646e0d4c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 6676bcfe711f621a0b1916ecfa5d0927f8084517 F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 -F VERSION f724de7326e87b7f3b0a55f16ef4b4d993680d54 +F VERSION bb37c274b503bbe73f00ea4f374eb817cba4b171 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 F art/2005osaward.gif 0d1851b2a7c1c9d0ccce545f3e14bca42d7fd248 @@ -23,7 +23,7 @@ F art/src_logo.gif 9341ef09f0e53cd44c0c9b6fc3c16f7f3d6c2ad9 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 405a958bdb3af382a809dccb08a44694923ddd61 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 4010a2e577b7d43c429672858d442ac5a570fdcd x +F configure 806c06aef5895860da49600ce098dbe4d5a8435c x F configure.ac 298a759c086e72c013da459c2aec02a104f4224f F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549 @@ -963,7 +963,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 3a261f383f11d839d3a23d454b4422298bef9c88 -R 333437cf067e53e389b09715ac478b4b -U mistachkin -Z 0999590e6e1cd2394f226d9ff7df4c00 +P af1c5718292c0326b785416b7109eafefaeb59a7 +R 683508422a28a1700de71635798902cb +U drh +Z fbf5cbfa4acf8c5482bae2d6dc544add diff --git a/manifest.uuid b/manifest.uuid index e0738b2bdf..950372854b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af1c5718292c0326b785416b7109eafefaeb59a7 \ No newline at end of file +14e28eb9546906b33eb03e596ad104c8ca049d6c \ No newline at end of file From 58ca31c9057ee914d9cf4d1e47cf901c7501e75f Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Sep 2011 14:41:16 +0000 Subject: [PATCH 21/56] Add the SQLITE_DB_STATUS_CACHE_HIT and MISS options. For querying the number of cache hits and misses on a per-connection basis. FossilOrigin-Name: 5100b6e9dc5107f0f835d0aac26fe6d4938ffc73 --- manifest | 23 +++++++------- manifest.uuid | 2 +- src/pager.c | 33 +++++++++++++++++--- src/pager.h | 1 + src/sqlite.h.in | 17 ++++++++-- src/status.c | 22 +++++++++++++ src/test_malloc.c | 6 ++-- test/dbstatus2.test | 76 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 160 insertions(+), 20 deletions(-) create mode 100644 test/dbstatus2.test diff --git a/manifest b/manifest index 29b8515f55..f689453daf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\sversion\snumber\sto\s3.7.9. -D 2011-09-22T00:56:38.282 +C Add\sthe\sSQLITE_DB_STATUS_CACHE_HIT\sand\sMISS\soptions.\sFor\squerying\sthe\snumber\sof\scache\shits\sand\smisses\son\sa\sper-connection\sbasis. +D 2011-09-22T14:41:16.523 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8de00a4e52f308ef6d564834c0973e53646e0d4c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,8 +167,8 @@ F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 10e0c4dcdbec8d4189890fdf3e71b32efae194e3 F src/os_win.c 0fc0f46c94b0385a940b0ee32992a833019a5985 -F src/pager.c 15d10371e2d560b68870a9ccec022ad8f01e70a2 -F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 +F src/pager.c 8a6ac3e0d9694412076e2273e3c81e9c4e08758f +F src/pager.h dbcaa791e8b6c3a6b77c168c5c27deec289fb176 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 @@ -181,11 +181,11 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c 13fe2aeddc3cc90d6a273831d1f63736d1596f81 -F src/sqlite.h.in 0a6c9c23337fd1352c5c75a613ff9533aa7d91cb +F src/sqlite.h.in c0ebc53056fd99590dec4cb4bd60a0787098ff18 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 76d81cd9da0618b231398bfcf90556e971972fca F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d -F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf +F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 20578e66dda94b4d4db3d4478644a4dd9c6084a6 F src/test1.c 0f41b7c67719207a5de24b009e172c4dcf189827 @@ -212,7 +212,7 @@ F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 F src/test_intarray.h 489edb9068bb926583445cb02589344961054207 F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e -F src/test_malloc.c 91d5cf1751d3e563754fd183da1c020727b5480e +F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 F src/test_multiplex.c 3fc368022c46fe44ec22c5e1ed727223a54a6a1d F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e @@ -361,6 +361,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7f0bd5084d9dd7da9ad46901810896edd2ebb463 F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff F test/dbstatus.test a719af0f226bd280748a4bb9054c0a5a9fc1b16c +F test/dbstatus2.test dc57b0d9610851c0ff58a8e1b5b191678398b72a F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa @@ -963,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P af1c5718292c0326b785416b7109eafefaeb59a7 -R 683508422a28a1700de71635798902cb -U drh -Z fbf5cbfa4acf8c5482bae2d6dc544add +P 14e28eb9546906b33eb03e596ad104c8ca049d6c +R 9879b749e51ddd30db2e7953d801cb26 +U dan +Z f68e24447a093110c356752c29a0f88a diff --git a/manifest.uuid b/manifest.uuid index 950372854b..a03b2aa84e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14e28eb9546906b33eb03e596ad104c8ca049d6c \ No newline at end of file +5100b6e9dc5107f0f835d0aac26fe6d4938ffc73 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index f8d3ba9989..99a3ebd4c3 100644 --- a/src/pager.c +++ b/src/pager.c @@ -670,8 +670,8 @@ struct Pager { char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ + int nHit, nMiss; /* Total cache hits and misses */ #ifdef SQLITE_TEST - int nHit, nMiss; /* Cache hits and missing */ int nRead, nWrite; /* Database pages read/written */ #endif void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ @@ -4169,7 +4169,7 @@ static int pagerStress(void *p, PgHdr *pPg){ ** ** Spilling is also prohibited when in an error state since that could ** lead to database corruption. In the current implementaton it - ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1 + ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1 ** while in the error state, hence it is impossible for this routine to ** be called in the error state. Nevertheless, we include a NEVER() ** test for the error state as a safeguard against future changes. @@ -5005,14 +5005,13 @@ int sqlite3PagerAcquire( /* In this case the pcache already contains an initialized copy of ** the page. Return without further ado. */ assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); - PAGER_INCR(pPager->nHit); + pPager->nHit++; return SQLITE_OK; }else{ /* The pager cache has created a new page. Its content needs to ** be initialized. */ - PAGER_INCR(pPager->nMiss); pPg = *ppPage; pPg->pPager = pPager; @@ -5048,6 +5047,7 @@ int sqlite3PagerAcquire( IOTRACE(("ZERO %p %d\n", pPager, pgno)); }else{ assert( pPg->pPager==pPager ); + pPager->nMiss++; rc = readDbPage(pPg); if( rc!=SQLITE_OK ){ goto pager_acquire_err; @@ -6082,6 +6082,31 @@ int *sqlite3PagerStats(Pager *pPager){ } #endif +/* +** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or +** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the +** current cache hit or miss count, according to the value of eStat. If the +** reset parameter is non-zero, the cache hit or miss count is zeroed before +** returning. +*/ +void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ + int *piStat; + + assert( eStat==SQLITE_DBSTATUS_CACHE_HIT + || eStat==SQLITE_DBSTATUS_CACHE_MISS + ); + if( eStat==SQLITE_DBSTATUS_CACHE_HIT ){ + piStat = &pPager->nHit; + }else{ + piStat = &pPager->nMiss; + } + + *pnVal += *piStat; + if( reset ){ + *piStat = 0; + } +} + /* ** Return true if this is an in-memory pager. */ diff --git a/src/pager.h b/src/pager.h index eab7ddaf80..540557248a 100644 --- a/src/pager.h +++ b/src/pager.h @@ -155,6 +155,7 @@ const char *sqlite3PagerJournalname(Pager*); int sqlite3PagerNosync(Pager*); void *sqlite3PagerTempSpace(Pager*); int sqlite3PagerIsMemdb(Pager*); +void sqlite3PagerCacheStat(Pager *, int, int, int *); /* Functions used to truncate the database file. */ void sqlite3PagerTruncateImage(Pager*,Pgno); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ba5c20265f..43694f5fad 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5810,6 +5810,18 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. ** +** +** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
SQLITE_DBSTATUS_CACHE_HIT
+**
This parameter returns the number of pager cache hits that have +** occurred. ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** is always 0. +**
+** +** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
SQLITE_DBSTATUS_CACHE_MISS
+**
This parameter returns the number of pager cache misses that have +** occurred. ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** is always 0. +**
** */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 @@ -5819,7 +5831,9 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 -#define SQLITE_DBSTATUS_MAX 6 /* Largest defined DBSTATUS */ +#define SQLITE_DBSTATUS_CACHE_HIT 7 +#define SQLITE_DBSTATUS_CACHE_MISS 8 +#define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */ /* @@ -5873,7 +5887,6 @@ int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** A non-zero value in this counter may indicate an opportunity to ** improvement performance by adding permanent indices that do not ** need to be reinitialized each time the statement is run. -** ** */ #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 diff --git a/src/status.c b/src/status.c index b8c1d58df7..b23238bb14 100644 --- a/src/status.c +++ b/src/status.c @@ -218,6 +218,28 @@ int sqlite3_db_status( break; } + /* + ** Set *pCurrent to the total cache hits or misses encountered by all + ** pagers the database handle is connected to. *pHighwater is always set + ** to zero. + */ + case SQLITE_DBSTATUS_CACHE_HIT: + case SQLITE_DBSTATUS_CACHE_MISS: { + int i; + int nRet = 0; + assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); + + for(i=0; inDb; i++){ + if( db->aDb[i].pBt ){ + Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); + sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); + } + } + *pHighwater = 0; + *pCurrent = nRet; + break; + } + default: { rc = SQLITE_ERROR; } diff --git a/src/test_malloc.c b/src/test_malloc.c index 46ec94d327..e955d57900 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1325,11 +1325,13 @@ static int test_db_status( { "STMT_USED", SQLITE_DBSTATUS_STMT_USED }, { "LOOKASIDE_HIT", SQLITE_DBSTATUS_LOOKASIDE_HIT }, { "LOOKASIDE_MISS_SIZE", SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE }, - { "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL } + { "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL }, + { "CACHE_HIT", SQLITE_DBSTATUS_CACHE_HIT }, + { "CACHE_MISS", SQLITE_DBSTATUS_CACHE_MISS } }; Tcl_Obj *pResult; if( objc!=4 ){ - Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG"); + Tcl_WrongNumArgs(interp, 1, objv, "DB PARAMETER RESETFLAG"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; diff --git a/test/dbstatus2.test b/test/dbstatus2.test new file mode 100644 index 0000000000..4dfa9b8ed2 --- /dev/null +++ b/test/dbstatus2.test @@ -0,0 +1,76 @@ +# 2011 September 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Tests for the sqlite3_stmt_status() function +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set ::testprefix dbstatus2 + +do_execsql_test 1.0 { + PRAGMA page_size = 1024; + PRAGMA auto_vacuum = 0; + + CREATE TABLE t1(a PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, randomblob(600)); + INSERT INTO t1 VALUES(2, randomblob(600)); + INSERT INTO t1 VALUES(3, randomblob(600)); +} + +proc db_hit_miss {db {reset 0}} { + set nHit [sqlite3_db_status $db CACHE_HIT $reset] + set nMiss [sqlite3_db_status $db CACHE_MISS $reset] + list $nHit $nMiss +} + +do_test 1.1 { + db close + sqlite3 db test.db + expr {[file size test.db] / 1024} +} 6 + +do_test 1.2 { + execsql { SELECT b FROM t1 WHERE a=2 } + db_hit_miss db +} {{0 2 0} {0 4 0}} + +do_test 1.3 { + execsql { SELECT b FROM t1 WHERE a=2 } + db_hit_miss db +} {{0 6 0} {0 4 0}} + +do_test 1.4 { + execsql { SELECT b FROM t1 WHERE a=2 } + db_hit_miss db +} {{0 10 0} {0 4 0}} + +do_test 1.5 { + db_hit_miss db 1 +} {{0 10 0} {0 4 0}} + +do_test 1.6 { + db_hit_miss db 0 +} {{0 0 0} {0 0 0}} + +do_test 1.7 { + set fd [db incrblob main t1 b 1] + fconfigure $fd -translation binary + set len [string length [read $fd]] + close $fd + set len +} 600 +do_test 1.8 { sqlite3_db_status db CACHE_HIT 0 } {0 2 0} +do_test 1.9 { sqlite3_db_status db CACHE_MISS 0 } {0 1 0} + + +finish_test From b5126dde0d4ec922be13837a7bc6a4fa9ec5c1c5 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Sep 2011 14:56:31 +0000 Subject: [PATCH 22/56] Remove the SQLITE_PAGECACHE_BLOCKALLOC compilation option. FossilOrigin-Name: 4eb4689834b538b9eeec5a5803528260e1aff78d --- manifest | 24 ++--- manifest.uuid | 2 +- src/ctime.c | 3 - src/pcache1.c | 250 +------------------------------------------ src/test_config.c | 6 -- test/ctime.test | 11 -- test/memdb.test | 2 +- test/memsubsys1.test | 7 -- test/pcache2.test | 8 -- 9 files changed, 18 insertions(+), 295 deletions(-) diff --git a/manifest b/manifest index f689453daf..0dbb2a594a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_DB_STATUS_CACHE_HIT\sand\sMISS\soptions.\sFor\squerying\sthe\snumber\sof\scache\shits\sand\smisses\son\sa\sper-connection\sbasis. -D 2011-09-22T14:41:16.523 +C Remove\sthe\sSQLITE_PAGECACHE_BLOCKALLOC\scompilation\soption. +D 2011-09-22T14:56:31.229 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8de00a4e52f308ef6d564834c0973e53646e0d4c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +130,7 @@ F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 851e81f26a75abbb98bd99a7c5f10e8670d867bb F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac -F src/ctime.c e3132ec65240b2e2f3d50831021eac387f27584d +F src/ctime.c 3f2715d38635b8e86d344b36a6f7f3e446fa5ec3 F src/date.c a3c6842bad7ae632281811de112a8ba63ff08ab3 F src/delete.c ff68e5ef23aee08c0ff528f699a19397ed8bbed8 F src/expr.c f4dcaeb8252c4b16fcdc245660f70ed366bc6cdd @@ -172,7 +172,7 @@ F src/pager.h dbcaa791e8b6c3a6b77c168c5c27deec289fb176 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 -F src/pcache1.c c8982f7048a70b7fd37975a8f6c84d6bc294175a +F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197 F src/pragma.c ebcd20f1e654f5cb3aeef864ed69c4697719fbaa F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1 @@ -201,7 +201,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c e342660556d64365aacea2b23cbb5e6654d7278f +F src/test_config.c 9bc44df77f22cd0648c651fcd459353b8a984d7b F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -358,7 +358,7 @@ F test/crash8.test 38767cb504bbe491de6be4a7006b154973a2309f F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c -F test/ctime.test 7f0bd5084d9dd7da9ad46901810896edd2ebb463 +F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff F test/dbstatus.test a719af0f226bd280748a4bb9054c0a5a9fc1b16c F test/dbstatus2.test dc57b0d9610851c0ff58a8e1b5b191678398b72a @@ -584,9 +584,9 @@ F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9 F test/malloc_common.tcl 2930895b0962823ec679853e67e58dd6d8198b3c F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f -F test/memdb.test 4b5d2671588ed59cb08642adc67fd78c666dc9c2 +F test/memdb.test 708a028d6d373e5b3842e4bdc8ba80998c9a4da6 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 -F test/memsubsys1.test 39f1ddddf76ce51a3232aab0279668e23cf00f83 +F test/memsubsys1.test 16ce163ac1ace3d71bf0eaa6a821ed153addd91f F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 @@ -619,7 +619,7 @@ F test/pagerfault3.test f16e2efcb5fc9996d1356f7cbc44c998318ae1d7 F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 -F test/pcache2.test bc67c6802989dba05cdf3a4574fd882e238c7ecf +F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/permutations.test ad17319066a90e2db71823c3ff104795ffc71b31 F test/pragma.test c8108e01da04f16e67e5754e610bc62c1b993f6c F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 14e28eb9546906b33eb03e596ad104c8ca049d6c -R 9879b749e51ddd30db2e7953d801cb26 +P 5100b6e9dc5107f0f835d0aac26fe6d4938ffc73 +R c0527ab7d53ddacfb2296ee9b8d0ee9c U dan -Z f68e24447a093110c356752c29a0f88a +Z f31c94b75567eb17d1f72beb13b1de1b diff --git a/manifest.uuid b/manifest.uuid index a03b2aa84e..e652151728 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5100b6e9dc5107f0f835d0aac26fe6d4938ffc73 \ No newline at end of file +4eb4689834b538b9eeec5a5803528260e1aff78d \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index cbf8ed55fa..028892d549 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -329,9 +329,6 @@ static const char * const azCompileOpt[] = { #ifdef SQLITE_OMIT_XFER_OPT "OMIT_XFER_OPT", #endif -#ifdef SQLITE_PAGECACHE_BLOCKALLOC - "PAGECACHE_BLOCKALLOC", -#endif #ifdef SQLITE_PERFORMANCE_TRACE "PERFORMANCE_TRACE", #endif diff --git a/src/pcache1.c b/src/pcache1.c index de96e5242a..077a7b2168 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -24,8 +24,6 @@ typedef struct PgHdr1 PgHdr1; typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; -typedef struct PGroupBlock PGroupBlock; -typedef struct PGroupBlockList PGroupBlockList; /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set ** of one or more PCaches that are able to recycle each others unpinned @@ -56,66 +54,8 @@ struct PGroup { int mxPinned; /* nMaxpage + 10 - nMinPage */ int nCurrentPage; /* Number of purgeable pages allocated */ PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */ -#ifdef SQLITE_PAGECACHE_BLOCKALLOC - int isBusy; /* Do not run ReleaseMemory() if true */ - PGroupBlockList *pBlockList; /* List of block-lists for this group */ -#endif }; -/* -** If SQLITE_PAGECACHE_BLOCKALLOC is defined when the library is built, -** each PGroup structure has a linked list of the the following starting -** at PGroup.pBlockList. There is one entry for each distinct page-size -** currently used by members of the PGroup (i.e. 1024 bytes, 4096 bytes -** etc.). Variable PGroupBlockList.nByte is set to the actual allocation -** size requested by each pcache, which is the database page-size plus -** the various header structures used by the pcache, pager and btree layers. -** Usually around (pgsz+200) bytes. -** -** This size (pgsz+200) bytes is not allocated efficiently by some -** implementations of malloc. In particular, some implementations are only -** able to allocate blocks of memory chunks of 2^N bytes, where N is some -** integer value. Since the page-size is a power of 2, this means we -** end up wasting (pgsz-200) bytes in each allocation. -** -** If SQLITE_PAGECACHE_BLOCKALLOC is defined, the (pgsz+200) byte blocks -** are not allocated directly. Instead, blocks of roughly M*(pgsz+200) bytes -** are requested from malloc allocator. After a block is returned, -** sqlite3MallocSize() is used to determine how many (pgsz+200) byte -** allocations can fit in the space returned by malloc(). This value may -** be more than M. -** -** The blocks are stored in a doubly-linked list. Variable PGroupBlock.nEntry -** contains the number of allocations that will fit in the aData[] space. -** nEntry is limited to the number of bits in bitmask mUsed. If a slot -** within aData is in use, the corresponding bit in mUsed is set. Thus -** when (mUsed+1==(1 << nEntry)) the block is completely full. -** -** Each time a slot within a block is freed, the block is moved to the start -** of the linked-list. And if a block becomes completely full, then it is -** moved to the end of the list. As a result, when searching for a free -** slot, only the first block in the list need be examined. If it is full, -** then it is guaranteed that all blocks are full. -*/ -struct PGroupBlockList { - int nByte; /* Size of each allocation in bytes */ - PGroupBlock *pFirst; /* First PGroupBlock in list */ - PGroupBlock *pLast; /* Last PGroupBlock in list */ - PGroupBlockList *pNext; /* Next block-list attached to group */ -}; - -struct PGroupBlock { - Bitmask mUsed; /* Mask of used slots */ - int nEntry; /* Maximum number of allocations in aData[] */ - u8 *aData; /* Pointer to data block */ - PGroupBlock *pNext; /* Next PGroupBlock in list */ - PGroupBlock *pPrev; /* Previous PGroupBlock in list */ - PGroupBlockList *pList; /* Owner list */ -}; - -/* Minimum value for PGroupBlock.nEntry */ -#define PAGECACHE_BLOCKALLOC_MINENTRY 15 - /* Each page cache is an instance of the following object. Every ** open database file (including each in-memory database and each ** temporary or transient database) has a single page cache which @@ -219,17 +159,6 @@ static SQLITE_WSD struct PCacheGlobal { #define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage) #define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage) -/* -** Blocks used by the SQLITE_PAGECACHE_BLOCKALLOC blocks to store/retrieve -** a PGroupBlock pointer based on a pointer to a page buffer. -*/ -#define PAGE_SET_BLOCKPTR(pCache, pPg, pBlock) \ - ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) = pBlock ) - -#define PAGE_GET_BLOCKPTR(pCache, pPg) \ - ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) ) - - /* ** Macros to enter and leave the PCache LRU mutex. */ @@ -355,139 +284,14 @@ static int pcache1MemSize(void *p){ } #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */ -#ifdef SQLITE_PAGECACHE_BLOCKALLOC -/* -** The block pBlock belongs to list pList but is not currently linked in. -** Insert it into the start of the list. -*/ -static void addBlockToList(PGroupBlockList *pList, PGroupBlock *pBlock){ - pBlock->pPrev = 0; - pBlock->pNext = pList->pFirst; - pList->pFirst = pBlock; - if( pBlock->pNext ){ - pBlock->pNext->pPrev = pBlock; - }else{ - assert( pList->pLast==0 ); - pList->pLast = pBlock; - } -} - -/* -** If there are no blocks in the list headed by pList, remove pList -** from the pGroup->pBlockList list and free it with sqlite3_free(). -*/ -static void freeListIfEmpty(PGroup *pGroup, PGroupBlockList *pList){ - assert( sqlite3_mutex_held(pGroup->mutex) ); - if( pList->pFirst==0 ){ - PGroupBlockList **pp; - for(pp=&pGroup->pBlockList; *pp!=pList; pp=&(*pp)->pNext); - *pp = (*pp)->pNext; - sqlite3_free(pList); - } -} -#endif /* SQLITE_PAGECACHE_BLOCKALLOC */ - /* ** Allocate a new page object initially associated with cache pCache. */ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ int nByte = sizeof(PgHdr1) + pCache->szPage; - void *pPg = 0; - PgHdr1 *p; + PgHdr1 *p = 0; + void *pPg; -#ifdef SQLITE_PAGECACHE_BLOCKALLOC - PGroup *pGroup = pCache->pGroup; - PGroupBlockList *pList; - PGroupBlock *pBlock; - int i; - - nByte += sizeof(PGroupBlockList *); - nByte = ROUND8(nByte); - - for(pList=pGroup->pBlockList; pList; pList=pList->pNext){ - if( pList->nByte==nByte ) break; - } - if( pList==0 ){ - PGroupBlockList *pNew; - assert( pGroup->isBusy==0 ); - assert( sqlite3_mutex_held(pGroup->mutex) ); - pGroup->isBusy = 1; /* Disable sqlite3PcacheReleaseMemory() */ - pNew = (PGroupBlockList *)sqlite3MallocZero(sizeof(PGroupBlockList)); - pGroup->isBusy = 0; /* Reenable sqlite3PcacheReleaseMemory() */ - if( pNew==0 ){ - /* malloc() failure. Return early. */ - return 0; - } -#ifdef SQLITE_DEBUG - for(pList=pGroup->pBlockList; pList; pList=pList->pNext){ - assert( pList->nByte!=nByte ); - } -#endif - pNew->nByte = nByte; - pNew->pNext = pGroup->pBlockList; - pGroup->pBlockList = pNew; - pList = pNew; - } - - pBlock = pList->pFirst; - if( pBlock==0 || pBlock->mUsed==(((Bitmask)1<nEntry)-1) ){ - int sz; - - /* Allocate a new block. Try to allocate enough space for the PGroupBlock - ** structure and MINENTRY allocations of nByte bytes each. If the - ** allocator returns more memory than requested, then more than MINENTRY - ** allocations may fit in it. */ - assert( sqlite3_mutex_held(pGroup->mutex) ); - pcache1LeaveMutex(pCache->pGroup); - sz = sizeof(PGroupBlock) + PAGECACHE_BLOCKALLOC_MINENTRY * nByte; - pBlock = (PGroupBlock *)sqlite3Malloc(sz); - pcache1EnterMutex(pCache->pGroup); - - if( !pBlock ){ - freeListIfEmpty(pGroup, pList); - return 0; - } - pBlock->nEntry = (sqlite3MallocSize(pBlock) - sizeof(PGroupBlock)) / nByte; - if( pBlock->nEntry>=BMS ){ - pBlock->nEntry = BMS-1; - } - pBlock->pList = pList; - pBlock->mUsed = 0; - pBlock->aData = (u8 *)&pBlock[1]; - addBlockToList(pList, pBlock); - - sz = sqlite3MallocSize(pBlock); - sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); - sqlite3_mutex_leave(pcache1.mutex); - } - - for(i=0; pPg==0 && ALWAYS(inEntry); i++){ - if( 0==(pBlock->mUsed & ((Bitmask)1<mUsed |= ((Bitmask)1<aData[pList->nByte * i]; - } - } - assert( pPg ); - PAGE_SET_BLOCKPTR(pCache, pPg, pBlock); - - /* If the block is now full, shift it to the end of the list */ - if( pBlock->mUsed==(((Bitmask)1<nEntry)-1) && pList->pLast!=pBlock ){ - assert( pList->pFirst==pBlock ); - assert( pBlock->pPrev==0 ); - assert( pList->pLast->pNext==0 ); - pList->pFirst = pBlock->pNext; - pList->pFirst->pPrev = 0; - pBlock->pPrev = pList->pLast; - pBlock->pNext = 0; - pList->pLast->pNext = pBlock; - pList->pLast = pBlock; - } - p = PAGE_TO_PGHDR1(pCache, pPg); - if( pCache->bPurgeable ){ - pCache->pGroup->nCurrentPage++; - } -#else /* The group mutex must be released before pcache1Alloc() is called. This ** is because it may call sqlite3_release_memory(), which assumes that ** this mutex is not held. */ @@ -495,15 +299,13 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ pcache1LeaveMutex(pCache->pGroup); pPg = pcache1Alloc(nByte); pcache1EnterMutex(pCache->pGroup); + if( pPg ){ p = PAGE_TO_PGHDR1(pCache, pPg); if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage++; } - }else{ - p = 0; } -#endif return p; } @@ -517,49 +319,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ static void pcache1FreePage(PgHdr1 *p){ if( ALWAYS(p) ){ PCache1 *pCache = p->pCache; - void *pPg = PGHDR1_TO_PAGE(p); - -#ifdef SQLITE_PAGECACHE_BLOCKALLOC - PGroupBlock *pBlock = PAGE_GET_BLOCKPTR(pCache, pPg); - PGroupBlockList *pList = pBlock->pList; - int i = ((u8 *)pPg - pBlock->aData) / pList->nByte; - - assert( pPg==(void *)&pBlock->aData[i*pList->nByte] ); - assert( pBlock->mUsed & ((Bitmask)1<mUsed &= ~((Bitmask)1<pFirst==pBlock ){ - pList->pFirst = pBlock->pNext; - if( pList->pFirst ) pList->pFirst->pPrev = 0; - }else{ - pBlock->pPrev->pNext = pBlock->pNext; - } - if( pList->pLast==pBlock ){ - pList->pLast = pBlock->pPrev; - if( pList->pLast ) pList->pLast->pNext = 0; - }else{ - pBlock->pNext->pPrev = pBlock->pPrev; - } - - if( pBlock->mUsed==0 ){ - PGroup *pGroup = p->pCache->pGroup; - - int sz = sqlite3MallocSize(pBlock); - sqlite3_mutex_enter(pcache1.mutex); - sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -sz); - sqlite3_mutex_leave(pcache1.mutex); - freeListIfEmpty(pGroup, pList); - sqlite3_free(pBlock); - }else{ - addBlockToList(pList, pBlock); - } -#else assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); - pcache1Free(pPg); -#endif + pcache1Free(PGHDR1_TO_PAGE(p)); if( pCache->bPurgeable ){ pCache->pGroup->nCurrentPage--; } @@ -1170,9 +931,6 @@ void sqlite3PCacheSetDefault(void){ */ int sqlite3PcacheReleaseMemory(int nReq){ int nFree = 0; -#ifdef SQLITE_PAGECACHE_BLOCKALLOC - if( pcache1.grp.isBusy ) return 0; -#endif assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); assert( sqlite3_mutex_notheld(pcache1.mutex) ); if( pcache1.pStart==0 ){ diff --git a/src/test_config.c b/src/test_config.c index 5af60bafd0..5b0ffaa697 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -555,12 +555,6 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double", Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY); #endif -#ifdef SQLITE_PAGECACHE_BLOCKALLOC - Tcl_SetVar2(interp, "sqlite_options", "blockalloc", "1", TCL_GLOBAL_ONLY); -#else - Tcl_SetVar2(interp, "sqlite_options", "blockalloc", "0", TCL_GLOBAL_ONLY); -#endif - #define LINKVAR(x) { \ static const int cv_ ## x = SQLITE_ ## x; \ Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \ diff --git a/test/ctime.test b/test/ctime.test index 11216f9016..e4cb156168 100644 --- a/test/ctime.test +++ b/test/ctime.test @@ -223,16 +223,5 @@ do_test ctime-2.5.$tc { } ] } {0 {{}}} -ifcapable blockalloc { - do_test ctime-3.1a { - db eval {SELECT sqlite_compileoption_used('PAGECACHE_BLOCKALLOC')} - } {1} -} else { - do_test ctime-3.1b { - db eval {SELECT sqlite_compileoption_used('PAGECACHE_BLOCKALLOC')} - } {0} -} - - finish_test diff --git a/test/memdb.test b/test/memdb.test index ec3accffa6..1da3d7c58b 100644 --- a/test/memdb.test +++ b/test/memdb.test @@ -407,7 +407,7 @@ do_test memdb-8.2 { # Test that auto-vacuum works with in-memory databases. # -ifcapable autovacuum&&!blockalloc { +ifcapable autovacuum { do_test memdb-9.1 { db close sqlite3 db test.db diff --git a/test/memsubsys1.test b/test/memsubsys1.test index dbd4f233ec..7eecf083a7 100644 --- a/test/memsubsys1.test +++ b/test/memsubsys1.test @@ -25,13 +25,6 @@ if {[permutation] == "memsubsys1"} { return } -# Nor will it work if the pager is allocating memory in blocks. -# -ifcapable blockalloc { - finish_test - return -} - # This procedure constructs a new database in test.db. It fills # this database with many small records (enough to force multiple # rebalance operations in the btree-layer and to require a large diff --git a/test/pcache2.test b/test/pcache2.test index bbfb90d29c..77e7a26132 100644 --- a/test/pcache2.test +++ b/test/pcache2.test @@ -16,14 +16,6 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -# If compiled with blockalloc, pagecache memory is not used. Which -# causes these tests to fail. -# -ifcapable blockalloc { - finish_test - return -} - # Set up a pcache memory pool so that we can easily track how many # pages are being used for cache. # From 40f048f54b5e06772fc6d217b700bde30e503942 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Sep 2011 15:31:30 +0000 Subject: [PATCH 23/56] Remove a redundant (and undefined) "forcedelete" command from corruptE.test. FossilOrigin-Name: 6d8d4e1694694c3e961fc1922f732d1da40caa6f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/corruptE.test | 2 -- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0dbb2a594a..ec8da322ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sSQLITE_PAGECACHE_BLOCKALLOC\scompilation\soption. -D 2011-09-22T14:56:31.229 +C Remove\sa\sredundant\s(and\sundefined)\s"forcedelete"\scommand\sfrom\scorruptE.test. +D 2011-09-22T15:31:30.163 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8de00a4e52f308ef6d564834c0973e53646e0d4c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -345,7 +345,7 @@ F test/corruptA.test fafa652aa585753be4f6b62ff0bb250266eaf7ce F test/corruptB.test 20d4a20cbed23958888c3e8995b424a47223d647 F test/corruptC.test 62a767fe64acb1975f58cc6171192839c783edbb F test/corruptD.test 99b1999dbfa7cc04aaeac9d695a2445d4e7c7458 -F test/corruptE.test 78f7e1b9fd4a92e5951c7a5e414f2c4492733870 +F test/corruptE.test 1b9eb20a8711251ce57b44a257e241085b39b52d F test/count.test 454e1ce985c94d13efeac405ce54439f49336163 F test/crash.test 519dc29f6fea151f015a23236e555239353946eb F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 5100b6e9dc5107f0f835d0aac26fe6d4938ffc73 -R c0527ab7d53ddacfb2296ee9b8d0ee9c +P 4eb4689834b538b9eeec5a5803528260e1aff78d +R 262c3aeccd7c893526a314d03fa12d82 U dan -Z f31c94b75567eb17d1f72beb13b1de1b +Z b984e82b28ae9a7089c19360a2ce9099 diff --git a/manifest.uuid b/manifest.uuid index e652151728..614e1201f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4eb4689834b538b9eeec5a5803528260e1aff78d \ No newline at end of file +6d8d4e1694694c3e961fc1922f732d1da40caa6f \ No newline at end of file diff --git a/test/corruptE.test b/test/corruptE.test index 94bc928fff..507721d85e 100644 --- a/test/corruptE.test +++ b/test/corruptE.test @@ -16,8 +16,6 @@ # # $Id: corruptE.test,v 1.14 2009/07/11 06:55:34 danielk1977 Exp $ -catch {forcedelete test.db test.db-journal test.bu} - set testdir [file dirname $argv0] source $testdir/tester.tcl From 5c62486cd822dbc4410b31e011e73170d6646643 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Sep 2011 18:46:34 +0000 Subject: [PATCH 24/56] Fix an issue in ANALYZE when STAT3 is disabled but both sqlite_stat2 and sqlite_stat3 tables exist. Also add testability tweaks to the STAT3 code. FossilOrigin-Name: 3ca7e449e2e20d95e516cf7fe87bfa0b51c07086 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/analyze.c | 22 ++++++++++++---------- src/sqliteInt.h | 2 +- src/where.c | 4 +++- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 0e783c5618..d4e2d30b7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\suninitialized\svariable\sand\sa\smisuse\sof\smemcpy(). -D 2011-09-22T00:28:55.958 +C Fix\san\sissue\sin\sANALYZE\swhen\sSTAT3\sis\sdisabled\sbut\sboth\ssqlite_stat2\sand\nsqlite_stat3\stables\sexist.\s\sAlso\sadd\stestability\stweaks\sto\sthe\sSTAT3\scode. +D 2011-09-22T18:46:34.844 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 78a513d6229689c40252aa5d820565bcba90634c +F src/analyze.c 12c096a7e2383559c451c7111938a2682661795a F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 28a4fe55327ff708bfaf9d4326d02686f7a553c3 @@ -183,7 +183,7 @@ F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c 13fe2aeddc3cc90d6a273831d1f63736d1596f81 F src/sqlite.h.in 3f531daa04457e83bc13765c98c06c7d71c27fa5 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 -F src/sqliteInt.h 6cb04e5216d68becf18fd4a4a6d47ec07f33219c +F src/sqliteInt.h 40bc71ab0840027d0b4e452b09467dc7274828e2 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -251,7 +251,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c bd9ca1bb5ab909b04bdba6da2fffdfe07207c655 +F src/where.c 432a42cf4392bafe80ff06affb62cc24c8eea3fb F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 63fc3e4bea6a7f5dc34b2af83f30458eb10b8fe0 -R 21208cbb3e90ead0385f6f34c9d78ada +P ee110d5a4a6f29400bb632a9a18c7dcd04638657 +R ed357b44bde952eee8192d464b59f2eb U drh -Z 173e771ada64f444efa1679d0416f2ab +Z b3542caa8ec714ec974a1ed2d471f84c diff --git a/manifest.uuid b/manifest.uuid index bcbf1257fb..353f35070c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee110d5a4a6f29400bb632a9a18c7dcd04638657 \ No newline at end of file +3ca7e449e2e20d95e516cf7fe87bfa0b51c07086 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 251560f14e..b1af3bf70a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -172,7 +172,10 @@ static void openStatTable( */ for(i=0; izName); - if( pTab ) sqlite3CodeDropTable(pParse, pTab, iDb, 0); + if( pTab ){ + sqlite3CodeDropTable(pParse, pTab, iDb, 0); + break; + } } /* Create new statistic tables if they do not exist, or clear them @@ -338,9 +341,8 @@ static void stat3Push( } if( !doInsert ) return; if( p->nSample==p->mxSample ){ - if( iMinnSample ){ - memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1)); - } + assert( p->nSample - iMin - 1 >= 0 ); + memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1)); pSample = &p->a[p->nSample-1]; }else{ pSample = &p->a[p->nSample++]; @@ -413,10 +415,10 @@ static void stat3Get( assert( p!=0 ); if( p->nSample<=n ) return; switch( argc ){ - case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; - case 3: sqlite3_result_int64(context, p->a[n].nEq); break; - case 4: sqlite3_result_int64(context, p->a[n].nLt); break; - case 5: sqlite3_result_int64(context, p->a[n].nDLt); break; + case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; + case 3: sqlite3_result_int64(context, p->a[n].nEq); break; + case 4: sqlite3_result_int64(context, p->a[n].nLt); break; + default: sqlite3_result_int64(context, p->a[n].nDLt); break; } } static const FuncDef stat3GetFuncdef = { @@ -972,6 +974,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){ pIdx = sqlite3FindIndex(db, zIndex, zDb); if( pIdx==0 ) continue; assert( pIdx->nSample==0 ); + testcase( nSample==255 ); pIdx->nSample = (u8)nSample; pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); pIdx->avgEq = pIdx->aiRowEst[1]; @@ -1042,8 +1045,7 @@ static int loadStat3(sqlite3 *db, const char *zDb){ sqlite3_column_text(pStmt, 4) ); int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; - if( n>0xffff ) n = 0xffff; - pSample->nByte = (u16)n; + pSample->nByte = n; if( n < 1){ pSample->u.z = 0; }else{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 75bafe81a6..6f92a1a41e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1524,7 +1524,7 @@ struct IndexSample { i64 i; /* Value if eType is SQLITE_INTEGER */ } u; u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ - u16 nByte; /* Size in byte of text or blob. */ + int nByte; /* Size in byte of text or blob. */ tRowcnt nEq; /* Est. number of rows where the key equals this sample */ tRowcnt nLt; /* Est. number of rows where key is less than this sample */ tRowcnt nDLt; /* Est. number of distinct keys less than this sample */ diff --git a/src/where.c b/src/where.c index db076ebaf0..bf6b52752f 100644 --- a/src/where.c +++ b/src/where.c @@ -2452,6 +2452,7 @@ static int whereKeyStats( double r, rS; assert( roundUp==0 || roundUp==1 ); + assert( pIdx->nSample>0 ); if( pVal==0 ) return SQLITE_ERROR; n = pIdx->aiRowEst[0]; aSample = pIdx->aSample; @@ -2494,7 +2495,7 @@ static int whereKeyStats( } }else if( eType==SQLITE_NULL ){ i = 0; - if( pIdx->nSample>=1 && aSample[0].eType==SQLITE_NULL ) isEq = 1; + if( aSample[0].eType==SQLITE_NULL ) isEq = 1; }else{ assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); for(i=0; inSample; i++){ @@ -2760,6 +2761,7 @@ static int whereEqualScanEst( tRowcnt a[2]; /* Statistics */ assert( p->aSample!=0 ); + assert( p->nSample>0 ); aff = p->pTable->aCol[p->aiColumn[0]].affinity; if( pExpr ){ rc = valueFromExpr(pParse, pExpr, aff, &pRhs); From 2b9cf669d84d8632a12dfff806a8615ff4948345 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Sep 2011 20:52:56 +0000 Subject: [PATCH 25/56] Remove the restriction on the number of entries per index in sqlite_stat3. FossilOrigin-Name: 374343c8ad53829c4ad715ed623d16635797de9a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 4 +--- src/sqliteInt.h | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d4e2d30b7b..77fc4add6c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\sin\sANALYZE\swhen\sSTAT3\sis\sdisabled\sbut\sboth\ssqlite_stat2\sand\nsqlite_stat3\stables\sexist.\s\sAlso\sadd\stestability\stweaks\sto\sthe\sSTAT3\scode. -D 2011-09-22T18:46:34.844 +C Remove\sthe\srestriction\son\sthe\snumber\sof\sentries\sper\sindex\sin\ssqlite_stat3. +D 2011-09-22T20:52:56.063 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 12c096a7e2383559c451c7111938a2682661795a +F src/analyze.c f2b6e33f13ea763fa26425ac2f37249c56153ccd F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 28a4fe55327ff708bfaf9d4326d02686f7a553c3 @@ -183,7 +183,7 @@ F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c 13fe2aeddc3cc90d6a273831d1f63736d1596f81 F src/sqlite.h.in 3f531daa04457e83bc13765c98c06c7d71c27fa5 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 -F src/sqliteInt.h 40bc71ab0840027d0b4e452b09467dc7274828e2 +F src/sqliteInt.h 28cca77ebdaf6025ae5df52717dff429c7c6d4ef F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P ee110d5a4a6f29400bb632a9a18c7dcd04638657 -R ed357b44bde952eee8192d464b59f2eb +P 3ca7e449e2e20d95e516cf7fe87bfa0b51c07086 +R c105c04b0bf619f9bd8e7351a02bbd18 U drh -Z b3542caa8ec714ec974a1ed2d471f84c +Z 3b0d1caf0749877c04e96ab7e0587090 diff --git a/manifest.uuid b/manifest.uuid index 353f35070c..b087a18354 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ca7e449e2e20d95e516cf7fe87bfa0b51c07086 \ No newline at end of file +374343c8ad53829c4ad715ed623d16635797de9a \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index b1af3bf70a..b98968a9e3 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -970,12 +970,10 @@ static int loadStat3(sqlite3 *db, const char *zDb){ zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; nSample = sqlite3_column_int(pStmt, 1); - if( nSample>255 ) continue; pIdx = sqlite3FindIndex(db, zIndex, zDb); if( pIdx==0 ) continue; assert( pIdx->nSample==0 ); - testcase( nSample==255 ); - pIdx->nSample = (u8)nSample; + pIdx->nSample = nSample; pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) ); pIdx->avgEq = pIdx->aiRowEst[1]; if( pIdx->aSample==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6f92a1a41e..35ab54a5f7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1501,13 +1501,13 @@ struct Index { u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */ u8 bUnordered; /* Use this index for == or IN queries only */ - u8 nSample; /* Number of elements in aSample[] */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ #ifdef SQLITE_ENABLE_STAT3 + int nSample; /* Number of elements in aSample[] */ tRowcnt avgEq; /* Average nEq value for key values not in aSample */ IndexSample *aSample; /* Samples of the left-most key */ #endif From 369980189bc595be18b3206c8e00bdbd166044a0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Sep 2011 13:25:03 +0000 Subject: [PATCH 26/56] Fix typos in the format description comment of analyze.c. FossilOrigin-Name: 74e27fad339a2d7899c1f42805e615128929f07a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 77fc4add6c..46ae41ea86 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\srestriction\son\sthe\snumber\sof\sentries\sper\sindex\sin\ssqlite_stat3. -D 2011-09-22T20:52:56.063 +C Fix\stypos\sin\sthe\sformat\sdescription\scomment\sof\sanalyze.c. +D 2011-09-23T13:25:03.244 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c f2b6e33f13ea763fa26425ac2f37249c56153ccd +F src/analyze.c 775421ced0bd78181cc206fbc63063658066c1da F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 28a4fe55327ff708bfaf9d4326d02686f7a553c3 @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 3ca7e449e2e20d95e516cf7fe87bfa0b51c07086 -R c105c04b0bf619f9bd8e7351a02bbd18 +P 374343c8ad53829c4ad715ed623d16635797de9a +R e7e1b2a1114af9230eb2e44197ed5da5 U drh -Z 3b0d1caf0749877c04e96ab7e0587090 +Z 6b4c74838ff582a42303843c6a42764e diff --git a/manifest.uuid b/manifest.uuid index b087a18354..06cafe1e0c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -374343c8ad53829c4ad715ed623d16635797de9a \ No newline at end of file +74e27fad339a2d7899c1f42805e615128929f07a \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index b98968a9e3..88a7761ed6 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -94,9 +94,9 @@ ** the left-most column of the index. The nEq column is the approximate ** number of entires in the index whose left-most column exactly matches ** the sample. nLt is the approximate number of entires whose left-most -** column is less than the same. The nDLt column is the approximate +** column is less than the sample. The nDLt column is the approximate ** number of distinct left-most entries in the index that are less than -** the same. +** the sample. ** ** Future versions of SQLite might change to store a string containing ** multiple integers values in the nDLt column of sqlite_stat3. The first From 567211ed0ecde5d02a81a48197df0f80642fed52 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Sep 2011 13:59:33 +0000 Subject: [PATCH 27/56] Testability enhancements. FossilOrigin-Name: be44928cf2a3c063c8228b769d90947acbfad1ef --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 2 +- src/where.c | 5 +++-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 46ae41ea86..343598e9a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypos\sin\sthe\sformat\sdescription\scomment\sof\sanalyze.c. -D 2011-09-23T13:25:03.244 +C Testability\senhancements. +D 2011-09-23T13:59:33.693 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -127,7 +127,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 77b09c69d4849a90361e6fe5db36d167f20600c0 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c 57e3b27c26e6754393cd63a2774a6c673df1e804 +F src/build.c 2dc09385981bf7f41eae7d3aeb47cb2453813456 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c dde6a9b835b9e8cc067b713de1a7f6a0c9ff807e @@ -251,7 +251,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 432a42cf4392bafe80ff06affb62cc24c8eea3fb +F src/where.c aafcb21a74e41f9aae76ea604e1e787ff8574125 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 374343c8ad53829c4ad715ed623d16635797de9a -R e7e1b2a1114af9230eb2e44197ed5da5 +P 74e27fad339a2d7899c1f42805e615128929f07a +R 2a02eac3daaa0669ad4c98fbdd4d2386 U drh -Z 6b4c74838ff582a42303843c6a42764e +Z 0b4e185fe7f24f4f88a2a412ad76b268 diff --git a/manifest.uuid b/manifest.uuid index 06cafe1e0c..1d09d551ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74e27fad339a2d7899c1f42805e615128929f07a \ No newline at end of file +be44928cf2a3c063c8228b769d90947acbfad1ef \ No newline at end of file diff --git a/src/build.c b/src/build.c index 8318cb1ff2..da0eaa1d44 100644 --- a/src/build.c +++ b/src/build.c @@ -2145,7 +2145,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } } #endif - if( !pParse->nested && sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } diff --git a/src/where.c b/src/where.c index bf6b52752f..220411de2f 100644 --- a/src/where.c +++ b/src/where.c @@ -2578,7 +2578,6 @@ static int whereKeyStats( iGap = 0; }else{ iGap = iUpper - iLower; - if( iGap>=aStat[1]/2 ) iGap -= aStat[1]/2; } if( roundUp ){ iGap = (iGap*2)/3; @@ -3119,11 +3118,13 @@ static void bestBtreeIndex( ** VALUE and how common that value is according to the histogram. */ if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){ + assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 ); if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){ testcase( pFirstTerm->eOperator==WO_EQ ); testcase( pFirstTerm->eOperator==WO_ISNULL ); whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow); - }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){ + }else if( bInEst==0 ){ + assert( pFirstTerm->eOperator==WO_IN ); whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow); } } From 0bab6c3ef7ed83dff5f2bb4608bd6faf7cda4377 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Sep 2011 16:34:49 +0000 Subject: [PATCH 28/56] Add the -DBUILD_sqlite option to the compiler when building testfixture.exe using the configure script. FossilOrigin-Name: 15a13b6c59ddf145c3fc860d993a7fa5587a0799 --- Makefile.in | 1 + manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile.in b/Makefile.in index 2c08e03b9f..cbcf8eca43 100644 --- a/Makefile.in +++ b/Makefile.in @@ -866,6 +866,7 @@ rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) # TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1 TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE +TESTFIXTURE_FLAGS += -DBUILD_sqlite TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la TESTFIXTURE_SRC1 = sqlite3.c diff --git a/manifest b/manifest index ec8da322ff..66e5ad5ff4 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,7 @@ -C Remove\sa\sredundant\s(and\sundefined)\s"forcedelete"\scommand\sfrom\scorruptE.test. -D 2011-09-22T15:31:30.163 +C Add\sthe\s-DBUILD_sqlite\soption\sto\sthe\scompiler\swhen\sbuilding\stestfixture.exe\nusing\sthe\sconfigure\sscript. +D 2011-09-23T16:34:49.242 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 8de00a4e52f308ef6d564834c0973e53646e0d4c +F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 6676bcfe711f621a0b1916ecfa5d0927f8084517 F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 4eb4689834b538b9eeec5a5803528260e1aff78d -R 262c3aeccd7c893526a314d03fa12d82 -U dan -Z b984e82b28ae9a7089c19360a2ce9099 +P 6d8d4e1694694c3e961fc1922f732d1da40caa6f +R 040dfcfdeae57e43ae6b152b05f4d580 +U drh +Z 20c1fc7fe5f59b298e53a25791050dac diff --git a/manifest.uuid b/manifest.uuid index 614e1201f0..0a9aaa44df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6d8d4e1694694c3e961fc1922f732d1da40caa6f \ No newline at end of file +15a13b6c59ddf145c3fc860d993a7fa5587a0799 \ No newline at end of file From c78e6e4c4bab97589f8cf81dde6789d10775f3d6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Sep 2011 18:58:23 +0000 Subject: [PATCH 29/56] Add SQLITE_DBSTATUS_CACHE_HIT and _MISS to the ".stat" command in the shell. FossilOrigin-Name: d279e1a309909a0897b6082753a0fadb5066c31a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 66e5ad5ff4..849b18969b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s-DBUILD_sqlite\soption\sto\sthe\scompiler\swhen\sbuilding\stestfixture.exe\nusing\sthe\sconfigure\sscript. -D 2011-09-23T16:34:49.242 +C Add\sSQLITE_DBSTATUS_CACHE_HIT\sand\s_MISS\sto\sthe\s".stat"\scommand\sin\sthe\sshell. +D 2011-09-23T18:58:23.501 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 -F src/shell.c 13fe2aeddc3cc90d6a273831d1f63736d1596f81 +F src/shell.c 1d3baca3399a36fc34883b6cdab457688ae8e248 F src/sqlite.h.in c0ebc53056fd99590dec4cb4bd60a0787098ff18 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 76d81cd9da0618b231398bfcf90556e971972fca @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 6d8d4e1694694c3e961fc1922f732d1da40caa6f -R 040dfcfdeae57e43ae6b152b05f4d580 +P 15a13b6c59ddf145c3fc860d993a7fa5587a0799 +R 8a846188b5a50b629e779a79335084c3 U drh -Z 20c1fc7fe5f59b298e53a25791050dac +Z fb711bd276d7d1d753d686357da5cf42 diff --git a/manifest.uuid b/manifest.uuid index 0a9aaa44df..4db7cfdbe5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -15a13b6c59ddf145c3fc860d993a7fa5587a0799 \ No newline at end of file +d279e1a309909a0897b6082753a0fadb5066c31a \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 9759e93b00..b36afb9d4c 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1029,7 +1029,12 @@ static int display_stats( fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); - fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); + fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); + fprintf(pArg->out, "Page cache hits: %d\n", iCur); + iHiwtr = iCur = -1; + sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); + fprintf(pArg->out, "Page cache misses: %d\n", iCur); iHiwtr = iCur = -1; sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur); From 5209132a48fdff176ec3ba07ff188ad237b95086 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 24 Sep 2011 05:55:36 +0000 Subject: [PATCH 30/56] Fix some test files so that they work with SQLITE_OMIT_WAL builds. FossilOrigin-Name: a38668dcff0a4d241d959ea19330ad43295d757d --- manifest | 28 ++++++++-------- manifest.uuid | 2 +- test/attach4.test | 6 ++-- test/oserror.test | 36 +++++++++++---------- test/pager1.test | 52 +++++++++++++++--------------- test/superlock.test | 5 +++ test/uri.test | 76 +++++++++++++++++++++++--------------------- test/walbig.test | 5 +++ test/walpersist.test | 5 +++ test/walro.test | 7 ++++ 10 files changed, 126 insertions(+), 96 deletions(-) diff --git a/manifest b/manifest index 849b18969b..7890a96310 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sSQLITE_DBSTATUS_CACHE_HIT\sand\s_MISS\sto\sthe\s".stat"\scommand\sin\sthe\sshell. -D 2011-09-23T18:58:23.501 +C Fix\ssome\stest\sfiles\sso\sthat\sthey\swork\swith\sSQLITE_OMIT_WAL\sbuilds. +D 2011-09-24T05:55:36.123 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -276,7 +276,7 @@ F test/async5.test 0dd8701bd588bf6e70c2557a22ae3f22b2567b4c F test/attach.test 0e6f8de2589f11a5f474ef57fe5af2877e61c0e8 F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966 F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e -F test/attach4.test 31f9eb0ca7bdbc393cc4657b877903a226a83d4b +F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test b047105c32da7db70b842fd24056723125ecc2ff F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882 @@ -609,8 +609,8 @@ F test/notify3.test a86259abbfb923aa27d30f0fc038c88e5251488a F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 -F test/oserror.test 3fe52e0bd2891a9bf7cdeb639554992453d46301 -F test/pager1.test 2d3a7c6facd899d8879d23f31454cc53f49358b9 +F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 +F test/pager1.test c8f202a460ba6a1cd7a36888042ca471220bb42d F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442 @@ -691,7 +691,7 @@ F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a -F test/superlock.test 5d7a4954b0059c903f82c7b67867bc5451a7c082 +F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test 966addf703faee6a5d509abe6d8885e393e552fd F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f @@ -858,7 +858,7 @@ F test/unique.test 083c7fff74695bcc27a71d75699deba3595bc9c2 F test/unixexcl.test 9d80a54d86d2261f660758928959368ffc36151e F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 -F test/uri.test 53de9a2549cbda9c343223236918ef502f6a9051 +F test/uri.test 0d289d32396bdbc491e9dc845f1a52e13f861e0b F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum.test 9516f3a8e49be666f2dde28561e4be5ae5612de0 F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324 @@ -894,7 +894,7 @@ F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877 -F test/walbig.test e882bc1d014afffbfa2b6ba36e0f07d30a633ad0 +F test/walbig.test 0ab8a430ef420a3114f7092e0f30fc9585ffa155 F test/walcksum.test f5447800a157c9e2234fbb8e80243f0813941bde F test/walcrash.test 4fcb661faf71db91214156d52d43ee327f52bde1 F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142 @@ -902,8 +902,8 @@ F test/walfault.test efb0d5724893133e71b8d9d90abdb781845a6bb0 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 -F test/walpersist.test 45fb0c94fb63908e2d66b1d99ce4645bfce0fa1e -F test/walro.test 2d5d69e2e99da19ce6faab340330234fc4ca0720 +F test/walpersist.test fd40d33765b2693f721c90c66d97f99757559006 +F test/walro.test 412d0809300b94ba142440e94d6a30eabf2220b7 F test/walshared.test 6dda2293880c300baf5d791c307f653094585761 F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a F test/walthread.test a2ed5270eb695284d4ad27d252517bdc3317ee2a @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 15a13b6c59ddf145c3fc860d993a7fa5587a0799 -R 8a846188b5a50b629e779a79335084c3 -U drh -Z fb711bd276d7d1d753d686357da5cf42 +P d279e1a309909a0897b6082753a0fadb5066c31a +R 1d47a8525f2f65e65f824b1ab6ac3952 +U dan +Z 402b9c23e658ae7ef163736478b873db diff --git a/manifest.uuid b/manifest.uuid index 4db7cfdbe5..1798c846b2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d279e1a309909a0897b6082753a0fadb5066c31a \ No newline at end of file +a38668dcff0a4d241d959ea19330ad43295d757d \ No newline at end of file diff --git a/test/attach4.test b/test/attach4.test index f597f5d035..77dd7e4115 100644 --- a/test/attach4.test +++ b/test/attach4.test @@ -75,10 +75,12 @@ set L [list] set S "" foreach {name f} $files { if {[permutation] == "journaltest"} { - lappend L delete + set mode delete } else { - lappend L wal + set mode wal } + ifcapable !wal { set mode delete } + lappend L $mode append S " PRAGMA $name.journal_mode = WAL; UPDATE $name.tbl SET x = '$name'; diff --git a/test/oserror.test b/test/oserror.test index bdeb868425..40d2966bcc 100644 --- a/test/oserror.test +++ b/test/oserror.test @@ -97,23 +97,25 @@ do_re_test 1.4.2 { lindex $::log 0 } {^os_unix.c:\d*: \(\d+\) open\(.*test.db\) #-------------------------------------------------------------------------- # Tests oserror-1.* test failures in the unlink() system call. # -do_test 2.1.1 { - set ::log [list] - file mkdir test.db-wal - forcedelete test.db - list [catch { - sqlite3 dbh test.db - execsql { SELECT * FROM sqlite_master } dbh - } msg] $msg -} {1 {disk I/O error}} - -do_re_test 2.1.2 { - lindex $::log 0 -} {^os_unix.c:\d+: \(\d+\) unlink\(.*test.db-wal\) - } -do_test 2.1.3 { - catch { dbh close } - forcedelete test.db-wal -} {} +ifcapable wal { + do_test 2.1.1 { + set ::log [list] + file mkdir test.db-wal + forcedelete test.db + list [catch { + sqlite3 dbh test.db + execsql { SELECT * FROM sqlite_master } dbh + } msg] $msg + } {1 {disk I/O error}} + + do_re_test 2.1.2 { + lindex $::log 0 + } {^os_unix.c:\d+: \(\d+\) unlink\(.*test.db-wal\) - } + do_test 2.1.3 { + catch { dbh close } + forcedelete test.db-wal + } {} +} test_syscall reset diff --git a/test/pager1.test b/test/pager1.test index b9ba775add..bed7d736cd 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -1992,31 +1992,33 @@ ifcapable wal { # pager1-22.1.*: is a no-op on a non-WAL db, and # pager1-22.2.*: does not cause xSync calls with a synchronous=off db. # -do_test pager1-22.1.1 { - faultsim_delete_and_reopen - execsql { - CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def'); - INSERT INTO ko DEFAULT VALUES; - } - execsql { PRAGMA wal_checkpoint } -} {0 -1 -1} -do_test pager1-22.2.1 { - testvfs tv -default 1 - tv filter xSync - tv script xSyncCb - proc xSyncCb {args} {incr ::synccount} - set ::synccount 0 - sqlite3 db test.db - execsql { - PRAGMA synchronous = off; - PRAGMA journal_mode = WAL; - INSERT INTO ko DEFAULT VALUES; - } - execsql { PRAGMA wal_checkpoint } - set synccount -} {0} -db close -tv delete +ifcapable wal { + do_test pager1-22.1.1 { + faultsim_delete_and_reopen + execsql { + CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def'); + INSERT INTO ko DEFAULT VALUES; + } + execsql { PRAGMA wal_checkpoint } + } {0 -1 -1} + do_test pager1-22.2.1 { + testvfs tv -default 1 + tv filter xSync + tv script xSyncCb + proc xSyncCb {args} {incr ::synccount} + set ::synccount 0 + sqlite3 db test.db + execsql { + PRAGMA synchronous = off; + PRAGMA journal_mode = WAL; + INSERT INTO ko DEFAULT VALUES; + } + execsql { PRAGMA wal_checkpoint } + set synccount + } {0} + db close + tv delete +} #------------------------------------------------------------------------- # Tests for changing journal mode. diff --git a/test/superlock.test b/test/superlock.test index b12863f7ff..8155d929ce 100644 --- a/test/superlock.test +++ b/test/superlock.test @@ -48,6 +48,11 @@ do_execsql_test 1.1 { PRAGMA journal_mode = DELETE; } {delete} +ifcapable !wal { + finish_test + return +} + do_test 1.2 { sqlite3demo_superlock unlock test.db } {unlock} do_catchsql_test 1.3 { SELECT * FROM t1 } {1 {database is locked}} do_test 1.4 { unlock } {} diff --git a/test/uri.test b/test/uri.test index f361e92917..90074d0d27 100644 --- a/test/uri.test +++ b/test/uri.test @@ -219,44 +219,46 @@ do_test 4.3.2 { # set, where X is the file-name the method is called on. Calls to the above # methods using "tvfs2" set entries in the global T2 array. # -testvfs tvfs1 -tvfs1 filter {xOpen xDelete xAccess xFullPathname} -tvfs1 script tvfs1_callback -proc tvfs1_callback {method filename args} { - set ::T1([file tail $filename]) 1 -} -testvfs tvfs2 -tvfs2 filter {xOpen xDelete xAccess xFullPathname} -tvfs2 script tvfs2_callback -proc tvfs2_callback {method filename args} { - set ::T2([file tail $filename]) 1 -} - -catch {db close} -eval forcedelete [glob test.db*] -do_test 5.1.1 { - sqlite3 db file:test.db1?vfs=tvfs1 - execsql { - ATTACH 'file:test.db2?vfs=tvfs2' AS aux; - PRAGMA main.journal_mode = PERSIST; - PRAGMA aux.journal_mode = PERSIST; - CREATE TABLE t1(a, b); - CREATE TABLE aux.t2(a, b); - PRAGMA main.journal_mode = WAL; - PRAGMA aux.journal_mode = WAL; - INSERT INTO t1 VALUES('x', 'y'); - INSERT INTO t2 VALUES('x', 'y'); +ifcapable wal { + testvfs tvfs1 + tvfs1 filter {xOpen xDelete xAccess xFullPathname} + tvfs1 script tvfs1_callback + proc tvfs1_callback {method filename args} { + set ::T1([file tail $filename]) 1 } - lsort [array names ::T1] -} {test.db1 test.db1-journal test.db1-wal} - -do_test 5.1.2 { - lsort [array names ::T2] -} {test.db2 test.db2-journal test.db2-wal} - -db close -tvfs1 delete -tvfs2 delete + testvfs tvfs2 + tvfs2 filter {xOpen xDelete xAccess xFullPathname} + tvfs2 script tvfs2_callback + proc tvfs2_callback {method filename args} { + set ::T2([file tail $filename]) 1 + } + + catch {db close} + eval forcedelete [glob test.db*] + do_test 5.1.1 { + sqlite3 db file:test.db1?vfs=tvfs1 + execsql { + ATTACH 'file:test.db2?vfs=tvfs2' AS aux; + PRAGMA main.journal_mode = PERSIST; + PRAGMA aux.journal_mode = PERSIST; + CREATE TABLE t1(a, b); + CREATE TABLE aux.t2(a, b); + PRAGMA main.journal_mode = WAL; + PRAGMA aux.journal_mode = WAL; + INSERT INTO t1 VALUES('x', 'y'); + INSERT INTO t2 VALUES('x', 'y'); + } + lsort [array names ::T1] + } {test.db1 test.db1-journal test.db1-wal} + + do_test 5.1.2 { + lsort [array names ::T2] + } {test.db2 test.db2-journal test.db2-wal} + db close + + tvfs1 delete + tvfs2 delete +} #------------------------------------------------------------------------- # Check that only "" and "localhost" are acceptable as authorities. diff --git a/test/walbig.test b/test/walbig.test index 9ceb8ede6d..092db2381b 100644 --- a/test/walbig.test +++ b/test/walbig.test @@ -17,6 +17,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +ifcapable !wal { + finish_test + return +} + # Do not use a codec for this file, as the database is manipulated using # external methods (the [fake_big_file] and [hexio_write] commands). # diff --git a/test/walpersist.test b/test/walpersist.test index 3f8b0b8930..175dcbf896 100644 --- a/test/walpersist.test +++ b/test/walpersist.test @@ -17,6 +17,11 @@ source $testdir/tester.tcl source $testdir/lock_common.tcl set ::testprefix walpersist +ifcapable !wal { + finish_test + return +} + do_test walpersist-1.0 { db eval { PRAGMA journal_mode=WAL; diff --git a/test/walro.test b/test/walro.test index 60bdce9e04..a8c489a792 100644 --- a/test/walro.test +++ b/test/walro.test @@ -24,6 +24,13 @@ if {$::tcl_platform(platform) != "unix"} { return } +# And only if the build is WAL-capable. +# +ifcapable !wal { + finish_test + return +} + do_multiclient_test tn { # Do not run tests with the connections in the same process. # From a682a6b578b09d7a60b3cf924abfed0568b5160c Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 24 Sep 2011 09:54:14 +0000 Subject: [PATCH 31/56] Fix misc3.test so that it works with OMIT_MERGE_SORT builds. FossilOrigin-Name: 87946c627f7230bea3739fd6aeec3e56115a3f93 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/misc3.test | 6 +++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7890a96310..5da7184a7d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\stest\sfiles\sso\sthat\sthey\swork\swith\sSQLITE_OMIT_WAL\sbuilds. -D 2011-09-24T05:55:36.123 +C Fix\smisc3.test\sso\sthat\sit\sworks\swith\sOMIT_MERGE_SORT\sbuilds. +D 2011-09-24T09:54:14.482 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -593,7 +593,7 @@ F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0 F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/misc1.test 55cb2bfbf4a8cd61f4be1effc30426ad41696bff F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d -F test/misc3.test 8e42d54b772a23b3c573672d3e0894d15b05221d +F test/misc3.test fe55130a43e444ee75e2156ff75dc96e964b5738 F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6 F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P d279e1a309909a0897b6082753a0fadb5066c31a -R 1d47a8525f2f65e65f824b1ab6ac3952 +P a38668dcff0a4d241d959ea19330ad43295d757d +R 62fed009ce85bf6f45bc23bd10da92d7 U dan -Z 402b9c23e658ae7ef163736478b873db +Z 385822c158a58f684ff65fda1a36a729 diff --git a/manifest.uuid b/manifest.uuid index 1798c846b2..383d95c20c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a38668dcff0a4d241d959ea19330ad43295d757d \ No newline at end of file +87946c627f7230bea3739fd6aeec3e56115a3f93 \ No newline at end of file diff --git a/test/misc3.test b/test/misc3.test index 2aec49af98..81a8266b9c 100644 --- a/test/misc3.test +++ b/test/misc3.test @@ -270,7 +270,11 @@ ifcapable {explain} { CREATE UNIQUE INDEX ex1i1 ON ex1(a); EXPLAIN REINDEX; }] - regexp { SorterCompare \d+ \d+ \d+ } $x + ifcapable mergesort { + regexp { SorterCompare \d+ \d+ \d+ } $x + } else { + regexp { IsUnique \d+ \d+ \d+ \d+ } $x + } } {1} if {[regexp {16} [db one {PRAGMA encoding}]]} { do_test misc3-6.11-utf16 { From 497ffc4c5d8a49f49faa2a283459067e8e4f5762 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 25 Sep 2011 17:47:58 +0000 Subject: [PATCH 32/56] If an open as read/write fails, do not try to reopen as read-only if in exclusive access mode. FossilOrigin-Name: 4a153f010037db83107314269b240c0ece8430f8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b1f37ef3ee..a3f07b8b92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\schanges\sinto\sthe\sstat3-trunk\sbranch. -D 2011-09-23T14:40:31.864 +C If\san\sopen\sas\sread/write\sfails,\sdo\snot\stry\sto\sreopen\sas\sread-only\sif\sin\nexclusive\saccess\smode. +D 2011-09-25T17:47:58.118 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8de00a4e52f308ef6d564834c0973e53646e0d4c F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 10e0c4dcdbec8d4189890fdf3e71b32efae194e3 -F src/os_win.c 0fc0f46c94b0385a940b0ee32992a833019a5985 +F src/os_win.c fbe47c7fdc9a846a772bbf98719c328becad5f8a F src/pager.c 8a6ac3e0d9694412076e2273e3c81e9c4e08758f F src/pager.h dbcaa791e8b6c3a6b77c168c5c27deec289fb176 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P be44928cf2a3c063c8228b769d90947acbfad1ef 6d8d4e1694694c3e961fc1922f732d1da40caa6f -R d77ad79f371c48e48b75d0b9ae4d6798 +P 0beb88a92c8f75231df120bef54616c7e4bb68c8 +R 89507550a3363f4f0fee38865f012e03 U drh -Z 325ba8d2018722c1460e52f95a5b9a1a +Z 8cbac2d25730672d9c2dfbd894fb75ea diff --git a/manifest.uuid b/manifest.uuid index d8ac7f71ab..a98917ce8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0beb88a92c8f75231df120bef54616c7e4bb68c8 \ No newline at end of file +4a153f010037db83107314269b240c0ece8430f8 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 33ca96c92c..b68b036701 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2615,7 +2615,7 @@ static int winOpen( pFile->lastErrno = GetLastError(); winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name); free(zConverted); - if( isReadWrite ){ + if( isReadWrite && !isExclusive ){ return winOpen(pVfs, zName, id, ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); }else{ From 3051dc1c7fa419a9ef000aa24e185db928d17e58 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 25 Sep 2011 17:49:26 +0000 Subject: [PATCH 33/56] If an open as read/write fails, do not try to reopen as read-only if in exclusive access mode. FossilOrigin-Name: 263c5fb2802f8c84835e42fc66acb1065b7e42b9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_win.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5da7184a7d..7223849835 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smisc3.test\sso\sthat\sit\sworks\swith\sOMIT_MERGE_SORT\sbuilds. -D 2011-09-24T09:54:14.482 +C If\san\sopen\sas\sread/write\sfails,\sdo\snot\stry\sto\sreopen\sas\sread-only\sif\sin\nexclusive\saccess\smode. +D 2011-09-25T17:49:26.535 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_unix.c 10e0c4dcdbec8d4189890fdf3e71b32efae194e3 -F src/os_win.c 0fc0f46c94b0385a940b0ee32992a833019a5985 +F src/os_win.c fbe47c7fdc9a846a772bbf98719c328becad5f8a F src/pager.c 8a6ac3e0d9694412076e2273e3c81e9c4e08758f F src/pager.h dbcaa791e8b6c3a6b77c168c5c27deec289fb176 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P a38668dcff0a4d241d959ea19330ad43295d757d -R 62fed009ce85bf6f45bc23bd10da92d7 -U dan -Z 385822c158a58f684ff65fda1a36a729 +P 87946c627f7230bea3739fd6aeec3e56115a3f93 +R 45c74df3a651dc62ff2bf197449037d8 +U drh +Z 9e8d9a9ad0cf791e3b92c0613c836ce2 diff --git a/manifest.uuid b/manifest.uuid index 383d95c20c..fb3a0aea69 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -87946c627f7230bea3739fd6aeec3e56115a3f93 \ No newline at end of file +263c5fb2802f8c84835e42fc66acb1065b7e42b9 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index 33ca96c92c..b68b036701 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2615,7 +2615,7 @@ static int winOpen( pFile->lastErrno = GetLastError(); winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name); free(zConverted); - if( isReadWrite ){ + if( isReadWrite && !isExclusive ){ return winOpen(pVfs, zName, id, ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags); }else{ From 64b41c71320bddf95b7279f87ed45dbb288308d1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Sep 2011 19:32:47 +0000 Subject: [PATCH 34/56] Changes to the analyzer script to make it work with zipvfs databases. FossilOrigin-Name: d82cffab6acafcf9d91fea4ac47cad73f6f09775 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/spaceanal.tcl | 13 ++++++++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7223849835..42eac2a0a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\san\sopen\sas\sread/write\sfails,\sdo\snot\stry\sto\sreopen\sas\sread-only\sif\sin\nexclusive\saccess\smode. -D 2011-09-25T17:49:26.535 +C Changes\sto\sthe\sanalyzer\sscript\sto\smake\sit\swork\swith\szipvfs\sdatabases. +D 2011-09-26T19:32:47.615 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -953,7 +953,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl 537f35d9e432695990ec855314d72eba9b999fe4 +F tool/spaceanal.tcl a7ffc29ba8db2fd791b4de83ee0a2a0436c07171 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 87946c627f7230bea3739fd6aeec3e56115a3f93 -R 45c74df3a651dc62ff2bf197449037d8 -U drh -Z 9e8d9a9ad0cf791e3b92c0613c836ce2 +P 263c5fb2802f8c84835e42fc66acb1065b7e42b9 +R 653cfc1894df476a0aac3944fac55ae4 +U dan +Z 3c688ce814d5c4f405619c4d3e366aaa diff --git a/manifest.uuid b/manifest.uuid index fb3a0aea69..4ad4ea9b90 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -263c5fb2802f8c84835e42fc66acb1065b7e42b9 \ No newline at end of file +d82cffab6acafcf9d91fea4ac47cad73f6f09775 \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index bb5c1a0c3c..52d8251b6e 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -34,8 +34,8 @@ if {[file size $file_to_analyze]<512} { sqlite3 db $file_to_analyze register_dbstat_vtab db -set pageSize [db one {PRAGMA page_size}] db eval {SELECT count(*) FROM sqlite_master} +set pageSize [db one {PRAGMA page_size}] # In-memory database for collecting statistics. This script loops through # the tables and indices in the database being analyzed, adding a row for each @@ -357,8 +357,15 @@ proc autovacuum_overhead {filePages pageSize} { # (not including sqlite_master) # user_percent: $user_payload as a percentage of total file size. -set file_bytes [file size $file_to_analyze] -set file_pgcnt [expr {$file_bytes/$pageSize}] +### The following, setting $file_bytes based on the actual size of the file +### on disk, causes this tool to choke on zipvfs databases. So set it based +### on the return of [PRAGMA page_count] instead. +if 0 { + set file_bytes [file size $file_to_analyze] + set file_pgcnt [expr {$file_bytes/$pageSize}] +} +set file_pgcnt [db one {PRAGMA page_count}] +set file_bytes [expr $file_pgcnt * $pageSize] set av_pgcnt [autovacuum_overhead $file_pgcnt $pageSize] set av_percent [percent $av_pgcnt $file_pgcnt] From f08f3843b7ccf084084a2f3e3f9b84d4c6650e39 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Sep 2011 13:40:26 +0000 Subject: [PATCH 35/56] Changes to sqlite3_analyzer to try to avoid integer overflow problems when linking against older versions of TCL. FossilOrigin-Name: 8c846311a0cd510bbf9361213bb60764e9b797aa --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/spaceanal.tcl | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 42eac2a0a0..f1fad15f2c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sthe\sanalyzer\sscript\sto\smake\sit\swork\swith\szipvfs\sdatabases. -D 2011-09-26T19:32:47.615 +C Changes\sto\ssqlite3_analyzer\sto\stry\sto\savoid\sinteger\soverflow\sproblems\s\nwhen\slinking\sagainst\solder\sversions\sof\sTCL. +D 2011-09-27T13:40:26.197 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -953,7 +953,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl a7ffc29ba8db2fd791b4de83ee0a2a0436c07171 +F tool/spaceanal.tcl 7591cccc6383cd649b4d5e5babe6a3dbba1625d6 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 263c5fb2802f8c84835e42fc66acb1065b7e42b9 -R 653cfc1894df476a0aac3944fac55ae4 -U dan -Z 3c688ce814d5c4f405619c4d3e366aaa +P d82cffab6acafcf9d91fea4ac47cad73f6f09775 +R 2bc38f424055a926b03e353359683766 +U drh +Z 8c563b03c7524b0b82590cf24a8a41f9 diff --git a/manifest.uuid b/manifest.uuid index 4ad4ea9b90..e160935999 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d82cffab6acafcf9d91fea4ac47cad73f6f09775 \ No newline at end of file +8c846311a0cd510bbf9361213bb60764e9b797aa \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index 52d8251b6e..6537349b06 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -35,7 +35,7 @@ sqlite3 db $file_to_analyze register_dbstat_vtab db db eval {SELECT count(*) FROM sqlite_master} -set pageSize [db one {PRAGMA page_size}] +set pageSize [expr {wide([db one {PRAGMA page_size}])}] # In-memory database for collecting statistics. This script loops through # the tables and indices in the database being analyzed, adding a row for each @@ -145,7 +145,7 @@ foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] { proc integerify {real} { if {[string is double -strict $real]} { - return [expr {int($real)}] + return [expr {wide($real)}] } else { return 0 } @@ -330,7 +330,7 @@ proc autovacuum_overhead {filePages pageSize} { set ptrsPerPage [expr double($pageSize/5)] # Return the number of pointer map pages in the database. - return [expr int(ceil( ($filePages-1.0)/($ptrsPerPage+1.0) ))] + return [expr wide(ceil( ($filePages-1.0)/($ptrsPerPage+1.0) ))] } @@ -365,16 +365,16 @@ if 0 { set file_pgcnt [expr {$file_bytes/$pageSize}] } set file_pgcnt [db one {PRAGMA page_count}] -set file_bytes [expr $file_pgcnt * $pageSize] +set file_bytes [expr {$file_pgcnt * $pageSize}] set av_pgcnt [autovacuum_overhead $file_pgcnt $pageSize] set av_percent [percent $av_pgcnt $file_pgcnt] set sql {SELECT sum(leaf_pages+int_pages+ovfl_pages) FROM space_used} -set inuse_pgcnt [expr int([mem eval $sql])] +set inuse_pgcnt [expr wide([mem eval $sql])] set inuse_percent [percent $inuse_pgcnt $file_pgcnt] -set free_pgcnt [expr $file_pgcnt-$inuse_pgcnt-$av_pgcnt] +set free_pgcnt [expr {$file_pgcnt-$inuse_pgcnt-$av_pgcnt}] set free_percent [percent $free_pgcnt $file_pgcnt] set free_pgcnt2 [db one {PRAGMA freelist_count}] set free_percent2 [percent $free_pgcnt2 $file_pgcnt] From 4c9f129d6074a89fe06df2d340e577ca52ca1ed8 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Sep 2011 00:50:14 +0000 Subject: [PATCH 36/56] Enhance the stat VFS to report out the total size of all pages used by a table, even if the ZIPVFS compression backend is in play. Update the sqlite3_analyzer logic to use these new outputs. FossilOrigin-Name: 19b8eaaf70db82d401d33beb7fd36045d5e8326f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/test_stat.c | 44 ++++++++++++++++++++++++++++++-------------- test/stat.test | 24 ++++++++++++++++-------- tool/spaceanal.tcl | 17 +++++++++++++---- 5 files changed, 68 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index f1fad15f2c..abcad1f792 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\ssqlite3_analyzer\sto\stry\sto\savoid\sinteger\soverflow\sproblems\s\nwhen\slinking\sagainst\solder\sversions\sof\sTCL. -D 2011-09-27T13:40:26.197 +C Enhance\sthe\sstat\sVFS\sto\sreport\sout\sthe\stotal\ssize\sof\sall\spages\sused\sby\na\stable,\seven\sif\sthe\sZIPVFS\scompression\sbackend\sis\sin\splay.\s\sUpdate\nthe\ssqlite3_analyzer\slogic\sto\suse\sthese\snew\soutputs. +D 2011-09-28T00:50:14.068 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,7 +223,7 @@ F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_stat.c 5bf0dcd0ffa469b2326d90f4a6e52d83e3f2df07 +F src/test_stat.c cf0a0e6d000ee4fbfd0d633d1e774a0267765f05 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa @@ -685,7 +685,7 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 -F test/stat.test 0997f6a57a35866b14111ed361ed8851ce7978ae +F test/stat.test 36bc951bdc2beac4224cc54396fd6a7dc65336f4 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd @@ -953,7 +953,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl 7591cccc6383cd649b4d5e5babe6a3dbba1625d6 +F tool/spaceanal.tcl 58d357384760020443c41d01db612c9809c75de7 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P d82cffab6acafcf9d91fea4ac47cad73f6f09775 -R 2bc38f424055a926b03e353359683766 +P 8c846311a0cd510bbf9361213bb60764e9b797aa +R 3bd6d041dec83962663bcd3d3bb93a06 U drh -Z 8c563b03c7524b0b82590cf24a8a41f9 +Z 6010793edcdb8e3508d42d2b73d9c2b0 diff --git a/manifest.uuid b/manifest.uuid index e160935999..13745e5d09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c846311a0cd510bbf9361213bb60764e9b797aa \ No newline at end of file +19b8eaaf70db82d401d33beb7fd36045d5e8326f \ No newline at end of file diff --git a/src/test_stat.c b/src/test_stat.c index 6e6accf6da..47791cf7f2 100644 --- a/src/test_stat.c +++ b/src/test_stat.c @@ -64,20 +64,11 @@ " ncell INTEGER, /* Cells on page (0 for overflow) */" \ " payload INTEGER, /* Bytes of payload on this page */" \ " unused INTEGER, /* Bytes of unused space on this page */" \ - " mx_payload INTEGER /* Largest payload size of all cells */" \ + " mx_payload INTEGER, /* Largest payload size of all cells */" \ + " pgoffset INTEGER, /* Offset of page in file */" \ + " pgsize INTEGER /* Size of the page */" \ ");" -#if 0 -#define VTAB_SCHEMA2 \ - "CREATE TABLE yy( " \ - " pageno INTEGER, /* B-tree page number */" \ - " cellno INTEGER, /* Cell number within page */" \ - " local INTEGER, /* Bytes of content stored locally */" \ - " payload INTEGER, /* Total cell payload size */" \ - " novfl INTEGER /* Number of overflow pages */" \ - ");" -#endif - typedef struct StatTable StatTable; typedef struct StatCursor StatCursor; @@ -126,6 +117,8 @@ struct StatCursor { int nPayload; /* Value of 'payload' column */ int nUnused; /* Value of 'unused' column */ int nMxPayload; /* Value of 'mx_payload' column */ + i64 iOffset; /* Value of 'pgOffset' column */ + int szPage; /* Value of 'pgSize' column */ }; struct StatTable { @@ -283,6 +276,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ int iOff; int nHdr; int isLeaf; + int szPage; u8 *aData = sqlite3PagerGetData(p->pPg); u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; @@ -303,10 +297,11 @@ static int statDecodePage(Btree *pBt, StatPage *p){ } p->nUnused = nUnused; p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); + szPage = sqlite3BtreeGetPageSize(pBt); if( p->nCell ){ int i; /* Used to iterate through cells */ - int nUsable = sqlite3BtreeGetPageSize(pBt) - sqlite3BtreeGetReserve(pBt); + int nUsable = szPage - sqlite3BtreeGetReserve(pBt); p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell)); memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell)); @@ -451,12 +446,28 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ */ if( rc==SQLITE_OK ){ int i; + sqlite3_file *fd; + sqlite3_int64 x[2]; StatPage *p = &pCsr->aPage[pCsr->iPage]; pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); pCsr->iPageno = p->iPgno; statDecodePage(pBt, p); + /* The default page size and offset */ + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); + pCsr->iOffset = pCsr->szPage * (p->iPgno - 1); + + /* If connected to a ZIPVFS backend, override the page size and + ** offset with actual values obtained from ZIPVFS. + */ + fd = sqlite3PagerFile(pPager); + x[0] = p->iPgno; + if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ + pCsr->iOffset = x[0]; + pCsr->szPage = x[1]; + } + switch( p->flags ){ case 0x05: /* table internal */ case 0x02: /* index internal */ @@ -531,6 +542,12 @@ static int statColumn( case 7: /* mx_payload */ sqlite3_result_int(ctx, pCsr->nMxPayload); break; + case 8: /* pgoffset */ + sqlite3_result_int64(ctx, pCsr->iOffset); + break; + case 9: /* pgsize */ + sqlite3_result_int(ctx, pCsr->szPage); + break; } return SQLITE_OK; } @@ -607,4 +624,3 @@ int SqlitetestStat_Init(Tcl_Interp *interp){ return TCL_OK; } #endif /* if defined(SQLITE_TEST) || TCLSH==2 */ - diff --git a/test/stat.test b/test/stat.test index 6737f5f4af..21726eb258 100644 --- a/test/stat.test +++ b/test/stat.test @@ -36,7 +36,8 @@ ifcapable wal { do_execsql_test stat-0.1 { PRAGMA journal_mode = WAL; PRAGMA journal_mode = delete; - SELECT * FROM stat; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat; } {wal delete sqlite_master / 1 leaf 0 0 916 0} } @@ -50,17 +51,20 @@ do_test stat-1.0 { } {} do_test stat-1.1 { execsql { - SELECT * FROM stat WHERE name = 't1'; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat WHERE name = 't1'; } } {t1 / 2 leaf 2 10 998 5} do_test stat-1.2 { execsql { - SELECT * FROM stat WHERE name = 'i1'; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat WHERE name = 'i1'; } } {i1 / 3 leaf 2 10 1000 5} do_test stat-1.3 { execsql { - SELECT * FROM stat WHERE name = 'sqlite_master'; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat WHERE name = 'sqlite_master'; } } {sqlite_master / 1 leaf 2 77 831 40} do_test stat-1.4 { @@ -77,7 +81,8 @@ do_execsql_test stat-2.1 { INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; INSERT INTO t3 SELECT a_string(110+rowid), a_string(221+rowid) FROM t3; - SELECT * FROM stat WHERE name != 'sqlite_master'; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat WHERE name != 'sqlite_master'; } [list \ sqlite_autoindex_t3_1 / 3 internal 3 368 623 125 \ sqlite_autoindex_t3_1 /000/ 8 leaf 8 946 46 123 \ @@ -108,7 +113,8 @@ do_execsql_test stat-3.1 { CREATE TABLE t4(x); CREATE INDEX i4 ON t4(x); INSERT INTO t4(rowid, x) VALUES(2, a_string(7777)); - SELECT * FROM stat WHERE name != 'sqlite_master'; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat WHERE name != 'sqlite_master'; } [list \ i4 / 3 leaf 1 103 905 7782 \ i4 /000+000000 9 overflow 0 1020 0 0 \ @@ -132,7 +138,8 @@ do_execsql_test stat-3.1 { do_execsql_test stat-4.1 { CREATE TABLE t5(x); CREATE INDEX i5 ON t5(x); - SELECT * FROM stat WHERE name = 't5' OR name = 'i5'; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat WHERE name = 't5' OR name = 'i5'; } [list \ i5 / 5 leaf 0 0 1016 0 \ t5 / 4 leaf 0 0 1016 0 \ @@ -149,7 +156,8 @@ do_execsql_test stat-5.1 { CREATE TABLE t1(x); INSERT INTO t1 VALUES(zeroblob(1513)); INSERT INTO t1 VALUES(zeroblob(1514)); - SELECT * FROM stat WHERE name = 't1'; + SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload + FROM stat WHERE name = 't1'; } [list \ t1 / 2 leaf 2 993 5 1517 \ t1 /000+000000 3 overflow 0 1020 0 0 \ diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index 6537349b06..ba7d1635b3 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -59,7 +59,8 @@ set tabledef {CREATE TABLE space_used( int_unused int, -- Number of unused bytes on interior pages leaf_unused int, -- Number of unused bytes on primary pages ovfl_unused int, -- Number of unused bytes on overflow pages - gap_cnt int -- Number of gaps in the page layout + gap_cnt int, -- Number of gaps in the page layout + compressed_size int -- Total bytes stored on disk );} mem eval $tabledef @@ -101,7 +102,8 @@ foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] { sum(isoverflow(pagetype, $is_index)) AS ovfl_pages, sum(isinternal(pagetype, $is_index) * unused) AS int_unused, sum(isleaf(pagetype, $is_index) * unused) AS leaf_unused, - sum(isoverflow(pagetype, $is_index) * unused) AS ovfl_unused + sum(isoverflow(pagetype, $is_index) * unused) AS ovfl_unused, + sum(pgsize) AS compressed_size FROM temp.dbstat WHERE name = $name } break @@ -138,7 +140,8 @@ foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] { $int_unused, $leaf_unused, $ovfl_unused, - $gap_cnt + $gap_cnt, + $compressed_size ); } } @@ -224,7 +227,8 @@ proc subreport {title where} { int(sum(leaf_unused)) AS leaf_unused, int(sum(int_unused)) AS int_unused, int(sum(ovfl_unused)) AS ovfl_unused, - int(sum(gap_cnt)) AS gap_cnt + int(sum(gap_cnt)) AS gap_cnt, + int(sum(compressed_size)) AS compressed_size FROM space_used WHERE $where" {} {} # Output the sub-report title, nicely decorated with * characters. @@ -274,6 +278,11 @@ proc subreport {title where} { statline {Percentage of total database} $total_pages_percent statline {Number of entries} $nleaf statline {Bytes of storage consumed} $storage + if {$compressed_size!=$storage} { + set pct [expr {$compressed_size*100.0/$storage}] + set pct [format {%5.1f%%} $pct] + statline {Bytes used after compression} $compressed_size $pct + } statline {Bytes of payload} $payload $payload_percent statline {Average payload per entry} $avg_payload statline {Average unused bytes per entry} $avg_unused From 7b075e3a1c2cc1e2d120063780bdeca8d17f6f63 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Sep 2011 01:10:00 +0000 Subject: [PATCH 37/56] In the shell, allow arbitrary table names on the ".import" command. Ticket [d1d84037b90a449]. FossilOrigin-Name: f4dd32d30ed54f847319664cf749fd0b92b4af3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index abcad1f792..f42ab64e80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sstat\sVFS\sto\sreport\sout\sthe\stotal\ssize\sof\sall\spages\sused\sby\na\stable,\seven\sif\sthe\sZIPVFS\scompression\sbackend\sis\sin\splay.\s\sUpdate\nthe\ssqlite3_analyzer\slogic\sto\suse\sthese\snew\soutputs. -D 2011-09-28T00:50:14.068 +C In\sthe\sshell,\sallow\sarbitrary\stable\snames\son\sthe\s".import"\scommand.\nTicket\s[d1d84037b90a449]. +D 2011-09-28T01:10:00.323 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -180,7 +180,7 @@ F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 -F src/shell.c 1d3baca3399a36fc34883b6cdab457688ae8e248 +F src/shell.c e8fe1251aee84baa2fb232ce83d938de25aa650f F src/sqlite.h.in c0ebc53056fd99590dec4cb4bd60a0787098ff18 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 76d81cd9da0618b231398bfcf90556e971972fca @@ -964,7 +964,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 8c846311a0cd510bbf9361213bb60764e9b797aa -R 3bd6d041dec83962663bcd3d3bb93a06 +P 19b8eaaf70db82d401d33beb7fd36045d5e8326f +R 435f0dc1b7e1759ce0909fde7c17ff57 U drh -Z 6010793edcdb8e3508d42d2b73d9c2b0 +Z 73ce79df8c2bde7f261efb2cafa35265 diff --git a/manifest.uuid b/manifest.uuid index 13745e5d09..7253c0cf03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19b8eaaf70db82d401d33beb7fd36045d5e8326f \ No newline at end of file +f4dd32d30ed54f847319664cf749fd0b92b4af3f \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index b36afb9d4c..48933bc790 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1678,7 +1678,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(stderr, "Error: non-null separator required for import\n"); return 1; } - zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); + zSql = sqlite3_mprintf("SELECT * FROM %s", zTable); if( zSql==0 ){ fprintf(stderr, "Error: out of memory\n"); return 1; @@ -1700,7 +1700,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ fprintf(stderr, "Error: out of memory\n"); return 1; } - sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable); + sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable); j = strlen30(zSql); for(i=1; i Date: Fri, 30 Sep 2011 12:01:01 +0000 Subject: [PATCH 38/56] Disable the xfer optimization if "PRAGMA count_changes=1" is configured. Ticket [c48d99d690]. FossilOrigin-Name: 9ddfe1e41300413bc9af7e5ce0ec9d1daf9136b1 --- manifest | 19 ++++++++++--------- manifest.uuid | 2 +- src/insert.c | 3 +++ src/vacuum.c | 2 +- test/tkt-c48d99d690.test | 26 ++++++++++++++++++++++++++ test/vacuum.test | 16 ++++++++++++++++ 6 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 test/tkt-c48d99d690.test diff --git a/manifest b/manifest index f42ab64e80..1d18abb522 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sshell,\sallow\sarbitrary\stable\snames\son\sthe\s".import"\scommand.\nTicket\s[d1d84037b90a449]. -D 2011-09-28T01:10:00.323 +C Disable\sthe\sxfer\soptimization\sif\s"PRAGMA\scount_changes=1"\sis\sconfigured.\sTicket\s[c48d99d690]. +D 2011-09-30T12:01:01.579 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -141,7 +141,7 @@ F src/global.c e230227de13601714b29f9363028514aada5ae2f F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 3eea5a53d2644116fb865afaa4699fabe62b441c +F src/insert.c ca18783512323f74aaf4ee74b46ffd75ec80d031 F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e @@ -237,7 +237,7 @@ F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 F src/update.c 74a6cfb34e9732c1e2a86278b229913b4b51eeec F src/utf.c c53eb7404b3eb5c1cbb5655c6a7a0e0ce6bd50f0 F src/util.c 06302ffd2b80408d4f6c7af71f7090e0cf8d8ff7 -F src/vacuum.c 05513dca036a1e7848fe18d5ed1265ac0b32365e +F src/vacuum.c 297f39745e05d7a6ed7def7929451474d570a31e F src/vdbe.c 60340bfb23f456ea0791cb28262a887363773371 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 693d6ac6810298fc6b4c503cfbe3f99a240f40af @@ -739,6 +739,7 @@ F test/tkt-b1d3a2e531.test 610ef582413171b379652663111b1f996d9f8f78 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 F test/tkt-b72787b1.test e6b62b2b2785c04d0d698d6a603507e384165049 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 +F test/tkt-c48d99d690.test bed446e3513ae10eec1b86fdd186ef750226c408 F test/tkt-cbd054fa6b.test f14f97ea43662e6f70c9e63287081e8be5d9d589 F test/tkt-d11f09d36e.test fb44f7961aa6d4b632fb7b9768239832210b5fc7 F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 @@ -860,7 +861,7 @@ F test/unordered.test e81169ce2a8f31b2c6b66af691887e1376ab3ced F test/update.test 8bc86fd7ef1a00014f76dc6a6a7c974df4aef172 F test/uri.test 0d289d32396bdbc491e9dc845f1a52e13f861e0b F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae -F test/vacuum.test 9516f3a8e49be666f2dde28561e4be5ae5612de0 +F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test af432e6e3bfc0ea20a80cb86a03c7d9876d38324 F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 @@ -964,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P 19b8eaaf70db82d401d33beb7fd36045d5e8326f -R 435f0dc1b7e1759ce0909fde7c17ff57 -U drh -Z 73ce79df8c2bde7f261efb2cafa35265 +P f4dd32d30ed54f847319664cf749fd0b92b4af3f +R 712f892aa9e5f34289b214c1af3c2cef +U dan +Z 65613378c768fb62c70f2ad14b487bbd diff --git a/manifest.uuid b/manifest.uuid index 7253c0cf03..604108eedb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f4dd32d30ed54f847319664cf749fd0b92b4af3f \ No newline at end of file +9ddfe1e41300413bc9af7e5ce0ec9d1daf9136b1 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 452939db94..277a852cc7 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1747,6 +1747,9 @@ static int xferOptimization( return 0; } #endif + if( (pParse->db->flags & SQLITE_CountRows)!=0 ){ + return 0; + } /* If we get this far, it means either: ** diff --git a/src/vacuum.c b/src/vacuum.c index 5a4ed32052..0e92f4fb0e 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -45,7 +45,7 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ return sqlite3_errcode(db); } VVA_ONLY( rc = ) sqlite3_step(pStmt); - assert( rc!=SQLITE_ROW ); + assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) ); return vacuumFinalize(db, pStmt, pzErrMsg); } diff --git a/test/tkt-c48d99d690.test b/test/tkt-c48d99d690.test new file mode 100644 index 0000000000..9b40579917 --- /dev/null +++ b/test/tkt-c48d99d690.test @@ -0,0 +1,26 @@ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set ::testprefix tkt-c48d99d690 + +do_test 1.0 { + execsql { + CREATE TABLE t1(a, b); + CREATE TABLE t2(a, b); + INSERT INTO t1 VALUES('one' , 1); + INSERT INTO t1 VALUES('two' , 5); + INSERT INTO t1 VALUES('two' , 2); + INSERT INTO t1 VALUES('three', 3); + PRAGMA count_changes = 1; + } +} {} + +do_test 1.1 { + execsql { INSERT INTO t2 SELECT * FROM t1 } +} {4} + +do_test 1.2 { execsql VACUUM } {} + +finish_test + diff --git a/test/vacuum.test b/test/vacuum.test index 9e6f5b2379..57429c29ea 100644 --- a/test/vacuum.test +++ b/test/vacuum.test @@ -385,4 +385,20 @@ ifcapable {autoinc} { forcedelete {a'z.db} +# Test that "PRAGMA count_changes" does not interfere with VACUUM or cause +# it to return any rows to the user. +# +do_test vacuum-10.1 { + db close + forcedelete test.db + sqlite3 db test.db + execsql { + CREATE TABLE t8(a, b); + INSERT INTO t8 VALUES('a', 'b'); + INSERT INTO t8 VALUES('c', 'd'); + PRAGMA count_changes = 1; + } +} {} +do_test vacuum-10.2 { execsql VACUUM } {} + finish_test From c756dedace29331429150a53ae243e880e6fb30a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 2 Oct 2011 05:23:16 +0000 Subject: [PATCH 39/56] Update MSVC makefile to allow targets to be built with support for ICU. FossilOrigin-Name: eb5da5e1dbe9c198095036827318fb381441cbd0 --- Makefile.msc | 56 +++++++++++++++++++++++++++++++++++++++++++-------- manifest | 14 ++++++------- manifest.uuid | 2 +- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 1521ceb5ae..f40936d915 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -11,6 +11,10 @@ TOP = . # USE_AMALGAMATION = 1 +# Set this non-0 to use the International Components for Unicode (ICU). +# +USE_ICU = 0 + # Set this to non-0 to create and use PDBs. # SYMBOLS = 1 @@ -31,8 +35,8 @@ DEBUG = 0 # Version numbers and release number for the SQLite being compiled. # VERSION = 3.7 -VERSION_NUMBER = 3007008 -RELEASE = 3.7.8 +VERSION_NUMBER = 3007009 +RELEASE = 3.7.9 # C Compiler and options for use in building executables that # will run on the platform that is doing the build. @@ -109,6 +113,23 @@ TCLLIBDIR = c:\tcl\lib LIBTCL = tcl85.lib !endif +# The locations of the ICU header and library files. These variables +# (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment +# prior to running nmake in order to match the actual installed location on +# this machine. +# +!if "$(ICUINCDIR)" == "" +ICUINCDIR = c:\icu\include +!endif + +!if "$(ICULIBDIR)" == "" +ICULIBDIR = c:\icu\lib +!endif + +!if "$(LIBICU)" == "" +LIBICU = icuuc.lib icuin.lib +!endif + # This is the command to use for tclsh - normally just "tclsh", but we may # know the specific version we want to use. This variable (TCLSH_CMD) may be # overridden via the environment prior to running nmake in order to select a @@ -136,7 +157,9 @@ TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1 # Any target libraries which libsqlite must be linked against # +!if "$(TLIBS)" == "" TLIBS = +!endif # Flags controlling use of the in memory btree implementation # @@ -179,6 +202,13 @@ TCC = $(TCC) -O2 TCC = $(TCC) -Zi !ENDIF +# If ICU support is enabled, add the compiler options for it. +!IF $(USE_ICU)!=0 +TCC = $(TCC) -DSQLITE_ENABLE_ICU=1 +TCC = $(TCC) -I$(TOP)\ext\icu +TCC = $(TCC) -I$(ICUINCDIR) +!ENDIF + # libtool compile/link LTCOMPILE = $(TCC) -Fo$@ LTLIB = lib.exe @@ -198,6 +228,16 @@ LTLIBOPTS = /MACHINE:$(PLATFORM) LTLINKOPTS = $(LTLINKOPTS) /DEBUG !ENDIF +# Start with the Tcl related linker options. +LTLIBPATHS = /LIBPATH:$(TCLLIBDIR) +LTLIBS = $(LIBTCL) + +# If ICU support is enabled, add the linker options for it. +!IF $(USE_ICU)!=0 +LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR) +LTLIBS = $(LTLIBS) $(LIBICU) +!ENDIF + # nawk compatible awk. NAWK = gawk.exe @@ -528,12 +568,12 @@ libsqlite3.lib: $(LIBOBJ) $(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS) libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib - $(LTLIB) $(LTLIBOPTS) /LIBPATH:$(TCLLIBDIR) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS) + $(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS) sqlite3.exe: $(TOP)\src\shell.c libsqlite3.lib sqlite3.h $(LTLINK) $(READLINE_FLAGS) \ $(TOP)\src\shell.c \ - /link $(LTLINKOPTS) libsqlite3.lib $(LIBREADLINE) $(TLIBS) + /link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LIBREADLINE) $(LTLIBS) $(TLIBS) # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to @@ -804,7 +844,7 @@ tclsqlite-shell.lo: $(TOP)\src\tclsqlite.c $(HDR) tclsqlite3.exe: tclsqlite-shell.lo libsqlite3.lib $(LTLINK) tclsqlite-shell.lo \ - /link $(LTLINKOPTS) /LIBPATH:$(TCLLIBDIR) libsqlite3.lib $(LIBTCL) + /link $(LTLINKOPTS) $(LTLIBPATHS) libsqlite3.lib $(LTLIBS) $(TLIBS) # Rules to build opcodes.c and opcodes.h # @@ -915,7 +955,7 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(HDR) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \ -DBUILD_sqlite -I$(TCLINCDIR) \ $(TESTFIXTURE_SRC) \ - /link $(LTLINKOPTS) /LIBPATH:$(TCLLIBDIR) $(LIBTCL) $(TLIBS) + /link $(LTLINKOPTS) $(LTLIBPATHS) $(LTLIBS) $(TLIBS) fulltest: testfixture.exe sqlite3.exe .\testfixture.exe $(TOP)\test\all.test @@ -935,7 +975,7 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)\src\test_stat.c $(TOP)\src\tclsqlite.c $(TO sqlite3_analyzer.exe: sqlite3_analyzer.c $(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \ - /link $(LTLINKOPTS) /LIBPATH:$(TCLLIBDIR) $(LIBTCL) $(TLIBS) + /link $(LTLINKOPTS) $(LTLIBPATHS) $(LTLIBS) $(TLIBS) clean: del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib @@ -962,4 +1002,4 @@ sqlite3.def: libsqlite3.lib | sort >> sqlite3.def sqlite3.dll: $(LIBOBJ) sqlite3.def - link $(LTLINKOPTS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) + link $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:sqlite3.def /OUT:$@ $(LIBOBJ) $(LTLIBS) $(TLIBS) diff --git a/manifest b/manifest index 1d18abb522..916f02c341 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Disable\sthe\sxfer\soptimization\sif\s"PRAGMA\scount_changes=1"\sis\sconfigured.\sTicket\s[c48d99d690]. -D 2011-09-30T12:01:01.579 +C Update\sMSVC\smakefile\sto\sallow\stargets\sto\sbe\sbuilt\swith\ssupport\sfor\sICU. +D 2011-10-02T05:23:16.470 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 6676bcfe711f621a0b1916ecfa5d0927f8084517 +F Makefile.msc dcad80fa69f17d46fe6778ba873fc108ca16298d F Makefile.vxworks 1deb39c8bb047296c30161ffa10c1b5423e632f9 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION bb37c274b503bbe73f00ea4f374eb817cba4b171 @@ -965,7 +965,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2 -P f4dd32d30ed54f847319664cf749fd0b92b4af3f -R 712f892aa9e5f34289b214c1af3c2cef -U dan -Z 65613378c768fb62c70f2ad14b487bbd +P 9ddfe1e41300413bc9af7e5ce0ec9d1daf9136b1 +R 03863d4dd01ba5995289085115b33375 +U mistachkin +Z 7dfdbd4e337132033acb3bc17ce78d60 diff --git a/manifest.uuid b/manifest.uuid index 604108eedb..c4bc7f0c61 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ddfe1e41300413bc9af7e5ce0ec9d1daf9136b1 \ No newline at end of file +eb5da5e1dbe9c198095036827318fb381441cbd0 \ No newline at end of file From c47167a6a887e09e627c10e10aa600183925f68d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Oct 2011 15:26:13 +0000 Subject: [PATCH 40/56] When finding the appropriate file permissions for journal files with SQLITE_ENABLE_8_3_NAMES, ignore "-" characters in the name of the containing directory. FossilOrigin-Name: 328cc1867ffbbf1c953dfd843649f5f209c8e6ec --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 12 ++++++++++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5b84fd0167..be61ddc5c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sSTAT3\schanges\sinto\strunk. -D 2011-10-03T15:30:33.910 +C When\sfinding\sthe\sappropriate\sfile\spermissions\sfor\sjournal\sfiles\swith\nSQLITE_ENABLE_8_3_NAMES,\signore\s"-"\scharacters\sin\sthe\sname\sof\sthe\ncontaining\sdirectory. +D 2011-10-05T15:26:13.326 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/os.c 3b3f69c34be7f998f5ea6bd46a2fe8a2b7fa8f70 F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 -F src/os_unix.c 10e0c4dcdbec8d4189890fdf3e71b32efae194e3 +F src/os_unix.c 9da63854b702e0855ce13711a80d8bdcc5b69549 F src/os_win.c fbe47c7fdc9a846a772bbf98719c328becad5f8a F src/pager.c 8a6ac3e0d9694412076e2273e3c81e9c4e08758f F src/pager.h dbcaa791e8b6c3a6b77c168c5c27deec289fb176 @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P eb5da5e1dbe9c198095036827318fb381441cbd0 4a153f010037db83107314269b240c0ece8430f8 -R 275c2a97143f629aefcc177df6bba902 +P 774d0842bcce8862f2aac371f1689536ed234a0a +R 8bd0da8f5be7e82af9f6bb3b243542c9 U drh -Z d37f9abd0dd218dc2e6379072330845e +Z 6258a1fa0558c65b7a4b3244943b1ca3 diff --git a/manifest.uuid b/manifest.uuid index b70915ef6b..7473e0a274 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -774d0842bcce8862f2aac371f1689536ed234a0a \ No newline at end of file +328cc1867ffbbf1c953dfd843649f5f209c8e6ec \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index d85a7949b5..a23a76234b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4888,8 +4888,16 @@ static int findCreateFileMode( ** used by the test_multiplex.c module. */ nDb = sqlite3Strlen30(zPath) - 1; - while( nDb>0 && zPath[nDb]!='-' ) nDb--; - if( nDb==0 ) return SQLITE_OK; +#ifdef SQLITE_ENABLE_8_3_NAMES + while( nDb>0 && zPath[nDb]!='-' && zPath[nDb]!='/' ) nDb--; + if( nDb==0 || zPath[nDb]=='/' ) return SQLITE_OK; +#else + while( zPath[nDb]!='-' ){ + assert( nDb>0 ); + assert( zPath[nDb]!='\n' ); + nDb--; + } +#endif memcpy(zDb, zPath, nDb); zDb[nDb] = '\0'; From 2cf7e0a712a8a5d6ee32367fcb739cbc82c5f5eb Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 5 Oct 2011 17:36:27 +0000 Subject: [PATCH 41/56] Fix test code related to reporting the size of overflow pages in zipvfs databases. FossilOrigin-Name: ad7c9eed8bbd607babce4f5965f587c873e7bc02 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_stat.c | 44 ++++++++++++++++++++++++++++---------------- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index be61ddc5c2..01e580b938 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sfinding\sthe\sappropriate\sfile\spermissions\sfor\sjournal\sfiles\swith\nSQLITE_ENABLE_8_3_NAMES,\signore\s"-"\scharacters\sin\sthe\sname\sof\sthe\ncontaining\sdirectory. -D 2011-10-05T15:26:13.326 +C Fix\stest\scode\srelated\sto\sreporting\sthe\ssize\sof\soverflow\spages\sin\szipvfs\sdatabases. +D 2011-10-05T17:36:27.323 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,7 +223,7 @@ F src/test_quota.c a391c866217e92986c6f523f05b08aa6956c8419 F src/test_rtree.c 6d06306e29946dc36f528a3a2cdc3add794656f1 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f -F src/test_stat.c cf0a0e6d000ee4fbfd0d633d1e774a0267765f05 +F src/test_stat.c 69de4361c7a69fc1136d31ab7144408cd00805c7 F src/test_superlock.c 2b97936ca127d13962c3605dbc9a4ef269c424cd F src/test_syscall.c a992d8c80ea91fbf21fb2dd570db40e77dd7e6ae F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 774d0842bcce8862f2aac371f1689536ed234a0a -R 8bd0da8f5be7e82af9f6bb3b243542c9 -U drh -Z 6258a1fa0558c65b7a4b3244943b1ca3 +P 328cc1867ffbbf1c953dfd843649f5f209c8e6ec +R 9966c1a1728c681681f9fe1b1d6773fc +U dan +Z 69c3b890ba0b067ca386e3a142264668 diff --git a/manifest.uuid b/manifest.uuid index 7473e0a274..a41affd0c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -328cc1867ffbbf1c953dfd843649f5f209c8e6ec \ No newline at end of file +ad7c9eed8bbd607babce4f5965f587c873e7bc02 \ No newline at end of file diff --git a/src/test_stat.c b/src/test_stat.c index 47791cf7f2..ef8176904a 100644 --- a/src/test_stat.c +++ b/src/test_stat.c @@ -356,6 +356,32 @@ static int statDecodePage(Btree *pBt, StatPage *p){ return SQLITE_OK; } +/* +** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on +** the current value of pCsr->iPageno. +*/ +static void statSizeAndOffset(StatCursor *pCsr){ + StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab; + Btree *pBt = pTab->db->aDb[0].pBt; + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3_file *fd; + sqlite3_int64 x[2]; + + /* The default page size and offset */ + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); + pCsr->iOffset = pCsr->szPage * (pCsr->iPageno - 1); + + /* If connected to a ZIPVFS backend, override the page size and + ** offset with actual values obtained from ZIPVFS. + */ + fd = sqlite3PagerFile(pPager); + x[0] = pCsr->iPageno; + if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ + pCsr->iOffset = x[0]; + pCsr->szPage = x[1]; + } +} + /* ** Move a statvfs cursor to the next entry in the file. */ @@ -414,6 +440,7 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ pCsr->nUnused = nUsable - 4 - pCsr->nPayload; } pCell->iOvfl++; + statSizeAndOffset(pCsr); return SQLITE_OK; } if( p->iRightChildPg ) break; @@ -446,27 +473,12 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ */ if( rc==SQLITE_OK ){ int i; - sqlite3_file *fd; - sqlite3_int64 x[2]; StatPage *p = &pCsr->aPage[pCsr->iPage]; pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); pCsr->iPageno = p->iPgno; statDecodePage(pBt, p); - - /* The default page size and offset */ - pCsr->szPage = sqlite3BtreeGetPageSize(pBt); - pCsr->iOffset = pCsr->szPage * (p->iPgno - 1); - - /* If connected to a ZIPVFS backend, override the page size and - ** offset with actual values obtained from ZIPVFS. - */ - fd = sqlite3PagerFile(pPager); - x[0] = p->iPgno; - if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ - pCsr->iOffset = x[0]; - pCsr->szPage = x[1]; - } + statSizeAndOffset(pCsr); switch( p->flags ){ case 0x05: /* table internal */ From b770894ec7e634e197241b941bb74e7db5d198de Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Oct 2011 18:18:13 +0000 Subject: [PATCH 42/56] Update the sqlite3_analyzer utility program to provide more details about the compression performance of ZIPVFS database files. FossilOrigin-Name: fa5ed53296d45a5f963d20fb361555c432e0f31b --- manifest | 14 +++++----- manifest.uuid | 2 +- tool/spaceanal.tcl | 66 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 01e580b938..a7c106eb23 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stest\scode\srelated\sto\sreporting\sthe\ssize\sof\soverflow\spages\sin\szipvfs\sdatabases. -D 2011-10-05T17:36:27.323 +C Update\sthe\ssqlite3_analyzer\sutility\sprogram\sto\sprovide\smore\sdetails\sabout\nthe\scompression\sperformance\sof\sZIPVFS\sdatabase\sfiles. +D 2011-10-05T18:18:13.395 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -956,7 +956,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl 58d357384760020443c41d01db612c9809c75de7 +F tool/spaceanal.tcl 7ba8b9784fe7c4fb89d3d9ca012d41c9d74b3c95 F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 328cc1867ffbbf1c953dfd843649f5f209c8e6ec -R 9966c1a1728c681681f9fe1b1d6773fc -U dan -Z 69c3b890ba0b067ca386e3a142264668 +P ad7c9eed8bbd607babce4f5965f587c873e7bc02 +R e170bea645862be3dfb0e179487437ed +U drh +Z 9854118ea63abc101ac650ae8a3b25fa diff --git a/manifest.uuid b/manifest.uuid index a41affd0c6..c7274fa718 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad7c9eed8bbd607babce4f5965f587c873e7bc02 \ No newline at end of file +fa5ed53296d45a5f963d20fb361555c432e0f31b \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index ba7d1635b3..22c63f3fbc 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -4,18 +4,29 @@ # if {[catch { -if {![info exists argv0]} { - set argv0 [file rootname [file tail [info nameofexecutable]]] -} - # Get the name of the database to analyze # -#set argv $argv0 -if {![info exists argv] || [llength $argv]!=1} { +proc usage {} { + set argv0 [file rootname [file tail [info nameofexecutable]]] puts stderr "Usage: $argv0 database-name" exit 1 } -set file_to_analyze [lindex $argv 0] +set file_to_analyze {} +set flags(-pageinfo) 0 +append argv {} +foreach arg $argv { + if {[regexp {^-+pageinfo$} $arg]} { + set flags(-pageinfo) 1 + } elseif {[regexp {^-} $arg]} { + puts stderr "Unknown option: $arg" + usage + } elseif {$file_to_analyze!=""} { + usage + } else { + set file_to_analyze $arg + } +} +if {$file_to_analyze==""} usage if {![file exists $file_to_analyze]} { puts stderr "No such file: $file_to_analyze" exit 1 @@ -24,7 +35,8 @@ if {![file readable $file_to_analyze]} { puts stderr "File is not readable: $file_to_analyze" exit 1 } -if {[file size $file_to_analyze]<512} { +set true_file_size [file size $file_to_analyze] +if {$true_file_size<512} { puts stderr "Empty or malformed database: $file_to_analyze" exit 1 } @@ -85,6 +97,8 @@ db func isleaf isleaf db func isinternal isinternal db func isoverflow isoverflow +set isCompressed 0 +set compressOverhead 0 set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 } foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] { @@ -107,6 +121,13 @@ foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] { FROM temp.dbstat WHERE name = $name } break + set total_pages [expr {$leaf_pages+$int_pages+$ovfl_pages}] + set storage [expr {$total_pages*$pageSize}] + if {!$isCompressed && $storage>$compressed_size} { + set isCompressed 1 + set compressOverhead 14 + } + # Column 'gap_cnt' is set to the number of non-contiguous entries in the # list of pages visited if the b-tree structure is traversed in a top-down # fashion (each node visited before its child-tree is passed). Any overflow @@ -203,7 +224,7 @@ proc divide {num denom} { # the $where clause determines which subset to analyze. # proc subreport {title where} { - global pageSize file_pgcnt + global pageSize file_pgcnt compressOverhead # Query the in-memory database for the sum of various statistics # for the subset of tables/indices identified by the WHERE clause in @@ -279,6 +300,7 @@ proc subreport {title where} { statline {Number of entries} $nleaf statline {Bytes of storage consumed} $storage if {$compressed_size!=$storage} { + set compressed_size [expr {$compressed_size+$compressOverhead*$total_pages}] set pct [expr {$compressed_size*100.0/$storage}] set pct [format {%5.1f%%} $pct] statline {Bytes used after compression} $compressed_size $pct @@ -419,7 +441,13 @@ statline {Number of tables in the database} $ntable statline {Number of indices} $nindex statline {Number of named indices} $nmanindex statline {Automatically generated indices} $nautoindex -statline {Size of the file in bytes} $file_bytes +if {$isCompressed} { + statline {Size of uncompressed content in bytes} $file_bytes + set efficiency [percent $true_file_size $file_bytes] + statline {Size of compressed file on disk} $true_file_size $efficiency +} else { + statline {Size of the file in bytes} $file_bytes +} statline {Bytes of user payload stored} $user_payload $user_percent # Output table rankings @@ -432,6 +460,24 @@ mem eval {SELECT tblname, count(*) AS cnt, FROM space_used GROUP BY tblname ORDER BY size+0 DESC, tblname} {} { statline [string toupper $tblname] $size [percent $size $file_pgcnt] } +if {$isCompressed} { + puts "" + puts "*** Bytes of disk space used after compression ***********************" + puts "" + set csum 0 + mem eval {SELECT tblname, + int(sum(compressed_size)) + + $compressOverhead*sum(int_pages+leaf_pages+ovfl_pages) + AS csize + FROM space_used GROUP BY tblname ORDER BY csize+0 DESC, tblname} {} { + incr csum $csize + statline [string toupper $tblname] $csize [percent $csize $true_file_size] + } + set overhead [expr {$true_file_size - $csum}] + if {$overhead>0} { + statline {Header and free space} $overhead [percent $overhead $true_file_size] + } +} # Output subreports # From a624fd50389b802e6eb11100277e524eff3c8628 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 5 Oct 2011 19:46:03 +0000 Subject: [PATCH 43/56] Add the --pageinfo and --stats options to the sqlite3_analyzer utility. FossilOrigin-Name: baa80c7bc31900decae0d8e6090b30fcde377492 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/spaceanal.tcl | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index a7c106eb23..e631f0a928 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\ssqlite3_analyzer\sutility\sprogram\sto\sprovide\smore\sdetails\sabout\nthe\scompression\sperformance\sof\sZIPVFS\sdatabase\sfiles. -D 2011-10-05T18:18:13.395 +C Add\sthe\s--pageinfo\sand\s--stats\soptions\sto\sthe\ssqlite3_analyzer\sutility. +D 2011-10-05T19:46:03.527 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -956,7 +956,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl 7ba8b9784fe7c4fb89d3d9ca012d41c9d74b3c95 +F tool/spaceanal.tcl 2dc915c21309029dbf0eb54868ad036454d2f77a F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P ad7c9eed8bbd607babce4f5965f587c873e7bc02 -R e170bea645862be3dfb0e179487437ed +P fa5ed53296d45a5f963d20fb361555c432e0f31b +R a181777b970b4ab76912e6ec4d5a6e74 U drh -Z 9854118ea63abc101ac650ae8a3b25fa +Z f1a2995e806e2cefa53579be0d3ef0a3 diff --git a/manifest.uuid b/manifest.uuid index c7274fa718..13131cb907 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa5ed53296d45a5f963d20fb361555c432e0f31b \ No newline at end of file +baa80c7bc31900decae0d8e6090b30fcde377492 \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index 22c63f3fbc..b6ebfba664 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -13,10 +13,13 @@ proc usage {} { } set file_to_analyze {} set flags(-pageinfo) 0 +set flags(-stats) 0 append argv {} foreach arg $argv { if {[regexp {^-+pageinfo$} $arg]} { set flags(-pageinfo) 1 + } elseif {[regexp {^-+stats$} $arg]} { + set flags(-stats) 1 } elseif {[regexp {^-} $arg]} { puts stderr "Unknown option: $arg" usage @@ -49,6 +52,44 @@ register_dbstat_vtab db db eval {SELECT count(*) FROM sqlite_master} set pageSize [expr {wide([db one {PRAGMA page_size}])}] +if {$flags(-pageinfo)} { + db eval {CREATE VIRTUAL TABLE temp.stat USING dbstat} + db eval {SELECT name, path, pageno FROM temp.stat ORDER BY pageno} { + puts "$pageno $name $path" + } + exit 0 +} +if {$flags(-stats)} { + db eval {CREATE VIRTUAL TABLE temp.stat USING dbstat} + puts "BEGIN;" + puts "CREATE TABLE stats(" + puts " name STRING, /* Name of table or index */" + puts " path INTEGER, /* Path to page from root */" + puts " pageno INTEGER, /* Page number */" + puts " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" + puts " ncell INTEGER, /* Cells on page (0 for overflow) */" + puts " payload INTEGER, /* Bytes of payload on this page */" + puts " unused INTEGER, /* Bytes of unused space on this page */" + puts " mx_payload INTEGER, /* Largest payload size of all cells */" + puts " pgoffset INTEGER, /* Offset of page in file */" + puts " pgsize INTEGER /* Size of the page */" + puts ");" + db eval {SELECT quote(name) || ',' || + quote(path) || ',' || + quote(pageno) || ',' || + quote(pagetype) || ',' || + quote(ncell) || ',' || + quote(payload) || ',' || + quote(unused) || ',' || + quote(mx_payload) || ',' || + quote(pgoffset) || ',' || + quote(pgsize) AS x FROM stat} { + puts "INSERT INTO stats VALUES($x);" + } + puts "COMMIT;" + exit 0 +} + # In-memory database for collecting statistics. This script loops through # the tables and indices in the database being analyzed, adding a row for each # to an in-memory database (for which the schema is shown below). It then From f3259997c017d9660587ffd61a5ca3d3a7db973e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Oct 2011 12:59:23 +0000 Subject: [PATCH 44/56] Enhance the sqlite3_data_count() routine so that it can be used to determine if SQLITE_DONE has been seen on the prepared statement. FossilOrigin-Name: 9913996e7b0f94ba1c51200b61433193002f3638 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 6 ++++++ src/vdbeaux.c | 1 + 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e631f0a928..791d69d826 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--pageinfo\sand\s--stats\soptions\sto\sthe\ssqlite3_analyzer\sutility. -D 2011-10-05T19:46:03.527 +C Enhance\sthe\ssqlite3_data_count()\sroutine\sso\sthat\sit\scan\sbe\sused\sto\sdetermine\nif\sSQLITE_DONE\shas\sbeen\sseen\son\sthe\sprepared\sstatement. +D 2011-10-07T12:59:23.182 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -181,7 +181,7 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c e8fe1251aee84baa2fb232ce83d938de25aa650f -F src/sqlite.h.in 3b238342522bfc3b9d68d7ff3240a27a2a59ee59 +F src/sqlite.h.in 1865923bdb9deb8dde42da5862aca0071adb6061 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 28cca77ebdaf6025ae5df52717dff429c7c6d4ef F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -242,7 +242,7 @@ F src/vdbe.c 60340bfb23f456ea0791cb28262a887363773371 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 693d6ac6810298fc6b4c503cfbe3f99a240f40af F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98 -F src/vdbeaux.c 461e3e39cc6084e23412f3ff85ef73839dae90e2 +F src/vdbeaux.c 9542e2fba791f14022c23fbe5cbe179eee36abc6 F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P fa5ed53296d45a5f963d20fb361555c432e0f31b -R a181777b970b4ab76912e6ec4d5a6e74 +P baa80c7bc31900decae0d8e6090b30fcde377492 +R 1223a474d1e5cea6170a2af45d3f0303 U drh -Z f1a2995e806e2cefa53579be0d3ef0a3 +Z 7e8fd93d23ec7d2fecbdff0e025997fa diff --git a/manifest.uuid b/manifest.uuid index 13131cb907..9fe70085bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -baa80c7bc31900decae0d8e6090b30fcde377492 \ No newline at end of file +9913996e7b0f94ba1c51200b61433193002f3638 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4c243796a0..d13f17639d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3348,6 +3348,12 @@ int sqlite3_step(sqlite3_stmt*); ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of ** interfaces) then sqlite3_data_count(P) returns 0. ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned +** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] +** where it always returns zero since each step of that multi-step +** pragma returns 0 columns of data. ** ** See also: [sqlite3_column_count()] */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8a9ef81ea2..90d1e9c8a2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1153,6 +1153,7 @@ int sqlite3VdbeList( ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, 8); + p->nResColumn = 0; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or From 8871ef5afd1217110189bcaa55400ab30bdac46b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Oct 2011 13:33:10 +0000 Subject: [PATCH 45/56] Begin an effort to enhance the query planner to do a better job with OR terms in the WHERE clause. This change allows ANDs outside of the OR to be factored into the OR terms if that is helpful in finding better indices. FossilOrigin-Name: 876bd21aaac444c7e056730e35696a74e9a1af0a --- manifest | 15 ++++---- manifest.uuid | 2 +- src/where.c | 96 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 74 insertions(+), 39 deletions(-) diff --git a/manifest b/manifest index 791d69d826..3749bfc8ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3_data_count()\sroutine\sso\sthat\sit\scan\sbe\sused\sto\sdetermine\nif\sSQLITE_DONE\shas\sbeen\sseen\son\sthe\sprepared\sstatement. -D 2011-10-07T12:59:23.182 +C Begin\san\seffort\sto\senhance\sthe\squery\splanner\sto\sdo\sa\sbetter\sjob\swith\sOR\sterms\nin\sthe\sWHERE\sclause.\s\sThis\schange\sallows\sANDs\soutside\sof\sthe\sOR\sto\sbe\sfactored\ninto\sthe\sOR\sterms\sif\sthat\sis\shelpful\sin\sfinding\sbetter\sindices. +D 2011-10-07T13:33:10.760 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -251,7 +251,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c aafcb21a74e41f9aae76ea604e1e787ff8574125 +F src/where.c 80c53e8e21fe9c5c5830e33d806fc168577427ed F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -967,7 +967,10 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P baa80c7bc31900decae0d8e6090b30fcde377492 -R 1223a474d1e5cea6170a2af45d3f0303 +P 9913996e7b0f94ba1c51200b61433193002f3638 +R 7d8737bed3e72adf3b068f98f3f5d762 +T *branch * or-opt +T *sym-or-opt * +T -sym-trunk * U drh -Z 7e8fd93d23ec7d2fecbdff0e025997fa +Z 6d6f0e795135cadc2210cb2fc14d2593 diff --git a/manifest.uuid b/manifest.uuid index 9fe70085bf..7e8c9eb4d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9913996e7b0f94ba1c51200b61433193002f3638 \ No newline at end of file +876bd21aaac444c7e056730e35696a74e9a1af0a \ No newline at end of file diff --git a/src/where.c b/src/where.c index 220411de2f..fa81094af9 100644 --- a/src/where.c +++ b/src/where.c @@ -127,11 +127,20 @@ struct WhereTerm { /* ** An instance of the following structure holds all information about a ** WHERE clause. Mostly this is a container for one or more WhereTerms. +** +** Explanation of pOuter: For a WHERE clause of the form +** +** a AND ((b AND c) OR (d AND e)) AND f +** +** There are separate WhereClause objects for the whole clause and for +** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the +** subclauses points to the WhereClause object for the whole clause. */ struct WhereClause { Parse *pParse; /* The parser context */ WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */ Bitmask vmask; /* Bitmask identifying virtual table cursors */ + WhereClause *pOuter; /* Outer conjunction */ u8 op; /* Split operator. TK_AND or TK_OR */ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ @@ -265,6 +274,7 @@ static void whereClauseInit( ){ pWC->pParse = pParse; pWC->pMaskSet = pMaskSet; + pWC->pOuter = 0; pWC->nTerm = 0; pWC->nSlot = ArraySize(pWC->aStatic); pWC->a = pWC->aStatic; @@ -584,36 +594,38 @@ static WhereTerm *findTerm( int k; assert( iCur>=0 ); op &= WO_ALL; - for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ - if( pTerm->leftCursor==iCur - && (pTerm->prereqRight & notReady)==0 - && pTerm->u.leftColumn==iColumn - && (pTerm->eOperator & op)!=0 - ){ - if( pIdx && pTerm->eOperator!=WO_ISNULL ){ - Expr *pX = pTerm->pExpr; - CollSeq *pColl; - char idxaff; - int j; - Parse *pParse = pWC->pParse; - - idxaff = pIdx->pTable->aCol[iColumn].affinity; - if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue; - - /* Figure out the collation sequence required from an index for - ** it to be useful for optimising expression pX. Store this - ** value in variable pColl. - */ - assert(pX->pLeft); - pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); - assert(pColl || pParse->nErr); - - for(j=0; pIdx->aiColumn[j]!=iColumn; j++){ - if( NEVER(j>=pIdx->nColumn) ) return 0; + for(; pWC; pWC=pWC->pOuter){ + for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){ + if( pTerm->leftCursor==iCur + && (pTerm->prereqRight & notReady)==0 + && pTerm->u.leftColumn==iColumn + && (pTerm->eOperator & op)!=0 + ){ + if( pIdx && pTerm->eOperator!=WO_ISNULL ){ + Expr *pX = pTerm->pExpr; + CollSeq *pColl; + char idxaff; + int j; + Parse *pParse = pWC->pParse; + + idxaff = pIdx->pTable->aCol[iColumn].affinity; + if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue; + + /* Figure out the collation sequence required from an index for + ** it to be useful for optimising expression pX. Store this + ** value in variable pColl. + */ + assert(pX->pLeft); + pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); + assert(pColl || pParse->nErr); + + for(j=0; pIdx->aiColumn[j]!=iColumn; j++){ + if( NEVER(j>=pIdx->nColumn) ) return 0; + } + if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue; } - if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue; + return pTerm; } - return pTerm; } } return 0; @@ -907,6 +919,7 @@ static void exprAnalyzeOrTerm( whereClauseInit(pAndWC, pWC->pParse, pMaskSet); whereSplit(pAndWC, pOrTerm->pExpr, TK_AND); exprAnalyzeAll(pSrc, pAndWC); + pAndWC->pOuter = pWC; testcase( db->mallocFailed ); if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ @@ -1833,6 +1846,7 @@ static void bestOrClauseIndex( WhereClause tempWC; tempWC.pParse = pWC->pParse; tempWC.pMaskSet = pWC->pMaskSet; + tempWC.pOuter = pWC; tempWC.op = TK_AND; tempWC.a = pOrTerm; tempWC.nTerm = 1; @@ -3769,7 +3783,8 @@ static Bitmask codeOneLoopStart( WhereInfo *pWInfo, /* Complete information about the WHERE clause */ int iLevel, /* Which level of pWInfo->a[] should be coded */ u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */ - Bitmask notReady /* Which tables are currently available */ + Bitmask notReady, /* Which tables are currently available */ + Expr *pWhere /* Complete WHERE clause */ ){ int j, k; /* Loop counters */ int iCur; /* The VDBE cursor for the table */ @@ -4251,7 +4266,8 @@ static Bitmask codeOneLoopStart( int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ - int ii; + int ii; /* Loop counter */ + Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ pTerm = pLevel->plan.u.pTerm; assert( pTerm!=0 ); @@ -4301,12 +4317,27 @@ static Bitmask codeOneLoopStart( } iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); + /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y + ** Then for every term xN, evaluate as the subexpression: xN AND z + ** That way, terms in y that are factored into the disjunction will + ** be picked up by the recursive calls to sqlite3WhereBegin() below. + */ + if( pWC->nTerm>1 ){ + pAndExpr = sqlite3ExprAlloc(pParse->db, TK_AND, 0, 0); + pAndExpr->pRight = pWhere; + } + for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){ WhereInfo *pSubWInfo; /* Info for single OR-term scan */ + Expr *pOrExpr = pOrTerm->pExpr; + if( pAndExpr ){ + pAndExpr->pLeft = pOrExpr; + pOrExpr = pAndExpr; + } /* Loop through table entries that match term pOrTerm. */ - pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrTerm->pExpr, 0, 0, + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY); if( pSubWInfo ){ @@ -4335,6 +4366,7 @@ static Bitmask codeOneLoopStart( } } } + sqlite3DbFree(pParse->db, pAndExpr); sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk); sqlite3VdbeResolveLabel(v, iLoopBody); @@ -4989,7 +5021,7 @@ WhereInfo *sqlite3WhereBegin( for(i=0; ia[i]; explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags); - notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady); + notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady, pWhere); pWInfo->iContinue = pLevel->addrCont; } From 9ef61f4f4ef46f4d95ebcff1e4f726224ae25e2e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Oct 2011 14:40:59 +0000 Subject: [PATCH 46/56] Prevent infinite recursion of in the query planner for some pathological test cases by disabling OR-clause processing upon first recursion. FossilOrigin-Name: 9fca05eac503d712886a05d03794f76c61fb39ed --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/sqliteInt.h | 8 ++++---- src/where.c | 24 +++++++++++++++--------- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 3749bfc8ff..d40e0138a7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Begin\san\seffort\sto\senhance\sthe\squery\splanner\sto\sdo\sa\sbetter\sjob\swith\sOR\sterms\nin\sthe\sWHERE\sclause.\s\sThis\schange\sallows\sANDs\soutside\sof\sthe\sOR\sto\sbe\sfactored\ninto\sthe\sOR\sterms\sif\sthat\sis\shelpful\sin\sfinding\sbetter\sindices. -D 2011-10-07T13:33:10.760 +C Prevent\sinfinite\srecursion\sof\sin\sthe\squery\splanner\sfor\ssome\spathological\ntest\scases\sby\sdisabling\sOR-clause\sprocessing\supon\sfirst\srecursion. +D 2011-10-07T14:40:59.269 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -183,7 +183,7 @@ F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c e8fe1251aee84baa2fb232ce83d938de25aa650f F src/sqlite.h.in 1865923bdb9deb8dde42da5862aca0071adb6061 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 -F src/sqliteInt.h 28cca77ebdaf6025ae5df52717dff429c7c6d4ef +F src/sqliteInt.h 2f66bf068131f0e499dd5e0abea3f68cd6b27b2d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -251,7 +251,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 80c53e8e21fe9c5c5830e33d806fc168577427ed +F src/where.c 2e82da485ae1e037d2e372fd361c926cd4885934 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -967,10 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 9913996e7b0f94ba1c51200b61433193002f3638 -R 7d8737bed3e72adf3b068f98f3f5d762 -T *branch * or-opt -T *sym-or-opt * -T -sym-trunk * +P 876bd21aaac444c7e056730e35696a74e9a1af0a +R 2e052ba91d5f74c653875a92f40f0614 U drh -Z 6d6f0e795135cadc2210cb2fc14d2593 +Z ec0c9bad465d9d136336e81b2a3d87e4 diff --git a/manifest.uuid b/manifest.uuid index 7e8c9eb4d6..a9d34afed4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -876bd21aaac444c7e056730e35696a74e9a1af0a \ No newline at end of file +9fca05eac503d712886a05d03794f76c61fb39ed \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 35ab54a5f7..2a54e4593a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1979,10 +1979,10 @@ struct WhereLevel { #define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */ #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */ #define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */ -#define WHERE_OMIT_OPEN 0x0010 /* Table cursors are already open */ -#define WHERE_OMIT_CLOSE 0x0020 /* Omit close of table & index cursors */ -#define WHERE_FORCE_TABLE 0x0040 /* Do not use an index-only search */ -#define WHERE_ONETABLE_ONLY 0x0080 /* Only code the 1st table in pTabList */ +#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */ +#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */ +#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */ +#define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */ /* ** The WHERE clause processing routine has two halves. The diff --git a/src/where.c b/src/where.c index fa81094af9..9d5adc1832 100644 --- a/src/where.c +++ b/src/where.c @@ -142,6 +142,7 @@ struct WhereClause { Bitmask vmask; /* Bitmask identifying virtual table cursors */ WhereClause *pOuter; /* Outer conjunction */ u8 op; /* Split operator. TK_AND or TK_OR */ + u16 wctrlFlags; /* Might include WHERE_AND_ONLY */ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ @@ -270,7 +271,8 @@ struct WhereCost { static void whereClauseInit( WhereClause *pWC, /* The WhereClause to be initialized */ Parse *pParse, /* The parsing context */ - WhereMaskSet *pMaskSet /* Mapping from table cursor numbers to bitmasks */ + WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmasks */ + u16 wctrlFlags /* Might include WHERE_AND_ONLY */ ){ pWC->pParse = pParse; pWC->pMaskSet = pMaskSet; @@ -279,6 +281,7 @@ static void whereClauseInit( pWC->nSlot = ArraySize(pWC->aStatic); pWC->a = pWC->aStatic; pWC->vmask = 0; + pWC->wctrlFlags = wctrlFlags; } /* Forward reference */ @@ -889,7 +892,7 @@ static void exprAnalyzeOrTerm( if( pOrInfo==0 ) return; pTerm->wtFlags |= TERM_ORINFO; pOrWc = &pOrInfo->wc; - whereClauseInit(pOrWc, pWC->pParse, pMaskSet); + whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags); whereSplit(pOrWc, pExpr, TK_OR); exprAnalyzeAll(pSrc, pOrWc); if( db->mallocFailed ) return; @@ -916,7 +919,7 @@ static void exprAnalyzeOrTerm( pOrTerm->wtFlags |= TERM_ANDINFO; pOrTerm->eOperator = WO_AND; pAndWC = &pAndInfo->wc; - whereClauseInit(pAndWC, pWC->pParse, pMaskSet); + whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags); whereSplit(pAndWC, pOrTerm->pExpr, TK_AND); exprAnalyzeAll(pSrc, pAndWC); pAndWC->pOuter = pWC; @@ -1814,11 +1817,14 @@ static void bestOrClauseIndex( WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */ WhereTerm *pTerm; /* A single term of the WHERE clause */ - /* No OR-clause optimization allowed if the INDEXED BY or NOT INDEXED clauses - ** are used */ + /* The OR-clause optimization is disallowed if the INDEXED BY or + ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */ if( pSrc->notIndexed || pSrc->pIndex!=0 ){ return; } + if( pWC->wctrlFlags & WHERE_AND_ONLY ){ + return; + } /* Search the WHERE clause terms for a usable WO_OR term. */ for(pTerm=pWC->a; pTermplan.wsFlags & WHERE_IDX_ONLY)==0 - && (wctrlFlags & WHERE_OMIT_OPEN)==0 ){ + && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){ int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead; sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); testcase( pTab->nCol==BMS-1 ); @@ -5156,7 +5162,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pTab!=0 ); if( (pTab->tabFlags & TF_Ephemeral)==0 && pTab->pSelect==0 - && (pWInfo->wctrlFlags & WHERE_OMIT_CLOSE)==0 + && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){ int ws = pLevel->plan.wsFlags; if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){ From 85ae206e69c69179e35c389617f0960ead17826e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Oct 2011 16:08:28 +0000 Subject: [PATCH 47/56] More test cases for the OR optimization. FossilOrigin-Name: 4997d8b81cd3ea7c708911bfece00020d11224f9 --- manifest | 14 ++++---- manifest.uuid | 2 +- test/where7.test | 4 +-- test/where9.test | 84 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 88 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index d40e0138a7..67d3608db6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sinfinite\srecursion\sof\sin\sthe\squery\splanner\sfor\ssome\spathological\ntest\scases\sby\sdisabling\sOR-clause\sprocessing\supon\sfirst\srecursion. -D 2011-10-07T14:40:59.269 +C More\stest\scases\sfor\sthe\sOR\soptimization. +D 2011-10-07T16:08:28.818 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -916,10 +916,10 @@ F test/where3.test 8e1175c7ef710c70502858fc4fb08d784b3620b9 F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b -F test/where7.test aa4cfcd6f66e2a4ef87b6717327325bf4d547502 +F test/where7.test 814d7373413398e074f134cff5f8872e2c08bd3b F test/where8.test a6c740fd286d7883e274e17b6230a9d672a7ab1f F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 -F test/where9.test 24f19ad14bb1b831564ced5273e681e495662848 +F test/where9.test bed66dcfc69a54a99661c0c9906189cb5e58f4e2 F test/whereA.test 24c234263c8fe358f079d5e57d884fb569d2da0a F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 876bd21aaac444c7e056730e35696a74e9a1af0a -R 2e052ba91d5f74c653875a92f40f0614 +P 9fca05eac503d712886a05d03794f76c61fb39ed +R bd6384414b9b60e15876987ee9f999e9 U drh -Z ec0c9bad465d9d136336e81b2a3d87e4 +Z 427731fab44d769232d079e056d051e3 diff --git a/manifest.uuid b/manifest.uuid index a9d34afed4..937b15f843 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9fca05eac503d712886a05d03794f76c61fb39ed \ No newline at end of file +4997d8b81cd3ea7c708911bfece00020d11224f9 \ No newline at end of file diff --git a/test/where7.test b/test/where7.test index e34778c763..ffb7173d21 100644 --- a/test/where7.test +++ b/test/where7.test @@ -10,8 +10,6 @@ #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the multi-index OR clause optimizer. -# -# $Id: where7.test,v 1.9 2009/06/07 23:45:11 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -23341,7 +23339,7 @@ do_execsql_test where7-3.1 { OR t301.c8 = 1407424651264000) ORDER BY t302.c5 LIMIT 200; } { - 0 0 1 {SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?) (~10 rows)} + 0 0 1 {SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?) (~5 rows)} 0 0 1 {SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 0 1 0 {SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?) (~2 rows)} 0 0 0 {USE TEMP B-TREE FOR ORDER BY} diff --git a/test/where9.test b/test/where9.test index 9a180116a8..b4a2d8d130 100644 --- a/test/where9.test +++ b/test/where9.test @@ -11,7 +11,6 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the multi-index OR clause optimizer. # -# $Id: where9.test,v 1.9 2009/06/05 17:09:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -365,7 +364,7 @@ ifcapable explain { } { 0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?) (~2 rows)} - 0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) (~10 rows)} + 0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) (~5 rows)} } do_execsql_test where9-3.2 { EXPLAIN QUERY PLAN @@ -375,7 +374,7 @@ ifcapable explain { } { 0 0 0 {SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)} 0 1 1 {SEARCH TABLE t2 USING INDEX t2d (d=?) (~2 rows)} - 0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) (~10 rows)} + 0 1 1 {SEARCH TABLE t2 USING COVERING INDEX t2f (f=?) (~5 rows)} } } @@ -454,8 +453,8 @@ ifcapable explain { do_execsql_test where9-5.1 { EXPLAIN QUERY PLAN SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL) } { - 0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?) (~10 rows)} - 0 0 0 {SEARCH TABLE t1 USING INDEX t1d (d=?) (~10 rows)} + 0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c=?) (~2 rows)} + 0 0 0 {SEARCH TABLE t1 USING INDEX t1d (d=?) (~2 rows)} } # In contrast, b=1000 is preferred over any OR-clause. @@ -783,4 +782,79 @@ do_test where9-6.8.2 { } } {1 {cannot use index: t1b}} +############################################################################ +# Test cases where terms inside an OR series are combined with AND terms +# external to the OR clause. In other words, cases where +# +# x AND (y OR z) +# +# is able to use indices on x,y and x,z, or indices y,x and z,x. +# +do_test where9-7.0 { + execsql { + CREATE TABLE t5(a, b, c, d, e, f, g, x, y); + INSERT INTO t5 + SELECT a, b, c, e, d, f, g, + CASE WHEN (a&1)!=0 THEN 'y' ELSE 'n' END, + CASE WHEN (a&2)!=0 THEN 'y' ELSE 'n' END + FROM t1; + CREATE INDEX t5xb ON t5(x, b); + CREATE INDEX t5xc ON t5(x, c); + CREATE INDEX t5xd ON t5(x, d); + CREATE INDEX t5xe ON t5(x, e); + CREATE INDEX t5xf ON t5(x, f); + CREATE INDEX t5xg ON t5(x, g); + CREATE INDEX t5yb ON t5(y, b); + CREATE INDEX t5yc ON t5(y, c); + CREATE INDEX t5yd ON t5(y, d); + CREATE INDEX t5ye ON t5(y, e); + CREATE INDEX t5yf ON t5(y, f); + CREATE INDEX t5yg ON t5(y, g); + CREATE TABLE t6(a, b, c, e, d, f, g, x, y); + INSERT INTO t6 SELECT * FROM t5; + ANALYZE t5; + } +} {} +do_test where9-7.1.1 { + count_steps { + SELECT a FROM t5 WHERE x='y' AND (b=913 OR c=27027) ORDER BY a; + } +} {79 81 83 scan 0 sort 1} +do_test where9-7.1.2 { + execsql { + SELECT a FROM t6 WHERE x='y' AND (b=913 OR c=27027) ORDER BY a; + } +} {79 81 83} +do_test where9-7.1.3 { + count_steps { + SELECT a FROM t5 WHERE x='n' AND (b=913 OR c=27027) ORDER BY a; + } +} {80 scan 0 sort 1} +do_test where9-7.1.4 { + execsql { + SELECT a FROM t6 WHERE x='n' AND (b=913 OR c=27027) ORDER BY a; + } +} {80} +do_test where9-7.2.1 { + count_steps { + SELECT a FROM t5 WHERE (x='y' OR y='y') AND b=913 ORDER BY a; + } +} {83 scan 0 sort 1} +do_test where9-7.2.2 { + execsql { + SELECT a FROM t6 WHERE (x='y' OR y='y') AND b=913 ORDER BY a; + } +} {83} +do_test where9-7.3.1 { + count_steps { + SELECT a FROM t5 WHERE (x='y' OR y='y') AND c=27027 ORDER BY a; + } +} {79 81 scan 0 sort 1} +do_test where9-7.3.2 { + execsql { + SELECT a FROM t6 WHERE (x='y' OR y='y') AND c=27027 ORDER BY a; + } +} {79 81} + + finish_test From c5f20a00616ca2d0d18cbacff234715b7682b0fb Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 7 Oct 2011 16:57:59 +0000 Subject: [PATCH 48/56] Add the SQLITE_FCNTL_OVERWRITE file-control. Used by SQLite to indicate to the OS layer that the current transaction will overwrite the entire file. FossilOrigin-Name: 1da87fcdacfa7d277c3ee98e410a9ea8b529c368 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/backup.c | 9 +++++++++ src/sqlite.h.in | 7 ++++++- src/vacuum.c | 12 +++++------- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 791d69d826..e2c9eff23d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3_data_count()\sroutine\sso\sthat\sit\scan\sbe\sused\sto\sdetermine\nif\sSQLITE_DONE\shas\sbeen\sseen\son\sthe\sprepared\sstatement. -D 2011-10-07T12:59:23.182 +C Add\sthe\sSQLITE_FCNTL_OVERWRITE\sfile-control.\sUsed\sby\sSQLite\sto\sindicate\sto\sthe\sOS\slayer\sthat\sthe\scurrent\stransaction\swill\soverwrite\sthe\sentire\sfile. +D 2011-10-07T16:57:59.355 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -121,7 +121,7 @@ F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 F src/analyze.c 775421ced0bd78181cc206fbc63063658066c1da F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 -F src/backup.c 28a4fe55327ff708bfaf9d4326d02686f7a553c3 +F src/backup.c 4fd4440c8f81339d8eb8e5d2df54b68d79e94f2f F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 77b09c69d4849a90361e6fe5db36d167f20600c0 @@ -181,7 +181,7 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c e8fe1251aee84baa2fb232ce83d938de25aa650f -F src/sqlite.h.in 1865923bdb9deb8dde42da5862aca0071adb6061 +F src/sqlite.h.in b22e3187e048661d98a748ad54099c69dccfe497 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 28cca77ebdaf6025ae5df52717dff429c7c6d4ef F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -237,7 +237,7 @@ F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 F src/update.c 74a6cfb34e9732c1e2a86278b229913b4b51eeec F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 06302ffd2b80408d4f6c7af71f7090e0cf8d8ff7 -F src/vacuum.c 297f39745e05d7a6ed7def7929451474d570a31e +F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c 60340bfb23f456ea0791cb28262a887363773371 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 693d6ac6810298fc6b4c503cfbe3f99a240f40af @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P baa80c7bc31900decae0d8e6090b30fcde377492 -R 1223a474d1e5cea6170a2af45d3f0303 -U drh -Z 7e8fd93d23ec7d2fecbdff0e025997fa +P 9913996e7b0f94ba1c51200b61433193002f3638 +R 95c2b529419f78d1f0a0f16ca9ea56e3 +U dan +Z 751eeeee5e1f94cafba63c56e2ffa2f0 diff --git a/manifest.uuid b/manifest.uuid index 9fe70085bf..abd31e2d97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9913996e7b0f94ba1c51200b61433193002f3638 \ No newline at end of file +1da87fcdacfa7d277c3ee98e410a9ea8b529c368 \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 70a782665b..411a9b8d6a 100644 --- a/src/backup.c +++ b/src/backup.c @@ -669,10 +669,18 @@ void sqlite3BackupRestart(sqlite3_backup *pBackup){ */ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ int rc; + sqlite3_file *pFd; /* File descriptor for database pTo */ sqlite3_backup b; sqlite3BtreeEnter(pTo); sqlite3BtreeEnter(pFrom); + assert( sqlite3BtreeIsInTrans(pTo) ); + pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); + if( pFd->pMethods ){ + i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + } + /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set ** to 0. This is used by the implementations of sqlite3_backup_step() ** and sqlite3_backup_finish() to detect that they are being called @@ -698,6 +706,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ pTo->pBt->pageSizeFixed = 0; } + assert( sqlite3BtreeIsInTrans(pTo)==0 ); sqlite3BtreeLeave(pFrom); sqlite3BtreeLeave(pTo); return rc; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d13f17639d..040c365d80 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -766,7 +766,11 @@ struct sqlite3_io_methods { ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. -** +** +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 @@ -778,6 +782,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_SYNC_OMITTED 8 #define SQLITE_FCNTL_WIN32_AV_RETRY 9 #define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 /* ** CAPI3REF: Mutex Handle diff --git a/src/vacuum.c b/src/vacuum.c index 0e92f4fb0e..58a3c9d683 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -263,13 +263,11 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ); if( rc ) goto end_of_vacuum; - /* At this point, unless the main db was completely empty, there is now a - ** transaction open on the vacuum database, but not on the main database. - ** Open a btree level transaction on the main database. This allows a - ** call to sqlite3BtreeCopyFile(). The main database btree level - ** transaction is then committed, so the SQL level never knows it was - ** opened for writing. This way, the SQL transaction used to create the - ** temporary database never needs to be committed. + /* At this point, there is a write transaction open on both the + ** vacuum database and the main database. Assuming no error occurs, + ** both transactions are closed by this block - the main database + ** transaction by sqlite3BtreeCopyFile() and the other by an explicit + ** call to sqlite3BtreeCommit(). */ { u32 meta; From 0a61df670ec218e98a7e1ac4768c2f3b7ebb1cda Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Oct 2011 17:45:58 +0000 Subject: [PATCH 49/56] Add testcase() macros to ensure good test coverage. FossilOrigin-Name: 5c132592820e9dc2355e26ea14e155c797c335b3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 67d3608db6..dd2d1469f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\sfor\sthe\sOR\soptimization. -D 2011-10-07T16:08:28.818 +C Add\stestcase()\smacros\sto\sensure\sgood\stest\scoverage. +D 2011-10-07T17:45:58.914 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -251,7 +251,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c 2e82da485ae1e037d2e372fd361c926cd4885934 +F src/where.c a6d127dd05daf0f9ffa654edfab4f1236dc759b7 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 9fca05eac503d712886a05d03794f76c61fb39ed -R bd6384414b9b60e15876987ee9f999e9 +P 4997d8b81cd3ea7c708911bfece00020d11224f9 +R b935363a5df75d52ae6d528d229f42f6 U drh -Z 427731fab44d769232d079e056d051e3 +Z e878c83927724d1c2481f6ca56873708 diff --git a/manifest.uuid b/manifest.uuid index 937b15f843..661a2a46ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4997d8b81cd3ea7c708911bfece00020d11224f9 \ No newline at end of file +5c132592820e9dc2355e26ea14e155c797c335b3 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 9d5adc1832..da7ffbdf86 100644 --- a/src/where.c +++ b/src/where.c @@ -3032,6 +3032,7 @@ static void bestBtreeIndex( pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx); if( pTerm==0 ) break; wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ); + testcase( pTerm->pWC!=pWC ); if( pTerm->eOperator & WO_IN ){ Expr *pExpr = pTerm->pExpr; wsFlags |= WHERE_COLUMN_IN; @@ -3063,11 +3064,13 @@ static void bestBtreeIndex( nBound = 1; wsFlags |= WHERE_TOP_LIMIT; used |= pTop->prereqRight; + testcase( pTop->pWC!=pWC ); } if( pBtm ){ nBound++; wsFlags |= WHERE_BTM_LIMIT; used |= pBtm->prereqRight; + testcase( pBtm->pWC!=pWC ); } wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE); } From 9734e6e1f47ba9627008ce15a87b52fc9f0b5856 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Oct 2011 18:24:25 +0000 Subject: [PATCH 50/56] Make sure sqlite3_data_count() behaves as documented, even for EXPLAIN QUERY PLAN queries. FossilOrigin-Name: d4f95b3b6e9f4a4072606af5daa17ea7c645382e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9d612d2a8a..4eb0032471 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\shandling\sof\sOR\sterms\sin\sthe\sWHERE\sclause\swith\smulti-column\sindexes. -D 2011-10-07T17:52:40.878 +C Make\ssure\ssqlite3_data_count()\sbehaves\sas\sdocumented,\seven\sfor\nEXPLAIN\sQUERY\sPLAN\squeries. +D 2011-10-07T18:24:25.948 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -242,7 +242,7 @@ F src/vdbe.c 60340bfb23f456ea0791cb28262a887363773371 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 693d6ac6810298fc6b4c503cfbe3f99a240f40af F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98 -F src/vdbeaux.c 9542e2fba791f14022c23fbe5cbe179eee36abc6 +F src/vdbeaux.c b4d509749502554e67ed14268928e4cc038b8efb F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbemem.c 2fc78b3e0fabcc1eaa23cd79dd2e30e6dcfe1e56 F src/vdbesort.c 468d43c057063e54da4f1988b38b4f46d60e7790 @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 1da87fcdacfa7d277c3ee98e410a9ea8b529c368 5c132592820e9dc2355e26ea14e155c797c335b3 -R 8ca3076f2df3dea6526cd23b3be813bd +P b23ae131874bc5c621f0f5ea8d76fce1ec089cc2 +R c851b7fc8ea31836b467cff36423209c U drh -Z ddb3b7cdb3a83c191cd3bc7c8f9d4238 +Z ec0b90c872666342728b41ee2195393b diff --git a/manifest.uuid b/manifest.uuid index 951a165865..396a541880 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b23ae131874bc5c621f0f5ea8d76fce1ec089cc2 \ No newline at end of file +d4f95b3b6e9f4a4072606af5daa17ea7c645382e \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 90d1e9c8a2..9de4fe04f2 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1142,7 +1142,7 @@ int sqlite3VdbeList( sqlite3 *db = p->db; /* The database connection */ int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ - Mem *pMem = p->pResultSet = &p->aMem[1]; /* First Mem of result set */ + Mem *pMem = &p->aMem[1]; /* First Mem of result set */ assert( p->explain ); assert( p->magic==VDBE_MAGIC_RUN ); @@ -1153,7 +1153,7 @@ int sqlite3VdbeList( ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, 8); - p->nResColumn = 0; + p->pResultSet = 0; if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or @@ -1308,6 +1308,7 @@ int sqlite3VdbeList( } p->nResColumn = 8 - 4*(p->explain-1); + p->pResultSet = &p->aMem[1]; p->rc = SQLITE_OK; rc = SQLITE_ROW; } From 08ccfaa1b183a7b365f0576d1aac0a5d8f66d755 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Oct 2011 23:52:25 +0000 Subject: [PATCH 51/56] Change the ANALYZE command so that it no longer tried to delete unused sqlite_stat2 and sqlite_stat3 tables. Change the DROP TABLE command so that it is able to drop those tables. FossilOrigin-Name: 589f3f5652e3674d3203f8bd32784a46b5ed530c --- manifest | 17 +++++++-------- manifest.uuid | 2 +- src/analyze.c | 17 --------------- src/build.c | 3 ++- test/stat3.test | 56 ------------------------------------------------- test/table.test | 12 +++++++++++ 6 files changed, 23 insertions(+), 84 deletions(-) delete mode 100644 test/stat3.test diff --git a/manifest b/manifest index 4eb0032471..7f9710268d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\ssqlite3_data_count()\sbehaves\sas\sdocumented,\seven\sfor\nEXPLAIN\sQUERY\sPLAN\squeries. -D 2011-10-07T18:24:25.948 +C Change\sthe\sANALYZE\scommand\sso\sthat\sit\sno\slonger\stried\sto\sdelete\sunused\nsqlite_stat2\sand\ssqlite_stat3\stables.\s\sChange\sthe\sDROP\sTABLE\scommand\sso\nthat\sit\sis\sable\sto\sdrop\sthose\stables. +D 2011-10-07T23:52:25.818 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -118,7 +118,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 -F src/analyze.c 775421ced0bd78181cc206fbc63063658066c1da +F src/analyze.c 682fd999a01c897a682365a459190758b83de836 F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4fd4440c8f81339d8eb8e5d2df54b68d79e94f2f @@ -127,7 +127,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 77b09c69d4849a90361e6fe5db36d167f20600c0 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 -F src/build.c 2dc09385981bf7f41eae7d3aeb47cb2453813456 +F src/build.c 119937b0ae1ff4dcec8fdea53771acc95bafca51 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 829f3261d3db48e3d87891bc887208734734c2e4 @@ -687,7 +687,6 @@ F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test 36bc951bdc2beac4224cc54396fd6a7dc65336f4 -F test/stat3.test 53e1e3282b6e62af3de160d186fa7336fe1b48bf F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd @@ -697,7 +696,7 @@ F test/superlock.test 7b1167925e9d30a5d1f0701d24812fdda42c3a86 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test 966addf703faee6a5d509abe6d8885e393e552fd F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f -F test/table.test 50c47f5fe9c112e92723af27cd735e6c92de6f85 +F test/table.test a59d985ca366e39b17b175f387f9d5db5a18d4e2 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tclsqlite.test 5ebcbb0dccc3fbc1edc3bba84c38e2c2d574c5aa F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c @@ -967,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P b23ae131874bc5c621f0f5ea8d76fce1ec089cc2 -R c851b7fc8ea31836b467cff36423209c +P d4f95b3b6e9f4a4072606af5daa17ea7c645382e +R 4fe120270d0591d545e8a0d8aa07746c U drh -Z ec0b90c872666342728b41ee2195393b +Z 90bf796c032cc3a71272ed4f53de20b0 diff --git a/manifest.uuid b/manifest.uuid index 396a541880..0be934d7e1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4f95b3b6e9f4a4072606af5daa17ea7c645382e \ No newline at end of file +589f3f5652e3674d3203f8bd32784a46b5ed530c \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 88a7761ed6..99929e93c7 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -148,12 +148,6 @@ static void openStatTable( { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, #endif }; - static const char *azToDrop[] = { - "sqlite_stat2", -#ifndef SQLITE_ENABLE_STAT3 - "sqlite_stat3", -#endif - }; int aRoot[] = {0, 0}; u8 aCreateTbl[] = {0, 0}; @@ -167,17 +161,6 @@ static void openStatTable( assert( sqlite3VdbeDb(v)==db ); pDb = &db->aDb[iDb]; - /* Drop all statistics tables that this version of SQLite does not - ** understand. - */ - for(i=0; izName); - if( pTab ){ - sqlite3CodeDropTable(pParse, pTab, iDb, 0); - break; - } - } - /* Create new statistic tables if they do not exist, or clear them ** if they do already exist. */ diff --git a/src/build.c b/src/build.c index da0eaa1d44..d7f08e4966 100644 --- a/src/build.c +++ b/src/build.c @@ -2145,7 +2145,8 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } } #endif - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } diff --git a/test/stat3.test b/test/stat3.test deleted file mode 100644 index 9477672f27..0000000000 --- a/test/stat3.test +++ /dev/null @@ -1,56 +0,0 @@ -# 2011 August 08 -# -# 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 implements regression tests for SQLite library. This file -# implements tests for the extra functionality provided by the ANALYZE -# command when the library is compiled with SQLITE_ENABLE_STAT3 defined. -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -set testprefix stat3 - - -# Verify that if not compiled with SQLITE_ENABLE_STAT2 that the ANALYZE -# command will delete the sqlite_stat2 table. Likewise, if not compiled -# with SQLITE_ENABLE_STAT3, the sqlite_stat3 table is deleted. -# -do_test 1.1 { - db eval { - PRAGMA writable_schema=ON; - CREATE TABLE sqlite_stat2(tbl,idx,sampleno,sample); - CREATE TABLE sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample); - SELECT name FROM sqlite_master ORDER BY 1; - } -} {sqlite_stat2 sqlite_stat3} -do_test 1.2 { - db close - sqlite3 db test.db - db eval {SELECT name FROM sqlite_master ORDER BY 1} -} {sqlite_stat2 sqlite_stat3} - -ifcapable {stat3} { - do_test 1.3 { - db eval {ANALYZE; SELECT name FROM sqlite_master ORDER BY 1} - } {sqlite_stat1 sqlite_stat3} -} else { - do_test 1.4 { - db eval {ANALYZE; ANALYZE; SELECT name FROM sqlite_master ORDER BY 1} - } {sqlite_stat1} - finish_test - return -} - - - - -finish_test diff --git a/test/table.test b/test/table.test index ae6f94c746..4826cb927d 100644 --- a/test/table.test +++ b/test/table.test @@ -260,6 +260,18 @@ do_test table-5.2 { catchsql {DROP TABLE IF EXISTS sqlite_master} } {1 {table sqlite_master may not be dropped}} +# Dropping sqlite_statN tables is OK. +# +do_test table-5.2.1 { + db eval { + ANALYZE; + DROP TABLE IF EXISTS sqlite_stat1; + DROP TABLE IF EXISTS sqlite_stat2; + DROP TABLE IF EXISTS sqlite_stat3; + SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_stat*'; + } +} {} + # Make sure an EXPLAIN does not really create a new table # do_test table-5.3 { From f4ba1093568851a1320a84ce195b1dc08e8964c1 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 8 Oct 2011 14:57:07 +0000 Subject: [PATCH 52/56] Add the SQLITE_DIRECT_OVERFLOW_READ compile time option. FossilOrigin-Name: 2ab14a846727857175eac7961b7338c4d3b417ca --- manifest | 22 ++++++++--------- manifest.uuid | 2 +- src/btree.c | 60 ++++++++++++++++++++++++++++++++++++---------- src/test_config.c | 6 +++++ test/corrupt3.test | 2 +- test/pager1.test | 5 ++++ test/pageropt.test | 2 +- 7 files changed, 72 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 7f9710268d..b38c1ac5fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sANALYZE\scommand\sso\sthat\sit\sno\slonger\stried\sto\sdelete\sunused\nsqlite_stat2\sand\ssqlite_stat3\stables.\s\sChange\sthe\sDROP\sTABLE\scommand\sso\nthat\sit\sis\sable\sto\sdrop\sthose\stables. -D 2011-10-07T23:52:25.818 +C Add\sthe\sSQLITE_DIRECT_OVERFLOW_READ\scompile\stime\soption. +D 2011-10-08T14:57:07.518 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -124,7 +124,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 4fd4440c8f81339d8eb8e5d2df54b68d79e94f2f F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 77b09c69d4849a90361e6fe5db36d167f20600c0 +F src/btree.c b53e009bccb4cfcbcde074f586f0c1c6712a0e12 F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3 F src/build.c 119937b0ae1ff4dcec8fdea53771acc95bafca51 @@ -201,7 +201,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 -F src/test_config.c 6b1b69da02eb9a19330d8c2c33403c6eafbc3416 +F src/test_config.c baf4eda361adc7444bd452d352999fea351fe256 F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 @@ -335,7 +335,7 @@ F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b F test/conflict.test cabc41f7616675df71b4fddabca3bd5d9221915a F test/corrupt.test 4aabd06cff3fe759e3e658bcc17b71789710665e F test/corrupt2.test 9c0ab4becd50e9050bc1ebb8675456a4e5587bf0 -F test/corrupt3.test e3006aaf579d2ed7f1b94bf4cc695d3c784fa5af +F test/corrupt3.test 889d7cdb811800303aa722d7813fe8a4299cf726 F test/corrupt4.test b963f9e01e0f92d15c76fb0747876fd4b96dc30a F test/corrupt5.test c23da7bfb20917cc7fdbb13ee25c7cc4e9fffeff F test/corrupt6.test 4e4161aef1f30b9f34582bb4142334b7f47eacae @@ -611,13 +611,13 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3 -F test/pager1.test c8f202a460ba6a1cd7a36888042ca471220bb42d +F test/pager1.test 1b630b3248c7d28862fe9e190cfe52234b502504 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test 452f2cc23e3bfcfa935f4442aec1da4fe1dc0442 F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401 F test/pagerfault3.test f16e2efcb5fc9996d1356f7cbc44c998318ae1d7 -F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806 +F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 @@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P d4f95b3b6e9f4a4072606af5daa17ea7c645382e -R 4fe120270d0591d545e8a0d8aa07746c -U drh -Z 90bf796c032cc3a71272ed4f53de20b0 +P 589f3f5652e3674d3203f8bd32784a46b5ed530c +R babeecaade74546f993a47787aab0e8e +U dan +Z de8a70093b027b61b524c5ce14f74c38 diff --git a/manifest.uuid b/manifest.uuid index 0be934d7e1..a11f91efcc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -589f3f5652e3674d3203f8bd32784a46b5ed530c \ No newline at end of file +2ab14a846727857175eac7961b7338c4d3b417ca \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7e6e02f144..72d61cc268 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3938,21 +3938,55 @@ static int accessPayload( /* Need to read this page properly. It contains some of the ** range of data that is being read (eOp==0) or written (eOp!=0). */ - DbPage *pDbPage; +#ifdef SQLITE_DIRECT_OVERFLOW_READ + sqlite3_file *fd; +#endif int a = amt; - rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); - if( rc==SQLITE_OK ){ - aPayload = sqlite3PagerGetData(pDbPage); - nextPage = get4byte(aPayload); - if( a + offset > ovflSize ){ - a = ovflSize - offset; - } - rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); - sqlite3PagerUnref(pDbPage); - offset = 0; - amt -= a; - pBuf += a; + if( a + offset > ovflSize ){ + a = ovflSize - offset; } + +#ifdef SQLITE_DIRECT_OVERFLOW_READ + /* If all the following are true: + ** + ** 1) this is a read operation, and + ** 2) data is required from the start of this overflow page, and + ** 3) the database is file-backed, and + ** 4) there is no open write-transaction, and + ** 5) the database is not a WAL database, + ** + ** then data can be read directly from the database file into the + ** output buffer, bypassing the page-cache altogether. This speeds + ** up loading large records that span many overflow pages. + */ + if( eOp==0 /* (1) */ + && offset==0 /* (2) */ + && pBt->inTransaction==TRANS_READ /* (4) */ + && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */ + && pBt->pPage1->aData[19]==0x01 /* (5) */ + ){ + u8 aSave[4]; + u8 *aWrite = &pBuf[-4]; + memcpy(aSave, aWrite, 4); + rc = sqlite3OsRead(fd, aWrite, a+4, pBt->pageSize * (nextPage-1)); + nextPage = get4byte(aWrite); + memcpy(aWrite, aSave, 4); + }else +#endif + + { + DbPage *pDbPage; + rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage); + if( rc==SQLITE_OK ){ + aPayload = sqlite3PagerGetData(pDbPage); + nextPage = get4byte(aPayload); + rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); + sqlite3PagerUnref(pDbPage); + offset = 0; + } + } + amt -= a; + pBuf += a; } } } diff --git a/src/test_config.c b/src/test_config.c index 4c4dfa3d80..b0efe23247 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -55,6 +55,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "debug", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_DIRECT_OVERFLOW_READ + Tcl_SetVar2(interp, "sqlite_options", "direct_read", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "direct_read", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_DISABLE_DIRSYNC Tcl_SetVar2(interp, "sqlite_options", "dirsync", "0", TCL_GLOBAL_ONLY); #else diff --git a/test/corrupt3.test b/test/corrupt3.test index fba3ba791a..a3827227b7 100644 --- a/test/corrupt3.test +++ b/test/corrupt3.test @@ -25,7 +25,7 @@ do_not_use_codec # We must have the page_size pragma for these tests to work. # -ifcapable !pager_pragmas { +ifcapable !pager_pragmas||direct_read { finish_test return } diff --git a/test/pager1.test b/test/pager1.test index bed7d736cd..0226fe49b2 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -1766,6 +1766,10 @@ do_multiclient_test tn { # + Page 0, # + A page with a page number greater than (2^31-1). # +# These tests will not work if SQLITE_DIRECT_OVERFLOW_READ is defined. In +# that case IO errors are sometimes reported instead of SQLITE_CORRUPT. +# +ifcapable !direct_read { do_test pager1-18.1 { faultsim_delete_and_reopen db func a_string a_string @@ -1841,6 +1845,7 @@ do_test pager1-18.6 { sqlite3 db test.db catchsql { SELECT length(x) FROM t1 } } {1 {database disk image is malformed}} +} do_test pager1-19.1 { sqlite3 db "" diff --git a/test/pageropt.test b/test/pageropt.test index 1c634f6443..82311965a5 100644 --- a/test/pageropt.test +++ b/test/pageropt.test @@ -17,7 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -ifcapable {!pager_pragmas||secure_delete} { +ifcapable {!pager_pragmas||secure_delete||direct_read} { finish_test return } From 385e52f60c984d57aedf29fff0eef0ed50842167 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 8 Oct 2011 21:39:11 +0000 Subject: [PATCH 53/56] All the soft_heap_limit to be exceeded by 10% in test cases. FossilOrigin-Name: 4be9dccc711c9ad252e2cbd99bbcbe43247503a1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/malloc5.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b38c1ac5fb..7bcbf5db6e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_DIRECT_OVERFLOW_READ\scompile\stime\soption. -D 2011-10-08T14:57:07.518 +C All\sthe\ssoft_heap_limit\sto\sbe\sexceeded\sby\s10%\sin\stest\scases. +D 2011-10-08T21:39:11.646 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -565,7 +565,7 @@ F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9 F test/malloc.test 8c727fe29fccd280cbf8f6acf08bd10b76beaf34 F test/malloc3.test de8eca0c3e748878845fdca3663ec4b642073caf F test/malloc4.test 957337613002b7058a85116493a262f679f3a261 -F test/malloc5.test 338e0f7df5fde4a0129c8002a915410e1080bfb4 +F test/malloc5.test 30dc30b57fa22552eba0d8c95210d96c3d958a39 F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151 F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d @@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 589f3f5652e3674d3203f8bd32784a46b5ed530c -R babeecaade74546f993a47787aab0e8e -U dan -Z de8a70093b027b61b524c5ce14f74c38 +P 2ab14a846727857175eac7961b7338c4d3b417ca +R cc54f7e76cf6a10d871ea3d2d9a8feff +U drh +Z e455d0c3668c3a5b3047df9ebe89d72b diff --git a/manifest.uuid b/manifest.uuid index a11f91efcc..4cf4ba7dae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2ab14a846727857175eac7961b7338c4d3b417ca \ No newline at end of file +4be9dccc711c9ad252e2cbd99bbcbe43247503a1 \ No newline at end of file diff --git a/test/malloc5.test b/test/malloc5.test index 3fe65c8a99..71f56bbbc1 100644 --- a/test/malloc5.test +++ b/test/malloc5.test @@ -219,7 +219,7 @@ do_test malloc5-4.2 { execsql {SELECT * FROM abc} set nMaxBytes [sqlite3_memory_highwater 1] puts -nonewline " (Highwater mark: $nMaxBytes) " - expr $nMaxBytes <= 100000 + expr $nMaxBytes <= 110000 } {1} do_test malloc5-4.3 { # Check that the content of table abc is at least roughly as expected. From 9471406cf2e485ed152ca245165099a5cee17533 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Oct 2011 12:04:14 +0000 Subject: [PATCH 54/56] Fix a typo in a comment for PRAGMA journal_mode. Also amplify that same comment. FossilOrigin-Name: c8ff2a484005ca48c52407db9f4a9a7d9f747158 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 7bcbf5db6e..076dfc3c3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C All\sthe\ssoft_heap_limit\sto\sbe\sexceeded\sby\s10%\sin\stest\scases. -D 2011-10-08T21:39:11.646 +C Fix\sa\stypo\sin\sa\scomment\sfor\sPRAGMA\sjournal_mode.\s\sAlso\samplify\sthat\ssame\ncomment. +D 2011-10-10T12:04:14.421 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -173,7 +173,7 @@ F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c 24f5e85a78514584b46190260ba7ab0a66312197 -F src/pragma.c ebcd20f1e654f5cb3aeef864ed69c4697719fbaa +F src/pragma.c 68d7db4fc9de8bcfae94c1d43120531ec252b9c0 F src/prepare.c e64261559a3187698a3e7e6c8b001a4f4f98dab4 F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 2ab14a846727857175eac7961b7338c4d3b417ca -R cc54f7e76cf6a10d871ea3d2d9a8feff +P 4be9dccc711c9ad252e2cbd99bbcbe43247503a1 +R 4f7aae45b96181a005dc5c4d09ba91e5 U drh -Z e455d0c3668c3a5b3047df9ebe89d72b +Z b16e865902308c681d3a83f00f2990fa diff --git a/manifest.uuid b/manifest.uuid index 4cf4ba7dae..600f6aeee1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4be9dccc711c9ad252e2cbd99bbcbe43247503a1 \ No newline at end of file +c8ff2a484005ca48c52407db9f4a9a7d9f747158 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index cd2aab223c..11345078ad 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -533,8 +533,10 @@ void sqlite3Pragma( int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ int ii; /* Loop counter */ - /* Force the schema to be loaded on all databases. This cases all - ** database files to be opened and the journal_modes set. */ + /* Force the schema to be loaded on all databases. This causes all + ** database files to be opened and the journal_modes set. This is + ** necessary because subsequent processing must know if the databases + ** are in WAL mode. */ if( sqlite3ReadSchema(pParse) ){ goto pragma_out; } From 36c0632127515a104b9ae86a23f44e81170bfa42 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Oct 2011 16:06:35 +0000 Subject: [PATCH 55/56] Enhance sqlite3_analyzer so that it is able to deal with multiplexed databases that have 8+3 filenames. FossilOrigin-Name: e5169f9a5b7e20b8adaf6ebb7868a64e44fd7321 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/spaceanal.tcl | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 076dfc3c3d..3f224c3dd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sa\scomment\sfor\sPRAGMA\sjournal_mode.\s\sAlso\samplify\sthat\ssame\ncomment. -D 2011-10-10T12:04:14.421 +C Enhance\ssqlite3_analyzer\sso\sthat\sit\sis\sable\sto\sdeal\swith\smultiplexed\sdatabases\nthat\shave\s8+3\sfilenames. +D 2011-10-10T16:06:35.583 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -955,7 +955,7 @@ F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02 F tool/showwal.c f09e5a80a293919290ec85a6a37c85a5ddcf37d9 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b -F tool/spaceanal.tcl 2dc915c21309029dbf0eb54868ad036454d2f77a +F tool/spaceanal.tcl 15f6cd939b4ecc14d061de7e8ace89e26c30c40b F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff @@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P 4be9dccc711c9ad252e2cbd99bbcbe43247503a1 -R 4f7aae45b96181a005dc5c4d09ba91e5 +P c8ff2a484005ca48c52407db9f4a9a7d9f747158 +R be244c8f58449ece0a1463fbe4e67da8 U drh -Z b16e865902308c681d3a83f00f2990fa +Z 10316430b1a9168938d816e89fe8c137 diff --git a/manifest.uuid b/manifest.uuid index 600f6aeee1..8657c30cca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8ff2a484005ca48c52407db9f4a9a7d9f747158 \ No newline at end of file +e5169f9a5b7e20b8adaf6ebb7868a64e44fd7321 \ No newline at end of file diff --git a/tool/spaceanal.tcl b/tool/spaceanal.tcl index b6ebfba664..3dddfe42d4 100644 --- a/tool/spaceanal.tcl +++ b/tool/spaceanal.tcl @@ -44,6 +44,25 @@ if {$true_file_size<512} { exit 1 } +# Compute the total file size assuming test_multiplexor is being used. +# Assume that SQLITE_ENABLE_8_3_NAMES might be enabled +# +set extension [file extension $file_to_analyze] +set pattern $file_to_analyze +append pattern {[0-9][0-9]} +foreach f [glob -nocomplain $pattern] { + incr true_file_size [file size $f] + set extension {} +} +if {[string length $extension]>=2 && [string length $extension]<=4} { + set pattern [file rootname $file_to_analyze] + append pattern [string range $extension 0 1] + append pattern {[0-9][0-9]} + foreach f [glob -nocomplain $pattern] { + incr true_file_size [file size $f] + } +} + # Open the database # sqlite3 db $file_to_analyze From 67855877ffa8a1d70ab17a65ead5dd3872e4623a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Oct 2011 12:39:19 +0000 Subject: [PATCH 56/56] Fix requirements marks associate with STAT3. FossilOrigin-Name: 9325c1a8c413dfbf0381190d8347f0a446ae5f5b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 4 ++-- src/where.c | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 3f224c3dd4..79c4572a2b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\ssqlite3_analyzer\sso\sthat\sit\sis\sable\sto\sdeal\swith\smultiplexed\sdatabases\nthat\shave\s8+3\sfilenames. -D 2011-10-10T16:06:35.583 +C Fix\srequirements\smarks\sassociate\swith\sSTAT3. +D 2011-10-11T12:39:19.194 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -181,7 +181,7 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c e8fe1251aee84baa2fb232ce83d938de25aa650f -F src/sqlite.h.in b22e3187e048661d98a748ad54099c69dccfe497 +F src/sqlite.h.in 821027573c481e45ba276b078a3ae9ebaeb9bb92 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 2f66bf068131f0e499dd5e0abea3f68cd6b27b2d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -251,7 +251,7 @@ F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9 F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f -F src/where.c a6d127dd05daf0f9ffa654edfab4f1236dc759b7 +F src/where.c 12939ac49f5122eb11b5ca4c35b2fdd8eaae9833 F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 @@ -966,7 +966,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P c8ff2a484005ca48c52407db9f4a9a7d9f747158 -R be244c8f58449ece0a1463fbe4e67da8 +P e5169f9a5b7e20b8adaf6ebb7868a64e44fd7321 +R fa1bfea306973bc99ccb0d80c9355cfe U drh -Z 10316430b1a9168938d816e89fe8c137 +Z 7aa6c1f7c4e6214ddb2d3b34feac8ca1 diff --git a/manifest.uuid b/manifest.uuid index 8657c30cca..076bf3c8fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e5169f9a5b7e20b8adaf6ebb7868a64e44fd7321 \ No newline at end of file +9325c1a8c413dfbf0381190d8347f0a446ae5f5b \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 040c365d80..3d210c31d1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5824,13 +5824,13 @@ int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); ** ** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
SQLITE_DBSTATUS_CACHE_HIT
**
This parameter returns the number of pager cache hits that have -** occurred. ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT ** is always 0. **
** ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
SQLITE_DBSTATUS_CACHE_MISS
**
This parameter returns the number of pager cache misses that have -** occurred. ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS ** is always 0. **
** diff --git a/src/where.c b/src/where.c index da7ffbdf86..3c0244e68d 100644 --- a/src/where.c +++ b/src/where.c @@ -705,7 +705,7 @@ static int isLikeOrGlob( if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ z = (char *)sqlite3_value_text(pVal); } - sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-23257-02778 */ + sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-31526-56213 */ assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ z = pRight->u.zToken; @@ -723,7 +723,7 @@ static int isLikeOrGlob( *ppPrefix = pPrefix; if( op==TK_VARIABLE ){ Vdbe *v = pParse->pVdbe; - sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-23257-02778 */ + sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-31526-56213 */ if( *pisComplete && pRight->u.zToken[1] ){ /* If the rhs of the LIKE expression is a variable, and the current ** value of the variable means there is no need to invoke the LIKE @@ -2637,7 +2637,7 @@ static int valueFromExpr( || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) ){ int iVar = pExpr->iColumn; - sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-23257-02778 */ + sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-31526-56213 */ *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff); return SQLITE_OK; }