1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-16 23:02:26 +03:00

Adjust ANALYZE for improved test coverage. Use the SQLITE_ENABLE_STAT3_OR_STAT4

macro (created in sqliteInt.h) to conditionally include code, instead of 
a boolean specifying both macros separately.

FossilOrigin-Name: 67a9a392edd62ef5a5a1ad3010b20a39b285793d
This commit is contained in:
drh
2013-08-27 23:15:44 +00:00
parent 9fecc546cb
commit 1435a9a126
6 changed files with 81 additions and 68 deletions

View File

@@ -1,5 +1,5 @@
C Reduce\sthe\samount\sof\scode\srun\sand\smemory\sused\sfor\sANALYZE\sin\sthe\scommon\scase\nwhere\sneither\sSTAT3\sand\sSTAT4\sare\senabled. C Adjust\sANALYZE\sfor\simproved\stest\scoverage.\s\sUse\sthe\sSQLITE_ENABLE_STAT3_OR_STAT4\nmacro\s(created\sin\ssqliteInt.h)\sto\sconditionally\sinclude\scode,\sinstead\sof\s\na\sboolean\sspecifying\sboth\smacros\sseparately.
D 2013-08-27T20:16:48.420 D 2013-08-27T23:15:44.027
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
F src/analyze.c f1dbc79cbe97f960b20dfc3d24143dff988db41d F src/analyze.c fa1a9eeeebdeceddf0b0ed141656dea6d4458699
F src/attach.c fea00cab11c854646a27641a263f5876569a51f9 F src/attach.c fea00cab11c854646a27641a263f5876569a51f9
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3 F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
@@ -221,7 +221,7 @@ F src/shell.c 00a23311466829d9b77f0be4f7cedee9328279db
F src/sqlite.h.in bd1451ba1ab681022a53bccc3c39580ba094a3ff F src/sqlite.h.in bd1451ba1ab681022a53bccc3c39580ba094a3ff
F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h 97b1005b812048469c80ec9394a77e0ad83ea9c0 F src/sqliteInt.h 600086a5082e2291b0aeeefcfbb546f2bbda67b2
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -283,14 +283,14 @@ F src/vdbeInt.h cbe71b8b36d8b3bba5709cc3f436c7e3b47b7b08
F src/vdbeapi.c 96b24b946cf21894f63d9393e821baa2f0a80979 F src/vdbeapi.c 96b24b946cf21894f63d9393e821baa2f0a80979
F src/vdbeaux.c c7fe2695e256dbf254113c4fe90d3ec9aabe3bbe F src/vdbeaux.c c7fe2695e256dbf254113c4fe90d3ec9aabe3bbe
F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69 F src/vdbeblob.c 5dc79627775bd9a9b494dd956e26297946417d69
F src/vdbemem.c 1bec36bf054521df810b2f9cc5078cba929ff10d F src/vdbemem.c 4511e1d2304a7d7916d14be20080036331740fcf
F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017 F src/vdbesort.c 3937e06b2a0e354500e17dc206ef4c35770a5017
F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc
F src/vtab.c 165ce0e797c2cd23badb104c9f2ae9042d6d942c F src/vtab.c 165ce0e797c2cd23badb104c9f2ae9042d6d942c
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73 F src/walker.c 4fa43583d0a84b48f93b1e88f11adf2065be4e73
F src/where.c 18cd15160c089dd7854febeaf5a9c065fce6a95a F src/where.c 289bfa239207945e27d4689a22e838aea4afcc49
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6 F test/aggnested.test 45c0201e28045ad38a530b5a144b73cd4aa2cfd6
@@ -1107,7 +1107,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
P 2460dfd8825d251e622e866e8dc1c0bf7fe7ec9f P 9d1424c91a21ed740aca53e437b8f7c1f0823c03
R d4ca9812963b4361724d44342b635223 R 89270b1d529ed825a8ce16c2a3d7caa2
U drh U drh
Z 6faf42c735288a2cfa68556541b907cb Z 2d085e9043e9441bdd89e3f37cf9f342

