]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Reduce the amount of code run and memory used for ANALYZE in the common case
authordrh <drh@noemail.net>
Tue, 27 Aug 2013 20:16:48 +0000 (20:16 +0000)
committerdrh <drh@noemail.net>
Tue, 27 Aug 2013 20:16:48 +0000 (20:16 +0000)
where neither STAT3 and STAT4 are enabled.

FossilOrigin-Name: 9d1424c91a21ed740aca53e437b8f7c1f0823c03

manifest
manifest.uuid
src/analyze.c
src/sqliteInt.h

index bf7e78d21a0d23dcac1b40ca7219fb9318f6d1d9..c679578fc01e01303bd6b217a5a1ec071b8c6f59 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\ssqlite3.pc.in\sto\suse\s@PACKAGE_VERSION@\sinstead\sof\s@RELEASE@.
-D 2013-08-27T15:41:09.212
+C Reduce\sthe\samount\sof\scode\srun\sand\smemory\sused\sfor\sANALYZE\sin\sthe\scommon\scase\nwhere\sneither\sSTAT3\sand\sSTAT4\sare\senabled.
+D 2013-08-27T20:16:48.420
 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 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
 F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
-F src/analyze.c ce2a3385ac05f61e07d384b1c7e8c52e6ef1a3a6
+F src/analyze.c f1dbc79cbe97f960b20dfc3d24143dff988db41d
 F src/attach.c fea00cab11c854646a27641a263f5876569a51f9
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3
@@ -221,7 +221,7 @@ F src/shell.c 00a23311466829d9b77f0be4f7cedee9328279db
 F src/sqlite.h.in bd1451ba1ab681022a53bccc3c39580ba094a3ff
 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h f3636620ad376f65bdbbf5e183f0e4309cb7526e
