]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Modify the vdbe code generated by ANALYZE to use fewer memory cells and cursor slots.
authordan <dan@noemail.net>
Mon, 5 Aug 2013 19:04:07 +0000 (19:04 +0000)
committerdan <dan@noemail.net>
Mon, 5 Aug 2013 19:04:07 +0000 (19:04 +0000)
FossilOrigin-Name: 4a51cf289fad8aebc637b5f96488de18e861195d

manifest
manifest.uuid
src/analyze.c

index 1bdf53de0cd280cfa90eb8155cf841b002f33dcb..dd8eb4715692e1b09c10a6662226c5ecee9996b6 100644 (file)
--- 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
index 22a684eebe523ebb30f3d17dee39847e4fc994a1..8b49a29bb2dafd93862cccc5bd2a45d7799bab2a 100644 (file)
@@ -1 +1 @@
-3a71afe67418ce00097cd9714c395fe9ff16f23b
\ No newline at end of file
+4a51cf289fad8aebc637b5f96488de18e861195d
\ No newline at end of file
index 07366b76aba26794149ca19698131bbbb2842325..564edb6139e72ea68cb8ecd54cf22e9bcbaba9cc 100644 (file)
@@ -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; i<nCol; i++){
       int iMode = (i==0 ? P4_KEYINFO_HANDOFF : P4_KEYINFO);
       sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur+i, pIdx->tnum, 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; i<regDLte+nCol; i++){
       sqlite3VdbeAddOp2(v, OP_Integer, 0, i);
     }
+    sqlite3VdbeAddOp2(v, OP_Integer, 0, regCnt);
+    sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof);
 
     /* Rewind all cursors open on the index. If the table is entry, this
     ** will cause control to jump to address endOfScan immediately.  */
@@ -773,7 +761,7 @@ static void analyzeOneTable(
     }
 
     /* Invoke stat4_push() */
-    sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp2);
+    sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
     sqlite3VdbeChangeP4(v, -1, (char*)&stat4PushFuncdef, P4_FUNCDEF);
     sqlite3VdbeChangeP5(v, 2 + 3*nCol);
 
@@ -790,23 +778,17 @@ static void analyzeOneTable(
 
     sqlite3VdbeResolveLabel(v, endOfScan);
 
-    /* Close all the cursors */
-    for(i=0; i<nCol; i++){
-      sqlite3VdbeAddOp1(v, OP_Close, iIdxCur+i);
-      VdbeComment((v, "close index cursor %d", i));
-    }
-
 #ifdef SQLITE_ENABLE_STAT4
     /* Add rows to the sqlite_stat4 table */
     regLoop = regStat4+1;
     sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop);
     shortJump = sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1);
-    sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regTemp1);
+    sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regTemp);
     sqlite3VdbeChangeP4(v, -1, (char*)&stat4GetFuncdef, P4_FUNCDEF);
     sqlite3VdbeChangeP5(v, 2);
-    sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1);
+    sqlite3VdbeAddOp1(v, OP_IsNull, regTemp);
 
-    sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1);
+    sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp);
     for(i=0; i<nCol; i++){
       int iCol = pIdx->aiColumn[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->nMem<regRec ) pParse->nMem = 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);
 }