/ Check-in [9d1424c9]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Reduce the amount of code run and memory used for ANALYZE in the common case where neither STAT3 and STAT4 are enabled.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9d1424c91a21ed740aca53e437b8f7c1f0823c03
User & Date: drh 2013-08-27 20:16:48
Context
2013-08-27
23:15
Adjust ANALYZE for improved test coverage. Use the SQLITE_ENABLE_STAT3_OR_STAT4 macro (created in sqliteInt.h) to conditionally include code, instead of a boolean specifying both macros separately. check-in: 67a9a392 user: drh tags: trunk
20:16
Reduce the amount of code run and memory used for ANALYZE in the common case where neither STAT3 and STAT4 are enabled. check-in: 9d1424c9 user: drh tags: trunk
15:41
Update sqlite3.pc.in to use @PACKAGE_VERSION@ instead of @RELEASE@. check-in: 2460dfd8 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

     1      1   /*
     2         -** 2005 July 8
            2  +** 2005-07-08
     3      3   **
     4      4   ** The author disclaims copyright to this source code.  In place of
     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
................................................................................
    27     27   ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
    28     28   ** with SQLITE_ENABLE_STAT2.  The sqlite_stat2 table is deprecated.
    29     29   ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
    30     30   ** created and used by SQLite versions 3.7.9 and later and with
    31     31   ** SQLITE_ENABLE_STAT3 defined.  The functionality of sqlite_stat3
    32     32   ** is a superset of sqlite_stat2.  The sqlite_stat4 is an enhanced
    33     33   ** version of sqlite_stat3 and is only available when compiled with
    34         -** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later.
           34  +** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later.  It is
           35  +** not possible to enable both STAT3 and STAT4 at the same time.  If they
           36  +** are both enabled, then STAT4 is precedence.
    35     37   **
    36     38   ** For most applications, sqlite_stat1 provides all the statisics required
    37     39   ** for the query planner to make good choices.
    38     40   **
    39     41   ** Format of sqlite_stat1:
    40     42   **
    41     43   ** There is normally one row per index, with the index identified by the
................................................................................
   148    150   # define IsStat4     0
   149    151   # define IsStat3     1
   150    152   # define SQLITE_ENABLE_STAT34 1
   151    153   #else
   152    154   # define IsStat4     0
   153    155   # define IsStat3     0
   154    156   # undef SQLITE_ENABLE_STAT34
          157  +# undef SQLITE_STAT4_SAMPLES
          158  +# define SQLITE_STAT4_SAMPLES 1
   155    159   #endif
          160  +#define IsStat34    (IsStat3+IsStat4)  /* 1 for STAT3 or STAT4. 0 otherwise */
   156    161   
   157    162   /*
   158         -** This routine generates code that opens the sqlite_stat1 table for
   159         -** writing with cursor iStatCur. If the library was built with the
   160         -** SQLITE_ENABLE_STAT4 macro defined, then the sqlite_stat4 table is
   161         -** opened for writing using cursor (iStatCur+1)
          163  +** This routine generates code that opens the sqlite_statN tables.
          164  +** The sqlite_stat1 table is always relevant.  sqlite_stat2 is now
          165  +** obsolete.  sqlite_stat3 and sqlite_stat4 are only opened when
          166  +** appropriate compile-time options are provided.
   162    167   **
   163         -** If the sqlite_stat1 tables does not previously exist, it is created.
   164         -** Similarly, if the sqlite_stat4 table does not exist and the library
   165         -** is compiled with SQLITE_ENABLE_STAT4 defined, it is created. 
          168  +** If the sqlite_statN tables do not previously exist, it is created.
   166    169   **
   167    170   ** Argument zWhere may be a pointer to a buffer containing a table name,
   168    171   ** or it may be a NULL pointer. If it is not NULL, then all entries in
   169         -** the sqlite_stat1 and (if applicable) sqlite_stat4 tables associated
   170         -** with the named table are deleted. If zWhere==0, then code is generated
   171         -** to delete all stat table entries.
          172  +** the sqlite_statN tables associated with the named table are deleted.
          173  +** If zWhere==0, then code is generated to delete all stat table entries.
   172    174   */
   173    175   static void openStatTable(
   174    176     Parse *pParse,          /* Parsing context */
   175    177     int iDb,                /* The database we are looking in */
   176    178     int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
   177    179     const char *zWhere,     /* Delete entries for this table or index */
   178    180     const char *zWhereType  /* Either "tbl" or "idx" */
................................................................................
   184    186       { "sqlite_stat1", "tbl,idx,stat" },
   185    187   #if defined(SQLITE_ENABLE_STAT4)
   186    188       { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
   187    189       { "sqlite_stat3", 0 },
   188    190   #elif defined(SQLITE_ENABLE_STAT3)
   189    191       { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
   190    192       { "sqlite_stat4", 0 },
          193  +#else
          194  +    { "sqlite_stat3", 0 },
          195  +    { "sqlite_stat4", 0 },
   191    196   #endif
   192    197     };
   193         -
   194         -  int aRoot[] = {0, 0};
   195         -  u8 aCreateTbl[] = {0, 0};
   196         -
   197    198     int i;
   198    199     sqlite3 *db = pParse->db;
   199    200     Db *pDb;
   200    201     Vdbe *v = sqlite3GetVdbe(pParse);
          202  +  int aRoot[ArraySize(aTable)];
          203  +  u8 aCreateTbl[ArraySize(aTable)];
          204  +
   201    205     if( v==0 ) return;
   202    206     assert( sqlite3BtreeHoldsAllMutexes(db) );
   203    207     assert( sqlite3VdbeDb(v)==db );
   204    208     pDb = &db->aDb[iDb];
   205    209   
   206    210     /* Create new statistic tables if they do not exist, or clear them
   207    211     ** if they do already exist.
   208    212     */
   209    213     for(i=0; i<ArraySize(aTable); i++){
   210    214       const char *zTab = aTable[i].zName;
   211    215       Table *pStat;
   212    216       if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
   213    217         if( aTable[i].zCols ){
   214         -        /* The sqlite_stat[12] table does not exist. Create it. Note that a 
          218  +        /* The sqlite_statN table does not exist. Create it. Note that a 
   215    219           ** side-effect of the CREATE TABLE statement is to leave the rootpage 
   216    220           ** of the new table in register pParse->regRoot. This is important 
   217    221           ** because the OpenWrite opcode below will be needing it. */
   218    222           sqlite3NestedParse(pParse,
   219    223               "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
   220    224           );
   221    225           aRoot[i] = pParse->regRoot;
................................................................................
   222    226           aCreateTbl[i] = OPFLAG_P2ISREG;
   223    227         }
   224    228       }else{
   225    229         /* The table already exists. If zWhere is not NULL, delete all entries 
   226    230         ** associated with the table zWhere. If zWhere is NULL, delete the
   227    231         ** entire contents of the table. */
   228    232         aRoot[i] = pStat->tnum;
          233  +      aCreateTbl[i] = 0;
   229    234         sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
   230    235         if( zWhere ){
   231    236           sqlite3NestedParse(pParse,
   232    237              "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
   233    238           );
   234    239         }else{
   235    240           /* The sqlite_stat[134] table already exists.  Delete all rows. */
   236    241           sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
   237    242         }
   238    243       }
   239    244     }
   240    245   
   241    246     /* Open the sqlite_stat[134] tables for writing. */
   242         -  for(i=0; i<ArraySize(aRoot); i++){
   243         -    sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
   244         -    sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
   245         -    sqlite3VdbeChangeP5(v, aCreateTbl[i]);
   246         -    if( !IsStat3 && !IsStat4 ) break;
          247  +  for(i=0; i<ArraySize(aTable); i++){
          248  +    if( aTable[i].zCols ){
          249  +      sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
          250  +      sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
          251  +      sqlite3VdbeChangeP5(v, aCreateTbl[i]);
          252  +    }else{
          253  +      break;
          254  +    }
   247    255     }
   248    256   }
   249    257   
   250    258   /*
   251    259   ** Recommended number of samples for sqlite_stat4
   252    260   */
   253    261   #ifndef SQLITE_STAT4_SAMPLES
................................................................................
   258    266   ** Three SQL functions - stat_init(), stat_push(), and stat_get() -
   259    267   ** share an instance of the following structure to hold their state
   260    268   ** information.
   261    269   */
   262    270   typedef struct Stat4Accum Stat4Accum;
   263    271   typedef struct Stat4Sample Stat4Sample;
   264    272   struct Stat4Sample {
   265         -  i64 iRowid;                     /* Rowid in main table of the key */
   266    273     tRowcnt *anEq;                  /* sqlite_stat4.nEq */
          274  +  tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
          275  +#ifdef SQLITE_ENABLE_STAT34
   267    276     tRowcnt *anLt;                  /* sqlite_stat4.nLt */
   268         -  tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
          277  +  i64 iRowid;                     /* Rowid in main table of the key */
   269    278     u8 isPSample;                   /* True if a periodic sample */
   270    279     int iCol;                       /* If !isPSample, the reason for inclusion */
   271    280     u32 iHash;                      /* Tiebreaker hash */
          281  +#endif
   272    282   };                                                    
   273    283   struct Stat4Accum {
   274    284     tRowcnt nRow;             /* Number of rows in the entire table */
   275    285     tRowcnt nPSample;         /* How often to do a periodic sample */
   276    286     int nCol;                 /* Number of columns in index + rowid */
   277    287     int mxSample;             /* Maximum number of samples to accumulate */
   278    288     Stat4Sample current;      /* Current row as a Stat4Sample */
................................................................................
   281    291     int iMin;                 /* Index in a[] of entry with minimum score */
   282    292     int nSample;              /* Current number of samples */
   283    293     int iGet;                 /* Index of current sample accessed by stat_get() */
   284    294     Stat4Sample *a;           /* Array of mxSample Stat4Sample objects */
   285    295   };
   286    296   
   287    297   /*
   288         -** Implementation of the stat_init(C,N) SQL function. The two parameters
          298  +** Implementation of the stat_init(N,C) SQL function. The two parameters
   289    299   ** are the number of rows in the table or index (C) and the number of columns
   290         -** in the index (N).
          300  +** in the index (N).  The second argument (C) is only used for STAT3 and STAT4.
   291    301   **
   292    302   ** This routine allocates the Stat4Accum object in heap memory. The return 
   293    303   ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. 
   294    304   ** the size of the blob is sizeof(void*) bytes). 
   295    305   */
   296    306   static void statInit(
   297    307     sqlite3_context *context,
   298    308     int argc,
   299    309     sqlite3_value **argv
   300    310   ){
   301    311     Stat4Accum *p;
   302         -  u8 *pSpace;                     /* Allocated space not yet assigned */
   303         -  tRowcnt nRow;                   /* Number of rows in table (C) */
   304         -  int mxSample;                   /* Maximum number of samples collected */
   305    312     int nCol;                       /* Number of columns in index being sampled */
          313  +  int nColUp;                     /* nCol rounded up for alignment */
   306    314     int n;                          /* Bytes of space to allocate */
   307         -  int i;                          /* Used to iterate through p->aSample[] */
          315  +#ifdef SQLITE_ENABLE_STAT34
          316  +  int mxSample = SQLITE_STAT4_SAMPLES;
          317  +#endif
   308    318   
   309    319     /* Decode the three function arguments */
   310    320     UNUSED_PARAMETER(argc);
   311         -  nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
   312         -  mxSample = SQLITE_STAT4_SAMPLES;
   313         -  nCol = sqlite3_value_int(argv[1]);
          321  +  nCol = sqlite3_value_int(argv[0]);
   314    322     assert( nCol>1 );               /* >1 because it includes the rowid column */
          323  +  nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
   315    324   
   316    325     /* Allocate the space required for the Stat4Accum object */
   317    326     n = sizeof(*p) 
   318         -    + sizeof(tRowcnt)*nCol                    /* Stat4Accum.anEq */
   319         -    + sizeof(tRowcnt)*nCol                    /* Stat4Accum.anLt */
   320         -    + sizeof(tRowcnt)*nCol                    /* Stat4Accum.anDLt */
   321         -    + sizeof(Stat4Sample)*(nCol+mxSample)     /* Stat4Accum.aBest[], a[] */
   322         -    + sizeof(tRowcnt)*3*nCol*(nCol+mxSample);
          327  +    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anEq */
          328  +    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
          329  +#ifdef SQLITE_ENABLE_STAT34
          330  +    + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anLt */
          331  +    + sizeof(Stat4Sample)*(nCol+mxSample)   /* Stat4Accum.aBest[], a[] */
          332  +    + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
          333  +#endif
          334  +  ;
   323    335     p = sqlite3MallocZero(n);
   324    336     if( p==0 ){
   325    337       sqlite3_result_error_nomem(context);
   326    338       return;
   327    339     }
   328    340   
   329         -  p->nRow = nRow;
          341  +  p->nRow = 0;
   330    342     p->nCol = nCol;
   331         -  p->mxSample = mxSample;
   332         -  p->nPSample = p->nRow/(mxSample/3+1) + 1;
   333         -  p->iGet = -1;
   334         -
   335    343     p->current.anDLt = (tRowcnt*)&p[1];
   336         -  p->current.anEq = &p->current.anDLt[nCol];
   337         -  p->current.anLt = &p->current.anEq[nCol];
   338         -  sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
   339         -
   340         -  /* Set up the Stat4Accum.a[] and aBest[] arrays */
   341         -  p->a = (struct Stat4Sample*)&p->current.anLt[nCol];
   342         -  p->aBest = &p->a[mxSample];
   343         -  pSpace = (u8*)(&p->a[mxSample+nCol]);
   344         -  for(i=0; i<(mxSample+nCol); i++){
   345         -    p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
   346         -    p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
   347         -    p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nCol);
   348         -  }
   349         -  assert( (pSpace - (u8*)p)==n );
   350         -
   351         -  for(i=0; i<nCol; i++){
   352         -    p->aBest[i].iCol = i;
   353         -  }
          344  +  p->current.anEq = &p->current.anDLt[nColUp];
          345  +
          346  +#ifdef SQLITE_ENABLE_STAT34
          347  +  {
          348  +    u8 *pSpace;                     /* Allocated space not yet assigned */
          349  +    int i;                          /* Used to iterate through p->aSample[] */
          350  +
          351  +    p->iGet = -1;
          352  +    p->mxSample = mxSample;
          353  +    p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1;
          354  +    p->current.anLt = &p->current.anEq[nColUp];
          355  +    sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
          356  +  
          357  +    /* Set up the Stat4Accum.a[] and aBest[] arrays */
          358  +    p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
          359  +    p->aBest = &p->a[mxSample];
          360  +    pSpace = (u8*)(&p->a[mxSample+nCol]);
          361  +    for(i=0; i<(mxSample+nCol); i++){
          362  +      p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
          363  +      p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
          364  +      p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
          365  +    }
          366  +    assert( (pSpace - (u8*)p)==n );
          367  +  
          368  +    for(i=0; i<nCol; i++){
          369  +      p->aBest[i].iCol = i;
          370  +    }
          371  +  }
          372  +#endif
   354    373   
   355    374     /* Return a pointer to the allocated object to the caller */
   356    375     sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
   357    376   }
   358    377   static const FuncDef statInitFuncdef = {
   359         -  2,               /* nArg */
          378  +  1+IsStat34,      /* nArg */
   360    379     SQLITE_UTF8,     /* iPrefEnc */
   361    380     0,               /* flags */
   362    381     0,               /* pUserData */
   363    382     0,               /* pNext */
   364    383     statInit,        /* xFunc */
   365    384     0,               /* xStep */
   366    385     0,               /* xFinalize */
................................................................................
   540    559         sampleInsert(p, &p->current, 0);
   541    560       }
   542    561     }
   543    562   #endif
   544    563   }
   545    564   
   546    565   /*
   547         -** Implementation of the stat_push SQL function. 
          566  +** Implementation of the stat_push SQL function:  stat_push(P,R,C)
          567  +** Arguments:
   548    568   **
   549         -**    stat_push(P,R,C)
          569  +**    P     Pointer to the Stat4Accum object created by stat_init()
          570  +**    C     Index of left-most column to differ from previous row
          571  +**    R     Rowid for the current row
          572  +**
          573  +** The SQL function always returns NULL.
   550    574   **
   551         -** The return value is always NULL.
          575  +** The R parameter is only used for STAT3 and STAT4.
   552    576   */
   553    577   static void statPush(
   554    578     sqlite3_context *context,
   555    579     int argc,
   556    580     sqlite3_value **argv
   557    581   ){
   558    582     int i;
   559    583   
   560    584     /* The three function arguments */
   561    585     Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
   562         -  i64 rowid = sqlite3_value_int64(argv[1]);
   563         -  int iChng = sqlite3_value_int(argv[2]);
          586  +  int iChng = sqlite3_value_int(argv[1]);
   564    587   
   565    588     assert( p->nCol>1 );        /* Includes rowid field */
   566    589     assert( iChng<p->nCol );
   567    590   
   568         -  /* p->current.anEq[0] is false the first time this function is called. */
   569         -  if( p->current.anEq[0] ){
   570         -
          591  +  if( p->nRow==0 ){
          592  +    /* anEq[0] is only zero for the very first call to this function.  Do
          593  +    ** appropriate initialization */
          594  +    for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
          595  +  }else{
          596  +    /* Second and subsequent calls get processed here */
   571    597       samplePushPrevious(p, iChng);
   572    598   
   573    599       /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
   574    600       ** to the current row of the index. */
   575    601       for(i=0; i<iChng; i++){
   576    602         p->current.anEq[i]++;
   577    603       }
   578    604       for(i=iChng; i<p->nCol; i++){
   579    605         p->current.anDLt[i]++;
          606  +#ifdef SQLITE_ENABLE_STAT34
   580    607         p->current.anLt[i] += p->current.anEq[i];
          608  +#endif
   581    609         p->current.anEq[i] = 1;
   582    610       }
   583         -
   584         -  }else{
   585         -    for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
   586    611     }
   587         -
   588         -  if( IsStat4 || IsStat3 ){
   589         -    p->current.iRowid = rowid;
   590         -    p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
   591         -  }
          612  +  p->nRow++;
          613  +#ifdef SQLITE_ENABLE_STAT34
          614  +  p->current.iRowid = sqlite3_value_int64(argv[2]);
          615  +  p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
          616  +#endif
   592    617   
   593    618   #ifdef SQLITE_ENABLE_STAT4
   594    619     {
   595    620       tRowcnt nLt = p->current.anLt[p->nCol-1];
   596    621   
   597    622       /* Check if this is to be a periodic sample. If so, add it. */
   598    623       if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
................................................................................
   609    634           sampleCopy(p, &p->aBest[i], &p->current);
   610    635         }
   611    636       }
   612    637     }
   613    638   #endif
   614    639   }
   615    640   static const FuncDef statPushFuncdef = {
   616         -  3,               /* nArg */
          641  +  2+IsStat34,      /* nArg */
   617    642     SQLITE_UTF8,     /* iPrefEnc */
   618    643     0,               /* flags */
   619    644     0,               /* pUserData */
   620    645     0,               /* pNext */
   621    646     statPush,        /* xFunc */
   622    647     0,               /* xStep */
   623    648     0,               /* xFinalize */
................................................................................
   745    770           sqlite3_result_text(context, zRet, -1, sqlite3_free);
   746    771         }
   747    772       }
   748    773     }
   749    774   #endif /* SQLITE_ENABLE_STAT34 */
   750    775   }
   751    776   static const FuncDef statGetFuncdef = {
   752         -  2,               /* nArg */
          777  +  1+IsStat34,      /* nArg */
   753    778     SQLITE_UTF8,     /* iPrefEnc */
   754    779     0,               /* flags */
   755    780     0,               /* pUserData */
   756    781     0,               /* pNext */
   757    782     statGet,         /* xFunc */
   758    783     0,               /* xStep */
   759    784     0,               /* xFinalize */
................................................................................
   767    792   #ifdef SQLITE_ENABLE_STAT34
   768    793     sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
   769    794   #else
   770    795     assert( iParam==STAT_GET_STAT1 );
   771    796   #endif
   772    797     sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut);
   773    798     sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF);
   774         -  sqlite3VdbeChangeP5(v, 1 + IsStat3 + IsStat4);
          799  +  sqlite3VdbeChangeP5(v, 1 + IsStat34);
   775    800   }
   776    801   
   777    802   /*
   778    803   ** Generate code to do an analysis of all indices associated with
   779    804   ** a single table.
   780    805   */
   781    806   static void analyzeOneTable(
................................................................................
   793    818     Vdbe *v;                     /* The virtual machine being built up */
   794    819     int i;                       /* Loop counter */
   795    820     int jZeroRows = -1;          /* Jump from here if number of rows is zero */
   796    821     int iDb;                     /* Index of database containing pTab */
   797    822     u8 needTableCnt = 1;         /* True to count the table */
   798    823     int regNewRowid = iMem++;    /* Rowid for the inserted record */
   799    824     int regStat4 = iMem++;       /* Register to hold Stat4Accum object */
   800         -  int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
   801    825     int regChng = iMem++;        /* Index of changed index field */
          826  +#ifdef SQLITE_ENABLE_STAT34
          827  +  int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
          828  +#endif
   802    829     int regTemp = iMem++;        /* Temporary use register */
   803    830     int regTabname = iMem++;     /* Register containing table name */
   804    831     int regIdxname = iMem++;     /* Register containing index name */
   805    832     int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
   806    833     int regPrev = iMem;          /* MUST BE LAST (see below) */
   807    834   
   808    835     pParse->nMem = MAX(pParse->nMem, iMem);
................................................................................
   880    907       **   regPrev(0) = idx(0)
   881    908       **  chng_addr_1:
   882    909       **   regPrev(1) = idx(1)
   883    910       **  ...
   884    911       **
   885    912       **  chng_addr_N:
   886    913       **   regRowid = idx(rowid)
   887         -    **   stat_push(P, regRowid, regChng)
          914  +    **   stat_push(P, regChng, regRowid)
   888    915       **   Next csr
   889    916       **   if !eof(csr) goto next_row;
   890    917       **
   891    918       **  end_of_scan:
   892    919       */
   893    920   
   894    921       /* Make sure there are enough memory cells allocated to accommodate 
................................................................................
   901    928       assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
   902    929       sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb);
   903    930       sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); 
   904    931       VdbeComment((v, "%s", pIdx->zName));
   905    932   
   906    933       /* Invoke the stat_init() function. The arguments are:
   907    934       ** 
   908         -    **     * the number of rows in the index,
   909         -    **     * the number of columns in the index including the rowid,
   910         -    **     * the recommended number of samples for the stat3/stat4 table.
          935  +    **    (1) the number of columns in the index including the rowid,
          936  +    **    (2) the number of rows in the index,
          937  +    **
          938  +    ** The second argument is only used for STAT3 and STAT4
   911    939       */
   912         -    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+1);
   913         -    sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+2);
          940  +#ifdef SQLITE_ENABLE_STAT34
          941  +    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
          942  +#endif
          943  +    sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
   914    944       sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
   915    945       sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
   916         -    sqlite3VdbeChangeP5(v, 2);
          946  +    sqlite3VdbeChangeP5(v, 1+IsStat34);
   917    947   
   918    948       /* Implementation of the following:
   919    949       **
   920    950       **   Rewind csr
   921    951       **   if eof(csr) goto end_of_scan;
   922    952       **   regChng = 0
   923    953       **   goto next_push_0;
................................................................................
   960    990       for(i=0; i<nCol; i++){
   961    991         sqlite3VdbeJumpHere(v, aGotoChng[i]);
   962    992         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
   963    993       }
   964    994   
   965    995       /*
   966    996       **  chng_addr_N:
   967         -    **   regRowid = idx(rowid)
   968         -    **   stat_push(P, regRowid, regChng)
          997  +    **   regRowid = idx(rowid)            // STAT34 only
          998  +    **   stat_push(P, regChng, regRowid)  // 3rd parameter STAT34 only
   969    999       **   Next csr
   970   1000       **   if !eof(csr) goto next_row;
   971   1001       */
   972   1002       sqlite3VdbeJumpHere(v, aGotoChng[nCol]);
         1003  +#ifdef SQLITE_ENABLE_STAT34
   973   1004       sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
         1005  +    assert( regRowid==(regStat4+2) );
         1006  +#endif
         1007  +    assert( regChng==(regStat4+1) );
   974   1008       sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
   975   1009       sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
   976         -    sqlite3VdbeChangeP5(v, 3);
   977         -    assert( regRowid==(regStat4+1) && regChng==(regStat4+2) );
         1010  +    sqlite3VdbeChangeP5(v, 2+IsStat34);
   978   1011       sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);
   979   1012   
   980   1013       /* Add the entry to the stat1 table. */
   981   1014       callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
   982   1015       sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
   983   1016       sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
   984   1017       sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
   985   1018       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
   986   1019   
   987   1020       /* Add the entries to the stat3 or stat4 table. */
   988         -    if( IsStat3 || IsStat4 ){
         1021  +#ifdef SQLITE_ENABLE_STAT34
         1022  +    {
   989   1023         int regEq = regStat1;
   990   1024         int regLt = regStat1+1;
   991   1025         int regDLt = regStat1+2;
   992   1026         int regSample = regStat1+3;
   993   1027         int regCol = regStat1+4;
   994   1028         int regSampleRowid = regCol + nCol;
   995   1029         int addrNext;
................................................................................
  1000   1034         addrNext = sqlite3VdbeCurrentAddr(v);
  1001   1035         callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
  1002   1036         addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
  1003   1037         callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
  1004   1038         callStatGet(v, regStat4, STAT_GET_NLT, regLt);
  1005   1039         callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
  1006   1040         sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid);
  1007         -      if( IsStat3 ){
  1008         -        int iCol = pIdx->aiColumn[0];
  1009         -        sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regSample);
  1010         -      }else{
  1011         -        for(i=0; i<nCol; i++){
  1012         -          int iCol = pIdx->aiColumn[i];
  1013         -          sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
  1014         -        }
  1015         -        sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
         1041  +#ifdef SQLITE_ENABLE_STAT3
         1042  +      sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, 
         1043  +                                      pIdx->aiColumn[0], regSample);
         1044  +#else
         1045  +      for(i=0; i<nCol; i++){
         1046  +        int iCol = pIdx->aiColumn[i];
         1047  +        sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
  1016   1048         }
  1017         -
         1049  +      sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
         1050  +#endif
  1018   1051         sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
  1019   1052         sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
  1020   1053         sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
  1021   1054         sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
  1022   1055         sqlite3VdbeJumpHere(v, addrIsNull);
  1023   1056       }
         1057  +#endif /* SQLITE_ENABLE_STAT34 */
  1024   1058   
  1025         -    /* Jump here if the index is empty */
         1059  +    /* End of analysis */
  1026   1060       sqlite3VdbeJumpHere(v, addrRewind);
  1027   1061       sqlite3DbFree(db, aGotoChng);
  1028   1062     }
  1029   1063   
  1030   1064   
  1031   1065     /* Create a single sqlite_stat1 entry containing NULL as the index
  1032   1066     ** name and the row count as the content.

Changes to src/sqliteInt.h.

  3052   3052   #ifndef SQLITE_OMIT_WSD
  3053   3053   extern int sqlite3PendingByte;
  3054   3054   #endif
  3055   3055   #endif
  3056   3056   void sqlite3RootPageMoved(sqlite3*, int, int, int);
  3057   3057   void sqlite3Reindex(Parse*, Token*, Token*);
  3058   3058   void sqlite3AlterFunctions(void);
  3059         -void sqlite3AnalyzeFunctions(void);
  3060   3059   void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
  3061   3060   int sqlite3GetToken(const unsigned char *, int *);
  3062   3061   void sqlite3NestedParse(Parse*, const char*, ...);
  3063   3062   void sqlite3ExpirePreparedStatements(sqlite3*);
  3064   3063   int sqlite3CodeSubselect(Parse *, Expr *, int, int);
  3065   3064   void sqlite3SelectPrep(Parse*, Select*, NameContext*);
  3066   3065   int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
................................................................................
  3103   3102   void sqlite3StrAccumReset(StrAccum*);
  3104   3103   void sqlite3SelectDestInit(SelectDest*,int,int);
  3105   3104   Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
  3106   3105   
  3107   3106   void sqlite3BackupRestart(sqlite3_backup *);
  3108   3107   void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
  3109   3108   
         3109  +#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
         3110  +void sqlite3AnalyzeFunctions(void);
  3110   3111   int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
  3111   3112   void sqlite3Stat4ProbeFree(UnpackedRecord*);
         3113  +#endif
  3112   3114   
  3113   3115   /*
  3114   3116   ** The interface to the LEMON-generated parser
  3115   3117   */
  3116   3118   void *sqlite3ParserAlloc(void*(*)(size_t));
  3117   3119   void sqlite3ParserFree(void*, void(*)(void*));
  3118   3120   void sqlite3Parser(void*, int, Token, Parse*);