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)}}