-C Fix\serrors\sin\sthe\stable\sresize\sdetection.
-D 2017-02-18T02:42:54.892
+C Add\sthe\sOP_SqlExec\sopcode\sand\suse\sit\sto\simplement\s"PRAGMA\sanalyze_as_needed",\ninvoking\sANALYZE\ssubcommands\sas\snecessary.\s\sThis\ssimplifies\sthe\simplementation.
+D 2017-02-18T15:58:52.451
F Makefile.in edb6bcdd37748d2b1c3422ff727c748df7ffe918
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc a89ea37ab5928026001569f056973b9059492fe2
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 3b23977620ce9662ac54443f65b87ba996e36121
-F src/analyze.c e01e5362ba2ac8430ab7833022afb6081ade8315
+F src/analyze.c 1b7197d619788353437d390de42a9bccbb4aa2ac
F src/attach.c 8c476f8bd5d2afe11d925f890d30e527e5b0ce43
F src/auth.c 930b376a9c56998557367e6f7f8aaeac82a2a792
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
-F src/pragma.c cf0f101d2986d258699cbbd249392858ec9a6b7e
+F src/pragma.c 1ed159f6fed5af7f5b095f55bdefcb0848956397
F src/pragma.h 065e184494f12e94111da1ab6984faa7b6142e68
F src/prepare.c b1140c3d0cf59bc85ace00ce363153041b424b7a
F src/printf.c 67427bbee66d891fc6f6f5aada857e9cdb368c1c
F src/sqlite.h.in 751ff125eb159c8f92c182b8df980a5e4f50e966
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
-F src/sqliteInt.h 70abfa92e02688f1d189bf63fd25d309ca8d8d1e
+F src/sqliteInt.h 87857c2b8d8825e22970ce3f466b8618ee55b44e
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6
F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
-F src/vdbe.c ac8538b96af5c63d6f18484ffd981d4f44db0073
+F src/vdbe.c 02f9db522c73ba4e1743585e9fd6f8ac6c71515b
F src/vdbe.h 59998ffd71d7caa8886bc78dafaf8caeccd4c13c
F src/vdbeInt.h 4e4b15b2e1330e1636e4e01974eab2b0b985092f
F src/vdbeapi.c 3e4a8893feeb78620f4aac4ac5b85d92255b97e1
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 882599a4a7ea92c9e7752e0745475508e58a11c3
-R cf9f80fd407d6e9e7cfac9c2957017b5
+P 4229caec0b60a1617b9d5ff94b47271cbd7be1e0
+R 03be76497e56750b0101f816e3587990
U drh
-Z 225df65ba1e601aba9cbc975df68b3a8
+Z 8d178351b984357dd4d18d50fe476798
Index *pOnlyIdx, /* If not NULL, only analyze this one index */
int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */
int iMem, /* Available memory locations begin here */
- int iTab, /* Next available cursor */
- LogEst szOld /* Run the analysis if table row count is larger than this */
+ int iTab /* Next available cursor */
){
sqlite3 *db = pParse->db; /* Database handle */
Index *pIdx; /* An index to being analyzed */
- int addrSizeCk = 0; /* Address of the IfSmaller */
int iIdxCur; /* Cursor open on index being analyzed */
int iTabCur; /* Table cursor */
Vdbe *v; /* The virtual machine being built up */
int jZeroRows = -1; /* Jump from here if number of rows is zero */
int iDb; /* Index of database containing pTab */
u8 needTableCnt = 1; /* True to count the table */
- int regWorkDone = iMem++; /* Set to 1 if any work is done */
int regNewRowid = iMem++; /* Rowid for the inserted record */
int regStat4 = iMem++; /* Register to hold Stat4Accum object */
int regChng = iMem++; /* Index of changed index field */
iIdxCur = iTab++;
pParse->nTab = MAX(pParse->nTab, iTab);
sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
- if( szOld>0 ){
- addrSizeCk = sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, 0, szOld);
- VdbeCoverage(v);
- }
sqlite3VdbeLoadString(v, regTabname, pTab->zName);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeJumpHere(v, jZeroRows);
}
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regWorkDone);
- VdbeComment((v, "work was done"));
- sqlite3VdbeJumpHere(v, addrSizeCk);
}
+
/*
-** Return true if table pTab might need to being reanalyzed. Return
-** false if we know that pTab should not be reanalyzed.
-**
-** If returning true, also set *pThreshold to a size threshold that
-** will determine at run-time whether or not the reanalysis occurs.
-** The reanalysis will only occur if the size of the table is greater
-** than the threshold. Not that the threshold is a logarithmic LogEst
-** value.
+** Generate code that will cause the most recent index analysis to
+** be loaded into internal hash tables where is can be used.
*/
-static int analyzeNeeded(Table *pTab, LogEst *pThreshold){
- Index *pIdx;
- if( (pTab->tabFlags & TF_StatsUsed)==0 ) return 0;
-
- /* If TF_StatsUsed is true, then we might need to reanalyze.
- ** TUNING: Only reanalyze if the table size has grown by a factor
- ** of 25 or more. */
- *pThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
-
- /* Except, if any of the indexes of the table do not have valid
- ** sqlite_stat1 entries, then set the size threshold to zero to
- ** ensure the analysis will always occur. */
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( !pIdx->hasStat1 ){
- *pThreshold = 0;
- break;
- }
+static void loadAnalysis(Parse *pParse, int iDb){
+ Vdbe *v = sqlite3GetVdbe(pParse);
+ if( v ){
+ sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
}
- return 1;
}
/*
-** Generate code that will do an analysis of an entire database, or
-** all databases in the connection if iDbReq is negative.
-**
-** If onlyIfNeeded is true, then only run the analysis if SQLite thinks
-** it is actually needed.
+** Generate code that will do an analysis of an entire database
*/
-void sqlite3AnalyzeDatabase(
- Parse *pParse, /* The parsing context */
- int iDbReq, /* Which schema to analyze. -1 for all (except TEMP) */
- int onlyIfNeeded /* Only do the analysis if needed, when true */
-){
+static void analyzeDatabase(Parse *pParse, int iDb){
sqlite3 *db = pParse->db;
- Schema *pSchema;
+ Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */
HashElem *k;
- int iStatCur = 0;
- int iMem = 0;
- int iTab = 0;
- int iDb; /* Database currently being analyzed */
- int iDbFirst, iDbLast; /* Range of databases to be analyzed */
- int bStatTabs = 0;
- Vdbe *v = sqlite3GetVdbe(pParse);
- int nHit = 0;
- unsigned char aHit[SQLITE_MAX_ATTACHED+2];
+ int iStatCur;
+ int iMem;
+ int iTab;
- if( v==0 ) return;
- if( iDbReq>=0 ){
- iDbFirst = iDbLast = iDbReq;
- }else{
- iDbFirst = 0;
- iDbLast = db->nDb-1;
- }
- for(iDb=iDbFirst; iDb<=iDbLast; iDb++, bStatTabs=0){
- if( iDb==1 ) continue; /* Do not analyze the TEMP database */
- pSchema = db->aDb[iDb].pSchema;
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
- Table *pTab = (Table*)sqliteHashData(k);
- LogEst szThreshold = 0;
- if( !onlyIfNeeded || analyzeNeeded(pTab, &szThreshold) ){
- if( iMem==0 ){
- iStatCur = pParse->nTab;
- pParse->nTab += 3;
- iMem = pParse->nMem+1;
- iTab = pParse->nTab;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem);
- }
- if( !bStatTabs ){
- aHit[nHit++] = iDb;
- sqlite3BeginWriteOperation(pParse, 0, iDb);
- openStatTable(pParse, iDb, iStatCur, 0, 0);
- bStatTabs = 1;
- }
- analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab, szThreshold);
- }
- }
- }
- if( iMem ){
- int addrTop = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); VdbeCoverage(v);
- for(iDb=0; iDb<nHit; iDb++){
- sqlite3VdbeAddOp1(v, OP_LoadAnalysis, aHit[iDb]);
- }
- sqlite3VdbeAddOp0(v, OP_Expire);
- sqlite3VdbeJumpHere(v, addrTop);
+ sqlite3BeginWriteOperation(pParse, 0, iDb);
+ iStatCur = pParse->nTab;
+ pParse->nTab += 3;
+ openStatTable(pParse, iDb, iStatCur, 0, 0);
+ iMem = pParse->nMem+1;
+ iTab = pParse->nTab;
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
+ Table *pTab = (Table*)sqliteHashData(k);
+ analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab);
}
+ loadAnalysis(pParse, iDb);
}
/*
static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){
int iDb;
int iStatCur;
- Vdbe *v;
assert( pTab!=0 );
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
}else{
openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
}
- analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1,
- pParse->nTab, 0);
- v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
- sqlite3VdbeAddOp0(v, OP_Expire);
- }
+ analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab);
+ loadAnalysis(pParse, iDb);
}
/*
** Form 1 causes all indices in all attached databases to be analyzed.
** Form 2 analyzes all indices the single database named.
** Form 3 analyzes all indices associated with the named table.
-**
-** If pName1 and pName2 are both NULL and if the ifNeeded flag is true,
-** this routine computes an conditional ANALYZE on only those tables
-** are believed to be in need of analysis. The conditional analysis
-** might well be a no-op.
*/
void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
sqlite3 *db = pParse->db;
int iDb;
+ int i;
char *z, *zDb;
Table *pTab;
Index *pIdx;
Token *pTableName;
+ Vdbe *v;
/* Read the database schema. If an error occurs, leave an error message
** and code in pParse and return NULL. */
assert( pName2!=0 || pName1==0 );
if( pName1==0 ){
/* Form 1: Analyze everything */
- sqlite3AnalyzeDatabase(pParse, -1, 0);
+ for(i=0; i<db->nDb; i++){
+ if( i==1 ) continue; /* Do not analyze the TEMP database */
+ analyzeDatabase(pParse, i);
+ }
}else if( pName2->n==0 ){
/* Form 2: Analyze the database or table named */
iDb = sqlite3FindDb(db, pName1);
if( iDb>=0 ){
- sqlite3AnalyzeDatabase(pParse, iDb, 0);
+ analyzeDatabase(pParse, iDb);
}else{
z = sqlite3NameFromToken(db, pName1);
if( z ){
}
}
}
+ v = sqlite3GetVdbe(pParse);
+ if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
}
/*