Index: third_party/sqlite/src/src/analyze.c |
diff --git a/third_party/sqlite/src/src/analyze.c b/third_party/sqlite/src/src/analyze.c |
index e655aaa50c7136cfb712f3799bcd3c65f3d050f6..06918eb7442ef3ddbc9e915bde02ff160c7927f6 100644 |
--- a/third_party/sqlite/src/src/analyze.c |
+++ b/third_party/sqlite/src/src/analyze.c |
@@ -448,7 +448,7 @@ static void statInit( |
p->mxSample = mxSample; |
p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); |
p->current.anLt = &p->current.anEq[nColUp]; |
- p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565; |
+ p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]); |
/* Set up the Stat4Accum.a[] and aBest[] arrays */ |
p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
@@ -943,7 +943,7 @@ static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ |
#else |
UNUSED_PARAMETER( iParam ); |
#endif |
- sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut); |
+ sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4, regOut); |
sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); |
sqlite3VdbeChangeP5(v, 1 + IsStat34); |
} |
@@ -990,7 +990,7 @@ static void analyzeOneTable( |
/* Do not gather statistics on views or virtual tables */ |
return; |
} |
- if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){ |
+ if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ |
/* Do not gather statistics on system tables */ |
return; |
} |
@@ -1014,7 +1014,7 @@ static void analyzeOneTable( |
iIdxCur = iTab++; |
pParse->nTab = MAX(pParse->nTab, iTab); |
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
- sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
+ sqlite3VdbeLoadString(v, regTabname, pTab->zName); |
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
int nCol; /* Number of columns in pIdx. "N" */ |
@@ -1036,7 +1036,7 @@ static void analyzeOneTable( |
} |
/* Populate the register containing the index name. */ |
- sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); |
+ sqlite3VdbeLoadString(v, regIdxname, zIdxName); |
VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
/* |
@@ -1098,7 +1098,7 @@ static void analyzeOneTable( |
#endif |
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); |
- sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4); |
+ sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4+1, regStat4); |
sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); |
sqlite3VdbeChangeP5(v, 2+IsStat34); |
@@ -1150,7 +1150,7 @@ static void analyzeOneTable( |
VdbeCoverage(v); |
} |
sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); |
- sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); |
+ sqlite3VdbeGoto(v, endDistinctTest); |
/* |
@@ -1186,6 +1186,7 @@ static void analyzeOneTable( |
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); |
for(j=0; j<pPk->nKeyCol; j++){ |
k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); |
+ assert( k>=0 && k<pTab->nCol ); |
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); |
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); |
} |
@@ -1194,7 +1195,7 @@ static void analyzeOneTable( |
} |
#endif |
assert( regChng==(regStat4+1) ); |
- sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); |
+ sqlite3VdbeAddOp3(v, OP_Function0, 1, regStat4, regTemp); |
sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); |
sqlite3VdbeChangeP5(v, 2+IsStat34); |
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); |
@@ -1235,12 +1236,10 @@ static void analyzeOneTable( |
** be taken */ |
VdbeCoverageNeverTaken(v); |
#ifdef SQLITE_ENABLE_STAT3 |
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, |
- pIdx->aiColumn[0], regSample); |
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample); |
#else |
for(i=0; i<nCol; i++){ |
- i16 iCol = pIdx->aiColumn[i]; |
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i); |
+ sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i); |
} |
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample); |
#endif |
@@ -1457,23 +1456,28 @@ static void decodeIntArray( |
if( *z==' ' ) z++; |
} |
#ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
- assert( pIndex!=0 ); |
+ assert( pIndex!=0 ); { |
#else |
- if( pIndex ) |
+ if( pIndex ){ |
#endif |
- while( z[0] ){ |
- if( sqlite3_strglob("unordered*", z)==0 ){ |
- pIndex->bUnordered = 1; |
- }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
- pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); |
- } |
+ pIndex->bUnordered = 0; |
+ pIndex->noSkipScan = 0; |
+ while( z[0] ){ |
+ if( sqlite3_strglob("unordered*", z)==0 ){ |
+ pIndex->bUnordered = 1; |
+ }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
+ pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); |
+ }else if( sqlite3_strglob("noskipscan*", z)==0 ){ |
+ pIndex->noSkipScan = 1; |
+ } |
#ifdef SQLITE_ENABLE_COSTMULT |
- else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ |
- pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); |
- } |
+ else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ |
+ pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); |
+ } |
#endif |
- while( z[0]!=0 && z[0]!=' ' ) z++; |
- while( z[0]==' ' ) z++; |
+ while( z[0]!=0 && z[0]!=' ' ) z++; |
+ while( z[0]==' ' ) z++; |
+ } |
} |
} |
@@ -1514,14 +1518,17 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ |
z = argv[2]; |
if( pIndex ){ |
+ tRowcnt *aiRowEst = 0; |
int nCol = pIndex->nKeyCol+1; |
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
- tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero( |
- sizeof(tRowcnt) * nCol |
- ); |
- if( aiRowEst==0 ) pInfo->db->mallocFailed = 1; |
-#else |
- tRowcnt * const aiRowEst = 0; |
+ /* Index.aiRowEst may already be set here if there are duplicate |
+ ** sqlite_stat1 entries for this index. In that case just clobber |
+ ** the old data with the new instead of allocating a new array. */ |
+ if( pIndex->aiRowEst==0 ){ |
+ pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); |
+ if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1; |
+ } |
+ aiRowEst = pIndex->aiRowEst; |
#endif |
pIndex->bUnordered = 0; |
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); |
@@ -1599,6 +1606,7 @@ static void initAvgEq(Index *pIdx){ |
nRow = pIdx->aiRowEst[0]; |
nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; |
} |
+ pIdx->nRowEst0 = nRow; |
/* Set nSum to the number of distinct (iCol+1) field prefixes that |
** occur in the stat4 table for this index. Set sumEq to the sum of |
@@ -1860,7 +1868,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ |
/* Load the statistics from the sqlite_stat4 table. */ |
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
- if( rc==SQLITE_OK ){ |
+ if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ |
int lookasideEnabled = db->lookaside.bEnabled; |
db->lookaside.bEnabled = 0; |
rc = loadStat4(db, sInfo.zDatabase); |