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 06918eb7442ef3ddbc9e915bde02ff160c7927f6..890ae7c3b2da8d331963fb1e286d99f65c09695f 100644 |
--- a/third_party/sqlite/src/src/analyze.c |
+++ b/third_party/sqlite/src/src/analyze.c |
@@ -210,14 +210,14 @@ static void openStatTable( |
for(i=0; i<ArraySize(aTable); i++){ |
const char *zTab = aTable[i].zName; |
Table *pStat; |
- if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){ |
+ if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){ |
if( aTable[i].zCols ){ |
/* The sqlite_statN table does not exist. Create it. Note that a |
** side-effect of the CREATE TABLE statement is to leave the rootpage |
** of the new table in register pParse->regRoot. This is important |
** because the OpenWrite opcode below will be needing it. */ |
sqlite3NestedParse(pParse, |
- "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
+ "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols |
); |
aRoot[i] = pParse->regRoot; |
aCreateTbl[i] = OPFLAG_P2ISREG; |
@@ -232,7 +232,7 @@ static void openStatTable( |
if( zWhere ){ |
sqlite3NestedParse(pParse, |
"DELETE FROM %Q.%s WHERE %s=%Q", |
- pDb->zName, zTab, zWhereType, zWhere |
+ pDb->zDbSName, zTab, zWhereType, zWhere |
); |
}else{ |
/* The sqlite_stat[134] table already exists. Delete all rows. */ |
@@ -313,7 +313,7 @@ static void sampleClear(sqlite3 *db, Stat4Sample *p){ |
static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ |
assert( db!=0 ); |
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); |
- p->u.aRowid = sqlite3DbMallocRaw(db, n); |
+ p->u.aRowid = sqlite3DbMallocRawNN(db, n); |
if( p->u.aRowid ){ |
p->nRowid = n; |
memcpy(p->u.aRowid, pData, n); |
@@ -478,12 +478,10 @@ static const FuncDef statInitFuncdef = { |
SQLITE_UTF8, /* funcFlags */ |
0, /* pUserData */ |
0, /* pNext */ |
- statInit, /* xFunc */ |
- 0, /* xStep */ |
+ statInit, /* xSFunc */ |
0, /* xFinalize */ |
"stat_init", /* zName */ |
- 0, /* pHash */ |
- 0 /* pDestructor */ |
+ {0} |
}; |
#ifdef SQLITE_ENABLE_STAT4 |
@@ -779,12 +777,10 @@ static const FuncDef statPushFuncdef = { |
SQLITE_UTF8, /* funcFlags */ |
0, /* pUserData */ |
0, /* pNext */ |
- statPush, /* xFunc */ |
- 0, /* xStep */ |
+ statPush, /* xSFunc */ |
0, /* xFinalize */ |
"stat_push", /* zName */ |
- 0, /* pHash */ |
- 0 /* pDestructor */ |
+ {0} |
}; |
#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ |
@@ -801,6 +797,12 @@ static const FuncDef statPushFuncdef = { |
** The content to returned is determined by the parameter J |
** which is one of the STAT_GET_xxxx values defined above. |
** |
+** The stat_get(P,J) function is not available to generic SQL. It is |
+** inserted as part of a manually constructed bytecode program. (See |
+** the callStatGet() routine below.) It is guaranteed that the P |
+** parameter will always be a poiner to a Stat4Accum object, never a |
+** NULL. |
+** |
** If neither STAT3 nor STAT4 are enabled, then J is always |
** STAT_GET_STAT1 and is hence omitted and this routine becomes |
** a one-parameter function, stat_get(P), that always returns the |
@@ -926,12 +928,10 @@ static const FuncDef statGetFuncdef = { |
SQLITE_UTF8, /* funcFlags */ |
0, /* pUserData */ |
0, /* pNext */ |
- statGet, /* xFunc */ |
- 0, /* xStep */ |
+ statGet, /* xSFunc */ |
0, /* xFinalize */ |
"stat_get", /* zName */ |
- 0, /* pHash */ |
- 0 /* pDestructor */ |
+ {0} |
}; |
static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ |
@@ -943,8 +943,8 @@ static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ |
#else |
UNUSED_PARAMETER( iParam ); |
#endif |
- sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4, regOut); |
- sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); |
+ sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut, |
+ (char*)&statGetFuncdef, P4_FUNCDEF); |
sqlite3VdbeChangeP5(v, 1 + IsStat34); |
} |
@@ -1000,7 +1000,7 @@ static void analyzeOneTable( |
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
#ifndef SQLITE_OMIT_AUTHORIZATION |
if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, |
- db->aDb[iDb].zName ) ){ |
+ db->aDb[iDb].zDbSName ) ){ |
return; |
} |
#endif |
@@ -1098,8 +1098,8 @@ static void analyzeOneTable( |
#endif |
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); |
- sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4+1, regStat4); |
- sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); |
+ sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4, |
+ (char*)&statInitFuncdef, P4_FUNCDEF); |
sqlite3VdbeChangeP5(v, 2+IsStat34); |
/* Implementation of the following: |
@@ -1118,7 +1118,7 @@ static void analyzeOneTable( |
if( nColTest>0 ){ |
int endDistinctTest = sqlite3VdbeMakeLabel(v); |
int *aGotoChng; /* Array of jump instruction addresses */ |
- aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); |
+ aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); |
if( aGotoChng==0 ) continue; |
/* |
@@ -1195,8 +1195,8 @@ static void analyzeOneTable( |
} |
#endif |
assert( regChng==(regStat4+1) ); |
- sqlite3VdbeAddOp3(v, OP_Function0, 1, regStat4, regTemp); |
- sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); |
+ sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp, |
+ (char*)&statPushFuncdef, P4_FUNCDEF); |
sqlite3VdbeChangeP5(v, 2+IsStat34); |
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); |
@@ -1390,7 +1390,7 @@ void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ |
/* Form 3: Analyze the fully qualified table name */ |
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); |
if( iDb>=0 ){ |
- zDb = db->aDb[iDb].zName; |
+ zDb = db->aDb[iDb].zDbSName; |
z = sqlite3NameFromToken(db, pTableName); |
if( z ){ |
if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ |
@@ -1526,7 +1526,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ |
** 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; |
+ if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); |
} |
aiRowEst = pIndex->aiRowEst; |
#endif |
@@ -1621,7 +1621,7 @@ static void initAvgEq(Index *pIdx){ |
} |
} |
- if( nDist100>nSum100 ){ |
+ if( nDist100>nSum100 && sumEq<nRow ){ |
avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100); |
} |
if( avgEq==0 ) avgEq = 1; |
@@ -1673,10 +1673,10 @@ static int loadStatTbl( |
Index *pPrevIdx = 0; /* Previous index in the loop */ |
IndexSample *pSample; /* A slot in pIdx->aSample[] */ |
- assert( db->lookaside.bEnabled==0 ); |
+ assert( db->lookaside.bDisable ); |
zSql = sqlite3MPrintf(db, zSql1, zDb); |
if( !zSql ){ |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
sqlite3DbFree(db, zSql); |
@@ -1716,7 +1716,7 @@ static int loadStatTbl( |
pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
if( pIdx->aSample==0 ){ |
sqlite3_finalize(pStmt); |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
pSpace = (tRowcnt*)&pIdx->aSample[nSample]; |
pIdx->aAvgEq = pSpace; pSpace += nIdxCol; |
@@ -1732,7 +1732,7 @@ static int loadStatTbl( |
zSql = sqlite3MPrintf(db, zSql2, zDb); |
if( !zSql ){ |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
} |
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
sqlite3DbFree(db, zSql); |
@@ -1770,9 +1770,11 @@ static int loadStatTbl( |
pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); |
if( pSample->p==0 ){ |
sqlite3_finalize(pStmt); |
- return SQLITE_NOMEM; |
+ return SQLITE_NOMEM_BKPT; |
+ } |
+ if( pSample->n ){ |
+ memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); |
} |
- memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); |
pIdx->nSample++; |
} |
rc = sqlite3_finalize(pStmt); |
@@ -1787,7 +1789,7 @@ static int loadStatTbl( |
static int loadStat4(sqlite3 *db, const char *zDb){ |
int rc = SQLITE_OK; /* Result codes from subroutines */ |
- assert( db->lookaside.bEnabled==0 ); |
+ assert( db->lookaside.bDisable ); |
if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ |
rc = loadStatTbl(db, 0, |
"SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", |
@@ -1832,7 +1834,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ |
analysisInfo sInfo; |
HashElem *i; |
char *zSql; |
- int rc; |
+ int rc = SQLITE_OK; |
assert( iDb>=0 && iDb<db->nDb ); |
assert( db->aDb[iDb].pBt!=0 ); |
@@ -1841,38 +1843,40 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ |
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
Index *pIdx = sqliteHashData(i); |
- sqlite3DefaultRowEst(pIdx); |
+ pIdx->aiRowLogEst[0] = 0; |
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
sqlite3DeleteIndexSamples(db, pIdx); |
pIdx->aSample = 0; |
#endif |
} |
- /* Check to make sure the sqlite_stat1 table exists */ |
+ /* Load new statistics out of the sqlite_stat1 table */ |
sInfo.db = db; |
- sInfo.zDatabase = db->aDb[iDb].zName; |
- if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ |
- return SQLITE_ERROR; |
+ sInfo.zDatabase = db->aDb[iDb].zDbSName; |
+ if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ |
+ zSql = sqlite3MPrintf(db, |
+ "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); |
+ if( zSql==0 ){ |
+ rc = SQLITE_NOMEM_BKPT; |
+ }else{ |
+ rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
+ sqlite3DbFree(db, zSql); |
+ } |
} |
- /* Load new statistics out of the sqlite_stat1 table */ |
- zSql = sqlite3MPrintf(db, |
- "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); |
- if( zSql==0 ){ |
- rc = SQLITE_NOMEM; |
- }else{ |
- rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
- sqlite3DbFree(db, zSql); |
+ /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ |
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
+ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
+ Index *pIdx = sqliteHashData(i); |
+ if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx); |
} |
- |
/* Load the statistics from the sqlite_stat4 table. */ |
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ |
- int lookasideEnabled = db->lookaside.bEnabled; |
- db->lookaside.bEnabled = 0; |
+ db->lookaside.bDisable++; |
rc = loadStat4(db, sInfo.zDatabase); |
- db->lookaside.bEnabled = lookasideEnabled; |
+ db->lookaside.bDisable--; |
} |
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
Index *pIdx = sqliteHashData(i); |
@@ -1882,7 +1886,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ |
#endif |
if( rc==SQLITE_NOMEM ){ |
- db->mallocFailed = 1; |
+ sqlite3OomFault(db); |
} |
return rc; |
} |