mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
If a table has one or more rows and it has a partial index has zero rows,
still make an entry in the sqlite_stat1 table for the partial index, so that we know that "PRAGMA optimize" does not need to redo the whole table. FossilOrigin-Name: e147b18991dd462fff367442acb0504fdf193a31843ed34ec8c1ced30747bf8a
This commit is contained in:
@@ -872,7 +872,7 @@ static void statGet(
|
||||
if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1;
|
||||
sqlite3_str_appendf(&sStat, " %llu", iVal);
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
assert( p->current.anEq[i] );
|
||||
assert( p->current.anEq[i] || p->nRow==0 );
|
||||
#endif
|
||||
}
|
||||
sqlite3ResultStrAccum(context, &sStat);
|
||||
@@ -1057,7 +1057,7 @@ static void analyzeOneTable(
|
||||
|
||||
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
|
||||
int nCol; /* Number of columns in pIdx. "N" */
|
||||
int addrRewind; /* Address of "OP_Rewind iIdxCur" */
|
||||
int addrGotoEnd; /* Address of "OP_Rewind iIdxCur" */
|
||||
int addrNextRow; /* Address of "next_row:" */
|
||||
const char *zIdxName; /* Name of the index */
|
||||
int nColTest; /* Number of columns to test for changes */
|
||||
@@ -1081,9 +1081,14 @@ static void analyzeOneTable(
|
||||
/*
|
||||
** Pseudo-code for loop that calls stat_push():
|
||||
**
|
||||
** Rewind csr
|
||||
** if eof(csr) goto end_of_scan;
|
||||
** regChng = 0
|
||||
** Rewind csr
|
||||
** if eof(csr){
|
||||
** stat_init() with count = 0;
|
||||
** goto end_of_scan;
|
||||
** }
|
||||
** count()
|
||||
** stat_init()
|
||||
** goto chng_addr_0;
|
||||
**
|
||||
** next_row:
|
||||
@@ -1122,41 +1127,36 @@ static void analyzeOneTable(
|
||||
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
|
||||
VdbeComment((v, "%s", pIdx->zName));
|
||||
|
||||
/* Invoke the stat_init() function. The arguments are:
|
||||
**
|
||||
/* Implementation of the following:
|
||||
**
|
||||
** regChng = 0
|
||||
** Rewind csr
|
||||
** if eof(csr){
|
||||
** stat_init() with count = 0;
|
||||
** goto end_of_scan;
|
||||
** }
|
||||
** count()
|
||||
** stat_init()
|
||||
** goto chng_addr_0;
|
||||
*/
|
||||
assert( regTemp2==regStat+4 );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
|
||||
|
||||
/* Arguments to stat_init():
|
||||
** (1) the number of columns in the index including the rowid
|
||||
** (or for a WITHOUT ROWID table, the number of PK columns),
|
||||
** (2) the number of columns in the key without the rowid/pk
|
||||
** (3) estimated number of rows in the index,
|
||||
*/
|
||||
** (3) estimated number of rows in the index. */
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
|
||||
assert( regRowid==regStat+2 );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( OptimizationEnabled(db, SQLITE_Stat4) ){
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
|
||||
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
||||
VdbeCoverage(v);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
|
||||
}
|
||||
assert( regTemp2==regStat+4 );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
|
||||
sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp,
|
||||
OptimizationDisabled(db, SQLITE_Stat4));
|
||||
sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
|
||||
&statInitFuncdef, 0);
|
||||
addrGotoEnd = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
||||
VdbeCoverage(v);
|
||||
|
||||
/* Implementation of the following:
|
||||
**
|
||||
** Rewind csr
|
||||
** if eof(csr) goto end_of_scan;
|
||||
** regChng = 0
|
||||
** goto next_push_0;
|
||||
**
|
||||
*/
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
|
||||
addrNextRow = sqlite3VdbeCurrentAddr(v);
|
||||
|
||||
@@ -1263,6 +1263,12 @@ static void analyzeOneTable(
|
||||
}
|
||||
|
||||
/* Add the entry to the stat1 table. */
|
||||
if( pIdx->pPartIdxWhere ){
|
||||
/* Partial indexes might get a zero-entry in sqlite_stat1. But
|
||||
** an empty table is omitted from sqlite_stat1. */
|
||||
sqlite3VdbeJumpHere(v, addrGotoEnd);
|
||||
addrGotoEnd = 0;
|
||||
}
|
||||
callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
|
||||
assert( "BBB"[0]==SQLITE_AFF_TEXT );
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
|
||||
@@ -1286,6 +1292,12 @@ static void analyzeOneTable(
|
||||
int addrIsNull;
|
||||
u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
|
||||
|
||||
/* No STAT4 data is generated if the number of rows is zero */
|
||||
if( addrGotoEnd==0 ){
|
||||
sqlite3VdbeAddOp2(v, OP_Cast, regStat1, SQLITE_AFF_INTEGER);
|
||||
addrGotoEnd = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
|
||||
}
|
||||
|
||||
if( doOnce ){
|
||||
int mxCol = nCol;
|
||||
Index *pX;
|
||||
@@ -1338,7 +1350,7 @@ static void analyzeOneTable(
|
||||
#endif /* SQLITE_ENABLE_STAT4 */
|
||||
|
||||
/* End of analysis */
|
||||
sqlite3VdbeJumpHere(v, addrRewind);
|
||||
if( addrGotoEnd ) sqlite3VdbeJumpHere(v, addrGotoEnd);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user