From: dan Date: Mon, 5 Aug 2013 19:04:07 +0000 (+0000) Subject: Modify the vdbe code generated by ANALYZE to use fewer memory cells and cursor slots. X-Git-Tag: version-3.8.1~132^2~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c612970c9d4d388b3dac6d7a885634f57c1eaee1;p=thirdparty%2Fsqlite.git Modify the vdbe code generated by ANALYZE to use fewer memory cells and cursor slots. FossilOrigin-Name: 4a51cf289fad8aebc637b5f96488de18e861195d --- diff --git a/manifest b/manifest index 1bdf53de0c..dd8eb47156 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sN\sseparate\scursors\swhen\sscanning\san\sindex\swith\sN\scolumns\sto\scollect\ssqlite_stat4\sdata.\sThis\sfixes\sa\sproblem\swith\scollecting\sincorrect\snEq\svalues\sfrom\smulti-column\sindexes. -D 2013-08-05T18:00:56.397 +C Modify\sthe\svdbe\scode\sgenerated\sby\sANALYZE\sto\suse\sfewer\smemory\scells\sand\scursor\sslots. +D 2013-08-05T19:04:07.083 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5e41da95d92656a5004b03d3576e8b226858a28e F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -157,7 +157,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad F src/alter.c f8db986c03eb0bfb221523fc9bbb9d0b70de3168 -F src/analyze.c a0979f7fdc8cd724f8e646ba9ef6ca1e56fa7491 +F src/analyze.c 726a63b19f7f1478b321b84fc03ae9d754624841 F src/attach.c 1816f5a9eea8d2010fc2b22b44f0f63eb3a62704 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 43b348822db3e4cef48b2ae5a445fbeb6c73a165 @@ -1106,7 +1106,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac -P badd24d987240db5528b37d1c177431617079f9b -R 2711e68fa0a11591cfe5a22173f05afc +P 3a71afe67418ce00097cd9714c395fe9ff16f23b +R a3a130eab7cfa15d823c14448800974a U dan -Z ccb7ab66bd998be3fb0311148b3ca62c +Z c7783dc63850c26ec6b79b95587c6286 diff --git a/manifest.uuid b/manifest.uuid index 22a684eebe..8b49a29bb2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a71afe67418ce00097cd9714c395fe9ff16f23b \ No newline at end of file +4a51cf289fad8aebc637b5f96488de18e861195d \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 07366b76ab..564edb6139 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -505,15 +505,15 @@ static void analyzeOneTable( Table *pTab, /* Table whose indices are to be analyzed */ 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 iMem, /* Available memory locations begin here */ + int iTab /* Next available cursor */ ){ sqlite3 *db = pParse->db; /* Database handle */ Index *pIdx; /* An index to being analyzed */ int iIdxCur; /* Cursor open on index being analyzed */ + int iTabCur; /* Table cursor */ Vdbe *v; /* The virtual machine being built up */ int i; /* Loop counter */ - int topOfLoop; /* The top of the loop */ - int endOfLoop; /* The end of the loop */ 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 */ @@ -525,23 +525,20 @@ static void analyzeOneTable( int regNumLt = iMem++; /* Number of keys less than regSample */ int regNumDLt = iMem++; /* Number of distinct keys less than regSample */ int regSample = iMem++; /* The next sample value */ - int regRowid = regSample; /* Rowid of a sample */ - int regAccum = iMem++; /* Register to hold Stat4Accum object */ int regLoop = iMem++; /* Loop counter */ - int regCount = iMem++; /* Number of rows in the table or index */ - int regTemp1 = iMem++; /* Intermediate register */ - int regTemp2 = iMem++; /* Intermediate register */ - int once = 1; /* One-time initialization */ int shortJump = 0; /* Instruction address */ - int iTabCur = pParse->nTab++; /* Table cursor */ #endif int regCol = iMem++; /* Content of a column in analyzed table */ int regRec = iMem++; /* Register holding completed record */ int regTemp = iMem++; /* Temporary use register */ int regNewRowid = iMem++; /* Rowid for the inserted record */ + int regEof = iMem++; /* True once cursors are all at EOF */ + int regCnt = iMem++; /* Row counter */ int regStat4 = iMem++; /* Register to hold Stat4Accum object */ + int regRowid = iMem++; /* Rowid argument passed to stat4_push() */ + pParse->nMem = MAX(pParse->nMem, regRowid); v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) ){ return; @@ -568,23 +565,20 @@ static void analyzeOneTable( /* Establish a read-lock on the table at the shared-cache level. ** Also open a read-only cursor on the table. */ sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - iTabCur = pParse->nTab++; + iTabCur = iTab++; + pParse->nTab = MAX(pParse->nTab, iTab); sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; /* Number of columns indexed by pIdx */ KeyInfo *pKey; /* KeyInfo structure for pIdx */ - int addrIfNot = 0; /* address of OP_IfNot */ int *aChngAddr; /* Array of jump instruction addresses */ - int regRowid; /* Register for rowid of current row */ int regPrev; /* First in array of previous values */ int regDLte; /* First in array of nDlt registers */ int regLt; /* First in array of nLt registers */ int regEq; /* First in array of nEq registers */ - int regCnt; /* Number of index entries */ - int regEof; /* True once cursors are all at EOF */ int endOfScan; /* Label to jump to once scan is finished */ if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; @@ -651,13 +645,10 @@ static void analyzeOneTable( ** integer identifier) is regStat4. Immediately following regStat4 ** we allocate the following: ** - ** regRowid - 1 register ** regEq - nCol registers ** regLt - nCol registers ** regDLte - nCol registers - ** regCnt - 1 register ** regPrev - nCol registers - ** regEof - 1 register ** ** The regRowid, regEq, regLt and regDLte registers must be positioned in ** that order immediately following regStat4 so that they can be passed @@ -665,21 +656,16 @@ static void analyzeOneTable( ** ** All of the above are initialized to contain integer value 0. */ - regRowid = regStat4+1; /* Rowid argument */ regEq = regRowid+1; /* First in array of nEq value registers */ regLt = regEq+nCol; /* First in array of nLt value registers */ regDLte = regLt+nCol; /* First in array of nDLt value registers */ - regCnt = regDLte+nCol; /* Row counter */ - regPrev = regCnt+1; /* First in array of prev. value registers */ - regEof = regPrev+nCol; /* True once last row read from index */ - if( regEof+1>pParse->nMem ){ - pParse->nMem = regPrev+nCol; - } + regPrev = regDLte+nCol; /* First in array of prev. value registers */ + pParse->nMem = MAX(pParse->nMem, regPrev+nCol); /* Open a read-only cursor for each column of the index. */ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); - iIdxCur = pParse->nTab++; - pParse->nTab += (nCol-1); + iIdxCur = iTab; + pParse->nTab = MAX(pParse->nTab, iTab+nCol); for(i=0; itnum, iDb); @@ -703,9 +689,11 @@ static void analyzeOneTable( #endif /* SQLITE_ENABLE_STAT4 */ /* Initialize all the memory registers allocated above to 0. */ - for(i=regRowid; i<=regEof; i++){ + for(i=regEq; iaiColumn[i]; sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regPrev+i); @@ -884,11 +866,6 @@ static void analyzeOneTable( sqlite3VdbeChangeP5(v, OPFLAG_APPEND); sqlite3VdbeJumpHere(v, jZeroRows); } - - sqlite3VdbeAddOp1(v, OP_Close, iTabCur); - - /* TODO: Not sure about this... */ - if( pParse->nMemnMem = regRec; } @@ -912,16 +889,18 @@ static void analyzeDatabase(Parse *pParse, int iDb){ HashElem *k; int iStatCur; int iMem; + int iTab; 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); + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); } loadAnalysis(pParse, iDb); } @@ -946,7 +925,7 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ }else{ openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); } - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1); + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); loadAnalysis(pParse, iDb); }