View File

@@ -1 +1 @@
9d1424c91a21ed740aca53e437b8f7c1f0823c03 67a9a392edd62ef5a5a1ad3010b20a39b285793d

View File

@@ -145,15 +145,12 @@
#if defined(SQLITE_ENABLE_STAT4) #if defined(SQLITE_ENABLE_STAT4)
# define IsStat4 1 # define IsStat4 1
# define IsStat3 0 # define IsStat3 0
# define SQLITE_ENABLE_STAT34 1
#elif defined(SQLITE_ENABLE_STAT3) #elif defined(SQLITE_ENABLE_STAT3)
# define IsStat4 0 # define IsStat4 0
# define IsStat3 1 # define IsStat3 1
# define SQLITE_ENABLE_STAT34 1
#else #else
# define IsStat4 0 # define IsStat4 0
# define IsStat3 0 # define IsStat3 0
# undef SQLITE_ENABLE_STAT34
# undef SQLITE_STAT4_SAMPLES # undef SQLITE_STAT4_SAMPLES
# define SQLITE_STAT4_SAMPLES 1 # define SQLITE_STAT4_SAMPLES 1
#endif #endif
@@ -234,7 +231,8 @@ static void openStatTable(
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){ if( zWhere ){
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere "DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zName, zTab, zWhereType, zWhere
); );
}else{ }else{
/* The sqlite_stat[134] table already exists. Delete all rows. */ /* The sqlite_stat[134] table already exists. Delete all rows. */
@@ -244,14 +242,11 @@ static void openStatTable(
} }
/* Open the sqlite_stat[134] tables for writing. */ /* Open the sqlite_stat[134] tables for writing. */
for(i=0; i<ArraySize(aTable); i++){ for(i=0; aTable[i].zCols; i++){
if( aTable[i].zCols ){ assert( i<ArraySize(aTable) );
sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb); sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32); sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
sqlite3VdbeChangeP5(v, aCreateTbl[i]); sqlite3VdbeChangeP5(v, aCreateTbl[i]);
}else{
break;
}
} }
} }
@@ -272,7 +267,7 @@ typedef struct Stat4Sample Stat4Sample;
struct Stat4Sample { struct Stat4Sample {
tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anEq; /* sqlite_stat4.nEq */
tRowcnt *anDLt; /* sqlite_stat4.nDLt */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
tRowcnt *anLt; /* sqlite_stat4.nLt */ tRowcnt *anLt; /* sqlite_stat4.nLt */
i64 iRowid; /* Rowid in main table of the key */ i64 iRowid; /* Rowid in main table of the key */
u8 isPSample; /* True if a periodic sample */ u8 isPSample; /* True if a periodic sample */
@@ -312,7 +307,7 @@ static void statInit(
int nCol; /* Number of columns in index being sampled */ int nCol; /* Number of columns in index being sampled */
int nColUp; /* nCol rounded up for alignment */ int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */ int n; /* Bytes of space to allocate */
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int mxSample = SQLITE_STAT4_SAMPLES; int mxSample = SQLITE_STAT4_SAMPLES;
#endif #endif
@@ -326,7 +321,7 @@ static void statInit(
n = sizeof(*p) n = sizeof(*p)
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
+ sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
@@ -343,7 +338,7 @@ static void statInit(
p->current.anDLt = (tRowcnt*)&p[1]; p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp]; p->current.anEq = &p->current.anDLt[nColUp];
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
{ {
u8 *pSpace; /* Allocated space not yet assigned */ u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */ int i; /* Used to iterate through p->aSample[] */
@@ -388,7 +383,7 @@ static const FuncDef statInitFuncdef = {
0 /* pDestructor */ 0 /* pDestructor */
}; };
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* /*
** Return true if pNew is to be preferred over pOld. ** Return true if pNew is to be preferred over pOld.
*/ */
@@ -510,7 +505,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
p->iMin = iMin; p->iMin = iMin;
} }
} }
#endif /* SQLITE_ENABLE_STAT34 */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* /*
** Field iChng of the index being scanned has changed. So at this point ** Field iChng of the index being scanned has changed. So at this point
@@ -603,14 +598,14 @@ static void statPush(
} }
for(i=iChng; i<p->nCol; i++){ for(i=iChng; i<p->nCol; i++){
p->current.anDLt[i]++; p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
p->current.anLt[i] += p->current.anEq[i]; p->current.anLt[i] += p->current.anEq[i];
#endif #endif
p->current.anEq[i] = 1; p->current.anEq[i] = 1;
} }
} }
p->nRow++; p->nRow++;
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
p->current.iRowid = sqlite3_value_int64(argv[2]); p->current.iRowid = sqlite3_value_int64(argv[2]);
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
#endif #endif
@@ -673,7 +668,7 @@ static void statGet(
sqlite3_value **argv sqlite3_value **argv
){ ){
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* STAT3 and STAT4 have a parameter on this routine. */ /* STAT3 and STAT4 have a parameter on this routine. */
int eCall = sqlite3_value_int(argv[1]); int eCall = sqlite3_value_int(argv[1]);
assert( argc==2 ); assert( argc==2 );
@@ -729,7 +724,7 @@ static void statGet(
sqlite3_result_text(context, zRet, -1, sqlite3_free); sqlite3_result_text(context, zRet, -1, sqlite3_free);
} }
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
else if( eCall==STAT_GET_ROWID ){ else if( eCall==STAT_GET_ROWID ){
if( p->iGet<0 ){ if( p->iGet<0 ){
samplePushPrevious(p, 0); samplePushPrevious(p, 0);
@@ -771,7 +766,7 @@ static void statGet(
} }
} }
} }
#endif /* SQLITE_ENABLE_STAT34 */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
} }
static const FuncDef statGetFuncdef = { static const FuncDef statGetFuncdef = {
1+IsStat34, /* nArg */ 1+IsStat34, /* nArg */
@@ -789,7 +784,7 @@ static const FuncDef statGetFuncdef = {
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
assert( regOut!=regStat4 && regOut!=regStat4+1 ); assert( regOut!=regStat4 && regOut!=regStat4+1 );
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
#else #else
assert( iParam==STAT_GET_STAT1 ); assert( iParam==STAT_GET_STAT1 );
@@ -823,7 +818,7 @@ static void analyzeOneTable(
int regNewRowid = iMem++; /* Rowid for the inserted record */ int regNewRowid = iMem++; /* Rowid for the inserted record */
int regStat4 = iMem++; /* Register to hold Stat4Accum object */ int regStat4 = iMem++; /* Register to hold Stat4Accum object */
int regChng = iMem++; /* Index of changed index field */ int regChng = iMem++; /* Index of changed index field */
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int regRowid = iMem++; /* Rowid argument passed to stat_push() */ int regRowid = iMem++; /* Rowid argument passed to stat_push() */
#endif #endif
int regTemp = iMem++; /* Temporary use register */ int regTemp = iMem++; /* Temporary use register */
@@ -937,7 +932,7 @@ static void analyzeOneTable(
** **
** The second argument is only used for STAT3 and STAT4 ** The second argument is only used for STAT3 and STAT4
*/ */
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2); sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
#endif #endif
sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1); sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
@@ -1000,7 +995,7 @@ static void analyzeOneTable(
** if !eof(csr) goto next_row; ** if !eof(csr) goto next_row;
*/ */
sqlite3VdbeJumpHere(v, aGotoChng[nCol]); sqlite3VdbeJumpHere(v, aGotoChng[nCol]);
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
assert( regRowid==(regStat4+2) ); assert( regRowid==(regStat4+2) );
#endif #endif
@@ -1018,7 +1013,7 @@ static void analyzeOneTable(
sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat3 or stat4 table. */ /* Add the entries to the stat3 or stat4 table. */
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
{ {
int regEq = regStat1; int regEq = regStat1;
int regLt = regStat1+1; int regLt = regStat1+1;
@@ -1054,7 +1049,7 @@ static void analyzeOneTable(
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
sqlite3VdbeJumpHere(v, addrIsNull); sqlite3VdbeJumpHere(v, addrIsNull);
} }
#endif /* SQLITE_ENABLE_STAT34 */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* End of analysis */ /* End of analysis */
sqlite3VdbeJumpHere(v, addrRewind); sqlite3VdbeJumpHere(v, addrRewind);
@@ -1236,7 +1231,7 @@ static void decodeIntArray(
assert( pbUnordered==0 || *pbUnordered==0 ); assert( pbUnordered==0 || *pbUnordered==0 );
if( z==0 ) z = ""; if( NEVER(z==0) ) z = "";
for(i=0; *z && i<nOut; i++){ for(i=0; *z && i<nOut; i++){
v = 0; v = 0;
while( (c=z[0])>='0' && c<='9' ){ while( (c=z[0])>='0' && c<='9' ){
@@ -1287,7 +1282,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
if( pIndex ){ if( pIndex ){
int bUnordered = 0; int bUnordered = 0;
decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst, &bUnordered); decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered);
if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0];
pIndex->bUnordered = bUnordered; pIndex->bUnordered = bUnordered;
}else{ }else{
@@ -1302,7 +1297,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
** and its contents. ** and its contents.
*/ */
void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pIdx->aSample ){ if( pIdx->aSample ){
int j; int j;
for(j=0; j<pIdx->nSample; j++){ for(j=0; j<pIdx->nSample; j++){
@@ -1318,10 +1313,10 @@ void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
#else #else
UNUSED_PARAMETER(db); UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pIdx); UNUSED_PARAMETER(pIdx);
#endif /* SQLITE_ENABLE_STAT34 */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
} }
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* /*
** Populate the pIdx->aAvgEq[] array based on the samples currently ** Populate the pIdx->aAvgEq[] array based on the samples currently
** stored in pIdx->aSample[]. ** stored in pIdx->aSample[].
@@ -1515,7 +1510,7 @@ static int loadStat4(sqlite3 *db, const char *zDb){
return rc; return rc;
} }
#endif /* SQLITE_ENABLE_STAT34 */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* /*
** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The ** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
@@ -1551,7 +1546,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i); Index *pIdx = sqliteHashData(i);
sqlite3DefaultRowEst(pIdx); sqlite3DefaultRowEst(pIdx);
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx); sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0; pIdx->aSample = 0;
#endif #endif
@@ -1576,7 +1571,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Load the statistics from the sqlite_stat4 table. */ /* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT34 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
int lookasideEnabled = db->lookaside.bEnabled; int lookasideEnabled = db->lookaside.bEnabled;
db->lookaside.bEnabled = 0; db->lookaside.bEnabled = 0;

View File

@@ -568,6 +568,20 @@ extern const int sqlite3one;
# define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
#endif #endif
/*
** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also
** define SQLITE_ENABLE_STAT3_OR_STAT4
*/
#ifdef SQLITE_ENABLE_STAT4
# undef SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3
# define SQLITE_ENABLE_STAT3_OR_STAT4 1
#elif SQLITE_ENABLE_STAT3_OR_STAT4
# undef SQLITE_ENABLE_STAT3_OR_STAT4
#endif
/* /*
** An instance of the following structure is used to store the busy-handler ** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle. ** callback for a given sqlite handle.
@@ -1550,7 +1564,7 @@ struct Index {
unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned bUnordered:1; /* Use this index for == or IN queries only */
unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */ int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */
tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */
@@ -3106,7 +3120,7 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
void sqlite3BackupRestart(sqlite3_backup *); void sqlite3BackupRestart(sqlite3_backup *);
void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
void sqlite3AnalyzeFunctions(void); void sqlite3AnalyzeFunctions(void);
int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
void sqlite3Stat4ProbeFree(UnpackedRecord*); void sqlite3Stat4ProbeFree(UnpackedRecord*);

View File

@@ -1023,7 +1023,7 @@ struct ValueNewStat4Ctx {
** an sqlite3_value within the UnpackedRecord.a[] array. ** an sqlite3_value within the UnpackedRecord.a[] array.
*/ */
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( p ){ if( p ){
UnpackedRecord *pRec = p->ppRec[0]; UnpackedRecord *pRec = p->ppRec[0];
@@ -1098,7 +1098,7 @@ int valueFromExpr(
** The ifdef here is to enable us to achieve 100% branch test coverage even ** The ifdef here is to enable us to achieve 100% branch test coverage even
** when SQLITE_ENABLE_STAT4 is omitted. ** when SQLITE_ENABLE_STAT4 is omitted.
*/ */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( op==TK_REGISTER ) op = pExpr->op2; if( op==TK_REGISTER ) op = pExpr->op2;
#else #else
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
@@ -1180,7 +1180,11 @@ no_mem:
db->mallocFailed = 1; db->mallocFailed = 1;
sqlite3DbFree(db, zVal); sqlite3DbFree(db, zVal);
assert( *ppVal==0 ); assert( *ppVal==0 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( pCtx==0 ) sqlite3ValueFree(pVal); if( pCtx==0 ) sqlite3ValueFree(pVal);
#else
assert( pCtx==0 ); sqlite3ValueFree(pVal);
#endif
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
@@ -1204,7 +1208,7 @@ int sqlite3ValueFromExpr(
return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
} }
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* /*
** The implementation of the sqlite_record() function. This function accepts ** The implementation of the sqlite_record() function. This function accepts
** a single argument of any type. The return value is a formatted database ** a single argument of any type. The return value is a formatted database

View File

@@ -286,7 +286,7 @@ struct WhereTerm {
#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ #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_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
#define TERM_OR_OK 0x40 /* Used during OR-clause processing */ #define TERM_OR_OK 0x40 /* Used during OR-clause processing */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
#else #else
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */ # define TERM_VNULL 0x00 /* Disabled if not using stat3 */
@@ -392,7 +392,7 @@ struct WhereLoopBuilder {
ExprList *pOrderBy; /* ORDER BY clause */ ExprList *pOrderBy; /* ORDER BY clause */
WhereLoop *pNew; /* Template WhereLoop */ WhereLoop *pNew; /* Template WhereLoop */
WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
UnpackedRecord *pRec; /* Probe for stat4 (if required) */ UnpackedRecord *pRec; /* Probe for stat4 (if required) */
int nRecValid; /* Number of valid fields currently in pRec */ int nRecValid; /* Number of valid fields currently in pRec */
#endif #endif
@@ -1790,7 +1790,7 @@ static void exprAnalyze(
} }
#endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* SQLITE_OMIT_VIRTUALTABLE */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* When sqlite_stat3 histogram data is available an operator of the /* When sqlite_stat3 histogram data is available an operator of the
** form "x IS NOT NULL" can sometimes be evaluated more efficiently ** 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 ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
@@ -1830,7 +1830,7 @@ static void exprAnalyze(
pNewTerm->prereqAll = pTerm->prereqAll; pNewTerm->prereqAll = pTerm->prereqAll;
} }
} }
#endif /* SQLITE_ENABLE_STAT */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* Prevent ON clause terms of a LEFT JOIN from being used to drive /* Prevent ON clause terms of a LEFT JOIN from being used to drive
** an index for tables to the left of the join. ** an index for tables to the left of the join.
@@ -2398,7 +2398,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* /*
** Estimate the location of a particular key among all keys in an ** Estimate the location of a particular key among all keys in an
** index. Store the results in aStat as follows: ** index. Store the results in aStat as follows:
@@ -2485,7 +2485,7 @@ static void whereKeyStats(
aStat[0] = iLower + iGap; aStat[0] = iLower + iGap;
} }
} }
#endif /* SQLITE_ENABLE_STAT4 */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* /*
** This function is used to estimate the number of rows that will be visited ** This function is used to estimate the number of rows that will be visited
@@ -2537,7 +2537,7 @@ static int whereRangeScanEst(
int rc = SQLITE_OK; int rc = SQLITE_OK;
int nOut = (int)*pnOut; int nOut = (int)*pnOut;
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
Index *p = pBuilder->pNew->u.btree.pIndex; Index *p = pBuilder->pNew->u.btree.pIndex;
int nEq = pBuilder->pNew->u.btree.nEq; int nEq = pBuilder->pNew->u.btree.nEq;
@@ -2645,7 +2645,7 @@ static int whereRangeScanEst(
return rc; return rc;
} }
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* /*
** Estimate the number of rows that will be returned based on ** Estimate the number of rows that will be returned based on
** an equality constraint x=VALUE and where that VALUE occurs in ** an equality constraint x=VALUE and where that VALUE occurs in
@@ -2709,9 +2709,9 @@ static int whereEqualScanEst(
return rc; return rc;
} }
#endif /* defined(SQLITE_ENABLE_STAT4) */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* /*
** Estimate the number of rows that will be returned based on ** Estimate the number of rows that will be returned based on
** an IN constraint where the right-hand side of the IN operator ** an IN constraint where the right-hand side of the IN operator
@@ -2757,7 +2757,7 @@ static int whereInScanEst(
assert( pBuilder->nRecValid==nRecValid ); assert( pBuilder->nRecValid==nRecValid );
return rc; return rc;
} }
#endif /* defined(SQLITE_ENABLE_STAT4) */ #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
/* /*
** Disable a term in the WHERE clause. Except, do not disable the term ** Disable a term in the WHERE clause. Except, do not disable the term
@@ -4302,7 +4302,7 @@ static int whereLoopAddBtreeIndex(
rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); rLogSize = estLog(whereCost(pProbe->aiRowEst[0]));
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
int nIn = 0; int nIn = 0;
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nRecValid = pBuilder->nRecValid; int nRecValid = pBuilder->nRecValid;
assert( pNew->nOut==saved_nOut ); assert( pNew->nOut==saved_nOut );
if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){ if( (pTerm->wtFlags & TERM_VNULL)!=0 && pSrc->pTab->aCol[iCol].notNull ){
@@ -4372,7 +4372,7 @@ static int whereLoopAddBtreeIndex(
assert( pNew->nOut==saved_nOut ); assert( pNew->nOut==saved_nOut );
whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut); whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut);
} }
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
if( nInMul==0 if( nInMul==0
&& pProbe->nSample && pProbe->nSample
&& pNew->u.btree.nEq<=pProbe->nSampleCol && pNew->u.btree.nEq<=pProbe->nSampleCol
@@ -4410,7 +4410,7 @@ static int whereLoopAddBtreeIndex(
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
} }
pNew->nOut = saved_nOut; pNew->nOut = saved_nOut;
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
pBuilder->nRecValid = nRecValid; pBuilder->nRecValid = nRecValid;
#endif #endif
} }
@@ -4644,7 +4644,7 @@ static int whereLoopAddBtree(
} }
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_ENABLE_STAT3) #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3Stat4ProbeFree(pBuilder->pRec); sqlite3Stat4ProbeFree(pBuilder->pRec);
pBuilder->nRecValid = 0; pBuilder->nRecValid = 0;
pBuilder->pRec = 0; pBuilder->pRec = 0;