+F src/sqliteInt.h 97b1005b812048469c80ec9394a77e0ad83ea9c0
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -1107,7 +1107,7 @@ F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/wherecosttest.c f407dc4c79786982a475261866a161cd007947ae
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P 959bb5acdc3b4e2b481e3c38f20867131bfc9dbc
-R 2e3b4a437bff68926c962c9ab6977363
-U dan
-Z 665cf10c770598d3c963d389b4e25d18
+P 2460dfd8825d251e622e866e8dc1c0bf7fe7ec9f
+R d4ca9812963b4361724d44342b635223
+U drh
+Z 6faf42c735288a2cfa68556541b907cb
index c8cd2432dcc19a198eb04eee75435b9023be893f..94e1055f64b07600104a769595875612c3f75667 100644 (file)
@@ -1 +1 @@
-2460dfd8825d251e622e866e8dc1c0bf7fe7ec9f
\ No newline at end of file
+9d1424c91a21ed740aca53e437b8f7c1f0823c03
\ No newline at end of file
index d2fd3682ae8bf277b1bfe5dc1448d3d4515428c4..9ea16b91e961ecaad690cc02b45b09781966331c 100644 (file)
@@ -1,5 +1,5 @@
 /*
-** 2005 July 8
+** 2005-07-08
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -31,7 +31,9 @@
 ** SQLITE_ENABLE_STAT3 defined.  The functionality of sqlite_stat3
 ** is a superset of sqlite_stat2.  The sqlite_stat4 is an enhanced
 ** version of sqlite_stat3 and is only available when compiled with
-** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later.
+** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later.  It is
+** not possible to enable both STAT3 and STAT4 at the same time.  If they
+** are both enabled, then STAT4 is precedence.
 **
 ** For most applications, sqlite_stat1 provides all the statisics required
 ** for the query planner to make good choices.
 # define IsStat4     0
 # define IsStat3     0
 # undef SQLITE_ENABLE_STAT34
+# undef SQLITE_STAT4_SAMPLES
+# define SQLITE_STAT4_SAMPLES 1
 #endif
+#define IsStat34    (IsStat3+IsStat4)  /* 1 for STAT3 or STAT4. 0 otherwise */
 
 /*
-** This routine generates code that opens the sqlite_stat1 table for
-** writing with cursor iStatCur. If the library was built with the
-** SQLITE_ENABLE_STAT4 macro defined, then the sqlite_stat4 table is
-** opened for writing using cursor (iStatCur+1)
+** This routine generates code that opens the sqlite_statN tables.
+** The sqlite_stat1 table is always relevant.  sqlite_stat2 is now
+** obsolete.  sqlite_stat3 and sqlite_stat4 are only opened when
+** appropriate compile-time options are provided.
 **
-** If the sqlite_stat1 tables does not previously exist, it is created.
-** Similarly, if the sqlite_stat4 table does not exist and the library
-** is compiled with SQLITE_ENABLE_STAT4 defined, it is created. 
+** If the sqlite_statN tables do not previously exist, it is created.
 **
 ** Argument zWhere may be a pointer to a buffer containing a table name,
 ** or it may be a NULL pointer. If it is not NULL, then all entries in
-** the sqlite_stat1 and (if applicable) sqlite_stat4 tables associated
-** with the named table are deleted. If zWhere==0, then code is generated
-** to delete all stat table entries.
+** the sqlite_statN tables associated with the named table are deleted.
+** If zWhere==0, then code is generated to delete all stat table entries.
 */
 static void openStatTable(
   Parse *pParse,          /* Parsing context */
@@ -188,16 +190,18 @@ static void openStatTable(
 #elif defined(SQLITE_ENABLE_STAT3)
     { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
     { "sqlite_stat4", 0 },
+#else
+    { "sqlite_stat3", 0 },
+    { "sqlite_stat4", 0 },
 #endif
   };
-
-  int aRoot[] = {0, 0};
-  u8 aCreateTbl[] = {0, 0};
-
   int i;
   sqlite3 *db = pParse->db;
   Db *pDb;
   Vdbe *v = sqlite3GetVdbe(pParse);
+  int aRoot[ArraySize(aTable)];
+  u8 aCreateTbl[ArraySize(aTable)];
+
   if( v==0 ) return;
   assert( sqlite3BtreeHoldsAllMutexes(db) );
   assert( sqlite3VdbeDb(v)==db );
@@ -211,7 +215,7 @@ static void openStatTable(
     Table *pStat;
     if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
       if( aTable[i].zCols ){
-        /* The sqlite_stat[12] table does not exist. Create it. Note that a 
+        /* 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. */
@@ -226,6 +230,7 @@ static void openStatTable(
       ** associated with the table zWhere. If zWhere is NULL, delete the
       ** entire contents of the table. */
       aRoot[i] = pStat->tnum;
+      aCreateTbl[i] = 0;
       sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
       if( zWhere ){
         sqlite3NestedParse(pParse,
@@ -239,11 +244,14 @@ static void openStatTable(
   }
 
   /* Open the sqlite_stat[134] tables for writing. */
-  for(i=0; i<ArraySize(aRoot); i++){
-    sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
-    sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
-    sqlite3VdbeChangeP5(v, aCreateTbl[i]);
-    if( !IsStat3 && !IsStat4 ) break;
+  for(i=0; i<ArraySize(aTable); i++){
+    if( aTable[i].zCols ){
+      sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
+      sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
+      sqlite3VdbeChangeP5(v, aCreateTbl[i]);
+    }else{
+      break;
+    }
   }
 }
 
@@ -262,13 +270,15 @@ static void openStatTable(
 typedef struct Stat4Accum Stat4Accum;
 typedef struct Stat4Sample Stat4Sample;
 struct Stat4Sample {
-  i64 iRowid;                     /* Rowid in main table of the key */
   tRowcnt *anEq;                  /* sqlite_stat4.nEq */
-  tRowcnt *anLt;                  /* sqlite_stat4.nLt */
   tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
+#ifdef SQLITE_ENABLE_STAT34
+  tRowcnt *anLt;                  /* sqlite_stat4.nLt */
+  i64 iRowid;                     /* Rowid in main table of the key */
   u8 isPSample;                   /* True if a periodic sample */
   int iCol;                       /* If !isPSample, the reason for inclusion */
   u32 iHash;                      /* Tiebreaker hash */
+#endif
 };                                                    
 struct Stat4Accum {
   tRowcnt nRow;             /* Number of rows in the entire table */
@@ -285,9 +295,9 @@ struct Stat4Accum {
 };
 
 /*
-** Implementation of the stat_init(C,N) SQL function. The two parameters
+** Implementation of the stat_init(N,C) SQL function. The two parameters
 ** are the number of rows in the table or index (C) and the number of columns
-** in the index (N).
+** in the index (N).  The second argument (C) is only used for STAT3 and STAT4.
 **
 ** This routine allocates the Stat4Accum object in heap memory. The return 
 ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. 
@@ -299,64 +309,73 @@ static void statInit(
   sqlite3_value **argv
 ){
   Stat4Accum *p;
-  u8 *pSpace;                     /* Allocated space not yet assigned */
-  tRowcnt nRow;                   /* Number of rows in table (C) */
-  int mxSample;                   /* Maximum number of samples collected */
   int nCol;                       /* Number of columns in index being sampled */
+  int nColUp;                     /* nCol rounded up for alignment */
   int n;                          /* Bytes of space to allocate */
-  int i;                          /* Used to iterate through p->aSample[] */
+#ifdef SQLITE_ENABLE_STAT34
+  int mxSample = SQLITE_STAT4_SAMPLES;
+#endif
 
   /* Decode the three function arguments */
   UNUSED_PARAMETER(argc);
-  nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
-  mxSample = SQLITE_STAT4_SAMPLES;
-  nCol = sqlite3_value_int(argv[1]);
+  nCol = sqlite3_value_int(argv[0]);
   assert( nCol>1 );               /* >1 because it includes the rowid column */
+  nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
 
   /* Allocate the space required for the Stat4Accum object */
   n = sizeof(*p) 
-    + sizeof(tRowcnt)*nCol                    /* Stat4Accum.anEq */
-    + sizeof(tRowcnt)*nCol                    /* Stat4Accum.anLt */
-    + sizeof(tRowcnt)*nCol                    /* Stat4Accum.anDLt */
-    + sizeof(Stat4Sample)*(nCol+mxSample)     /* Stat4Accum.aBest[], a[] */
-    + sizeof(tRowcnt)*3*nCol*(nCol+mxSample);
+    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anEq */
+    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
+#ifdef SQLITE_ENABLE_STAT34
+    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anLt */
+    + sizeof(Stat4Sample)*(nCol+mxSample)   /* Stat4Accum.aBest[], a[] */
+    + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
+#endif
+  ;
   p = sqlite3MallocZero(n);
   if( p==0 ){
     sqlite3_result_error_nomem(context);
     return;
   }
 
-  p->nRow = nRow;
+  p->nRow = 0;
   p->nCol = nCol;
-  p->mxSample = mxSample;
-  p->nPSample = p->nRow/(mxSample/3+1) + 1;
-  p->iGet = -1;
-
   p->current.anDLt = (tRowcnt*)&p[1];
-  p->current.anEq = &p->current.anDLt[nCol];
-  p->current.anLt = &p->current.anEq[nCol];
-  sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
-
-  /* Set up the Stat4Accum.a[] and aBest[] arrays */
-  p->a = (struct Stat4Sample*)&p->current.anLt[nCol];
-  p->aBest = &p->a[mxSample];
-  pSpace = (u8*)(&p->a[mxSample+nCol]);
-  for(i=0; i<(mxSample+nCol); i++){
-    p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
-    p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
-    p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
-  }
-  assert( (pSpace - (u8*)p)==n );
+  p->current.anEq = &p->current.anDLt[nColUp];
 
-  for(i=0; i<nCol; i++){
-    p->aBest[i].iCol = i;
+#ifdef SQLITE_ENABLE_STAT34
+  {
+    u8 *pSpace;                     /* Allocated space not yet assigned */
+    int i;                          /* Used to iterate through p->aSample[] */
+
+    p->iGet = -1;
+    p->mxSample = mxSample;
+    p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1;
+    p->current.anLt = &p->current.anEq[nColUp];
+    sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
+  
+    /* Set up the Stat4Accum.a[] and aBest[] arrays */
+    p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
+    p->aBest = &p->a[mxSample];
+    pSpace = (u8*)(&p->a[mxSample+nCol]);
+    for(i=0; i<(mxSample+nCol); i++){
+      p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+      p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+      p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
+    }
+    assert( (pSpace - (u8*)p)==n );
+  
+    for(i=0; i<nCol; i++){
+      p->aBest[i].iCol = i;
+    }
   }
+#endif
 
   /* Return a pointer to the allocated object to the caller */
   sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
 }
 static const FuncDef statInitFuncdef = {
-  2,               /* nArg */
+  1+IsStat34,      /* nArg */
   SQLITE_UTF8,     /* iPrefEnc */
   0,               /* flags */
   0,               /* pUserData */
@@ -544,11 +563,16 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
 }
 
 /*
-** Implementation of the stat_push SQL function. 
+** Implementation of the stat_push SQL function:  stat_push(P,R,C)
+** Arguments:
+**
+**    P     Pointer to the Stat4Accum object created by stat_init()
+**    C     Index of left-most column to differ from previous row
+**    R     Rowid for the current row
 **
-**    stat_push(P,R,C)
+** The SQL function always returns NULL.
 **
-** The return value is always NULL.
+** The R parameter is only used for STAT3 and STAT4.
 */
 static void statPush(
   sqlite3_context *context,
@@ -559,15 +583,17 @@ static void statPush(
 
   /* The three function arguments */
   Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
-  i64 rowid = sqlite3_value_int64(argv[1]);
-  int iChng = sqlite3_value_int(argv[2]);
+  int iChng = sqlite3_value_int(argv[1]);
 
   assert( p->nCol>1 );        /* Includes rowid field */
   assert( iChng<p->nCol );
 
-  /* p->current.anEq[0] is false the first time this function is called. */
-  if( p->current.anEq[0] ){
-
+  if( p->nRow==0 ){
+    /* anEq[0] is only zero for the very first call to this function.  Do
+    ** appropriate initialization */
+    for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
+  }else{
+    /* Second and subsequent calls get processed here */
     samplePushPrevious(p, iChng);
 
     /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
@@ -577,18 +603,17 @@ static void statPush(
     }
     for(i=iChng; i<p->nCol; i++){
       p->current.anDLt[i]++;
+#ifdef SQLITE_ENABLE_STAT34
       p->current.anLt[i] += p->current.anEq[i];
+#endif
       p->current.anEq[i] = 1;
     }
-
-  }else{
-    for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
-  }
-
-  if( IsStat4 || IsStat3 ){
-    p->current.iRowid = rowid;
-    p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
   }
+  p->nRow++;
+#ifdef SQLITE_ENABLE_STAT34
+  p->current.iRowid = sqlite3_value_int64(argv[2]);
+  p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
+#endif
 
 #ifdef SQLITE_ENABLE_STAT4
   {
@@ -613,7 +638,7 @@ static void statPush(
 #endif
 }
 static const FuncDef statPushFuncdef = {
-  3,               /* nArg */
+  2+IsStat34,      /* nArg */
   SQLITE_UTF8,     /* iPrefEnc */
   0,               /* flags */
   0,               /* pUserData */
@@ -749,7 +774,7 @@ static void statGet(
 #endif /* SQLITE_ENABLE_STAT34 */
 }
 static const FuncDef statGetFuncdef = {
-  2,               /* nArg */
+  1+IsStat34,      /* nArg */
   SQLITE_UTF8,     /* iPrefEnc */
   0,               /* flags */
   0,               /* pUserData */
@@ -771,7 +796,7 @@ static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
 #endif
   sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut);
   sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF);
-  sqlite3VdbeChangeP5(v, 1 + IsStat3 + IsStat4);
+  sqlite3VdbeChangeP5(v, 1 + IsStat34);
 }
 
 /*
@@ -797,8 +822,10 @@ static void analyzeOneTable(
   u8 needTableCnt = 1;         /* True to count the table */
   int regNewRowid = iMem++;    /* Rowid for the inserted record */
   int regStat4 = iMem++;       /* Register to hold Stat4Accum object */
-  int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
   int regChng = iMem++;        /* Index of changed index field */
+#ifdef SQLITE_ENABLE_STAT34
+  int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
+#endif
   int regTemp = iMem++;        /* Temporary use register */
   int regTabname = iMem++;     /* Register containing table name */
   int regIdxname = iMem++;     /* Register containing index name */
@@ -884,7 +911,7 @@ static void analyzeOneTable(
     **
     **  chng_addr_N:
     **   regRowid = idx(rowid)
-    **   stat_push(P, regRowid, regChng)
+    **   stat_push(P, regChng, regRowid)
     **   Next csr
     **   if !eof(csr) goto next_row;
     **
@@ -905,15 +932,18 @@ static void analyzeOneTable(
 
     /* Invoke the stat_init() function. The arguments are:
     ** 
-    **     * the number of rows in the index,
-    **     * the number of columns in the index including the rowid,
-    **     * the recommended number of samples for the stat3/stat4 table.
+    **    (1) the number of columns in the index including the rowid,
+    **    (2) the number of rows in the index,
+    **
+    ** The second argument is only used for STAT3 and STAT4
     */
-    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+1);
-    sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+2);
+#ifdef SQLITE_ENABLE_STAT34
+    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
+#endif
+    sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
     sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
     sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
-    sqlite3VdbeChangeP5(v, 2);
+    sqlite3VdbeChangeP5(v, 1+IsStat34);
 
     /* Implementation of the following:
     **
@@ -964,17 +994,20 @@ static void analyzeOneTable(
 
     /*
     **  chng_addr_N:
-    **   regRowid = idx(rowid)
-    **   stat_push(P, regRowid, regChng)
+    **   regRowid = idx(rowid)            // STAT34 only
+    **   stat_push(P, regChng, regRowid)  // 3rd parameter STAT34 only
     **   Next csr
     **   if !eof(csr) goto next_row;
     */
     sqlite3VdbeJumpHere(v, aGotoChng[nCol]);
+#ifdef SQLITE_ENABLE_STAT34
     sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
+    assert( regRowid==(regStat4+2) );
+#endif
+    assert( regChng==(regStat4+1) );
     sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
     sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
-    sqlite3VdbeChangeP5(v, 3);
-    assert( regRowid==(regStat4+1) && regChng==(regStat4+2) );
+    sqlite3VdbeChangeP5(v, 2+IsStat34);
     sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);
 
     /* Add the entry to the stat1 table. */
@@ -985,7 +1018,8 @@ static void analyzeOneTable(
     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
 
     /* Add the entries to the stat3 or stat4 table. */
-    if( IsStat3 || IsStat4 ){
+#ifdef SQLITE_ENABLE_STAT34
+    {
       int regEq = regStat1;
       int regLt = regStat1+1;
       int regDLt = regStat1+2;
@@ -1004,25 +1038,25 @@ static void analyzeOneTable(
       callStatGet(v, regStat4, STAT_GET_NLT, regLt);
       callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
       sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid);
-      if( IsStat3 ){
-        int iCol = pIdx->aiColumn[0];
-        sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regSample);
-      }else{
-        for(i=0; i<nCol; i++){
-          int iCol = pIdx->aiColumn[i];
-          sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
-        }
-        sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
+#ifdef SQLITE_ENABLE_STAT3
+      sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, 
+                                      pIdx->aiColumn[0], regSample);
+#else
+      for(i=0; i<nCol; i++){
+        int iCol = pIdx->aiColumn[i];
+        sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
       }
-
+      sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
+#endif
       sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
       sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
       sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
       sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
       sqlite3VdbeJumpHere(v, addrIsNull);
     }
+#endif /* SQLITE_ENABLE_STAT34 */
 
-    /* Jump here if the index is empty */
+    /* End of analysis */
     sqlite3VdbeJumpHere(v, addrRewind);
     sqlite3DbFree(db, aGotoChng);
   }
index d705bd750061aabd27e150be805d4c952703fec1..47d085ca93d6d66af6918b408c88c3414739c87e 100644 (file)
@@ -3056,7 +3056,6 @@ extern int sqlite3PendingByte;
 void sqlite3RootPageMoved(sqlite3*, int, int, int);
 void sqlite3Reindex(Parse*, Token*, Token*);
 void sqlite3AlterFunctions(void);
-void sqlite3AnalyzeFunctions(void);
 void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
 int sqlite3GetToken(const unsigned char *, int *);
 void sqlite3NestedParse(Parse*, const char*, ...);
@@ -3107,8 +3106,11 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
 void sqlite3BackupRestart(sqlite3_backup *);
 void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
 
+#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
+void sqlite3AnalyzeFunctions(void);
 int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
 void sqlite3Stat4ProbeFree(UnpackedRecord*);
+#endif
 
 /*
 ** The interface to the LEMON-generated parser