/ Changes On Branch omit-stat3
Login

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

Changes In Branch omit-stat3 Excluding Merge-Ins

This is equivalent to a diff from 30e6ee27a9 to 845d2f17de

2019-08-08
19:19
Remove support for SQLITE_ENABLE_STAT3. The sqlite_stat3 table is now ignored, if it exists. Run ANALYZE using STAT4 to get the equivalent functionality, which presumably everybody has been doing for a long time now. (check-in: f1cd234c98 user: drh tags: trunk)
18:49
Fix a case of the Expr.affinity to Expr.affExpr refactor that was missed in the [a29f2a7d07beff64] check-in. (check-in: 83450d1070 user: drh tags: trunk)
16:23
More legacy STAT3 code removed. (Closed-Leaf check-in: 845d2f17de user: drh tags: omit-stat3)
15:24
Remove support for STAT3. The sqlite_stat3 tables are ignored, if they exist. STAT4 continues to work as it always has, and as it is a superset of STAT3 is the recommended replacement. (check-in: 1e17ea2fd1 user: drh tags: omit-stat3)
01:39
Remove a NEVER() that is reachable from a corrupt database. (check-in: 30e6ee27a9 user: drh tags: trunk)
2019-08-07
19:57
Remove use of the affinity() function from view.test, as it is only available in SQLITE_DEBUG builds. (check-in: 7f2246a17b user: dan tags: trunk)

Changes to src/analyze.c.

    23     23   **    CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample);
    24     24   **
    25     25   ** Additional tables might be added in future releases of SQLite.
    26     26   ** The sqlite_stat2 table is not created or used unless the SQLite version
    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         -** created and used by SQLite versions 3.7.9 and later and with
           30  +** created and used by SQLite versions 3.7.9 through 3.29.0 when
    31     31   ** SQLITE_ENABLE_STAT3 defined.  The functionality of sqlite_stat3
    32         -** is a superset of sqlite_stat2.  The sqlite_stat4 is an enhanced
    33         -** version of sqlite_stat3 and is only available when compiled with
    34         -** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.1 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 takes precedence.
           32  +** is a superset of sqlite_stat2 and is also now deprecated.  The
           33  +** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only 
           34  +** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite
           35  +** versions 3.8.1 and later.  STAT4 is the only variant that is still
           36  +** supported.
    37     37   **
    38     38   ** For most applications, sqlite_stat1 provides all the statistics required
    39     39   ** for the query planner to make good choices.
    40     40   **
    41     41   ** Format of sqlite_stat1:
    42     42   **
    43     43   ** There is normally one row per index, with the index identified by the
................................................................................
   140    140   ** integer in the equivalent columns in sqlite_stat4.
   141    141   */
   142    142   #ifndef SQLITE_OMIT_ANALYZE
   143    143   #include "sqliteInt.h"
   144    144   
   145    145   #if defined(SQLITE_ENABLE_STAT4)
   146    146   # define IsStat4     1
   147         -# define IsStat3     0
   148         -#elif defined(SQLITE_ENABLE_STAT3)
   149         -# define IsStat4     0
   150         -# define IsStat3     1
   151    147   #else
   152    148   # define IsStat4     0
   153         -# define IsStat3     0
   154    149   # undef SQLITE_STAT4_SAMPLES
   155    150   # define SQLITE_STAT4_SAMPLES 1
   156    151   #endif
   157         -#define IsStat34    (IsStat3+IsStat4)  /* 1 for STAT3 or STAT4. 0 otherwise */
   158    152   
   159    153   /*
   160    154   ** This routine generates code that opens the sqlite_statN tables.
   161    155   ** The sqlite_stat1 table is always relevant.  sqlite_stat2 is now
   162    156   ** obsolete.  sqlite_stat3 and sqlite_stat4 are only opened when
   163    157   ** appropriate compile-time options are provided.
   164    158   **
................................................................................
   179    173     static const struct {
   180    174       const char *zName;
   181    175       const char *zCols;
   182    176     } aTable[] = {
   183    177       { "sqlite_stat1", "tbl,idx,stat" },
   184    178   #if defined(SQLITE_ENABLE_STAT4)
   185    179       { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
   186         -    { "sqlite_stat3", 0 },
   187         -#elif defined(SQLITE_ENABLE_STAT3)
   188         -    { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
   189         -    { "sqlite_stat4", 0 },
   190    180   #else
   191         -    { "sqlite_stat3", 0 },
   192    181       { "sqlite_stat4", 0 },
   193    182   #endif
          183  +    { "sqlite_stat3", 0 },
   194    184     };
   195    185     int i;
   196    186     sqlite3 *db = pParse->db;
   197    187     Db *pDb;
   198    188     Vdbe *v = sqlite3GetVdbe(pParse);
   199    189     int aRoot[ArraySize(aTable)];
   200    190     u8 aCreateTbl[ArraySize(aTable)];
................................................................................
   267    257   ** information.
   268    258   */
   269    259   typedef struct Stat4Accum Stat4Accum;
   270    260   typedef struct Stat4Sample Stat4Sample;
   271    261   struct Stat4Sample {
   272    262     tRowcnt *anEq;                  /* sqlite_stat4.nEq */
   273    263     tRowcnt *anDLt;                 /* sqlite_stat4.nDLt */
   274         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          264  +#ifdef SQLITE_ENABLE_STAT4
   275    265     tRowcnt *anLt;                  /* sqlite_stat4.nLt */
   276    266     union {
   277    267       i64 iRowid;                     /* Rowid in main table of the key */
   278    268       u8 *aRowid;                     /* Key for WITHOUT ROWID tables */
   279    269     } u;
   280    270     u32 nRowid;                     /* Sizeof aRowid[] */
   281    271     u8 isPSample;                   /* True if a periodic sample */
................................................................................
   298    288     int iGet;                 /* Index of current sample accessed by stat_get() */
   299    289     Stat4Sample *a;           /* Array of mxSample Stat4Sample objects */
   300    290     sqlite3 *db;              /* Database connection, for malloc() */
   301    291   };
   302    292   
   303    293   /* Reclaim memory used by a Stat4Sample
   304    294   */
   305         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          295  +#ifdef SQLITE_ENABLE_STAT4
   306    296   static void sampleClear(sqlite3 *db, Stat4Sample *p){
   307    297     assert( db!=0 );
   308    298     if( p->nRowid ){
   309    299       sqlite3DbFree(db, p->u.aRowid);
   310    300       p->nRowid = 0;
   311    301     }
   312    302   }
   313    303   #endif
   314    304   
   315    305   /* Initialize the BLOB value of a ROWID
   316    306   */
   317         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          307  +#ifdef SQLITE_ENABLE_STAT4
   318    308   static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
   319    309     assert( db!=0 );
   320    310     if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
   321    311     p->u.aRowid = sqlite3DbMallocRawNN(db, n);
   322    312     if( p->u.aRowid ){
   323    313       p->nRowid = n;
   324    314       memcpy(p->u.aRowid, pData, n);
................................................................................
   326    316       p->nRowid = 0;
   327    317     }
   328    318   }
   329    319   #endif
   330    320   
   331    321   /* Initialize the INTEGER value of a ROWID.
   332    322   */
   333         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          323  +#ifdef SQLITE_ENABLE_STAT4
   334    324   static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
   335    325     assert( db!=0 );
   336    326     if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
   337    327     p->nRowid = 0;
   338    328     p->u.iRowid = iRowid;
   339    329   }
   340    330   #endif
   341    331   
   342    332   
   343    333   /*
   344    334   ** Copy the contents of object (*pFrom) into (*pTo).
   345    335   */
   346         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          336  +#ifdef SQLITE_ENABLE_STAT4
   347    337   static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
   348    338     pTo->isPSample = pFrom->isPSample;
   349    339     pTo->iCol = pFrom->iCol;
   350    340     pTo->iHash = pFrom->iHash;
   351    341     memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
   352    342     memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
   353    343     memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
................................................................................
   360    350   #endif
   361    351   
   362    352   /*
   363    353   ** Reclaim all memory of a Stat4Accum structure.
   364    354   */
   365    355   static void stat4Destructor(void *pOld){
   366    356     Stat4Accum *p = (Stat4Accum*)pOld;
   367         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          357  +#ifdef SQLITE_ENABLE_STAT4
   368    358     int i;
   369    359     for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
   370    360     for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
   371    361     sampleClear(p->db, &p->current);
   372    362   #endif
   373    363     sqlite3DbFree(p->db, p);
   374    364   }
................................................................................
   380    370   **     K:    The number of columns in the index excluding the rowid/pk.
   381    371   **     C:    The number of rows in the index (note 2)
   382    372   **
   383    373   ** Note 1:  In the special case of the covering index that implements a
   384    374   ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
   385    375   ** total number of columns in the table.
   386    376   **
   387         -** Note 2:  C is only used for STAT3 and STAT4.
          377  +** Note 2:  C is only used for STAT4.
   388    378   **
   389    379   ** For indexes on ordinary rowid tables, N==K+1.  But for indexes on
   390    380   ** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
   391    381   ** PRIMARY KEY of the table.  The covering index that implements the
   392    382   ** original WITHOUT ROWID table as N==K as a special case.
   393    383   **
   394    384   ** This routine allocates the Stat4Accum object in heap memory. The return 
................................................................................
   403    393   ){
   404    394     Stat4Accum *p;
   405    395     int nCol;                       /* Number of columns in index being sampled */
   406    396     int nKeyCol;                    /* Number of key columns */
   407    397     int nColUp;                     /* nCol rounded up for alignment */
   408    398     int n;                          /* Bytes of space to allocate */
   409    399     sqlite3 *db;                    /* Database connection */
   410         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          400  +#ifdef SQLITE_ENABLE_STAT4
   411    401     int mxSample = SQLITE_STAT4_SAMPLES;
   412    402   #endif
   413    403   
   414    404     /* Decode the three function arguments */
   415    405     UNUSED_PARAMETER(argc);
   416    406     nCol = sqlite3_value_int(argv[0]);
   417    407     assert( nCol>0 );
................................................................................
   420    410     assert( nKeyCol<=nCol );
   421    411     assert( nKeyCol>0 );
   422    412   
   423    413     /* Allocate the space required for the Stat4Accum object */
   424    414     n = sizeof(*p) 
   425    415       + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anEq */
   426    416       + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anDLt */
   427         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          417  +#ifdef SQLITE_ENABLE_STAT4
   428    418       + sizeof(tRowcnt)*nColUp                  /* Stat4Accum.anLt */
   429    419       + sizeof(Stat4Sample)*(nCol+mxSample)     /* Stat4Accum.aBest[], a[] */
   430    420       + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
   431    421   #endif
   432    422     ;
   433    423     db = sqlite3_context_db_handle(context);
   434    424     p = sqlite3DbMallocZero(db, n);
................................................................................
   440    430     p->db = db;
   441    431     p->nRow = 0;
   442    432     p->nCol = nCol;
   443    433     p->nKeyCol = nKeyCol;
   444    434     p->current.anDLt = (tRowcnt*)&p[1];
   445    435     p->current.anEq = &p->current.anDLt[nColUp];
   446    436   
   447         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          437  +#ifdef SQLITE_ENABLE_STAT4
   448    438     {
   449    439       u8 *pSpace;                     /* Allocated space not yet assigned */
   450    440       int i;                          /* Used to iterate through p->aSample[] */
   451    441   
   452    442       p->iGet = -1;
   453    443       p->mxSample = mxSample;
   454    444       p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
................................................................................
   475    465     /* Return a pointer to the allocated object to the caller.  Note that
   476    466     ** only the pointer (the 2nd parameter) matters.  The size of the object
   477    467     ** (given by the 3rd parameter) is never used and can be any positive
   478    468     ** value. */
   479    469     sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
   480    470   }
   481    471   static const FuncDef statInitFuncdef = {
   482         -  2+IsStat34,      /* nArg */
          472  +  2+IsStat4,       /* nArg */
   483    473     SQLITE_UTF8,     /* funcFlags */
   484    474     0,               /* pUserData */
   485    475     0,               /* pNext */
   486    476     statInit,        /* xSFunc */
   487    477     0,               /* xFinalize */
   488    478     0, 0,            /* xValue, xInverse */
   489    479     "stat_init",     /* zName */
................................................................................
   515    505       if( pNew->anEq[i]<pOld->anEq[i] ) return 0;
   516    506     }
   517    507     if( pNew->iHash>pOld->iHash ) return 1;
   518    508     return 0;
   519    509   }
   520    510   #endif
   521    511   
   522         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          512  +#ifdef SQLITE_ENABLE_STAT4
   523    513   /*
   524    514   ** Return true if pNew is to be preferred over pOld.
   525    515   **
   526    516   ** This function assumes that for each argument sample, the contents of
   527    517   ** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. 
   528    518   */
   529    519   static int sampleIsBetter(
................................................................................
   534    524     tRowcnt nEqNew = pNew->anEq[pNew->iCol];
   535    525     tRowcnt nEqOld = pOld->anEq[pOld->iCol];
   536    526   
   537    527     assert( pOld->isPSample==0 && pNew->isPSample==0 );
   538    528     assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );
   539    529   
   540    530     if( (nEqNew>nEqOld) ) return 1;
   541         -#ifdef SQLITE_ENABLE_STAT4
   542    531     if( nEqNew==nEqOld ){
   543    532       if( pNew->iCol<pOld->iCol ) return 1;
   544    533       return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));
   545    534     }
   546    535     return 0;
   547         -#else
   548         -  return (nEqNew==nEqOld && pNew->iHash>pOld->iHash);
   549         -#endif
   550    536   }
   551    537   
   552    538   /*
   553    539   ** Copy the contents of sample *pNew into the p->a[] array. If necessary,
   554    540   ** remove the least desirable sample from p->a[] to make room.
   555    541   */
   556    542   static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
   557    543     Stat4Sample *pSample = 0;
   558    544     int i;
   559    545   
   560    546     assert( IsStat4 || nEqZero==0 );
   561    547   
   562         -#ifdef SQLITE_ENABLE_STAT4
   563    548     /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
   564    549     ** values in the anEq[] array of any sample in Stat4Accum.a[]. In
   565    550     ** other words, if nMaxEqZero is n, then it is guaranteed that there
   566    551     ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
   567    552     if( nEqZero>p->nMaxEqZero ){
   568    553       p->nMaxEqZero = nEqZero;
   569    554     }
................................................................................
   589    574       }
   590    575       if( pUpgrade ){
   591    576         pUpgrade->iCol = pNew->iCol;
   592    577         pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol];
   593    578         goto find_new_min;
   594    579       }
   595    580     }
   596         -#endif
   597    581   
   598    582     /* If necessary, remove sample iMin to make room for the new sample. */
   599    583     if( p->nSample>=p->mxSample ){
   600    584       Stat4Sample *pMin = &p->a[p->iMin];
   601    585       tRowcnt *anEq = pMin->anEq;
   602    586       tRowcnt *anLt = pMin->anLt;
   603    587       tRowcnt *anDLt = pMin->anDLt;
................................................................................
   610    594       pSample->anLt = anLt;
   611    595       p->nSample = p->mxSample-1;
   612    596     }
   613    597   
   614    598     /* The "rows less-than" for the rowid column must be greater than that
   615    599     ** for the last sample in the p->a[] array. Otherwise, the samples would
   616    600     ** be out of order. */
   617         -#ifdef SQLITE_ENABLE_STAT4
   618    601     assert( p->nSample==0 
   619    602          || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
   620         -#endif
   621    603   
   622    604     /* Insert the new sample */
   623    605     pSample = &p->a[p->nSample];
   624    606     sampleCopy(p, pSample, pNew);
   625    607     p->nSample++;
   626    608   
   627    609     /* Zero the first nEqZero entries in the anEq[] array. */
   628    610     memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);
   629    611   
   630         -#ifdef SQLITE_ENABLE_STAT4
   631         - find_new_min:
   632         -#endif
          612  +find_new_min:
   633    613     if( p->nSample>=p->mxSample ){
   634    614       int iMin = -1;
   635    615       for(i=0; i<p->mxSample; i++){
   636    616         if( p->a[i].isPSample ) continue;
   637    617         if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){
   638    618           iMin = i;
   639    619         }
   640    620       }
   641    621       assert( iMin>=0 );
   642    622       p->iMin = iMin;
   643    623     }
   644    624   }
   645         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
          625  +#endif /* SQLITE_ENABLE_STAT4 */
   646    626   
   647    627   /*
   648    628   ** Field iChng of the index being scanned has changed. So at this point
   649    629   ** p->current contains a sample that reflects the previous row of the
   650    630   ** index. The value of anEq[iChng] and subsequent anEq[] elements are
   651    631   ** correct at this point.
   652    632   */
................................................................................
   679    659           if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
   680    660         }
   681    661       }
   682    662       p->nMaxEqZero = iChng;
   683    663     }
   684    664   #endif
   685    665   
   686         -#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
   687         -  if( iChng==0 ){
   688         -    tRowcnt nLt = p->current.anLt[0];
   689         -    tRowcnt nEq = p->current.anEq[0];
   690         -
   691         -    /* Check if this is to be a periodic sample. If so, add it. */
   692         -    if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){
   693         -      p->current.isPSample = 1;
   694         -      sampleInsert(p, &p->current, 0);
   695         -      p->current.isPSample = 0;
   696         -    }else 
   697         -
   698         -    /* Or if it is a non-periodic sample. Add it in this case too. */
   699         -    if( p->nSample<p->mxSample 
   700         -     || sampleIsBetter(p, &p->current, &p->a[p->iMin]) 
   701         -    ){
   702         -      sampleInsert(p, &p->current, 0);
   703         -    }
   704         -  }
   705         -#endif
   706         -
   707         -#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
          666  +#ifndef SQLITE_ENABLE_STAT4
   708    667     UNUSED_PARAMETER( p );
   709    668     UNUSED_PARAMETER( iChng );
   710    669   #endif
   711    670   }
   712    671   
   713    672   /*
   714    673   ** Implementation of the stat_push SQL function:  stat_push(P,C,R)
................................................................................
   720    679   **          WITHOUT ROWID tables.
   721    680   **
   722    681   ** This SQL function always returns NULL.  It's purpose it to accumulate
   723    682   ** statistical data and/or samples in the Stat4Accum object about the
   724    683   ** index being analyzed.  The stat_get() SQL function will later be used to
   725    684   ** extract relevant information for constructing the sqlite_statN tables.
   726    685   **
   727         -** The R parameter is only used for STAT3 and STAT4
          686  +** The R parameter is only used for STAT4
   728    687   */
   729    688   static void statPush(
   730    689     sqlite3_context *context,
   731    690     int argc,
   732    691     sqlite3_value **argv
   733    692   ){
   734    693     int i;
................................................................................
   752    711       /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
   753    712       ** to the current row of the index. */
   754    713       for(i=0; i<iChng; i++){
   755    714         p->current.anEq[i]++;
   756    715       }
   757    716       for(i=iChng; i<p->nCol; i++){
   758    717         p->current.anDLt[i]++;
   759         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          718  +#ifdef SQLITE_ENABLE_STAT4
   760    719         p->current.anLt[i] += p->current.anEq[i];
   761    720   #endif
   762    721         p->current.anEq[i] = 1;
   763    722       }
   764    723     }
   765    724     p->nRow++;
   766         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          725  +#ifdef SQLITE_ENABLE_STAT4
   767    726     if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
   768    727       sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
   769    728     }else{
   770    729       sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
   771    730                                          sqlite3_value_blob(argv[2]));
   772    731     }
   773    732     p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
................................................................................
   792    751           sampleCopy(p, &p->aBest[i], &p->current);
   793    752         }
   794    753       }
   795    754     }
   796    755   #endif
   797    756   }
   798    757   static const FuncDef statPushFuncdef = {
   799         -  2+IsStat34,      /* nArg */
          758  +  2+IsStat4,       /* nArg */
   800    759     SQLITE_UTF8,     /* funcFlags */
   801    760     0,               /* pUserData */
   802    761     0,               /* pNext */
   803    762     statPush,        /* xSFunc */
   804    763     0,               /* xFinalize */
   805    764     0, 0,            /* xValue, xInverse */
   806    765     "stat_push",     /* zName */
................................................................................
   823    782   **
   824    783   ** The stat_get(P,J) function is not available to generic SQL.  It is
   825    784   ** inserted as part of a manually constructed bytecode program.  (See
   826    785   ** the callStatGet() routine below.)  It is guaranteed that the P
   827    786   ** parameter will always be a poiner to a Stat4Accum object, never a
   828    787   ** NULL.
   829    788   **
   830         -** If neither STAT3 nor STAT4 are enabled, then J is always
          789  +** If STAT4 is not enabled, then J is always
   831    790   ** STAT_GET_STAT1 and is hence omitted and this routine becomes
   832    791   ** a one-parameter function, stat_get(P), that always returns the
   833    792   ** stat1 table entry information.
   834    793   */
   835    794   static void statGet(
   836    795     sqlite3_context *context,
   837    796     int argc,
   838    797     sqlite3_value **argv
   839    798   ){
   840    799     Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
   841         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   842         -  /* STAT3 and STAT4 have a parameter on this routine. */
          800  +#ifdef SQLITE_ENABLE_STAT4
          801  +  /* STAT4 has a parameter on this routine. */
   843    802     int eCall = sqlite3_value_int(argv[1]);
   844    803     assert( argc==2 );
   845    804     assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ 
   846    805          || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
   847    806          || eCall==STAT_GET_NDLT 
   848    807     );
   849    808     if( eCall==STAT_GET_STAT1 )
................................................................................
   890    849         z += sqlite3Strlen30(z);
   891    850         assert( p->current.anEq[i] );
   892    851       }
   893    852       assert( z[0]=='\0' && z>zRet );
   894    853   
   895    854       sqlite3_result_text(context, zRet, -1, sqlite3_free);
   896    855     }
   897         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          856  +#ifdef SQLITE_ENABLE_STAT4
   898    857     else if( eCall==STAT_GET_ROWID ){
   899    858       if( p->iGet<0 ){
   900    859         samplePushPrevious(p, 0);
   901    860         p->iGet = 0;
   902    861       }
   903    862       if( p->iGet<p->nSample ){
   904    863         Stat4Sample *pS = p->a + p->iGet;
................................................................................
   919    878         default: {
   920    879           aCnt = p->a[p->iGet].anDLt; 
   921    880           p->iGet++;
   922    881           break;
   923    882         }
   924    883       }
   925    884   
   926         -    if( IsStat3 ){
   927         -      sqlite3_result_int64(context, (i64)aCnt[0]);
   928         -    }else{
          885  +    {
   929    886         char *zRet = sqlite3MallocZero(p->nCol * 25);
   930    887         if( zRet==0 ){
   931    888           sqlite3_result_error_nomem(context);
   932    889         }else{
   933    890           int i;
   934    891           char *z = zRet;
   935    892           for(i=0; i<p->nCol; i++){
................................................................................
   938    895           }
   939    896           assert( z[0]=='\0' && z>zRet );
   940    897           z[-1] = '\0';
   941    898           sqlite3_result_text(context, zRet, -1, sqlite3_free);
   942    899         }
   943    900       }
   944    901     }
   945         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
          902  +#endif /* SQLITE_ENABLE_STAT4 */
   946    903   #ifndef SQLITE_DEBUG
   947    904     UNUSED_PARAMETER( argc );
   948    905   #endif
   949    906   }
   950    907   static const FuncDef statGetFuncdef = {
   951         -  1+IsStat34,      /* nArg */
          908  +  1+IsStat4,       /* nArg */
   952    909     SQLITE_UTF8,     /* funcFlags */
   953    910     0,               /* pUserData */
   954    911     0,               /* pNext */
   955    912     statGet,         /* xSFunc */
   956    913     0,               /* xFinalize */
   957    914     0, 0,            /* xValue, xInverse */
   958    915     "stat_get",      /* zName */
   959    916     {0}
   960    917   };
   961    918   
   962    919   static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
   963    920     assert( regOut!=regStat4 && regOut!=regStat4+1 );
   964         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          921  +#ifdef SQLITE_ENABLE_STAT4
   965    922     sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
   966    923   #elif SQLITE_DEBUG
   967    924     assert( iParam==STAT_GET_STAT1 );
   968    925   #else
   969    926     UNUSED_PARAMETER( iParam );
   970    927   #endif
   971    928     sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut,
   972    929                       (char*)&statGetFuncdef, P4_FUNCDEF);
   973         -  sqlite3VdbeChangeP5(v, 1 + IsStat34);
          930  +  sqlite3VdbeChangeP5(v, 1 + IsStat4);
   974    931   }
   975    932   
   976    933   /*
   977    934   ** Generate code to do an analysis of all indices associated with
   978    935   ** a single table.
   979    936   */
   980    937   static void analyzeOneTable(
................................................................................
   993    950     int i;                       /* Loop counter */
   994    951     int jZeroRows = -1;          /* Jump from here if number of rows is zero */
   995    952     int iDb;                     /* Index of database containing pTab */
   996    953     u8 needTableCnt = 1;         /* True to count the table */
   997    954     int regNewRowid = iMem++;    /* Rowid for the inserted record */
   998    955     int regStat4 = iMem++;       /* Register to hold Stat4Accum object */
   999    956     int regChng = iMem++;        /* Index of changed index field */
  1000         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          957  +#ifdef SQLITE_ENABLE_STAT4
  1001    958     int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
  1002    959   #endif
  1003    960     int regTemp = iMem++;        /* Temporary use register */
  1004    961     int regTabname = iMem++;     /* Register containing table name */
  1005    962     int regIdxname = iMem++;     /* Register containing index name */
  1006    963     int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
  1007    964     int regPrev = iMem;          /* MUST BE LAST (see below) */
................................................................................
  1127   1084       ** 
  1128   1085       **    (1) the number of columns in the index including the rowid
  1129   1086       **        (or for a WITHOUT ROWID table, the number of PK columns),
  1130   1087       **    (2) the number of columns in the key without the rowid/pk
  1131   1088       **    (3) the number of rows in the index,
  1132   1089       **
  1133   1090       **
  1134         -    ** The third argument is only used for STAT3 and STAT4
         1091  +    ** The third argument is only used for STAT4
  1135   1092       */
  1136         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1093  +#ifdef SQLITE_ENABLE_STAT4
  1137   1094       sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
  1138   1095   #endif
  1139   1096       sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
  1140   1097       sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
  1141   1098       sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4,
  1142   1099                        (char*)&statInitFuncdef, P4_FUNCDEF);
  1143         -    sqlite3VdbeChangeP5(v, 2+IsStat34);
         1100  +    sqlite3VdbeChangeP5(v, 2+IsStat4);
  1144   1101   
  1145   1102       /* Implementation of the following:
  1146   1103       **
  1147   1104       **   Rewind csr
  1148   1105       **   if eof(csr) goto end_of_scan;
  1149   1106       **   regChng = 0
  1150   1107       **   goto next_push_0;
................................................................................
  1207   1164         }
  1208   1165         sqlite3VdbeResolveLabel(v, endDistinctTest);
  1209   1166         sqlite3DbFree(db, aGotoChng);
  1210   1167       }
  1211   1168     
  1212   1169       /*
  1213   1170       **  chng_addr_N:
  1214         -    **   regRowid = idx(rowid)            // STAT34 only
  1215         -    **   stat_push(P, regChng, regRowid)  // 3rd parameter STAT34 only
         1171  +    **   regRowid = idx(rowid)            // STAT4 only
         1172  +    **   stat_push(P, regChng, regRowid)  // 3rd parameter STAT4 only
  1216   1173       **   Next csr
  1217   1174       **   if !eof(csr) goto next_row;
  1218   1175       */
  1219         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1176  +#ifdef SQLITE_ENABLE_STAT4
  1220   1177       assert( regRowid==(regStat4+2) );
  1221   1178       if( HasRowid(pTab) ){
  1222   1179         sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
  1223   1180       }else{
  1224   1181         Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
  1225   1182         int j, k, regKey;
  1226   1183         regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
................................................................................
  1233   1190         sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
  1234   1191         sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
  1235   1192       }
  1236   1193   #endif
  1237   1194       assert( regChng==(regStat4+1) );
  1238   1195       sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp,
  1239   1196                        (char*)&statPushFuncdef, P4_FUNCDEF);
  1240         -    sqlite3VdbeChangeP5(v, 2+IsStat34);
         1197  +    sqlite3VdbeChangeP5(v, 2+IsStat4);
  1241   1198       sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
  1242   1199   
  1243   1200       /* Add the entry to the stat1 table. */
  1244   1201       callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
  1245   1202       assert( "BBB"[0]==SQLITE_AFF_TEXT );
  1246   1203       sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
  1247   1204       sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  1248   1205       sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
  1249   1206   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  1250   1207       sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
  1251   1208   #endif
  1252   1209       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
  1253   1210   
  1254         -    /* Add the entries to the stat3 or stat4 table. */
  1255         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1211  +    /* Add the entries to the stat4 table. */
         1212  +#ifdef SQLITE_ENABLE_STAT4
  1256   1213       {
  1257   1214         int regEq = regStat1;
  1258   1215         int regLt = regStat1+1;
  1259   1216         int regDLt = regStat1+2;
  1260   1217         int regSample = regStat1+3;
  1261   1218         int regCol = regStat1+4;
  1262   1219         int regSampleRowid = regCol + nCol;
................................................................................
  1271   1228         addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
  1272   1229         VdbeCoverage(v);
  1273   1230         callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
  1274   1231         callStatGet(v, regStat4, STAT_GET_NLT, regLt);
  1275   1232         callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
  1276   1233         sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
  1277   1234         VdbeCoverage(v);
  1278         -#ifdef SQLITE_ENABLE_STAT3
  1279         -      sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample);
  1280         -#else
  1281   1235         for(i=0; i<nCol; i++){
  1282   1236           sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
  1283   1237         }
  1284   1238         sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
  1285         -#endif
  1286   1239         sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
  1287   1240         sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
  1288   1241         sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
  1289   1242         sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
  1290   1243         sqlite3VdbeJumpHere(v, addrIsNull);
  1291   1244       }
  1292         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1245  +#endif /* SQLITE_ENABLE_STAT4 */
  1293   1246   
  1294   1247       /* End of analysis */
  1295   1248       sqlite3VdbeJumpHere(v, addrRewind);
  1296   1249     }
  1297   1250   
  1298   1251   
  1299   1252     /* Create a single sqlite_stat1 entry containing NULL as the index
................................................................................
  1460   1413     Index *pIndex          /* Handle extra flags for this index, if not NULL */
  1461   1414   ){
  1462   1415     char *z = zIntArray;
  1463   1416     int c;
  1464   1417     int i;
  1465   1418     tRowcnt v;
  1466   1419   
  1467         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1420  +#ifdef SQLITE_ENABLE_STAT4
  1468   1421     if( z==0 ) z = "";
  1469   1422   #else
  1470   1423     assert( z!=0 );
  1471   1424   #endif
  1472   1425     for(i=0; *z && i<nOut; i++){
  1473   1426       v = 0;
  1474   1427       while( (c=z[0])>='0' && c<='9' ){
  1475   1428         v = v*10 + c - '0';
  1476   1429         z++;
  1477   1430       }
  1478         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1431  +#ifdef SQLITE_ENABLE_STAT4
  1479   1432       if( aOut ) aOut[i] = v;
  1480   1433       if( aLog ) aLog[i] = sqlite3LogEst(v);
  1481   1434   #else
  1482   1435       assert( aOut==0 );
  1483   1436       UNUSED_PARAMETER(aOut);
  1484   1437       assert( aLog!=0 );
  1485   1438       aLog[i] = sqlite3LogEst(v);
  1486   1439   #endif
  1487   1440       if( *z==' ' ) z++;
  1488   1441     }
  1489         -#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
         1442  +#ifndef SQLITE_ENABLE_STAT4
  1490   1443     assert( pIndex!=0 ); {
  1491   1444   #else
  1492   1445     if( pIndex ){
  1493   1446   #endif
  1494   1447       pIndex->bUnordered = 0;
  1495   1448       pIndex->noSkipScan = 0;
  1496   1449       while( z[0] ){
................................................................................
  1547   1500       pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
  1548   1501     }
  1549   1502     z = argv[2];
  1550   1503   
  1551   1504     if( pIndex ){
  1552   1505       tRowcnt *aiRowEst = 0;
  1553   1506       int nCol = pIndex->nKeyCol+1;
  1554         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1507  +#ifdef SQLITE_ENABLE_STAT4
  1555   1508       /* Index.aiRowEst may already be set here if there are duplicate 
  1556   1509       ** sqlite_stat1 entries for this index. In that case just clobber
  1557   1510       ** the old data with the new instead of allocating a new array.  */
  1558   1511       if( pIndex->aiRowEst==0 ){
  1559   1512         pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
  1560   1513         if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db);
  1561   1514       }
................................................................................
  1583   1536   }
  1584   1537   
  1585   1538   /*
  1586   1539   ** If the Index.aSample variable is not NULL, delete the aSample[] array
  1587   1540   ** and its contents.
  1588   1541   */
  1589   1542   void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
  1590         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1543  +#ifdef SQLITE_ENABLE_STAT4
  1591   1544     if( pIdx->aSample ){
  1592   1545       int j;
  1593   1546       for(j=0; j<pIdx->nSample; j++){
  1594   1547         IndexSample *p = &pIdx->aSample[j];
  1595   1548         sqlite3DbFree(db, p->p);
  1596   1549       }
  1597   1550       sqlite3DbFree(db, pIdx->aSample);
................................................................................
  1599   1552     if( db && db->pnBytesFreed==0 ){
  1600   1553       pIdx->nSample = 0;
  1601   1554       pIdx->aSample = 0;
  1602   1555     }
  1603   1556   #else
  1604   1557     UNUSED_PARAMETER(db);
  1605   1558     UNUSED_PARAMETER(pIdx);
  1606         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1559  +#endif /* SQLITE_ENABLE_STAT4 */
  1607   1560   }
  1608   1561   
  1609         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1562  +#ifdef SQLITE_ENABLE_STAT4
  1610   1563   /*
  1611   1564   ** Populate the pIdx->aAvgEq[] array based on the samples currently
  1612   1565   ** stored in pIdx->aSample[]. 
  1613   1566   */
  1614   1567   static void initAvgEq(Index *pIdx){
  1615   1568     if( pIdx ){
  1616   1569       IndexSample *aSample = pIdx->aSample;
................................................................................
  1680   1633       Table *pTab = sqlite3FindTable(db, zName, zDb);
  1681   1634       if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
  1682   1635     }
  1683   1636     return pIdx;
  1684   1637   }
  1685   1638   
  1686   1639   /*
  1687         -** Load the content from either the sqlite_stat4 or sqlite_stat3 table 
         1640  +** Load the content from either the sqlite_stat4
  1688   1641   ** into the relevant Index.aSample[] arrays.
  1689   1642   **
  1690   1643   ** Arguments zSql1 and zSql2 must point to SQL statements that return
  1691         -** data equivalent to the following (statements are different for stat3,
  1692         -** see the caller of this function for details):
         1644  +** data equivalent to the following:
  1693   1645   **
  1694   1646   **    zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
  1695   1647   **    zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
  1696   1648   **
  1697   1649   ** where %Q is replaced with the database name before the SQL is executed.
  1698   1650   */
  1699   1651   static int loadStatTbl(
  1700   1652     sqlite3 *db,                  /* Database handle */
  1701         -  int bStat3,                   /* Assume single column records only */
  1702   1653     const char *zSql1,            /* SQL statement 1 (see above) */
  1703   1654     const char *zSql2,            /* SQL statement 2 (see above) */
  1704   1655     const char *zDb               /* Database name (e.g. "main") */
  1705   1656   ){
  1706   1657     int rc;                       /* Result codes from subroutines */
  1707   1658     sqlite3_stmt *pStmt = 0;      /* An SQL statement being run */
  1708   1659     char *zSql;                   /* Text of the SQL statement */
................................................................................
  1728   1679       int i;          /* Bytes of space required */
  1729   1680       tRowcnt *pSpace;
  1730   1681   
  1731   1682       zIndex = (char *)sqlite3_column_text(pStmt, 0);
  1732   1683       if( zIndex==0 ) continue;
  1733   1684       nSample = sqlite3_column_int(pStmt, 1);
  1734   1685       pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
  1735         -    assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
  1736         -    /* Index.nSample is non-zero at this point if data has already been
  1737         -    ** loaded from the stat4 table. In this case ignore stat3 data.  */
  1738         -    if( pIdx==0 || pIdx->nSample ) continue;
  1739         -    if( bStat3==0 ){
  1740         -      assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
  1741         -      if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
  1742         -        nIdxCol = pIdx->nKeyCol;
  1743         -      }else{
  1744         -        nIdxCol = pIdx->nColumn;
  1745         -      }
         1686  +    assert( pIdx==0 || pIdx->nSample==0 );
         1687  +    if( pIdx==0 ) continue;
         1688  +    assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
         1689  +    if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
         1690  +      nIdxCol = pIdx->nKeyCol;
         1691  +    }else{
         1692  +      nIdxCol = pIdx->nColumn;
  1746   1693       }
  1747   1694       pIdx->nSampleCol = nIdxCol;
  1748   1695       nByte = sizeof(IndexSample) * nSample;
  1749   1696       nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
  1750   1697       nByte += nIdxCol * sizeof(tRowcnt);     /* Space for Index.aAvgEq[] */
  1751   1698   
  1752   1699       pIdx->aSample = sqlite3DbMallocZero(db, nByte);
................................................................................
  1780   1727       int nCol = 1;                 /* Number of columns in index */
  1781   1728   
  1782   1729       zIndex = (char *)sqlite3_column_text(pStmt, 0);
  1783   1730       if( zIndex==0 ) continue;
  1784   1731       pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
  1785   1732       if( pIdx==0 ) continue;
  1786   1733       /* This next condition is true if data has already been loaded from 
  1787         -    ** the sqlite_stat4 table. In this case ignore stat3 data.  */
         1734  +    ** the sqlite_stat4 table. */
  1788   1735       nCol = pIdx->nSampleCol;
  1789         -    if( bStat3 && nCol>1 ) continue;
  1790   1736       if( pIdx!=pPrevIdx ){
  1791   1737         initAvgEq(pPrevIdx);
  1792   1738         pPrevIdx = pIdx;
  1793   1739       }
  1794   1740       pSample = &pIdx->aSample[pIdx->nSample];
  1795   1741       decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0);
  1796   1742       decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0);
................................................................................
  1815   1761     }
  1816   1762     rc = sqlite3_finalize(pStmt);
  1817   1763     if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);
  1818   1764     return rc;
  1819   1765   }
  1820   1766   
  1821   1767   /*
  1822         -** Load content from the sqlite_stat4 and sqlite_stat3 tables into 
         1768  +** Load content from the sqlite_stat4 table into 
  1823   1769   ** the Index.aSample[] arrays of all indices.
  1824   1770   */
  1825   1771   static int loadStat4(sqlite3 *db, const char *zDb){
  1826   1772     int rc = SQLITE_OK;             /* Result codes from subroutines */
  1827   1773   
  1828   1774     assert( db->lookaside.bDisable );
  1829   1775     if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
  1830         -    rc = loadStatTbl(db, 0,
         1776  +    rc = loadStatTbl(db,
  1831   1777         "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
  1832   1778         "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
  1833   1779         zDb
  1834   1780       );
  1835   1781     }
  1836         -
  1837         -  if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
  1838         -    rc = loadStatTbl(db, 1,
  1839         -      "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", 
  1840         -      "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
  1841         -      zDb
  1842         -    );
  1843         -  }
  1844         -
  1845   1782     return rc;
  1846   1783   }
  1847         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1784  +#endif /* SQLITE_ENABLE_STAT4 */
  1848   1785   
  1849   1786   /*
  1850         -** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The
         1787  +** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The
  1851   1788   ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
  1852         -** arrays. The contents of sqlite_stat3/4 are used to populate the
         1789  +** arrays. The contents of sqlite_stat4 are used to populate the
  1853   1790   ** Index.aSample[] arrays.
  1854   1791   **
  1855   1792   ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
  1856         -** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined 
  1857         -** during compilation and the sqlite_stat3/4 table is present, no data is 
         1793  +** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined 
         1794  +** during compilation and the sqlite_stat4 table is present, no data is 
  1858   1795   ** read from it.
  1859   1796   **
  1860         -** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the 
         1797  +** If SQLITE_ENABLE_STAT4 was defined during compilation and the 
  1861   1798   ** sqlite_stat4 table is not present in the database, SQLITE_ERROR is
  1862   1799   ** returned. However, in this case, data is read from the sqlite_stat1
  1863   1800   ** table (if it is present) before returning.
  1864   1801   **
  1865   1802   ** If an OOM error occurs, this function always sets db->mallocFailed.
  1866   1803   ** This means if the caller does not care about other errors, the return
  1867   1804   ** code may be ignored.
................................................................................
  1881   1818     for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
  1882   1819       Table *pTab = sqliteHashData(i);
  1883   1820       pTab->tabFlags &= ~TF_HasStat1;
  1884   1821     }
  1885   1822     for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
  1886   1823       Index *pIdx = sqliteHashData(i);
  1887   1824       pIdx->hasStat1 = 0;
  1888         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1825  +#ifdef SQLITE_ENABLE_STAT4
  1889   1826       sqlite3DeleteIndexSamples(db, pIdx);
  1890   1827       pIdx->aSample = 0;
  1891   1828   #endif
  1892   1829     }
  1893   1830   
  1894   1831     /* Load new statistics out of the sqlite_stat1 table */
  1895   1832     sInfo.db = db;
................................................................................
  1909   1846     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  1910   1847     for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
  1911   1848       Index *pIdx = sqliteHashData(i);
  1912   1849       if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
  1913   1850     }
  1914   1851   
  1915   1852     /* Load the statistics from the sqlite_stat4 table. */
  1916         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1853  +#ifdef SQLITE_ENABLE_STAT4
  1917   1854     if( rc==SQLITE_OK ){
  1918   1855       db->lookaside.bDisable++;
  1919   1856       rc = loadStat4(db, sInfo.zDatabase);
  1920   1857       db->lookaside.bDisable--;
  1921   1858     }
  1922   1859     for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
  1923   1860       Index *pIdx = sqliteHashData(i);

Changes to src/build.c.

   452    452   #ifndef SQLITE_OMIT_ANALYZE
   453    453     sqlite3DeleteIndexSamples(db, p);
   454    454   #endif
   455    455     sqlite3ExprDelete(db, p->pPartIdxWhere);
   456    456     sqlite3ExprListDelete(db, p->aColExpr);
   457    457     sqlite3DbFree(db, p->zColAff);
   458    458     if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl);
   459         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          459  +#ifdef SQLITE_ENABLE_STAT4
   460    460     sqlite3_free(p->aiRowEst);
   461    461   #endif
   462    462     sqlite3DbFree(db, p);
   463    463   }
   464    464   
   465    465   /*
   466    466   ** For the index called zIdxName which is found in the database iDb,

Changes to src/ctime.c.

   302    302     "ENABLE_SORTER_REFERENCES",
   303    303   #endif
   304    304   #if SQLITE_ENABLE_SQLLOG
   305    305     "ENABLE_SQLLOG",
   306    306   #endif
   307    307   #if defined(SQLITE_ENABLE_STAT4)
   308    308     "ENABLE_STAT4",
   309         -#elif defined(SQLITE_ENABLE_STAT3)
   310         -  "ENABLE_STAT3",
   311    309   #endif
   312    310   #if SQLITE_ENABLE_STMTVTAB
   313    311     "ENABLE_STMTVTAB",
   314    312   #endif
   315    313   #if SQLITE_ENABLE_STMT_SCANSTATUS
   316    314     "ENABLE_STMT_SCANSTATUS",
   317    315   #endif

Changes to src/func.c.

  1982   1982       FUNCTION(coalesce,           0, 0, 0, 0                ),
  1983   1983       FUNCTION2(coalesce,         -1, 0, 0, noopFunc,  SQLITE_FUNC_COALESCE),
  1984   1984     };
  1985   1985   #ifndef SQLITE_OMIT_ALTERTABLE
  1986   1986     sqlite3AlterFunctions();
  1987   1987   #endif
  1988   1988     sqlite3WindowFunctions();
  1989         -#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4)
  1990         -  sqlite3AnalyzeFunctions();
  1991         -#endif
  1992   1989     sqlite3RegisterDateTimeFunctions();
  1993   1990     sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc));
  1994   1991   
  1995   1992   #if 0  /* Enable to print out how the built-in functions are hashed */
  1996   1993     {
  1997   1994       int i;
  1998   1995       FuncDef *p;

Changes to src/shell.c.in.

  7503   7503       }else{
  7504   7504         raw_printf(p->out, "ANALYZE sqlite_master;\n");
  7505   7505         sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
  7506   7506                      callback, &data, &zErrMsg);
  7507   7507         data.cMode = data.mode = MODE_Insert;
  7508   7508         data.zDestTable = "sqlite_stat1";
  7509   7509         shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
  7510         -      data.zDestTable = "sqlite_stat3";
  7511         -      shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
  7512   7510         data.zDestTable = "sqlite_stat4";
  7513   7511         shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
  7514   7512         raw_printf(p->out, "ANALYZE sqlite_master;\n");
  7515   7513       }
  7516   7514     }else
  7517   7515   
  7518   7516     if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
................................................................................
  8925   8923                              " ORDER BY name;", 0);
  8926   8924         }else if( strcmp(zTab, "sqlite_sequence")==0 ){
  8927   8925           appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
  8928   8926                              " ORDER BY name;", 0);
  8929   8927         }else if( strcmp(zTab, "sqlite_stat1")==0 ){
  8930   8928           appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
  8931   8929                              " ORDER BY tbl,idx;", 0);
  8932         -      }else if( strcmp(zTab, "sqlite_stat3")==0
  8933         -             || strcmp(zTab, "sqlite_stat4")==0 ){
         8930  +      }else if( strcmp(zTab, "sqlite_stat4")==0 ){
  8934   8931           appendText(&sQuery, "SELECT * FROM ", 0);
  8935   8932           appendText(&sQuery, zTab, 0);
  8936   8933           appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
  8937   8934         }
  8938   8935         appendText(&sSql, zSep, 0);
  8939   8936         appendText(&sSql, sQuery.z, '\'');
  8940   8937         sQuery.n = 0;

Changes to src/sqlite.h.in.

  3810   3810   ** WHERE clause might influence the choice of query plan for a statement,
  3811   3811   ** then the statement will be automatically recompiled, as if there had been 
  3812   3812   ** a schema change, on the first  [sqlite3_step()] call following any change
  3813   3813   ** to the [sqlite3_bind_text | bindings] of that [parameter]. 
  3814   3814   ** ^The specific value of WHERE-clause [parameter] might influence the 
  3815   3815   ** choice of query plan if the parameter is the left-hand side of a [LIKE]
  3816   3816   ** or [GLOB] operator or if the parameter is compared to an indexed column
  3817         -** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
         3817  +** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
  3818   3818   ** </li>
  3819   3819   ** </ol>
  3820   3820   **
  3821   3821   ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
  3822   3822   ** the extra prepFlags parameter, which is a bit array consisting of zero or
  3823   3823   ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
  3824   3824   ** sqlite3_prepare_v2() interface works exactly the same as

Changes to src/sqliteInt.h.

   931    931   # define SQLITE_DEFAULT_MMAP_SIZE 0
   932    932   #endif
   933    933   #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE
   934    934   # undef SQLITE_DEFAULT_MMAP_SIZE
   935    935   # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE
   936    936   #endif
   937    937   
   938         -/*
   939         -** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined.
   940         -** Priority is given to SQLITE_ENABLE_STAT4.  If either are defined, also
   941         -** define SQLITE_ENABLE_STAT3_OR_STAT4
   942         -*/
   943         -#ifdef SQLITE_ENABLE_STAT4
   944         -# undef SQLITE_ENABLE_STAT3
   945         -# define SQLITE_ENABLE_STAT3_OR_STAT4 1
   946         -#elif SQLITE_ENABLE_STAT3
   947         -# define SQLITE_ENABLE_STAT3_OR_STAT4 1
   948         -#elif SQLITE_ENABLE_STAT3_OR_STAT4
   949         -# undef SQLITE_ENABLE_STAT3_OR_STAT4
   950         -#endif
   951         -
   952    938   /*
   953    939   ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
   954    940   ** the Select query generator tracing logic is turned on.
   955    941   */
   956    942   #if defined(SQLITE_ENABLE_SELECTTRACE)
   957    943   # define SELECTTRACE_ENABLED 1
   958    944   #else
................................................................................
  1583   1569   #define SQLITE_DistinctOpt    0x0010   /* DISTINCT using indexes */
  1584   1570   #define SQLITE_CoverIdxScan   0x0020   /* Covering index scans */
  1585   1571   #define SQLITE_OrderByIdxJoin 0x0040   /* ORDER BY of joins via index */
  1586   1572   #define SQLITE_Transitive     0x0080   /* Transitive constraints */
  1587   1573   #define SQLITE_OmitNoopJoin   0x0100   /* Omit unused tables in joins */
  1588   1574   #define SQLITE_CountOfView    0x0200   /* The count-of-view optimization */
  1589   1575   #define SQLITE_CursorHints    0x0400   /* Add OP_CursorHint opcodes */
  1590         -#define SQLITE_Stat34         0x0800   /* Use STAT3 or STAT4 data */
  1591         -   /* TH3 expects the Stat34  ^^^^^^ value to be 0x0800.  Don't change it */
         1576  +#define SQLITE_Stat4          0x0800   /* Use STAT4 data */
         1577  +   /* TH3 expects the Stat4   ^^^^^^ value to be 0x0800.  Don't change it */
  1592   1578   #define SQLITE_PushDown       0x1000   /* The push-down optimization */
  1593   1579   #define SQLITE_SimplifyJoin   0x2000   /* Convert LEFT JOIN to JOIN */
  1594   1580   #define SQLITE_SkipScan       0x4000   /* Skip-scans */
  1595   1581   #define SQLITE_PropagateConst 0x8000   /* The constant propagation opt */
  1596   1582   #define SQLITE_AllOpts        0xffff   /* All optimizations */
  1597   1583   
  1598   1584   /*
................................................................................
  2254   2240     unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
  2255   2241     unsigned isResized:1;    /* True if resizeIndexObject() has been called */
  2256   2242     unsigned isCovering:1;   /* True if this is a covering index */
  2257   2243     unsigned noSkipScan:1;   /* Do not try to use skip-scan if true */
  2258   2244     unsigned hasStat1:1;     /* aiRowLogEst values come from sqlite_stat1 */
  2259   2245     unsigned bNoQuery:1;     /* Do not use this index to optimize queries */
  2260   2246     unsigned bAscKeyBug:1;   /* True if the bba7b69f9849b5bf bug applies */
  2261         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         2247  +#ifdef SQLITE_ENABLE_STAT4
  2262   2248     int nSample;             /* Number of elements in aSample[] */
  2263   2249     int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
  2264   2250     tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
  2265   2251     IndexSample *aSample;    /* Samples of the left-most key */
  2266   2252     tRowcnt *aiRowEst;       /* Non-logarithmic stat1 data for this index */
  2267   2253     tRowcnt nRowEst0;        /* Non-logarithmic number of rows in the index */
  2268   2254   #endif
................................................................................
  2286   2272   /* The Index.aiColumn[] values are normally positive integer.  But
  2287   2273   ** there are some negative values that have special meaning:
  2288   2274   */
  2289   2275   #define XN_ROWID     (-1)     /* Indexed column is the rowid */
  2290   2276   #define XN_EXPR      (-2)     /* Indexed column is an expression */
  2291   2277   
  2292   2278   /*
  2293         -** Each sample stored in the sqlite_stat3 table is represented in memory
         2279  +** Each sample stored in the sqlite_stat4 table is represented in memory
  2294   2280   ** using a structure of this type.  See documentation at the top of the
  2295   2281   ** analyze.c source file for additional information.
  2296   2282   */
  2297   2283   struct IndexSample {
  2298   2284     void *p;          /* Pointer to sampled record */
  2299   2285     int n;            /* Size of record in bytes */
  2300   2286     tRowcnt *anEq;    /* Est. number of rows where the key equals this sample */
................................................................................
  4210   4196   u32 sqlite3Utf8Read(const u8**);
  4211   4197   LogEst sqlite3LogEst(u64);
  4212   4198   LogEst sqlite3LogEstAdd(LogEst,LogEst);
  4213   4199   #ifndef SQLITE_OMIT_VIRTUALTABLE
  4214   4200   LogEst sqlite3LogEstFromDouble(double);
  4215   4201   #endif
  4216   4202   #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
  4217         -    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
         4203  +    defined(SQLITE_ENABLE_STAT4) || \
  4218   4204       defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
  4219   4205   u64 sqlite3LogEstToInt(LogEst);
  4220   4206   #endif
  4221   4207   VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
  4222   4208   const char *sqlite3VListNumToName(VList*,int);
  4223   4209   int sqlite3VListNameToNum(VList*,const char*,int);
  4224   4210   
................................................................................
  4397   4383   
  4398   4384   #ifndef SQLITE_OMIT_SUBQUERY
  4399   4385   int sqlite3ExprCheckIN(Parse*, Expr*);
  4400   4386   #else
  4401   4387   # define sqlite3ExprCheckIN(x,y) SQLITE_OK
  4402   4388   #endif
  4403   4389   
  4404         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  4405         -void sqlite3AnalyzeFunctions(void);
         4390  +#ifdef SQLITE_ENABLE_STAT4
  4406   4391   int sqlite3Stat4ProbeSetValue(
  4407   4392       Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
  4408   4393   int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
  4409   4394   void sqlite3Stat4ProbeFree(UnpackedRecord*);
  4410   4395   int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
  4411   4396   char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
  4412   4397   #endif

Changes to src/test1.c.

  7169   7169       { "groupby-order",       SQLITE_GroupByOrder   },
  7170   7170       { "factor-constants",    SQLITE_FactorOutConst },
  7171   7171       { "distinct-opt",        SQLITE_DistinctOpt    },
  7172   7172       { "cover-idx-scan",      SQLITE_CoverIdxScan   },
  7173   7173       { "order-by-idx-join",   SQLITE_OrderByIdxJoin },
  7174   7174       { "transitive",          SQLITE_Transitive     },
  7175   7175       { "omit-noop-join",      SQLITE_OmitNoopJoin   },
  7176         -    { "stat3",               SQLITE_Stat34         },
  7177         -    { "stat4",               SQLITE_Stat34         },
         7176  +    { "stat4",               SQLITE_Stat4          },
  7178   7177       { "skip-scan",           SQLITE_SkipScan       },
  7179   7178     };
  7180   7179   
  7181   7180     if( objc!=4 ){
  7182   7181       Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN");
  7183   7182       return TCL_ERROR;
  7184   7183     }

Changes to src/test_config.c.

   581    581   #endif
   582    582   
   583    583   #ifdef SQLITE_ENABLE_STAT4
   584    584     Tcl_SetVar2(interp, "sqlite_options", "stat4", "1", TCL_GLOBAL_ONLY);
   585    585   #else
   586    586     Tcl_SetVar2(interp, "sqlite_options", "stat4", "0", TCL_GLOBAL_ONLY);
   587    587   #endif
   588         -#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4)
   589         -  Tcl_SetVar2(interp, "sqlite_options", "stat3", "1", TCL_GLOBAL_ONLY);
   590         -#else
   591         -  Tcl_SetVar2(interp, "sqlite_options", "stat3", "0", TCL_GLOBAL_ONLY);
   592         -#endif
   593         -
   594    588   #if defined(SQLITE_ENABLE_STMTVTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
   595    589     Tcl_SetVar2(interp, "sqlite_options", "stmtvtab", "1", TCL_GLOBAL_ONLY);
   596    590   #else
   597    591     Tcl_SetVar2(interp, "sqlite_options", "stmtvtab", "0", TCL_GLOBAL_ONLY);
   598    592   #endif
   599    593   
   600    594   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS

Changes to src/util.c.

  1494   1494     memcpy(&a, &x, 8);
  1495   1495     e = (a>>52) - 1022;
  1496   1496     return e*10;
  1497   1497   }
  1498   1498   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  1499   1499   
  1500   1500   #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
  1501         -    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
         1501  +    defined(SQLITE_ENABLE_STAT4) || \
  1502   1502       defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
  1503   1503   /*
  1504   1504   ** Convert a LogEst into an integer.
  1505   1505   **
  1506   1506   ** Note that this routine is only used when one or more of various
  1507   1507   ** non-standard compile-time options is enabled.
  1508   1508   */
................................................................................
  1512   1512     x /= 10;
  1513   1513     if( n>=5 ) n -= 2;
  1514   1514     else if( n>=1 ) n -= 1;
  1515   1515   #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
  1516   1516       defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
  1517   1517     if( x>60 ) return (u64)LARGEST_INT64;
  1518   1518   #else
  1519         -  /* If only SQLITE_ENABLE_STAT3_OR_STAT4 is on, then the largest input
         1519  +  /* If only SQLITE_ENABLE_STAT4 is on, then the largest input
  1520   1520     ** possible to this routine is 310, resulting in a maximum x of 31 */
  1521   1521     assert( x<=60 );
  1522   1522   #endif
  1523   1523     return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
  1524   1524   }
  1525   1525   #endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
  1526   1526   

Changes to src/vdbeInt.h.

   482    482   void sqlite3VdbeError(Vdbe*, const char *, ...);
   483    483   void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
   484    484   void sqliteVdbePopStack(Vdbe*,int);
   485    485   int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
   486    486   int sqlite3VdbeCursorRestore(VdbeCursor*);
   487    487   u32 sqlite3VdbeSerialTypeLen(u32);
   488    488   u8 sqlite3VdbeOneByteSerialTypeLen(u8);
   489         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   490         -u32 sqlite3VdbeSerialType(Mem*, int, u32*);
   491         -#endif
   492    489   u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
   493    490   u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
   494    491   void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
   495    492   
   496    493   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
   497    494   int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
   498    495   int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);

Changes to src/vdbeapi.c.

   840    840   ** is requested more than once within the same run of a single prepared
   841    841   ** statement, the exact same time is returned for each invocation regardless
   842    842   ** of the amount of time that elapses between invocations.  In other words,
   843    843   ** the time returned is always the time of the first call.
   844    844   */
   845    845   sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
   846    846     int rc;
   847         -#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
          847  +#ifndef SQLITE_ENABLE_STAT4
   848    848     sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime;
   849    849     assert( p->pVdbe!=0 );
   850    850   #else
   851    851     sqlite3_int64 iTime = 0;
   852    852     sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
   853    853   #endif
   854    854     if( *piTime==0 ){
................................................................................
   905    905   ** auxiliary data pointers that is available to all functions within a
   906    906   ** single prepared statement.  The iArg values must match.
   907    907   */
   908    908   void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
   909    909     AuxData *pAuxData;
   910    910   
   911    911     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   912         -#if SQLITE_ENABLE_STAT3_OR_STAT4
          912  +#if SQLITE_ENABLE_STAT4
   913    913     if( pCtx->pVdbe==0 ) return 0;
   914    914   #else
   915    915     assert( pCtx->pVdbe!=0 );
   916    916   #endif
   917    917     for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
   918    918       if(  pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){
   919    919         return pAuxData->pAux;
................................................................................
   939    939     void *pAux, 
   940    940     void (*xDelete)(void*)
   941    941   ){
   942    942     AuxData *pAuxData;
   943    943     Vdbe *pVdbe = pCtx->pVdbe;
   944    944   
   945    945     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   946         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          946  +#ifdef SQLITE_ENABLE_STAT4
   947    947     if( pVdbe==0 ) goto failed;
   948    948   #else
   949    949     assert( pVdbe!=0 );
   950    950   #endif
   951    951   
   952    952     for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNextAux){
   953    953       if( pAuxData->iAuxArg==iArg && (pAuxData->iAuxOp==pCtx->iOp || iArg<0) ){

Changes to src/vdbeaux.c.

  3429   3429   **    N>=12 and even       (N-12)/2        BLOB
  3430   3430   **    N>=13 and odd        (N-13)/2        text
  3431   3431   **
  3432   3432   ** The 8 and 9 types were added in 3.3.0, file format 4.  Prior versions
  3433   3433   ** of SQLite will not understand those serial types.
  3434   3434   */
  3435   3435   
  3436         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         3436  +#if 0 /* Inlined into the OP_MakeRecord opcode */
  3437   3437   /*
  3438   3438   ** Return the serial-type for the value stored in pMem.
  3439   3439   **
  3440   3440   ** This routine might convert a large MEM_IntReal value into MEM_Real.
  3441   3441   **
  3442   3442   ** 2019-07-11:  The primary user of this subroutine was the OP_MakeRecord
  3443   3443   ** opcode in the byte-code engine.  But by moving this routine in-line, we
  3444   3444   ** can omit some redundant tests and make that opcode a lot faster.  So
  3445         -** this routine is now only used by the STAT3/4 logic.
         3445  +** this routine is now only used by the STAT3 logic and STAT3 support has
         3446  +** ended.  The code is kept here for historical reference only.
  3446   3447   */
  3447   3448   u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
  3448   3449     int flags = pMem->flags;
  3449   3450     u32 n;
  3450   3451   
  3451   3452     assert( pLen!=0 );
  3452   3453     if( flags&MEM_Null ){
................................................................................
  3499   3500     n = (u32)pMem->n;
  3500   3501     if( flags & MEM_Zero ){
  3501   3502       n += pMem->u.nZero;
  3502   3503     }
  3503   3504     *pLen = n;
  3504   3505     return ((n*2) + 12 + ((flags&MEM_Str)!=0));
  3505   3506   }
  3506         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         3507  +#endif /* inlined into OP_MakeRecord */
  3507   3508   
  3508   3509   /*
  3509   3510   ** The sizes for serial types less than 128
  3510   3511   */
  3511   3512   static const u8 sqlite3SmallTypeSizes[] = {
  3512   3513           /*  0   1   2   3   4   5   6   7   8   9 */   
  3513   3514   /*   0 */   0,  1,  2,  3,  4,  6,  8,  8,  0,  0,
................................................................................
  4904   4905   **
  4905   4906   ** OP_PureFunc means that the function must be deterministic, and should
  4906   4907   ** throw an error if it is given inputs that would make it non-deterministic.
  4907   4908   ** This routine is invoked by date/time functions that use non-deterministic
  4908   4909   ** features such as 'now'.
  4909   4910   */
  4910   4911   int sqlite3NotPureFunc(sqlite3_context *pCtx){
  4911         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         4912  +#ifdef SQLITE_ENABLE_STAT4
  4912   4913     if( pCtx->pVdbe==0 ) return 1;
  4913   4914   #endif
  4914   4915     if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){
  4915   4916       sqlite3_result_error(pCtx, 
  4916   4917          "non-deterministic function in index expression or CHECK constraint",
  4917   4918          -1);
  4918   4919       return 0;

Changes to src/vdbemem.c.

  1299   1299   ** Otherwise, if the second argument is non-zero, then this function is 
  1300   1300   ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
  1301   1301   ** already been allocated, allocate the UnpackedRecord structure that 
  1302   1302   ** that function will return to its caller here. Then return a pointer to
  1303   1303   ** an sqlite3_value within the UnpackedRecord.a[] array.
  1304   1304   */
  1305   1305   static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
  1306         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1306  +#ifdef SQLITE_ENABLE_STAT4
  1307   1307     if( p ){
  1308   1308       UnpackedRecord *pRec = p->ppRec[0];
  1309   1309   
  1310   1310       if( pRec==0 ){
  1311   1311         Index *pIdx = p->pIdx;      /* Index being probed */
  1312   1312         int nByte;                  /* Bytes of space to allocate */
  1313   1313         int i;                      /* Counter variable */
................................................................................
  1335   1335       }
  1336   1336     
  1337   1337       pRec->nField = p->iVal+1;
  1338   1338       return &pRec->aMem[p->iVal];
  1339   1339     }
  1340   1340   #else
  1341   1341     UNUSED_PARAMETER(p);
  1342         -#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
         1342  +#endif /* defined(SQLITE_ENABLE_STAT4) */
  1343   1343     return sqlite3ValueNew(db);
  1344   1344   }
  1345   1345   
  1346   1346   /*
  1347   1347   ** The expression object indicated by the second argument is guaranteed
  1348   1348   ** to be a scalar SQL function. If
  1349   1349   **
................................................................................
  1359   1359   ** If the result is a text value, the sqlite3_value object uses encoding 
  1360   1360   ** enc.
  1361   1361   **
  1362   1362   ** If the conditions above are not met, this function returns SQLITE_OK
  1363   1363   ** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
  1364   1364   ** NULL and an SQLite error code returned.
  1365   1365   */
  1366         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1366  +#ifdef SQLITE_ENABLE_STAT4
  1367   1367   static int valueFromFunction(
  1368   1368     sqlite3 *db,                    /* The database connection */
  1369   1369     Expr *p,                        /* The expression to evaluate */
  1370   1370     u8 enc,                         /* Encoding to use */
  1371   1371     u8 aff,                         /* Affinity to use */
  1372   1372     sqlite3_value **ppVal,          /* Write the new value here */
  1373   1373     struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
................................................................................
  1442   1442     }
  1443   1443   
  1444   1444     *ppVal = pVal;
  1445   1445     return rc;
  1446   1446   }
  1447   1447   #else
  1448   1448   # define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
  1449         -#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
         1449  +#endif /* defined(SQLITE_ENABLE_STAT4) */
  1450   1450   
  1451   1451   /*
  1452   1452   ** Extract a value from the supplied expression in the manner described
  1453   1453   ** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
  1454   1454   ** using valueNew().
  1455   1455   **
  1456   1456   ** If pCtx is NULL and an error occurs after the sqlite3_value object
................................................................................
  1471   1471     sqlite3_value *pVal = 0;
  1472   1472     int negInt = 1;
  1473   1473     const char *zNeg = "";
  1474   1474     int rc = SQLITE_OK;
  1475   1475   
  1476   1476     assert( pExpr!=0 );
  1477   1477     while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
  1478         -#if defined(SQLITE_ENABLE_STAT3_OR_STAT4)
         1478  +#if defined(SQLITE_ENABLE_STAT4)
  1479   1479     if( op==TK_REGISTER ) op = pExpr->op2;
  1480   1480   #else
  1481   1481     if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
  1482   1482   #endif
  1483   1483   
  1484   1484     /* Compressed expressions only appear when parsing the DEFAULT clause
  1485   1485     ** on a table column definition, and hence only when pCtx==0.  This
................................................................................
  1564   1564       zVal = &pExpr->u.zToken[2];
  1565   1565       nVal = sqlite3Strlen30(zVal)-1;
  1566   1566       assert( zVal[nVal]=='\'' );
  1567   1567       sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
  1568   1568                            0, SQLITE_DYNAMIC);
  1569   1569     }
  1570   1570   #endif
  1571         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1571  +#ifdef SQLITE_ENABLE_STAT4
  1572   1572     else if( op==TK_FUNCTION && pCtx!=0 ){
  1573   1573       rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
  1574   1574     }
  1575   1575   #endif
  1576   1576     else if( op==TK_TRUEFALSE ){
  1577   1577       pVal = valueNew(db, pCtx);
  1578   1578       if( pVal ){
................................................................................
  1581   1581       }
  1582   1582     }
  1583   1583   
  1584   1584     *ppVal = pVal;
  1585   1585     return rc;
  1586   1586   
  1587   1587   no_mem:
  1588         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1588  +#ifdef SQLITE_ENABLE_STAT4
  1589   1589     if( pCtx==0 || pCtx->pParse->nErr==0 )
  1590   1590   #endif
  1591   1591       sqlite3OomFault(db);
  1592   1592     sqlite3DbFree(db, zVal);
  1593   1593     assert( *ppVal==0 );
  1594         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1594  +#ifdef SQLITE_ENABLE_STAT4
  1595   1595     if( pCtx==0 ) sqlite3ValueFree(pVal);
  1596   1596   #else
  1597   1597     assert( pCtx==0 ); sqlite3ValueFree(pVal);
  1598   1598   #endif
  1599   1599     return SQLITE_NOMEM_BKPT;
  1600   1600   }
  1601   1601   
................................................................................
  1615   1615     u8 enc,                   /* Encoding to use */
  1616   1616     u8 affinity,              /* Affinity to use */
  1617   1617     sqlite3_value **ppVal     /* Write the new value here */
  1618   1618   ){
  1619   1619     return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
  1620   1620   }
  1621   1621   
  1622         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  1623         -/*
  1624         -** The implementation of the sqlite_record() function. This function accepts
  1625         -** a single argument of any type. The return value is a formatted database 
  1626         -** record (a blob) containing the argument value.
  1627         -**
  1628         -** This is used to convert the value stored in the 'sample' column of the
  1629         -** sqlite_stat3 table to the record format SQLite uses internally.
  1630         -*/
  1631         -static void recordFunc(
  1632         -  sqlite3_context *context,
  1633         -  int argc,
  1634         -  sqlite3_value **argv
  1635         -){
  1636         -  const int file_format = 1;
  1637         -  u32 iSerial;                    /* Serial type */
  1638         -  int nSerial;                    /* Bytes of space for iSerial as varint */
  1639         -  u32 nVal;                       /* Bytes of space required for argv[0] */
  1640         -  int nRet;
  1641         -  sqlite3 *db;
  1642         -  u8 *aRet;
  1643         -
  1644         -  UNUSED_PARAMETER( argc );
  1645         -  iSerial = sqlite3VdbeSerialType(argv[0], file_format, &nVal);
  1646         -  nSerial = sqlite3VarintLen(iSerial);
  1647         -  db = sqlite3_context_db_handle(context);
  1648         -
  1649         -  nRet = 1 + nSerial + nVal;
  1650         -  aRet = sqlite3DbMallocRawNN(db, nRet);
  1651         -  if( aRet==0 ){
  1652         -    sqlite3_result_error_nomem(context);
  1653         -  }else{
  1654         -    aRet[0] = nSerial+1;
  1655         -    putVarint32(&aRet[1], iSerial);
  1656         -    sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
  1657         -    sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
  1658         -    sqlite3DbFreeNN(db, aRet);
  1659         -  }
  1660         -}
  1661         -
  1662         -/*
  1663         -** Register built-in functions used to help read ANALYZE data.
  1664         -*/
  1665         -void sqlite3AnalyzeFunctions(void){
  1666         -  static FuncDef aAnalyzeTableFuncs[] = {
  1667         -    FUNCTION(sqlite_record,   1, 0, 0, recordFunc),
  1668         -  };
  1669         -  sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs));
  1670         -}
  1671         -
         1622  +#ifdef SQLITE_ENABLE_STAT4
  1672   1623   /*
  1673   1624   ** Attempt to extract a value from pExpr and use it to construct *ppVal.
  1674   1625   **
  1675   1626   ** If pAlloc is not NULL, then an UnpackedRecord object is created for
  1676   1627   ** pAlloc if one does not exist and the new value is added to the
  1677   1628   ** UnpackedRecord object.
  1678   1629   **

Changes to src/where.c.

  1073   1073     }
  1074   1074     sqlite3_free(pVtab->zErrMsg);
  1075   1075     pVtab->zErrMsg = 0;
  1076   1076     return rc;
  1077   1077   }
  1078   1078   #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
  1079   1079   
  1080         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1080  +#ifdef SQLITE_ENABLE_STAT4
  1081   1081   /*
  1082   1082   ** Estimate the location of a particular key among all keys in an
  1083   1083   ** index.  Store the results in aStat as follows:
  1084   1084   **
  1085   1085   **    aStat[0]      Est. number of rows less than pRec
  1086   1086   **    aStat[1]      Est. number of rows equal to pRec
  1087   1087   **
................................................................................
  1266   1266       aStat[1] = pIdx->aAvgEq[nField-1];
  1267   1267     }
  1268   1268   
  1269   1269     /* Restore the pRec->nField value before returning.  */
  1270   1270     pRec->nField = nField;
  1271   1271     return i;
  1272   1272   }
  1273         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1273  +#endif /* SQLITE_ENABLE_STAT4 */
  1274   1274   
  1275   1275   /*
  1276   1276   ** If it is not NULL, pTerm is a term that provides an upper or lower
  1277   1277   ** bound on a range scan. Without considering pTerm, it is estimated 
  1278   1278   ** that the scan will visit nNew rows. This function returns the number
  1279   1279   ** estimated to be visited after taking pTerm into account.
  1280   1280   **
................................................................................
  1292   1292         nRet -= 20;        assert( 20==sqlite3LogEst(4) );
  1293   1293       }
  1294   1294     }
  1295   1295     return nRet;
  1296   1296   }
  1297   1297   
  1298   1298   
  1299         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1299  +#ifdef SQLITE_ENABLE_STAT4
  1300   1300   /*
  1301   1301   ** Return the affinity for a single column of an index.
  1302   1302   */
  1303   1303   char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
  1304   1304     assert( iCol>=0 && iCol<pIdx->nColumn );
  1305   1305     if( !pIdx->zColAff ){
  1306   1306       if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
................................................................................
  1307   1307     }
  1308   1308     assert( pIdx->zColAff[iCol]!=0 );
  1309   1309     return pIdx->zColAff[iCol];
  1310   1310   }
  1311   1311   #endif
  1312   1312   
  1313   1313   
  1314         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1314  +#ifdef SQLITE_ENABLE_STAT4
  1315   1315   /* 
  1316   1316   ** This function is called to estimate the number of rows visited by a
  1317   1317   ** range-scan on a skip-scan index. For example:
  1318   1318   **
  1319   1319   **   CREATE INDEX i1 ON t1(a, b, c);
  1320   1320   **   SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?;
  1321   1321   **
................................................................................
  1413   1413   
  1414   1414     sqlite3ValueFree(p1);
  1415   1415     sqlite3ValueFree(p2);
  1416   1416     sqlite3ValueFree(pVal);
  1417   1417   
  1418   1418     return rc;
  1419   1419   }
  1420         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1420  +#endif /* SQLITE_ENABLE_STAT4 */
  1421   1421   
  1422   1422   /*
  1423   1423   ** This function is used to estimate the number of rows that will be visited
  1424   1424   ** by scanning an index for a range of values. The range may have an upper
  1425   1425   ** bound, a lower bound, or both. The WHERE clause terms that set the upper
  1426   1426   ** and lower bounds are represented by pLower and pUpper respectively. For
  1427   1427   ** example, assuming that index p is on t1(a):
................................................................................
  1466   1466     WhereTerm *pUpper,   /* Upper bound on the range. ex: "x<455" Might be NULL */
  1467   1467     WhereLoop *pLoop     /* Modify the .nOut and maybe .rRun fields */
  1468   1468   ){
  1469   1469     int rc = SQLITE_OK;
  1470   1470     int nOut = pLoop->nOut;
  1471   1471     LogEst nNew;
  1472   1472   
  1473         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1473  +#ifdef SQLITE_ENABLE_STAT4
  1474   1474     Index *p = pLoop->u.btree.pIndex;
  1475   1475     int nEq = pLoop->u.btree.nEq;
  1476   1476   
  1477         -  if( p->nSample>0 && nEq<p->nSampleCol
  1478         -   && OptimizationEnabled(pParse->db, SQLITE_Stat34)
         1477  +  if( p->nSample>0 && ALWAYS(nEq<p->nSampleCol)
         1478  +   && OptimizationEnabled(pParse->db, SQLITE_Stat4)
  1479   1479     ){
  1480   1480       if( nEq==pBuilder->nRecValid ){
  1481   1481         UnpackedRecord *pRec = pBuilder->pRec;
  1482   1482         tRowcnt a[2];
  1483   1483         int nBtm = pLoop->u.btree.nBtm;
  1484   1484         int nTop = pLoop->u.btree.nTop;
  1485   1485   
................................................................................
  1569   1569         pBuilder->pRec = pRec;
  1570   1570         if( rc==SQLITE_OK ){
  1571   1571           if( iUpper>iLower ){
  1572   1572             nNew = sqlite3LogEst(iUpper - iLower);
  1573   1573             /* TUNING:  If both iUpper and iLower are derived from the same
  1574   1574             ** sample, then assume they are 4x more selective.  This brings
  1575   1575             ** the estimated selectivity more in line with what it would be
  1576         -          ** if estimated without the use of STAT3/4 tables. */
         1576  +          ** if estimated without the use of STAT4 tables. */
  1577   1577             if( iLwrIdx==iUprIdx ) nNew -= 20;  assert( 20==sqlite3LogEst(4) );
  1578   1578           }else{
  1579   1579             nNew = 10;        assert( 10==sqlite3LogEst(2) );
  1580   1580           }
  1581   1581           if( nNew<nOut ){
  1582   1582             nOut = nNew;
  1583   1583           }
................................................................................
  1618   1618                       pLoop->nOut, nOut));
  1619   1619     }
  1620   1620   #endif
  1621   1621     pLoop->nOut = (LogEst)nOut;
  1622   1622     return rc;
  1623   1623   }
  1624   1624   
  1625         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1625  +#ifdef SQLITE_ENABLE_STAT4
  1626   1626   /*
  1627   1627   ** Estimate the number of rows that will be returned based on
  1628   1628   ** an equality constraint x=VALUE and where that VALUE occurs in
  1629   1629   ** the histogram data.  This only works when x is the left-most
  1630         -** column of an index and sqlite_stat3 histogram data is available
         1630  +** column of an index and sqlite_stat4 histogram data is available
  1631   1631   ** for that index.  When pExpr==NULL that means the constraint is
  1632   1632   ** "x IS NULL" instead of "x=VALUE".
  1633   1633   **
  1634   1634   ** Write the estimated row count into *pnRow and return SQLITE_OK. 
  1635   1635   ** If unable to make an estimate, leave *pnRow unchanged and return
  1636   1636   ** non-zero.
  1637   1637   **
................................................................................
  1681   1681     whereKeyStats(pParse, p, pRec, 0, a);
  1682   1682     WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
  1683   1683                      p->zName, nEq-1, (int)a[1]));
  1684   1684     *pnRow = a[1];
  1685   1685     
  1686   1686     return rc;
  1687   1687   }
  1688         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1688  +#endif /* SQLITE_ENABLE_STAT4 */
  1689   1689   
  1690         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         1690  +#ifdef SQLITE_ENABLE_STAT4
  1691   1691   /*
  1692   1692   ** Estimate the number of rows that will be returned based on
  1693   1693   ** an IN constraint where the right-hand side of the IN operator
  1694   1694   ** is a list of values.  Example:
  1695   1695   **
  1696   1696   **        WHERE x IN (1,2,3,4)
  1697   1697   **
................................................................................
  1730   1730       if( nRowEst > nRow0 ) nRowEst = nRow0;
  1731   1731       *pnRow = nRowEst;
  1732   1732       WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst));
  1733   1733     }
  1734   1734     assert( pBuilder->nRecValid==nRecValid );
  1735   1735     return rc;
  1736   1736   }
  1737         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1737  +#endif /* SQLITE_ENABLE_STAT4 */
  1738   1738   
  1739   1739   
  1740   1740   #ifdef WHERETRACE_ENABLED
  1741   1741   /*
  1742   1742   ** Print the content of a WhereTerm object
  1743   1743   */
  1744   1744   static void whereTermPrint(WhereTerm *pTerm, int iTerm){
................................................................................
  2451   2451     rSize = pProbe->aiRowLogEst[0];
  2452   2452     rLogSize = estLog(rSize);
  2453   2453     for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
  2454   2454       u16 eOp = pTerm->eOperator;   /* Shorthand for pTerm->eOperator */
  2455   2455       LogEst rCostIdx;
  2456   2456       LogEst nOutUnadjusted;        /* nOut before IN() and WHERE adjustments */
  2457   2457       int nIn = 0;
  2458         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         2458  +#ifdef SQLITE_ENABLE_STAT4
  2459   2459       int nRecValid = pBuilder->nRecValid;
  2460   2460   #endif
  2461   2461       if( (eOp==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0)
  2462   2462        && indexColumnNotNull(pProbe, saved_nEq)
  2463   2463       ){
  2464   2464         continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */
  2465   2465       }
................................................................................
  2609   2609       /* At this point pNew->nOut is set to the number of rows expected to
  2610   2610       ** be visited by the index scan before considering term pTerm, or the
  2611   2611       ** values of nIn and nInMul. In other words, assuming that all 
  2612   2612       ** "x IN(...)" terms are replaced with "x = ?". This block updates
  2613   2613       ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul).  */
  2614   2614       assert( pNew->nOut==saved_nOut );
  2615   2615       if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
  2616         -      /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4
         2616  +      /* Adjust nOut using stat4 data. Or, if there is no stat4
  2617   2617         ** data, using some other estimate.  */
  2618   2618         whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
  2619   2619       }else{
  2620   2620         int nEq = ++pNew->u.btree.nEq;
  2621   2621         assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
  2622   2622   
  2623   2623         assert( pNew->nOut==saved_nOut );
  2624   2624         if( pTerm->truthProb<=0 && pProbe->aiColumn[saved_nEq]>=0 ){
  2625   2625           assert( (eOp & WO_IN) || nIn==0 );
  2626   2626           testcase( eOp & WO_IN );
  2627   2627           pNew->nOut += pTerm->truthProb;
  2628   2628           pNew->nOut -= nIn;
  2629   2629         }else{
  2630         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         2630  +#ifdef SQLITE_ENABLE_STAT4
  2631   2631           tRowcnt nOut = 0;
  2632   2632           if( nInMul==0 
  2633   2633            && pProbe->nSample 
  2634   2634            && pNew->u.btree.nEq<=pProbe->nSampleCol
  2635   2635            && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
  2636         -         && OptimizationEnabled(db, SQLITE_Stat34)
         2636  +         && OptimizationEnabled(db, SQLITE_Stat4)
  2637   2637           ){
  2638   2638             Expr *pExpr = pTerm->pExpr;
  2639   2639             if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
  2640   2640               testcase( eOp & WO_EQ );
  2641   2641               testcase( eOp & WO_IS );
  2642   2642               testcase( eOp & WO_ISNULL );
  2643   2643               rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
................................................................................
  2691   2691   
  2692   2692       if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
  2693   2693        && pNew->u.btree.nEq<pProbe->nColumn
  2694   2694       ){
  2695   2695         whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
  2696   2696       }
  2697   2697       pNew->nOut = saved_nOut;
  2698         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         2698  +#ifdef SQLITE_ENABLE_STAT4
  2699   2699       pBuilder->nRecValid = nRecValid;
  2700   2700   #endif
  2701   2701     }
  2702   2702     pNew->prereq = saved_prereq;
  2703   2703     pNew->u.btree.nEq = saved_nEq;
  2704   2704     pNew->u.btree.nBtm = saved_nBtm;
  2705   2705     pNew->u.btree.nTop = saved_nTop;
................................................................................
  3064   3064       if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
  3065   3065         /* If a non-unique index is used, or if a prefix of the key for
  3066   3066         ** unique index is used (making the index functionally non-unique)
  3067   3067         ** then the sqlite_stat1 data becomes important for scoring the
  3068   3068         ** plan */
  3069   3069         pTab->tabFlags |= TF_StatsUsed;
  3070   3070       }
  3071         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
         3071  +#ifdef SQLITE_ENABLE_STAT4
  3072   3072       sqlite3Stat4ProbeFree(pBuilder->pRec);
  3073   3073       pBuilder->nRecValid = 0;
  3074   3074       pBuilder->pRec = 0;
  3075   3075   #endif
  3076   3076     }
  3077   3077     return rc;
  3078   3078   }

Changes to src/whereInt.h.

   275    275   #define TERM_DYNAMIC    0x01   /* Need to call sqlite3ExprDelete(db, pExpr) */
   276    276   #define TERM_VIRTUAL    0x02   /* Added by the optimizer.  Do not code */
   277    277   #define TERM_CODED      0x04   /* This term is already coded */
   278    278   #define TERM_COPIED     0x08   /* Has a child */
   279    279   #define TERM_ORINFO     0x10   /* Need to free the WhereTerm.u.pOrInfo object */
   280    280   #define TERM_ANDINFO    0x20   /* Need to free the WhereTerm.u.pAndInfo obj */
   281    281   #define TERM_OR_OK      0x40   /* Used during OR-clause processing */
   282         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          282  +#ifdef SQLITE_ENABLE_STAT4
   283    283   #  define TERM_VNULL    0x80   /* Manufactured x>NULL or x<=NULL term */
   284    284   #else
   285         -#  define TERM_VNULL    0x00   /* Disabled if not using stat3 */
          285  +#  define TERM_VNULL    0x00   /* Disabled if not using stat4 */
   286    286   #endif
   287    287   #define TERM_LIKEOPT    0x100  /* Virtual terms from the LIKE optimization */
   288    288   #define TERM_LIKECOND   0x200  /* Conditionally this LIKE operator term */
   289    289   #define TERM_LIKE       0x400  /* The original LIKE operator */
   290    290   #define TERM_IS         0x800  /* Term.pExpr is an IS operator */
   291    291   #define TERM_VARSELECT  0x1000 /* Term.pExpr contains a correlated sub-query */
   292    292   
................................................................................
   395    395   */
   396    396   struct WhereLoopBuilder {
   397    397     WhereInfo *pWInfo;        /* Information about this WHERE */
   398    398     WhereClause *pWC;         /* WHERE clause terms */
   399    399     ExprList *pOrderBy;       /* ORDER BY clause */
   400    400     WhereLoop *pNew;          /* Template WhereLoop */
   401    401     WhereOrSet *pOrSet;       /* Record best loops here, if not NULL */
   402         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
          402  +#ifdef SQLITE_ENABLE_STAT4
   403    403     UnpackedRecord *pRec;     /* Probe for stat4 (if required) */
   404    404     int nRecValid;            /* Number of valid fields currently in pRec */
   405    405   #endif
   406    406     unsigned int bldFlags;    /* SQLITE_BLDF_* flags */
   407    407     unsigned int iPlanLimit;  /* Search limiter */
   408    408   };
   409    409   

Changes to src/whereexpr.c.

  1377   1377         idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
  1378   1378         pWC->a[idxNew].iField = i+1;
  1379   1379         exprAnalyze(pSrc, pWC, idxNew);
  1380   1380         markTermAsChild(pWC, idxNew, idxTerm);
  1381   1381       }
  1382   1382     }
  1383   1383   
  1384         -#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  1385         -  /* When sqlite_stat3 histogram data is available an operator of the
         1384  +#ifdef SQLITE_ENABLE_STAT4
         1385  +  /* When sqlite_stat4 histogram data is available an operator of the
  1386   1386     ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
  1387   1387     ** as "x>NULL" if x is not an INTEGER PRIMARY KEY.  So construct a
  1388   1388     ** virtual term of that form.
  1389   1389     **
  1390   1390     ** Note that the virtual term must be tagged with TERM_VNULL.
  1391   1391     */
  1392   1392     if( pExpr->op==TK_NOTNULL
  1393   1393      && pExpr->pLeft->op==TK_COLUMN
  1394   1394      && pExpr->pLeft->iColumn>=0
  1395   1395      && !ExprHasProperty(pExpr, EP_FromJoin)
  1396         -   && OptimizationEnabled(db, SQLITE_Stat34)
         1396  +   && OptimizationEnabled(db, SQLITE_Stat4)
  1397   1397     ){
  1398   1398       Expr *pNewExpr;
  1399   1399       Expr *pLeft = pExpr->pLeft;
  1400   1400       int idxNew;
  1401   1401       WhereTerm *pNewTerm;
  1402   1402   
  1403   1403       pNewExpr = sqlite3PExpr(pParse, TK_GT,
................................................................................
  1414   1414         pNewTerm->eOperator = WO_GT;
  1415   1415         markTermAsChild(pWC, idxNew, idxTerm);
  1416   1416         pTerm = &pWC->a[idxTerm];
  1417   1417         pTerm->wtFlags |= TERM_COPIED;
  1418   1418         pNewTerm->prereqAll = pTerm->prereqAll;
  1419   1419       }
  1420   1420     }
  1421         -#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
         1421  +#endif /* SQLITE_ENABLE_STAT4 */
  1422   1422   
  1423   1423     /* Prevent ON clause terms of a LEFT JOIN from being used to drive
  1424   1424     ** an index for tables to the left of the join.
  1425   1425     */
  1426   1426     testcase( pTerm!=&pWC->a[idxTerm] );
  1427   1427     pTerm = &pWC->a[idxTerm];
  1428   1428     pTerm->prereqRight |= extraRight;

Changes to test/alter.test.

   852    852   
   853    853   #-------------------------------------------------------------------------
   854    854   # Test that it is not possible to use ALTER TABLE on any system table.
   855    855   #
   856    856   set system_table_list {1 sqlite_master}
   857    857   catchsql ANALYZE
   858    858   ifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
   859         -ifcapable stat3   { lappend system_table_list 3 sqlite_stat3 }
   860    859   ifcapable stat4   { lappend system_table_list 4 sqlite_stat4 }
   861    860   
   862    861   foreach {tn tbl} $system_table_list {
   863    862     do_test alter-15.$tn.1 {
   864    863       catchsql "ALTER TABLE $tbl RENAME TO xyz"
   865    864     } [list 1 "table $tbl may not be altered"]
   866    865   

Changes to test/altertab.test.

   590    590     ALTER TABLE t0 RENAME COLUMN c0 TO c1;
   591    591   }
   592    592   do_execsql_test 18.2.2 {
   593    593     SELECT sql FROM sqlite_master;
   594    594   } {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}}
   595    595   
   596    596   finish_test
   597         -

Changes to test/altertab3.test.

   379    379   {CREATE TRIGGER AFTER INSERT ON "t1x" WHEN new.aaa NOT NULL BEGIN
   380    380       SELECT a () FILTER (WHERE aaa>0) FROM "t1x";
   381    381     END}
   382    382   }
   383    383   
   384    384   
   385    385   finish_test
   386         -

Changes to test/analyze.test.

   284    284     sqlite3 db test.db
   285    285     execsql {
   286    286       SELECT * FROM t4 WHERE x=1234;
   287    287     }
   288    288   } {}
   289    289   
   290    290   # Verify that DROP TABLE and DROP INDEX remove entries from the 
   291         -# sqlite_stat1, sqlite_stat3 and sqlite_stat4 tables.
          291  +# sqlite_stat1 and sqlite_stat4 tables.
   292    292   #
   293    293   do_test analyze-5.0 {
   294    294     execsql {
   295    295       DELETE FROM t3;
   296    296       DELETE FROM t4;
   297    297       INSERT INTO t3 VALUES(1,2,3,4);
   298    298       INSERT INTO t3 VALUES(5,6,7,8);
................................................................................
   302    302       INSERT INTO t3 SELECT a+64, b+64, c+64, d+64 FROM t3;
   303    303       INSERT INTO t4 SELECT a, b, c FROM t3;
   304    304       ANALYZE;
   305    305       SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
   306    306       SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
   307    307     }
   308    308   } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
   309         -ifcapable stat4||stat3 {
   310         -  ifcapable stat4 {set stat sqlite_stat4} else {set stat sqlite_stat3}
          309  +ifcapable stat4 {
   311    310     do_test analyze-5.1 {
   312         -    execsql "
   313         -      SELECT DISTINCT idx FROM $stat ORDER BY 1;
   314         -      SELECT DISTINCT tbl FROM $stat ORDER BY 1;
   315         -    "
          311  +    execsql {
          312  +      SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
          313  +      SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
          314  +    }
   316    315     } {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
   317    316   }
   318    317   do_test analyze-5.2 {
   319    318     execsql {
   320    319       DROP INDEX t3i2;
   321    320       SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
   322    321       SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
   323    322     }
   324    323   } {t3i1 t3i3 t4i1 t4i2 t3 t4}
   325         -ifcapable stat4||stat3 {
          324  +ifcapable stat4 {
   326    325     do_test analyze-5.3 {
   327         -    execsql "
   328         -      SELECT DISTINCT idx FROM $stat ORDER BY 1;
   329         -      SELECT DISTINCT tbl FROM $stat ORDER BY 1;
   330         -    "
          326  +    execsql {
          327  +      SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
          328  +      SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
          329  +    }
   331    330     } {t3i1 t3i3 t4i1 t4i2 t3 t4}
   332    331   }
   333    332   do_test analyze-5.4 {
   334    333     execsql {
   335    334       DROP TABLE t3;
   336    335       SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
   337    336       SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
   338    337     }
   339    338   } {t4i1 t4i2 t4}
   340         -ifcapable stat4||stat3 {
          339  +ifcapable stat4 {
   341    340     do_test analyze-5.5 {
   342         -    execsql "
   343         -      SELECT DISTINCT idx FROM $stat ORDER BY 1;
   344         -      SELECT DISTINCT tbl FROM $stat ORDER BY 1;
   345         -    "
          341  +    execsql {
          342  +      SELECT DISTINCT idx FROM sqlite_stat4 ORDER BY 1;
          343  +      SELECT DISTINCT tbl FROM sqlite_stat4 ORDER BY 1;
          344  +    }
   346    345     } {t4i1 t4i2 t4}
   347    346   }
   348    347   
   349    348   # This test corrupts the database file so it must be the last test
   350    349   # in the series.
   351    350   #
   352    351   do_test analyze-5.99 {

Changes to test/analyze3.test.

    14     14   # instead of literal constant arguments.
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   set testprefix analyze3
    20     20   
    21         -ifcapable !stat4&&!stat3 {
           21  +ifcapable !stat4 {
    22     22     finish_test
    23     23     return
    24     24   }
    25     25   
    26     26   #----------------------------------------------------------------------
    27     27   # Test Organization:
    28     28   #
................................................................................
    96     96       execsql { INSERT INTO t1 VALUES($i+100, $i) }
    97     97     }
    98     98     execsql {
    99     99       COMMIT;
   100    100       ANALYZE;
   101    101     }
   102    102   
   103         -  ifcapable stat4 {
   104         -    execsql { SELECT count(*)>0 FROM sqlite_stat4; }
   105         -  } else {
   106         -    execsql { SELECT count(*)>0 FROM sqlite_stat3; }
   107         -  }
          103  +  execsql { SELECT count(*)>0 FROM sqlite_stat4; }
   108    104   } {1}
   109    105   
   110    106   do_execsql_test analyze3-1.1.x {
   111    107     SELECT count(*) FROM t1 WHERE x>200 AND x<300;
   112    108     SELECT count(*) FROM t1 WHERE x>0 AND x<1100;
   113    109   } {99 1000}
   114    110   

Changes to test/analyze5.test.

    13     13   # in this file is the use of the sqlite_stat4 histogram data on tables
    14     14   # with many repeated values and only a few distinct values.
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20         -ifcapable !stat4&&!stat3 {
           20  +ifcapable !stat4 {
    21     21     finish_test
    22     22     return
    23     23   }
    24     24   
    25     25   set testprefix analyze5
    26     26   
    27     27   proc eqp {sql {db db}} {
................................................................................
    63     63       CREATE INDEX t1v ON t1(v);  -- mixed case text
    64     64       CREATE INDEX t1w ON t1(w);  -- integers 0, 1, 2 and a few NULLs
    65     65       CREATE INDEX t1x ON t1(x);  -- integers 1, 2, 3 and many NULLs
    66     66       CREATE INDEX t1y ON t1(y);  -- integers 0 and very few 1s
    67     67       CREATE INDEX t1z ON t1(z);  -- integers 0, 1, 2, and 3
    68     68       ANALYZE;
    69     69     }
    70         -  ifcapable stat4 {
    71         -    db eval {
    72         -      SELECT DISTINCT lindex(test_decode(sample),0) 
    73         -        FROM sqlite_stat4 WHERE idx='t1u' ORDER BY nlt;
    74         -    }
    75         -  } else {
    76         -    db eval {
    77         -      SELECT sample FROM sqlite_stat3 WHERE idx='t1u' ORDER BY nlt;
    78         -    }
           70  +  db eval {
           71  +    SELECT DISTINCT lindex(test_decode(sample),0) 
           72  +      FROM sqlite_stat4 WHERE idx='t1u' ORDER BY nlt;
    79     73     }
    80     74   } {alpha bravo charlie delta}
    81     75   
    82     76   do_test analyze5-1.1 {
    83         -  ifcapable stat4 {
    84         -    db eval {
    85         -      SELECT DISTINCT lower(lindex(test_decode(sample), 0)) 
    86         -        FROM sqlite_stat4 WHERE idx='t1v' ORDER BY 1
    87         -    }
    88         -  } else {
    89         -    db eval {
    90         -      SELECT lower(sample) FROM sqlite_stat3 WHERE idx='t1v' ORDER BY 1
    91         -    }
           77  +  db eval {
           78  +    SELECT DISTINCT lower(lindex(test_decode(sample), 0)) 
           79  +      FROM sqlite_stat4 WHERE idx='t1v' ORDER BY 1
    92     80     }
    93     81   } {alpha bravo charlie delta}
    94         -ifcapable stat4 {
    95         -  do_test analyze5-1.2 {
    96         -    db eval {SELECT idx, count(*) FROM sqlite_stat4 GROUP BY 1 ORDER BY 1}
    97         -  } {t1t 8 t1u 8 t1v 8 t1w 8 t1x 8 t1y 9 t1z 8}
    98         -} else {
    99         -  do_test analyze5-1.2 {
   100         -    db eval {SELECT idx, count(*) FROM sqlite_stat3 GROUP BY 1 ORDER BY 1}
   101         -  } {t1t 4 t1u 4 t1v 4 t1w 4 t1x 4 t1y 2 t1z 4}
   102         -}
           82  +do_test analyze5-1.2 {
           83  +  db eval {SELECT idx, count(*) FROM sqlite_stat4 GROUP BY 1 ORDER BY 1}
           84  +} {t1t 8 t1u 8 t1v 8 t1w 8 t1x 8 t1y 9 t1z 8}
   103     85   
   104     86   # Verify that range queries generate the correct row count estimates
   105     87   #
   106     88   foreach {testid where index rows} {
   107     89       1  {z>=0 AND z<=0}       t1z  400
   108     90       2  {z>=1 AND z<=1}       t1z  300
   109     91       3  {z>=2 AND z<=2}       t1z  175

Changes to test/analyze6.test.

    13     13   # in this file a corner-case query planner optimization involving the
    14     14   # join order of two tables of different sizes.
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20         -ifcapable !stat4&&!stat3 {
           20  +ifcapable !stat4 {
    21     21     finish_test
    22     22     return
    23     23   }
    24     24   
    25     25   set testprefix analyze6
    26     26   
    27     27   proc eqp {sql {db db}} {

Changes to test/analyze7.test.

    78     78   } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
    79     79   do_test analyze7-3.1 {
    80     80     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE b=123;}
    81     81   } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
    82     82   do_test analyze7-3.2.1 {
    83     83     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
    84     84   } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    85         -ifcapable stat4||stat3 {
           85  +ifcapable stat4 {
    86     86     # If ENABLE_STAT4 is defined, SQLite comes up with a different estimated
    87     87     # row count for (c=2) than it does for (c=?).
    88     88     do_test analyze7-3.2.2 {
    89     89       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
    90     90     } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    91     91   } else {
    92     92     # If ENABLE_STAT4 is not defined, the expected row count for (c=2) is the
................................................................................
    95     95       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
    96     96     } {/*SEARCH TABLE t1 USING INDEX t1cd (c=?)*/}
    97     97   }
    98     98   do_test analyze7-3.3 {
    99     99     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
   100    100   } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
   101    101   
   102         -ifcapable {!stat4 && !stat3} {
          102  +ifcapable {!stat4} {
   103    103     do_test analyze7-3.4 {
   104    104       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123}
   105    105     } {/*SEARCH TABLE t1 USING INDEX t1b (b=?)*/}
   106    106     do_test analyze7-3.5 {
   107    107       execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123}
   108    108     } {/*SEARCH TABLE t1 USING INDEX t1a (a=?)*/}
   109    109   }
   110    110   do_test analyze7-3.6 {
   111    111     execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123}
   112    112   } {/*SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?)*/}
   113    113   
   114    114   finish_test

Changes to test/analyze8.test.

     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   # This file implements tests for SQLite library.  The focus of the tests
    13         -# in this file is testing the capabilities of sqlite_stat3.
           13  +# in this file is testing the capabilities of sqlite_stat4.
    14     14   #
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19         -ifcapable !stat4&&!stat3 {
           19  +ifcapable !stat4 {
    20     20     finish_test
    21     21     return
    22     22   }
    23     23   
    24     24   set testprefix analyze8
    25     25   
    26     26   proc eqp {sql {db db}} {

Deleted test/analyzeA.test.

     1         -# 2013 August 3
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -#
    12         -# This file contains automated tests used to verify that the current build
    13         -# (which must be either ENABLE_STAT3 or ENABLE_STAT4) works with both stat3
    14         -# and stat4 data.
    15         -#
    16         -
    17         -set testdir [file dirname $argv0]
    18         -source $testdir/tester.tcl
    19         -set testprefix analyzeA
    20         -
    21         -ifcapable !stat4&&!stat3 {
    22         -  finish_test
    23         -  return
    24         -}
    25         -
    26         -# Populate the stat3 table according to the current contents of the db
    27         -#
    28         -proc populate_stat3 {{bDropTable 1}} {
    29         -  # Open a second connection on database "test.db" and run ANALYZE. If this
    30         -  # is an ENABLE_STAT3 build, this is all that is required to create and
    31         -  # populate the sqlite_stat3 table. 
    32         -  # 
    33         -  sqlite3 db2 test.db
    34         -  execsql { ANALYZE }
    35         -
    36         -  # Now, if this is an ENABLE_STAT4 build, create and populate the 
    37         -  # sqlite_stat3 table based on the stat4 data gathered by the ANALYZE
    38         -  # above. Then drop the sqlite_stat4 table.
    39         -  #
    40         -  ifcapable stat4 {
    41         -    db2 func lindex lindex
    42         -    execsql {
    43         -      PRAGMA writable_schema = on;
    44         -      CREATE TABLE sqlite_stat3(tbl,idx,neq,nlt,ndlt,sample);
    45         -      INSERT INTO sqlite_stat3 
    46         -      SELECT DISTINCT tbl, idx, 
    47         -        lindex(neq,0), lindex(nlt,0), lindex(ndlt,0), test_extract(sample, 0)
    48         -      FROM sqlite_stat4;
    49         -    } db2
    50         -    if {$bDropTable} { execsql {DROP TABLE sqlite_stat4} db2 }
    51         -    execsql { PRAGMA writable_schema = off }
    52         -  }
    53         -
    54         -  # Modify the database schema cookie to ensure that the other connection
    55         -  # reloads the schema.
    56         -  #
    57         -  execsql {
    58         -    CREATE TABLE obscure_tbl_nm(x);
    59         -    DROP TABLE obscure_tbl_nm;
    60         -  } db2
    61         -  db2 close
    62         -}
    63         -
    64         -# Populate the stat4 table according to the current contents of the db
    65         -#
    66         -proc populate_stat4 {{bDropTable 1}} {
    67         -  sqlite3 db2 test.db
    68         -  execsql { ANALYZE }
    69         -
    70         -  ifcapable stat3 {
    71         -    execsql {
    72         -      PRAGMA writable_schema = on;
    73         -      CREATE TABLE sqlite_stat4(tbl,idx,neq,nlt,ndlt,sample);
    74         -      INSERT INTO sqlite_stat4 
    75         -      SELECT tbl, idx, neq, nlt, ndlt, sqlite_record(sample) 
    76         -      FROM sqlite_stat3;
    77         -    } db2
    78         -    if {$bDropTable} { execsql {DROP TABLE sqlite_stat3} db2 }
    79         -    execsql { PRAGMA writable_schema = off }
    80         -  }
    81         - 
    82         -  # Modify the database schema cookie to ensure that the other connection
    83         -  # reloads the schema.
    84         -  #
    85         -  execsql {
    86         -    CREATE TABLE obscure_tbl_nm(x);
    87         -    DROP TABLE obscure_tbl_nm;
    88         -  } db2
    89         -  db2 close
    90         -}
    91         -
    92         -# Populate the stat4 table according to the current contents of the db.
    93         -# Leave deceptive data in the stat3 table. This data should be ignored
    94         -# in favour of that from the stat4 table.
    95         -#
    96         -proc populate_both {} {
    97         -  ifcapable stat4 { populate_stat3 0 }
    98         -  ifcapable stat3 { populate_stat4 0 }
    99         -
   100         -  sqlite3 db2 test.db
   101         -  execsql {
   102         -    PRAGMA writable_schema = on;
   103         -    UPDATE sqlite_stat3 SET idx = 
   104         -      CASE idx WHEN 't1b' THEN 't1c' ELSE 't1b'
   105         -    END;
   106         -    PRAGMA writable_schema = off;
   107         -    CREATE TABLE obscure_tbl_nm(x);
   108         -    DROP TABLE obscure_tbl_nm;
   109         -  } db2
   110         -  db2 close
   111         -}
   112         -
   113         -foreach {tn analyze_cmd} {
   114         -  1 populate_stat4 
   115         -  2 populate_stat3
   116         -  3 populate_both
   117         -} {
   118         -  reset_db
   119         -  do_test 1.$tn.1 {
   120         -    execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT) }
   121         -    for {set i 0} {$i < 100} {incr i} {
   122         -      set c [expr int(pow(1.1,$i)/100)]
   123         -      set b [expr 125 - int(pow(1.1,99-$i))/100]
   124         -      execsql {INSERT INTO t1 VALUES($i, $b, $c)}
   125         -    }
   126         -  } {}
   127         -
   128         -  execsql { CREATE INDEX t1b ON t1(b) }
   129         -  execsql { CREATE INDEX t1c ON t1(c) }
   130         -  $analyze_cmd
   131         -
   132         -  do_execsql_test 1.$tn.2.1 { SELECT count(*) FROM t1 WHERE b=31 } 1
   133         -  do_execsql_test 1.$tn.2.2 { SELECT count(*) FROM t1 WHERE c=0  } 49
   134         -  do_execsql_test 1.$tn.2.3 { SELECT count(*) FROM t1 WHERE b=125  } 49
   135         -  do_execsql_test 1.$tn.2.4 { SELECT count(*) FROM t1 WHERE c=16  } 1
   136         -
   137         -  do_eqp_test 1.$tn.2.5 {
   138         -    SELECT * FROM t1 WHERE b = 31 AND c = 0;
   139         -  } {SEARCH TABLE t1 USING INDEX t1b (b=?)}
   140         -  do_eqp_test 1.$tn.2.6 {
   141         -    SELECT * FROM t1 WHERE b = 125 AND c = 16;
   142         -  } {SEARCH TABLE t1 USING INDEX t1c (c=?)}
   143         -
   144         -  do_execsql_test 1.$tn.3.1 { 
   145         -    SELECT count(*) FROM t1 WHERE b BETWEEN 0 AND 50
   146         -  } {6}
   147         -  do_execsql_test 1.$tn.3.2 { 
   148         -    SELECT count(*) FROM t1 WHERE c BETWEEN 0 AND 50
   149         -  } {90}
   150         -  do_execsql_test 1.$tn.3.3 { 
   151         -    SELECT count(*) FROM t1 WHERE b BETWEEN 75 AND 125
   152         -  } {90}
   153         -  do_execsql_test 1.$tn.3.4 { 
   154         -    SELECT count(*) FROM t1 WHERE c BETWEEN 75 AND 125
   155         -  } {6}
   156         -
   157         -  do_eqp_test 1.$tn.3.5 {
   158         -    SELECT * FROM t1 WHERE b BETWEEN 0 AND 50 AND c BETWEEN 0 AND 50
   159         -  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
   160         -
   161         -  do_eqp_test 1.$tn.3.6 {
   162         -    SELECT * FROM t1 WHERE b BETWEEN 75 AND 125 AND c BETWEEN 75 AND 125
   163         -  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
   164         -
   165         -  do_eqp_test 1.$tn.3.7 {
   166         -    SELECT * FROM t1 WHERE b BETWEEN +0 AND +50 AND c BETWEEN +0 AND +50
   167         -  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
   168         -
   169         -  do_eqp_test 1.$tn.3.8 {
   170         -    SELECT * FROM t1
   171         -     WHERE b BETWEEN cast('0' AS int) AND cast('50.0' AS real)
   172         -       AND c BETWEEN cast('0' AS numeric) AND cast('50.0' AS real)
   173         -  } {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)}
   174         -
   175         -  do_eqp_test 1.$tn.3.9 {
   176         -    SELECT * FROM t1 WHERE b BETWEEN +75 AND +125 AND c BETWEEN +75 AND +125
   177         -  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
   178         -
   179         -  do_eqp_test 1.$tn.3.10 {
   180         -    SELECT * FROM t1
   181         -     WHERE b BETWEEN cast('75' AS int) AND cast('125.0' AS real)
   182         -       AND c BETWEEN cast('75' AS numeric) AND cast('125.0' AS real)
   183         -  } {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?)}
   184         -}
   185         -
   186         -finish_test

Deleted test/analyzeB.test.

     1         -# 2013 August 3
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -#
    12         -# This file contains automated tests used to verify that the sqlite_stat3
    13         -# functionality is working. The tests in this file are based on a subset
    14         -# of the sqlite_stat4 tests in analyze9.test.
    15         -#
    16         -
    17         -set testdir [file dirname $argv0]
    18         -source $testdir/tester.tcl
    19         -set testprefix analyzeB
    20         -
    21         -ifcapable !stat3 {
    22         -  finish_test
    23         -  return
    24         -}
    25         -
    26         -do_execsql_test 1.0 {
    27         -  CREATE TABLE t1(a TEXT, b TEXT); 
    28         -  INSERT INTO t1 VALUES('(0)', '(0)');
    29         -  INSERT INTO t1 VALUES('(1)', '(1)');
    30         -  INSERT INTO t1 VALUES('(2)', '(2)');
    31         -  INSERT INTO t1 VALUES('(3)', '(3)');
    32         -  INSERT INTO t1 VALUES('(4)', '(4)');
    33         -  CREATE INDEX i1 ON t1(a, b);
    34         -} {}
    35         -
    36         -
    37         -do_execsql_test 1.1 {
    38         -  ANALYZE;
    39         -} {}
    40         -
    41         -do_execsql_test 1.2 {
    42         -  SELECT tbl,idx,nEq,nLt,nDLt,quote(sample) FROM sqlite_stat3;
    43         -} {
    44         -  t1 i1 1 0 0 '(0)'
    45         -  t1 i1 1 1 1 '(1)'
    46         -  t1 i1 1 2 2 '(2)'
    47         -  t1 i1 1 3 3 '(3)'
    48         -  t1 i1 1 4 4 '(4)'
    49         -}
    50         -
    51         -if {[permutation] != "utf16"} {
    52         -  do_execsql_test 1.3 {
    53         -    SELECT tbl,idx,nEq,nLt,nDLt,quote(sample) FROM sqlite_stat3;
    54         -  } {
    55         -    t1 i1 1 0 0 '(0)'
    56         -    t1 i1 1 1 1 '(1)'
    57         -    t1 i1 1 2 2 '(2)'
    58         -    t1 i1 1 3 3 '(3)'
    59         -    t1 i1 1 4 4 '(4)'
    60         -  }
    61         -}
    62         -
    63         -
    64         -#-------------------------------------------------------------------------
    65         -# This is really just to test SQL user function "test_decode".
    66         -#
    67         -reset_db
    68         -do_execsql_test 2.1 {
    69         -  CREATE TABLE t1(a, b, c);
    70         -  INSERT INTO t1(a) VALUES('some text');
    71         -  INSERT INTO t1(a) VALUES(14);
    72         -  INSERT INTO t1(a) VALUES(NULL);
    73         -  INSERT INTO t1(a) VALUES(22.0);
    74         -  INSERT INTO t1(a) VALUES(x'656667');
    75         -  CREATE INDEX i1 ON t1(a, b, c);
    76         -  ANALYZE;
    77         -  SELECT quote(sample) FROM sqlite_stat3;
    78         -} {
    79         -  NULL 14 22.0 {'some text'} X'656667' 
    80         -}
    81         -
    82         -#-------------------------------------------------------------------------
    83         -# 
    84         -reset_db
    85         -do_execsql_test 3.1 {
    86         -  CREATE TABLE t2(a, b);
    87         -  CREATE INDEX i2 ON t2(a, b);
    88         -  BEGIN;
    89         -}
    90         -
    91         -do_test 3.2 {
    92         -  for {set i 0} {$i < 1000} {incr i} {
    93         -    set a [expr $i / 10]
    94         -    set b [expr int(rand() * 15.0)]
    95         -    execsql { INSERT INTO t2 VALUES($a, $b) }
    96         -  }
    97         -  execsql COMMIT
    98         -} {}
    99         -
   100         -db func lindex lindex
   101         -
   102         -# Each value of "a" occurs exactly 10 times in the table.
   103         -#
   104         -do_execsql_test 3.3.1 {
   105         -  SELECT count(*) FROM t2 GROUP BY a;
   106         -} [lrange [string repeat "10 " 100] 0 99]
   107         -
   108         -# The first element in the "nEq" list of all samples should therefore be 10.
   109         -#
   110         -do_execsql_test 3.3.2 {
   111         -  ANALYZE;
   112         -  SELECT nEq FROM sqlite_stat3;
   113         -} [lrange [string repeat "10 " 100] 0 23]
   114         -
   115         -#-------------------------------------------------------------------------
   116         -# 
   117         -do_execsql_test 3.4 {
   118         -  DROP TABLE IF EXISTS t1;
   119         -  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
   120         -  INSERT INTO t1 VALUES(1, 1, 'one-a');
   121         -  INSERT INTO t1 VALUES(11, 1, 'one-b');
   122         -  INSERT INTO t1 VALUES(21, 1, 'one-c');
   123         -  INSERT INTO t1 VALUES(31, 1, 'one-d');
   124         -  INSERT INTO t1 VALUES(41, 1, 'one-e');
   125         -  INSERT INTO t1 VALUES(51, 1, 'one-f');
   126         -  INSERT INTO t1 VALUES(61, 1, 'one-g');
   127         -  INSERT INTO t1 VALUES(71, 1, 'one-h');
   128         -  INSERT INTO t1 VALUES(81, 1, 'one-i');
   129         -  INSERT INTO t1 VALUES(91, 1, 'one-j');
   130         -  INSERT INTO t1 SELECT a+1,2,'two' || substr(c,4) FROM t1;
   131         -  INSERT INTO t1 SELECT a+2,3,'three'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
   132         -  INSERT INTO t1 SELECT a+3,4,'four'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
   133         -  INSERT INTO t1 SELECT a+4,5,'five'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';
   134         -  INSERT INTO t1 SELECT a+5,6,'six'||substr(c,4) FROM t1 WHERE c GLOB 'one-*';	
   135         -  CREATE INDEX t1b ON t1(b);
   136         -  ANALYZE;
   137         -  SELECT c FROM t1 WHERE b=3 AND a BETWEEN 30 AND 60;
   138         -} {three-d three-e three-f}
   139         -
   140         -
   141         -#-------------------------------------------------------------------------
   142         -# These tests verify that the sample selection for stat3 appears to be 
   143         -# working as designed.
   144         -#
   145         -
   146         -reset_db
   147         -db func lindex lindex
   148         -db func lrange lrange
   149         -
   150         -do_execsql_test 4.0 {
   151         -  DROP TABLE IF EXISTS t1;
   152         -  CREATE TABLE t1(a, b, c);
   153         -  CREATE INDEX i1 ON t1(c, b, a);
   154         -}
   155         -
   156         -
   157         -proc insert_filler_rows_n {iStart args} {
   158         -  set A(-ncopy) 1
   159         -  set A(-nval) 1
   160         -
   161         -  foreach {k v} $args {
   162         -    if {[info exists A($k)]==0} { error "no such option: $k" }
   163         -    set A($k) $v
   164         -  }
   165         -  if {[llength $args] % 2} {
   166         -    error "option requires an argument: [lindex $args end]"
   167         -  }
   168         -
   169         -  for {set i 0} {$i < $A(-nval)} {incr i} {
   170         -    set iVal [expr $iStart+$i]
   171         -    for {set j 0} {$j < $A(-ncopy)} {incr j} {
   172         -      execsql { INSERT INTO t1 VALUES($iVal, $iVal, $iVal) }
   173         -    }
   174         -  }
   175         -}
   176         -
   177         -do_test 4.1 {
   178         -  execsql { BEGIN }
   179         -  insert_filler_rows_n  0  -ncopy 10 -nval 19
   180         -  insert_filler_rows_n 20  -ncopy  1 -nval 100
   181         -
   182         -  execsql {
   183         -    INSERT INTO t1(c, b, a) VALUES(200, 1, 'a');
   184         -    INSERT INTO t1(c, b, a) VALUES(200, 1, 'b');
   185         -    INSERT INTO t1(c, b, a) VALUES(200, 1, 'c');
   186         -
   187         -    INSERT INTO t1(c, b, a) VALUES(200, 2, 'e');
   188         -    INSERT INTO t1(c, b, a) VALUES(200, 2, 'f');
   189         -
   190         -    INSERT INTO t1(c, b, a) VALUES(201, 3, 'g');
   191         -    INSERT INTO t1(c, b, a) VALUES(201, 4, 'h');
   192         -
   193         -    ANALYZE;
   194         -    SELECT count(*) FROM sqlite_stat3;
   195         -    SELECT count(*) FROM t1;
   196         -  }
   197         -} {24 297}
   198         -
   199         -do_execsql_test 4.2 {
   200         -  SELECT neq, nlt, ndlt, sample FROM sqlite_stat3 ORDER BY rowid LIMIT 16;
   201         -} {
   202         -  10 0 0 0
   203         -  10 10 1 1
   204         -  10 20 2 2
   205         -  10 30 3 3
   206         -  10 40 4 4
   207         -  10 50 5 5
   208         -  10 60 6 6
   209         -  10 70 7 7
   210         -  10 80 8 8
   211         -  10 90 9 9
   212         -  10 100 10 10
   213         -  10 110 11 11
   214         -  10 120 12 12
   215         -  10 130 13 13
   216         -  10 140 14 14
   217         -  10 150 15 15
   218         -}
   219         -
   220         -do_execsql_test 4.3 {
   221         -  SELECT neq, nlt, ndlt, sample FROM sqlite_stat3
   222         -  ORDER BY rowid DESC LIMIT 2;
   223         -} {
   224         -  2 295 120 201
   225         -  5 290 119 200
   226         -}
   227         -
   228         -do_execsql_test 4.4 { SELECT count(DISTINCT c) FROM t1 WHERE c<201 } 120
   229         -do_execsql_test 4.5 { SELECT count(DISTINCT c) FROM t1 WHERE c<200 } 119
   230         -
   231         -reset_db
   232         -do_test 4.7 {
   233         -  execsql { 
   234         -    BEGIN;
   235         -    CREATE TABLE t1(o,t INTEGER PRIMARY KEY);
   236         -    CREATE INDEX i1 ON t1(o);
   237         -  }
   238         -  for {set i 0} {$i<10000} {incr i [expr (($i<1000)?1:10)]} {
   239         -    execsql { INSERT INTO t1 VALUES('x', $i) }
   240         -  }
   241         -  execsql {
   242         -    COMMIT;
   243         -    ANALYZE;
   244         -    SELECT count(*) FROM sqlite_stat3;
   245         -  }
   246         -} {1}
   247         -do_execsql_test 4.8 {
   248         -  SELECT sample FROM sqlite_stat3;
   249         -} {x}
   250         -
   251         -
   252         -#-------------------------------------------------------------------------
   253         -# The following would cause a crash at one point.
   254         -#
   255         -reset_db
   256         -do_execsql_test 5.1 {
   257         -  PRAGMA encoding = 'utf-16';
   258         -  CREATE TABLE t0(v);
   259         -  ANALYZE;
   260         -}
   261         -
   262         -#-------------------------------------------------------------------------
   263         -# This was also crashing (corrupt sqlite_stat3 table).
   264         -#
   265         -reset_db
   266         -do_execsql_test 6.1 {
   267         -  CREATE TABLE t1(a, b);
   268         -  CREATE INDEX i1 ON t1(a);
   269         -  CREATE INDEX i2 ON t1(b);
   270         -  INSERT INTO t1 VALUES(1, 1);
   271         -  INSERT INTO t1 VALUES(2, 2);
   272         -  INSERT INTO t1 VALUES(3, 3);
   273         -  INSERT INTO t1 VALUES(4, 4);
   274         -  INSERT INTO t1 VALUES(5, 5);
   275         -  ANALYZE;
   276         -  PRAGMA writable_schema = 1;
   277         -  CREATE TEMP TABLE x1 AS
   278         -    SELECT tbl,idx,neq,nlt,ndlt,sample FROM sqlite_stat3
   279         -    ORDER BY (rowid%5), rowid;
   280         -  DELETE FROM sqlite_stat3;
   281         -  INSERT INTO sqlite_stat3 SELECT * FROM x1;
   282         -  PRAGMA writable_schema = 0;
   283         -  ANALYZE sqlite_master;
   284         -}
   285         -do_execsql_test 6.2 {
   286         -  SELECT * FROM t1 WHERE a = 'abc';
   287         -}
   288         -
   289         -#-------------------------------------------------------------------------
   290         -# The following tests experiment with adding corrupted records to the
   291         -# 'sample' column of the sqlite_stat3 table.
   292         -#
   293         -reset_db
   294         -sqlite3_db_config_lookaside db 0 0 0
   295         -
   296         -do_execsql_test 7.1 {
   297         -  CREATE TABLE t1(a, b);
   298         -  CREATE INDEX i1 ON t1(a, b);
   299         -  INSERT INTO t1 VALUES(1, 1);
   300         -  INSERT INTO t1 VALUES(2, 2);
   301         -  INSERT INTO t1 VALUES(3, 3);
   302         -  INSERT INTO t1 VALUES(4, 4);
   303         -  INSERT INTO t1 VALUES(5, 5);
   304         -  ANALYZE;
   305         -  UPDATE sqlite_stat3 SET sample = X'' WHERE rowid = 1;
   306         -  ANALYZE sqlite_master;
   307         -}
   308         -
   309         -do_execsql_test 7.2 {
   310         -  UPDATE sqlite_stat3 SET sample = X'FFFF';
   311         -  ANALYZE sqlite_master;
   312         -  SELECT * FROM t1 WHERE a = 1;
   313         -} {1 1}
   314         -
   315         -do_execsql_test 7.3 {
   316         -  ANALYZE;
   317         -  UPDATE sqlite_stat3 SET neq = '0 0 0';
   318         -  ANALYZE sqlite_master;
   319         -  SELECT * FROM t1 WHERE a = 1;
   320         -} {1 1}
   321         -
   322         -do_execsql_test 7.4 {
   323         -  ANALYZE;
   324         -  UPDATE sqlite_stat3 SET ndlt = '0 0 0';
   325         -  ANALYZE sqlite_master;
   326         -  SELECT * FROM t1 WHERE a = 3;
   327         -} {3 3}
   328         -
   329         -do_execsql_test 7.5 {
   330         -  ANALYZE;
   331         -  UPDATE sqlite_stat3 SET nlt = '0 0 0';
   332         -  ANALYZE sqlite_master;
   333         -  SELECT * FROM t1 WHERE a = 5;
   334         -} {5 5}
   335         -
   336         -#-------------------------------------------------------------------------
   337         -#
   338         -reset_db
   339         -do_execsql_test 8.1 {
   340         -  CREATE TABLE t1(x TEXT);
   341         -  CREATE INDEX i1 ON t1(x);
   342         -  INSERT INTO t1 VALUES('1');
   343         -  INSERT INTO t1 VALUES('2');
   344         -  INSERT INTO t1 VALUES('3');
   345         -  INSERT INTO t1 VALUES('4');
   346         -  ANALYZE;
   347         -}
   348         -do_execsql_test 8.2 {
   349         -  SELECT * FROM t1 WHERE x = 3;
   350         -} {3}
   351         -
   352         -#-------------------------------------------------------------------------
   353         -#
   354         -reset_db
   355         -do_execsql_test 9.1 {
   356         -  CREATE TABLE t1(a, b, c, d, e);
   357         -  CREATE INDEX i1 ON t1(a, b, c, d);
   358         -  CREATE INDEX i2 ON t1(e);
   359         -}
   360         -do_test 9.2 {
   361         -  execsql BEGIN;
   362         -  for {set i 0} {$i < 100} {incr i} {
   363         -    execsql "INSERT INTO t1 VALUES('x', 'y', 'z', $i, [expr $i/2])"
   364         -  }
   365         -  for {set i 0} {$i < 20} {incr i} {
   366         -    execsql "INSERT INTO t1 VALUES('x', 'y', 'z', 101, $i)"
   367         -  }
   368         -  for {set i 102} {$i < 200} {incr i} {
   369         -    execsql "INSERT INTO t1 VALUES('x', 'y', 'z', $i, [expr $i/2])"
   370         -  }
   371         -  execsql COMMIT
   372         -  execsql ANALYZE
   373         -} {}
   374         -
   375         -do_eqp_test 9.3.1 {
   376         -  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=101 AND e=5;
   377         -} {/t1 USING INDEX i1/}
   378         -do_eqp_test 9.3.2 {
   379         -  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=99 AND e=5;
   380         -} {/t1 USING INDEX i1/}
   381         -
   382         -set value_d [expr 101]
   383         -do_eqp_test 9.4.1 {
   384         -  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=$value_d AND e=5
   385         -} {/t1 USING INDEX i1/}
   386         -set value_d [expr 99]
   387         -do_eqp_test 9.4.2 {
   388         -  SELECT * FROM t1 WHERE a='x' AND b='y' AND c='z' AND d=$value_d AND e=5
   389         -} {/t1 USING INDEX i1/}
   390         -
   391         -#-------------------------------------------------------------------------
   392         -# Check that the planner takes stat3 data into account when considering
   393         -# "IS NULL" and "IS NOT NULL" constraints.
   394         -#
   395         -do_execsql_test 10.1.1 {
   396         -  DROP TABLE IF EXISTS t3;
   397         -  CREATE TABLE t3(a, b);
   398         -  CREATE INDEX t3a ON t3(a);
   399         -  CREATE INDEX t3b ON t3(b);
   400         -}
   401         -do_test 10.1.2 {
   402         -  for {set i 1} {$i < 100} {incr i} {
   403         -    if {$i>90} { set a $i } else { set a NULL }
   404         -    set b [expr $i % 5]
   405         -    execsql "INSERT INTO t3 VALUES($a, $b)"
   406         -  }
   407         -  execsql ANALYZE
   408         -} {}
   409         -do_eqp_test 10.1.3 {
   410         -  SELECT * FROM t3 WHERE a IS NULL AND b = 2
   411         -} {/t3 USING INDEX t3b/}
   412         -do_eqp_test 10.1.4 {
   413         -  SELECT * FROM t3 WHERE a IS NOT NULL AND b = 2
   414         -} {/t3 USING INDEX t3a/}
   415         -
   416         -#-------------------------------------------------------------------------
   417         -# Check that stat3 data is used correctly with non-default collation
   418         -# sequences.
   419         -#
   420         -foreach {tn schema} {
   421         -  1 {
   422         -    CREATE TABLE t4(a COLLATE nocase, b);
   423         -    CREATE INDEX t4a ON t4(a);
   424         -    CREATE INDEX t4b ON t4(b);
   425         -  }
   426         -  2 {
   427         -    CREATE TABLE t4(a, b);
   428         -    CREATE INDEX t4a ON t4(a COLLATE nocase);
   429         -    CREATE INDEX t4b ON t4(b);
   430         -  }
   431         -} {
   432         -  drop_all_tables
   433         -  do_test 11.$tn.1 { execsql $schema } {}
   434         -
   435         -  do_test 11.$tn.2 {
   436         -    for {set i 0} {$i < 100} {incr i} {
   437         -      if { ($i % 10)==0 } { set a ABC } else { set a DEF }
   438         -      set b [expr $i % 5]
   439         -        execsql { INSERT INTO t4 VALUES($a, $b) }
   440         -    }
   441         -    execsql ANALYZE
   442         -  } {}
   443         -
   444         -  do_eqp_test 11.$tn.3 {
   445         -    SELECT * FROM t4 WHERE a = 'def' AND b = 3;
   446         -  } {/t4 USING INDEX t4b/}
   447         -
   448         -  if {$tn==1} {
   449         -    set sql "SELECT * FROM t4 WHERE a = 'abc' AND b = 3;"
   450         -    do_eqp_test 11.$tn.4 $sql {/t4 USING INDEX t4a/}
   451         -  } else {
   452         -
   453         -    set sql "SELECT * FROM t4 WHERE a = 'abc' COLLATE nocase AND b = 3;"
   454         -    do_eqp_test 11.$tn.5 $sql {/t4 USING INDEX t4a/}
   455         -
   456         -    set sql "SELECT * FROM t4 WHERE a COLLATE nocase = 'abc' AND b = 3;"
   457         -    do_eqp_test 11.$tn.6 $sql {/t4 USING INDEX t4a/}
   458         -  }
   459         -}
   460         -
   461         -#-------------------------------------------------------------------------
   462         -# Test that nothing untoward happens if the stat3 table contains entries
   463         -# for indexes that do not exist. Or NULL values in the idx column.
   464         -# Or NULL values in any of the other columns.
   465         -#
   466         -drop_all_tables
   467         -do_execsql_test 15.1 {
   468         -  CREATE TABLE x1(a, b, UNIQUE(a, b));
   469         -  INSERT INTO x1 VALUES(1, 2);
   470         -  INSERT INTO x1 VALUES(3, 4);
   471         -  INSERT INTO x1 VALUES(5, 6);
   472         -  ANALYZE;
   473         -  INSERT INTO sqlite_stat3 VALUES(NULL, NULL, NULL, NULL, NULL, NULL);
   474         -}
   475         -db close
   476         -sqlite3 db test.db
   477         -do_execsql_test 15.2 { SELECT * FROM x1 } {1 2 3 4 5 6}
   478         -
   479         -do_execsql_test 15.3 {
   480         -  INSERT INTO sqlite_stat3 VALUES(42, 42, 42, 42, 42, 42);
   481         -}
   482         -db close
   483         -sqlite3 db test.db
   484         -do_execsql_test 15.4 { SELECT * FROM x1 } {1 2 3 4 5 6}
   485         -
   486         -do_execsql_test 15.5 {
   487         -  UPDATE sqlite_stat1 SET stat = NULL;
   488         -}
   489         -db close
   490         -sqlite3 db test.db
   491         -do_execsql_test 15.6 { SELECT * FROM x1 } {1 2 3 4 5 6}
   492         -
   493         -do_execsql_test 15.7 {
   494         -  ANALYZE;
   495         -  UPDATE sqlite_stat1 SET tbl = 'no such tbl';
   496         -}
   497         -db close
   498         -sqlite3 db test.db
   499         -do_execsql_test 15.8 { SELECT * FROM x1 } {1 2 3 4 5 6}
   500         -
   501         -do_execsql_test 15.9 {
   502         -  ANALYZE;
   503         -  UPDATE sqlite_stat3 SET neq = NULL, nlt=NULL, ndlt=NULL;
   504         -}
   505         -db close
   506         -sqlite3 db test.db
   507         -do_execsql_test 15.10 { SELECT * FROM x1 } {1 2 3 4 5 6}
   508         -
   509         -# This is just for coverage....
   510         -do_execsql_test 15.11 {
   511         -  ANALYZE;
   512         -  UPDATE sqlite_stat1 SET stat = stat || ' unordered';
   513         -}
   514         -db close
   515         -sqlite3 db test.db
   516         -do_execsql_test 15.12 { SELECT * FROM x1 } {1 2 3 4 5 6}
   517         -
   518         -#-------------------------------------------------------------------------
   519         -# Test that allocations used for sqlite_stat3 samples are included in
   520         -# the quantity returned by SQLITE_DBSTATUS_SCHEMA_USED.
   521         -#
   522         -set one [string repeat x 1000]
   523         -set two [string repeat x 2000]
   524         -do_test 16.1 {
   525         -  reset_db
   526         -  execsql {
   527         -    CREATE TABLE t1(a, UNIQUE(a));
   528         -    INSERT INTO t1 VALUES($one);
   529         -    ANALYZE;
   530         -  }
   531         -  set nByte [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
   532         -
   533         -  reset_db
   534         -  execsql {
   535         -    CREATE TABLE t1(a, UNIQUE(a));
   536         -    INSERT INTO t1 VALUES($two);
   537         -    ANALYZE;
   538         -  }
   539         -  set nByte2 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1]
   540         -
   541         -  expr {$nByte2 > $nByte+950 && $nByte2 < $nByte+1050}
   542         -} {1}
   543         -
   544         -#-------------------------------------------------------------------------
   545         -# Test that stat3 data may be used with partial indexes.
   546         -#
   547         -do_test 17.1 {
   548         -  reset_db
   549         -  execsql {
   550         -    CREATE TABLE t1(a, b, c, d);
   551         -    CREATE INDEX i1 ON t1(a, b) WHERE d IS NOT NULL;
   552         -    INSERT INTO t1 VALUES(-1, -1, -1, NULL);
   553         -    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
   554         -    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
   555         -    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
   556         -    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
   557         -    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
   558         -    INSERT INTO t1 SELECT 2*a,2*b,2*c,d FROM t1;
   559         -  }
   560         -
   561         -  for {set i 0} {$i < 32} {incr i} {
   562         -    execsql { INSERT INTO t1 VALUES($i%2, $b, $i/2, 'abc') }
   563         -  }
   564         -  execsql {ANALYZE main.t1}
   565         -} {}
   566         -
   567         -do_catchsql_test 17.1.2 {
   568         -  ANALYZE temp.t1;
   569         -} {1 {no such table: temp.t1}}
   570         -
   571         -do_eqp_test 17.2 {
   572         -  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
   573         -} {/USING INDEX i1/}
   574         -do_eqp_test 17.3 {
   575         -  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
   576         -} {/USING INDEX i1/}
   577         -
   578         -do_execsql_test 17.4 {
   579         -  CREATE INDEX i2 ON t1(c) WHERE d IS NOT NULL;
   580         -  ANALYZE main.i2;
   581         -}
   582         -do_eqp_test 17.5 {
   583         -  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0;
   584         -} {/USING INDEX i1/}
   585         -do_eqp_test 17.6 {
   586         -  SELECT * FROM t1 WHERE d IS NOT NULL AND a=0 AND b=0 AND c=10;
   587         -} {/USING INDEX i2/}
   588         -
   589         -#-------------------------------------------------------------------------
   590         -#
   591         -do_test 18.1 {
   592         -  reset_db
   593         -  execsql {
   594         -    CREATE TABLE t1(a, b);
   595         -    CREATE INDEX i1 ON t1(a, b);
   596         -  }
   597         -  for {set i 0} {$i < 9} {incr i} {
   598         -    execsql {
   599         -      INSERT INTO t1 VALUES($i, 0);
   600         -      INSERT INTO t1 VALUES($i, 0);
   601         -      INSERT INTO t1 VALUES($i, 0);
   602         -      INSERT INTO t1 VALUES($i, 0);
   603         -      INSERT INTO t1 VALUES($i, 0);
   604         -      INSERT INTO t1 VALUES($i, 0);
   605         -      INSERT INTO t1 VALUES($i, 0);
   606         -      INSERT INTO t1 VALUES($i, 0);
   607         -      INSERT INTO t1 VALUES($i, 0);
   608         -      INSERT INTO t1 VALUES($i, 0);
   609         -      INSERT INTO t1 VALUES($i, 0);
   610         -      INSERT INTO t1 VALUES($i, 0);
   611         -      INSERT INTO t1 VALUES($i, 0);
   612         -      INSERT INTO t1 VALUES($i, 0);
   613         -      INSERT INTO t1 VALUES($i, 0);
   614         -    }
   615         -  }
   616         -  execsql ANALYZE
   617         -  execsql { SELECT count(*) FROM sqlite_stat3 }
   618         -} {9}
   619         -
   620         -#-------------------------------------------------------------------------
   621         -# For coverage.
   622         -#
   623         -ifcapable view {
   624         -  do_test 19.1 {
   625         -    reset_db 
   626         -    execsql {
   627         -      CREATE TABLE t1(x, y);
   628         -      CREATE INDEX i1 ON t1(x, y);
   629         -      CREATE VIEW v1 AS SELECT * FROM t1;
   630         -      ANALYZE;
   631         -    }
   632         -  } {}
   633         -}
   634         -ifcapable auth {
   635         -  proc authproc {op args} {
   636         -    if {$op == "SQLITE_ANALYZE"} { return "SQLITE_DENY" }
   637         -    return "SQLITE_OK"
   638         -  }
   639         -  do_test 19.2 {
   640         -    reset_db 
   641         -    db auth authproc
   642         -    execsql {
   643         -      CREATE TABLE t1(x, y);
   644         -      CREATE VIEW v1 AS SELECT * FROM t1;
   645         -    }
   646         -    catchsql ANALYZE
   647         -  } {1 {not authorized}}
   648         -}
   649         -
   650         -#-------------------------------------------------------------------------
   651         -#
   652         -reset_db
   653         -proc r {args} { expr rand() }
   654         -db func r r
   655         -db func lrange lrange
   656         -do_test 20.1 {
   657         -  execsql {
   658         -    CREATE TABLE t1(a,b,c,d);
   659         -    CREATE INDEX i1 ON t1(a,b,c,d);
   660         -  }
   661         -  for {set i 0} {$i < 16} {incr i} {
   662         -    execsql {
   663         -      INSERT INTO t1 VALUES($i, r(), r(), r());
   664         -      INSERT INTO t1 VALUES($i, $i,  r(), r());
   665         -      INSERT INTO t1 VALUES($i, $i,  $i,  r());
   666         -      INSERT INTO t1 VALUES($i, $i,  $i,  $i);
   667         -      INSERT INTO t1 VALUES($i, $i,  $i,  $i);
   668         -      INSERT INTO t1 VALUES($i, $i,  $i,  r());
   669         -      INSERT INTO t1 VALUES($i, $i,  r(), r());
   670         -      INSERT INTO t1 VALUES($i, r(), r(), r());
   671         -    }
   672         -  }
   673         -} {}
   674         -do_execsql_test 20.2 { ANALYZE }
   675         -for {set i 0} {$i<16} {incr i} {
   676         -    set val $i
   677         -    do_execsql_test 20.3.$i {
   678         -      SELECT count(*) FROM sqlite_stat3 WHERE sample=$val
   679         -    } {1}
   680         -}
   681         -
   682         -finish_test

Changes to test/auth.test.

  2446   2446           DROP TABLE v1chng;
  2447   2447         }
  2448   2448       }
  2449   2449     }
  2450   2450     ifcapable stat4 {
  2451   2451       set stat4 "sqlite_stat4 "
  2452   2452     } else {
  2453         -    ifcapable stat3 {
  2454         -      set stat4 "sqlite_stat3 "
  2455         -    } else {
  2456         -      set stat4 ""
  2457         -    }
         2453  +    set stat4 ""
  2458   2454     }
  2459   2455     do_test auth-5.2 {
  2460   2456       execsql {
  2461   2457         SELECT name FROM (
  2462   2458           SELECT * FROM sqlite_master UNION ALL SELECT * FROM temp.sqlite_master)
  2463   2459         WHERE type='table'
  2464   2460         ORDER BY name

Changes to test/dbstatus.test.

    59     59   
    60     60   proc lookaside {db} {
    61     61     expr { $::lookaside_buffer_size *
    62     62       [lindex [sqlite3_db_status $db SQLITE_DBSTATUS_LOOKASIDE_USED 0] 1]
    63     63     }
    64     64   }
    65     65   
    66         -ifcapable stat4||stat3 {
           66  +ifcapable stat4 {
    67     67     set STAT3 1
    68     68   } else {
    69     69     set STAT3 0
    70     70   }
    71     71   
    72     72   #---------------------------------------------------------------------------
    73     73   # Run the dbstatus-2 and dbstatus-3 tests with several of different

Changes to test/filter1.test.

    98     98   } {1 {misuse of window function max()}}
    99     99   
   100    100   do_catchsql_test 2.3 {
   101    101     SELECT sum(a) FILTER (WHERE 1 - count(a)) FROM t1
   102    102   } {1 {misuse of aggregate function count()}}
   103    103   
   104    104   finish_test
   105         -
   106         -

Changes to test/fkey8.test.

   225    225     COMMIT;
   226    226   }
   227    227   do_execsql_test 5.3 {
   228    228     PRAGMA integrity_check;
   229    229   } {ok}
   230    230   
   231    231   finish_test
   232         -

Changes to test/fts3corrupt4.test.

  5315   5315     INSERT INTO t1(a) SELECT X'819192E578DE3F';
  5316   5316     UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*';
  5317   5317     INSERT INTO t1(b) VALUES(x'78');
  5318   5318     INSERT INTO t1(t1) SELECT x FROM t2;
  5319   5319   } {1 {database disk image is malformed}}
  5320   5320   
  5321   5321   finish_test
  5322         -

Changes to test/fts3corrupt5.test.

    53     53     if {$bCorrupt} { set res {1 {database disk image is malformed}}}
    54     54     do_catchsql_test 1.3.$tn.2 {
    55     55       SELECT * FROM ft WHERE ft MATCH $q
    56     56     } $res
    57     57   }
    58     58   
    59     59   finish_test
    60         -

Changes to test/fts3expr5.test.

    60     60     test_fts3expr {(a:123)(b:234)(c:456)}
    61     61   } {AND {AND {PHRASE 0 0 123} {PHRASE 1 0 234}} {PHRASE 2 0 456}}
    62     62   do_test 2.2 {
    63     63     list [catch { test_fts3expr {"123" AND ( )} } msg] $msg
    64     64   } {1 {Error parsing expression}}
    65     65   
    66     66   finish_test
    67         -

Changes to test/fts4rename.test.

    37     37   
    38     38   do_catchsql_test 1.3 {
    39     39     ROLLBACK;
    40     40     DROP TABLE t1;
    41     41   } {0 {}}
    42     42   
    43     43   finish_test
    44         -

Changes to test/index6.test.

   155    155   } {500}
   156    156   do_test index6-2.2 {
   157    157     execsql {
   158    158       EXPLAIN QUERY PLAN
   159    159       SELECT * FROM t2 WHERE a=5;
   160    160     }
   161    161   } {/.* TABLE t2 USING INDEX t2a1 .*/}
   162         -ifcapable stat4||stat3 {
          162  +ifcapable stat4 {
   163    163     execsql ANALYZE
   164    164     do_test index6-2.3stat4 {
   165    165       execsql {
   166    166         EXPLAIN QUERY PLAN
   167    167         SELECT * FROM t2 WHERE a IS NOT NULL;
   168    168       }
   169    169     } {/.* TABLE t2 USING INDEX t2a1 .*/}
................................................................................
   434    434   } {{} row}
   435    435   
   436    436   do_execsql_test index6-14.2 {
   437    437     SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END;
   438    438   } {{} row}
   439    439   
   440    440   finish_test
   441         -

Changes to test/index7.test.

   199    199   } {800}
   200    200   do_test index7-2.2 {
   201    201     execsql {
   202    202       EXPLAIN QUERY PLAN
   203    203       SELECT * FROM t2 WHERE a=5;
   204    204     }
   205    205   } {/.* TABLE t2 USING COVERING INDEX t2a1 .*/}
   206         -ifcapable stat4||stat3 {
          206  +ifcapable stat4 {
   207    207     do_test index7-2.3stat4 {
   208    208       execsql {
   209    209         EXPLAIN QUERY PLAN
   210    210         SELECT * FROM t2 WHERE a IS NOT NULL;
   211    211       }
   212    212     } {/.* TABLE t2 USING COVERING INDEX t2a1 .*/}
   213    213   } else {

Changes to test/json104.test.

   149    149   do_execsql_test 405 {
   150    150     UPDATE obj SET x = json_set(x, '$."d"', 4);
   151    151     SELECT json_extract(x, '$."d"') FROM obj;
   152    152   } {4}
   153    153   
   154    154   
   155    155   finish_test
   156         -
   157         -

Changes to test/like.test.

  1110   1110     SELECT * FROM t1 WHERE a LIKE ' 1%';
  1111   1111   } {{ 1x} { 1-}}
  1112   1112   do_execsql_test 16.2 {
  1113   1113     SELECT * FROM t1 WHERE a LIKE ' 1-';
  1114   1114   } {{ 1-}}
  1115   1115   
  1116   1116   finish_test
  1117         -

Changes to test/mallocA.test.

    92     92     faultsim_test_result [list 0 2]
    93     93   }
    94     94   do_faultsim_test 6.2 -faults oom* -body {
    95     95     execsql { SELECT rowid FROM t1 WHERE a='abc' AND b<'y' }
    96     96   } -test {
    97     97     faultsim_test_result [list 0 {1 2}]
    98     98   }
    99         -ifcapable stat3 {
   100         -  do_test 6.3-prep {
   101         -    execsql {
   102         -      PRAGMA writable_schema = 1;
   103         -      CREATE TABLE sqlite_stat4 AS 
   104         -      SELECT tbl, idx, neq, nlt, ndlt, sqlite_record(sample) AS sample 
   105         -      FROM sqlite_stat3;
   106         -    }
   107         -  } {}
   108         -  do_faultsim_test 6.3 -faults oom* -body {
   109         -    execsql { 
   110         -      ANALYZE sqlite_master;
   111         -      SELECT rowid FROM t1 WHERE a='abc' AND b<'y';
   112         -    }
   113         -  } -test {
   114         -    faultsim_test_result [list 0 {1 2}]
   115         -  }
   116         -}
   117     99   
   118    100   do_execsql_test 7.0 {
   119    101     PRAGMA cache_size = 5;
   120    102   }
   121    103   do_faultsim_test 7 -faults oom-trans* -prep {
   122    104   } -body {
   123    105     execsql {

Changes to test/minmax4.test.

   197    197     CREATE INDEX i1 ON t1(a, b DESC);
   198    198   }
   199    199   do_execsql_test 5.1 {
   200    200     SELECT MIN(a) FROM t1 WHERE a=123;
   201    201   } {123}
   202    202   
   203    203   finish_test
   204         -

Changes to test/skipscan1.test.

   230    230     EXPLAIN QUERY PLAN
   231    231       SELECT xh, loc FROM t5 WHERE loc >= 'M' AND loc < 'N';
   232    232   } {/.*COVERING INDEX t5i1 .*/}
   233    233   do_execsql_test skipscan1-5.2 {
   234    234     ANALYZE;
   235    235     DELETE FROM sqlite_stat1;
   236    236     DROP TABLE IF EXISTS sqlite_stat4;
   237         -  DROP TABLE IF EXISTS sqlite_stat3;
   238    237     INSERT INTO sqlite_stat1 VALUES('t5','t5i1','2702931 3 2 2 2 2');
   239    238     INSERT INTO sqlite_stat1 VALUES('t5','t5i2','2702931 686 2 2 2');
   240    239     ANALYZE sqlite_master;
   241    240   } {}
   242    241   db cache flush
   243    242   do_execsql_test skipscan1-5.3 {
   244    243     EXPLAIN QUERY PLAN

Changes to test/tempdb2.test.

    93     93   }
    94     94   
    95     95   do_execsql_test 2.2 {
    96     96     SELECT b FROM t1 WHERE a = 10001;
    97     97   } "[int2str 1001][int2str 1001][int2str 1001]"
    98     98   
    99     99   finish_test
   100         -

Changes to test/tkt-cbd054fa6b.test.

    12     12   # This file implements tests to verify that ticket [cbd054fa6b] has been
    13     13   # fixed.  
    14     14   #
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   
    19         -ifcapable !stat4&&!stat3 {
           19  +ifcapable !stat4 {
    20     20     finish_test
    21     21     return
    22     22   }
    23     23   
    24     24   proc s {blob} {
    25     25     set ret ""
    26     26     binary scan $blob c* bytes
................................................................................
    51     51       INSERT INTO t1 VALUES (NULL, 'H');
    52     52       INSERT INTO t1 VALUES (NULL, 'I');
    53     53       SELECT count(*) FROM t1;
    54     54     }
    55     55   } {10}
    56     56   do_test tkt-cbd05-1.2 {
    57     57     db eval { ANALYZE; }
    58         -  ifcapable stat4 {
    59         -    db eval {
    60         -      PRAGMA writable_schema = 1;
    61         -      CREATE VIEW vvv AS 
    62         -      SELECT tbl,idx,neq,nlt,ndlt,test_extract(sample,0) AS sample
    63         -      FROM sqlite_stat4;
    64         -      PRAGMA writable_schema = 0;
    65         -    }
    66         -  } else {
    67         -    db eval {
    68         -      CREATE VIEW vvv AS 
    69         -      SELECT tbl,idx,neq,nlt,ndlt,sample FROM sqlite_stat3;
    70         -    }
           58  +  db eval {
           59  +    PRAGMA writable_schema = 1;
           60  +    CREATE VIEW vvv AS 
           61  +    SELECT tbl,idx,neq,nlt,ndlt,test_extract(sample,0) AS sample
           62  +    FROM sqlite_stat4;
           63  +    PRAGMA writable_schema = 0;
    71     64     }
    72     65   } {}
    73     66   do_test tkt-cbd05-1.3 {
    74     67     execsql { 
    75     68       SELECT tbl,idx,group_concat(s(sample),' ') 
    76     69       FROM vvv 
    77     70       WHERE idx = 't1_x' 

Changes to test/triggerC.test.

  1068   1068   }
  1069   1069   do_catchsql_test 17.1 {
  1070   1070     INSERT INTO xyz VALUES('hello', 2, 3);
  1071   1071   } {1 {datatype mismatch}}
  1072   1072   
  1073   1073   
  1074   1074   finish_test
  1075         -

Changes to test/walvfs.test.

   422    422     catchsql { SELECT count(*) FROM t1 } db2
   423    423   } {1 {disk I/O error}}
   424    424   
   425    425   db close
   426    426   db2 close
   427    427   tvfs delete
   428    428   finish_test
   429         -

Changes to test/where.test.

  1535   1535   } {0 {}}
  1536   1536   do_catchsql_test where-25.5 {
  1537   1537     INSERT INTO t1 VALUES(4, 'four', 'iii') 
  1538   1538       ON CONFLICT(c) DO UPDATE SET b=NULL
  1539   1539   } {1 {corrupt database}}
  1540   1540   
  1541   1541   finish_test
  1542         -

Changes to test/where9.test.

   783    783        WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
   784    784           OR (b NOT NULL AND c IS NULL AND d NOT NULL)
   785    785           OR (b NOT NULL AND c NOT NULL AND d IS NULL)
   786    786     }
   787    787   } {1 {no query solution}}
   788    788   
   789    789   set solution_possible 0
   790         -ifcapable stat4||stat3 {
          790  +ifcapable stat4 {
   791    791     if {[permutation] != "no_optimization"} { set solution_possible 1 }
   792    792   }
   793    793   if $solution_possible {
   794    794     # When STAT3 is enabled, the "b NOT NULL" terms get translated
   795    795     # into b>NULL, which can be satified by the index t1b.  It is a very
   796    796     # expensive way to do the query, but it works, and so a solution is possible.
   797    797     do_test where9-6.8.3-stat4 {
................................................................................
   856    856       CREATE INDEX t5ye ON t5(y, e);
   857    857       CREATE INDEX t5yf ON t5(y, f);
   858    858       CREATE INDEX t5yg ON t5(y, g);
   859    859       CREATE TABLE t6(a, b, c, e, d, f, g, x, y);
   860    860       INSERT INTO t6 SELECT * FROM t5;
   861    861       ANALYZE t5;
   862    862     }
   863         -  ifcapable stat3 {
   864         -    sqlite3 db2 test.db
   865         -    db2 eval { DROP TABLE IF EXISTS sqlite_stat3 }
   866         -    db2 close
   867         -  }
   868    863   } {}
   869    864   do_test where9-7.1.1 {
   870    865     count_steps {
   871    866       SELECT a FROM t5 WHERE x='y' AND (b=913 OR c=27027) ORDER BY a;
   872    867     }
   873    868   } {79 81 83 scan 0 sort 1}
   874    869   do_test where9-7.1.2 {

Deleted test/wild001.test.

     1         -# 2013-07-01
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# 
    12         -# This is a test case from content taken "from the wild".  In this
    13         -# particular instance, the query was provided with permission by
    14         -# Elan Feingold on 2013-06-27.  His message on the SQLite mailing list
    15         -# on that date reads:
    16         -#
    17         -#------------------------------------------------------------------------------
    18         -# > Can you send (1) the schema (2) the query that is giving problems, and (3)
    19         -# > the content of the sqlite_stat1 table after you have run ANALYZE?   If you
    20         -# > can combine all of the above into a script, that would be great!
    21         -# >
    22         -# > If you send (1..3) above and you give us written permission to include the
    23         -# > query in our test suite, that would be off-the-chain terrific.
    24         -#
    25         -# Please find items 1..3 in this file: http://www.plexapp.com/elan/sqlite_bug.txt
    26         -# 
    27         -# You have our permission to include the query in your test suite.
    28         -# 
    29         -# Thanks for an amazing product.
    30         -#-----------------------------------------------------------------------------
    31         -#
    32         -# This test case merely creates the schema and populates SQLITE_STAT1 and
    33         -# SQLITE_STAT3 then runs an EXPLAIN QUERY PLAN to ensure that the right plan
    34         -# is discovered.  This test case may need to be adjusted for future revisions
    35         -# of the query planner manage to select a better query plan.  The query plan
    36         -# shown here is known to be very fast with the original data.
    37         -#
    38         -# This test should work the same with and without SQLITE_ENABLE_STAT3
    39         -#
    40         -###############################################################################
    41         -
    42         -set testdir [file dirname $argv0]
    43         -source $testdir/tester.tcl
    44         -
    45         -ifcapable !stat3 {
    46         -  finish_test
    47         -  return
    48         -}
    49         -
    50         -do_execsql_test wild001.01 {
    51         -  CREATE TABLE "items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "secid" integer, "parent_id" integer, "metadata_type" integer, "guid" varchar(255), "media_item_count" integer, "title" varchar(255), "title_sort" varchar(255) COLLATE NOCASE, "original_title" varchar(255), "studio" varchar(255), "rating" float, "rating_count" integer, "tagline" varchar(255), "summary" text, "trivia" text, "quotes" text, "content_rating" varchar(255), "content_rating_age" integer, "index" integer, "absolute_index" integer, "duration" integer, "user_thumb_url" varchar(255), "user_art_url" varchar(255), "user_banner_url" varchar(255), "user_music_url" varchar(255), "user_fields" varchar(255), "tags_genre" varchar(255), "tags_collection" varchar(255), "tags_director" varchar(255), "tags_writer" varchar(255), "tags_star" varchar(255), "originally_available_at" datetime, "available_at" datetime, "expires_at" datetime, "refreshed_at" datetime, "year" integer, "added_at" datetime, "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "tags_country" varchar(255), "extra_data" varchar(255), "hash" varchar(255));
    52         -  CREATE INDEX "i_secid" ON "items" ("secid" );
    53         -  CREATE INDEX "i_parent_id" ON "items" ("parent_id" );
    54         -  CREATE INDEX "i_created_at" ON "items" ("created_at" );
    55         -  CREATE INDEX "i_index" ON "items" ("index" );
    56         -  CREATE INDEX "i_title" ON "items" ("title" );
    57         -  CREATE INDEX "i_title_sort" ON "items" ("title_sort" );
    58         -  CREATE INDEX "i_guid" ON "items" ("guid" );
    59         -  CREATE INDEX "i_metadata_type" ON "items" ("metadata_type" );
    60         -  CREATE INDEX "i_deleted_at" ON "items" ("deleted_at" );
    61         -  CREATE INDEX "i_secid_ex1" ON "items" ("secid", "metadata_type", "added_at" );
    62         -  CREATE INDEX "i_hash" ON "items" ("hash" );
    63         -  CREATE TABLE "settings" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "account_id" integer, "guid" varchar(255), "rating" float, "view_offset" integer, "view_count" integer, "last_viewed_at" datetime, "created_at" datetime, "updated_at" datetime);
    64         -  CREATE INDEX "s_account_id" ON "settings" ("account_id" );
    65         -  CREATE INDEX "s_guid" ON "settings" ("guid" );
    66         -  ANALYZE;
    67         -  INSERT INTO sqlite_stat1 VALUES('settings','s_guid','4740 1');
    68         -  INSERT INTO sqlite_stat1 VALUES('settings','s_account_id','4740 4740');
    69         -  INSERT INTO sqlite_stat1 VALUES('items','i_hash','27316 2');
    70         -  INSERT INTO sqlite_stat1 VALUES('items','i_secid_ex1','27316 6829 4553 3');
    71         -  INSERT INTO sqlite_stat1 VALUES('items','i_deleted_at','27316 27316');
    72         -  INSERT INTO sqlite_stat1 VALUES('items','i_metadata_type','27316 6829');
    73         -  INSERT INTO sqlite_stat1 VALUES('items','i_guid','27316 2');
    74         -  INSERT INTO sqlite_stat1 VALUES('items','i_title_sort','27316 2');
    75         -  INSERT INTO sqlite_stat1 VALUES('items','i_title','27316 2');
    76         -  INSERT INTO sqlite_stat1 VALUES('items','i_index','27316 144');
    77         -  INSERT INTO sqlite_stat1 VALUES('items','i_created_at','27316 2');
    78         -  INSERT INTO sqlite_stat1 VALUES('items','i_parent_id','27316 15');
    79         -  INSERT INTO sqlite_stat1 VALUES('items','i_secid','27316 6829');
    80         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,150,150,'com.plexapp.agents.thetvdb://153021/2/9?lang=en');
    81         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,198,198,'com.plexapp.agents.thetvdb://194031/1/10?lang=en');
    82         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,526,526,'com.plexapp.agents.thetvdb://71256/12/92?lang=en');
    83         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,923,923,'com.plexapp.agents.thetvdb://71256/15/16?lang=en');
    84         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1008,1008,'com.plexapp.agents.thetvdb://71256/15/93?lang=en');
    85         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1053,1053,'com.plexapp.agents.thetvdb://71256/16/21?lang=en');
    86         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1068,1068,'com.plexapp.agents.thetvdb://71256/16/35?lang=en');
    87         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1235,1235,'com.plexapp.agents.thetvdb://71256/17/44?lang=en');
    88         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1255,1255,'com.plexapp.agents.thetvdb://71256/17/62?lang=en');
    89         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1573,1573,'com.plexapp.agents.thetvdb://71663/20/9?lang=en');
    90         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,1580,1580,'com.plexapp.agents.thetvdb://71663/21/16?lang=en');
    91         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2000,2000,'com.plexapp.agents.thetvdb://73141/9/8?lang=en');
    92         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2107,2107,'com.plexapp.agents.thetvdb://73244/6/17?lang=en');
    93         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2256,2256,'com.plexapp.agents.thetvdb://74845/4/7?lang=en');
    94         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2408,2408,'com.plexapp.agents.thetvdb://75978/2/21?lang=en');
    95         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2634,2634,'com.plexapp.agents.thetvdb://79126/1/1?lang=en');
    96         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,2962,2962,'com.plexapp.agents.thetvdb://79274/3/94?lang=en');
    97         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3160,3160,'com.plexapp.agents.thetvdb://79274/5/129?lang=en');
    98         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3161,3161,'com.plexapp.agents.thetvdb://79274/5/12?lang=en');
    99         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3688,3688,'com.plexapp.agents.thetvdb://79274/8/62?lang=en');
   100         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,3714,3714,'com.plexapp.agents.thetvdb://79274/8/86?lang=en');
   101         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4002,4002,'com.plexapp.agents.thetvdb://79590/13/17?lang=en');
   102         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4215,4215,'com.plexapp.agents.thetvdb://80727/3/6?lang=en');
   103         -  INSERT INTO sqlite_stat3 VALUES('settings','s_guid',1,4381,4381,'com.plexapp.agents.thetvdb://83462/3/24?lang=en');
   104         -  INSERT INTO sqlite_stat3 VALUES('settings','s_account_id',4740,0,0,1);
   105         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,1879,1879,'1113f632ccd52ec8b8d7ca3d6d56da4701e48018');
   106         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,2721,2721,'1936154b97bb5567163edaebc2806830ae419ccf');
   107         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,3035,3035,'1c122331d4b7bfa0dc2c003ab5fb4f7152b9987a');
   108         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,3393,3393,'1f81bdbc9acc3321dc592b1a109ca075731b549a');
   109         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,6071,6070,'393cf7713efb4519c7a3d1d5403f0d945d15a16a');
   110         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,7462,7461,'4677dd37011f8bd9ae7fbbdd3af6dcd8a5b4ab2d');
   111         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,8435,8434,'4ffa339485334e81a5e12e03a63b6508d76401cf');
   112         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,8716,8714,'52a093852e6599dd5004857b7ff5b5b82c7cdb25');
   113         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,9107,9104,'561183e39f866d97ec728e9ff16ac4ad01466111');
   114         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,10942,10939,'66e99b72e29610f49499ae09ee04a376210d1f08');
   115         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,12143,12139,'71f0602427e173dc2c551535f73fdb6885fe4302');
   116         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,14962,14958,'8ca8e4dfba696019830c19ab8a32c7ece9d8534b');
   117         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,15179,15174,'8ebf1a5cf33f8ada1fc5853ac06ac4d7e074f825');
   118         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,15375,15370,'908bc211bebdf21c79d2d2b54ebaa442ac1f5cae');
   119         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18215,18210,'ab29e4e18ec5a14fef95aa713d69e31c045a22c1');
   120         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18615,18610,'ae84c008cc0c338bf4f28d798a88575746452f6d');
   121         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,18649,18644,'aec7c901353e115aa5307e94018ba7507bec3a45');
   122         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,19517,19512,'b75025fbf2e9c504e3c1197ff1b69250402a31f8');
   123         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,21251,21245,'c7d32f0e3a8f3a0a3dbd00833833d2ccee62f0fd');
   124         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,23616,23610,'dd5ff61479a9bd4100de802515d9dcf72d46f07a');
   125         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,24287,24280,'e3db00034301b7555419d4ef6f64769298d5845e');
   126         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,24949,24942,'ea336abd197ecd7013854a25a4f4eb9dea7927c6');
   127         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',1,25574,25567,'f018ea5182ec3f32768ca1c3cefbf3ad160ec20b');
   128         -  INSERT INTO sqlite_stat3 VALUES('items','i_hash',2,26139,26132,'f53709a8d81c12cb0f4f8d58004a25dd063de67c');
   129         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',25167,0,0,2);
   130         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',736,25167,1,3);
   131         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',15,25903,2,4);
   132         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid_ex1',1398,25918,3,5);
   133         -  INSERT INTO sqlite_stat3 VALUES('items','i_deleted_at',27316,0,0,NULL);
   134         -  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',2149,0,0,1);
   135         -  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',411,2149,1,2);
   136         -  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',1440,2560,2,3);
   137         -  INSERT INTO sqlite_stat3 VALUES('items','i_metadata_type',23316,4000,3,4);
   138         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,215,215,'com.plexapp.agents.imdb://tt0065702?lang=en');
   139         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,711,711,'com.plexapp.agents.imdb://tt0198781?lang=en');
   140         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,987,986,'com.plexapp.agents.imdb://tt0454876?lang=en');
   141         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1004,1002,'com.plexapp.agents.imdb://tt0464154?lang=en');
   142         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1056,1053,'com.plexapp.agents.imdb://tt0499549?lang=en');
   143         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1120,1116,'com.plexapp.agents.imdb://tt0903624?lang=en');
   144         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1250,1245,'com.plexapp.agents.imdb://tt1268799?lang=en');
   145         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1270,1264,'com.plexapp.agents.imdb://tt1320261?lang=en');
   146         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',2,1376,1369,'com.plexapp.agents.imdb://tt1772341?lang=en');
   147         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,3035,3027,'com.plexapp.agents.thetvdb://153021/3/14?lang=en');
   148         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,6071,6063,'com.plexapp.agents.thetvdb://71173/1/18?lang=en');
   149         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,6342,6334,'com.plexapp.agents.thetvdb://71256/13/4?lang=en');
   150         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,9107,9099,'com.plexapp.agents.thetvdb://72389/2/19?lang=en');
   151         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,11740,11732,'com.plexapp.agents.thetvdb://73893/2/13?lang=en');
   152         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,12143,12135,'com.plexapp.agents.thetvdb://73976/4/23?lang=en');
   153         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,15179,15171,'com.plexapp.agents.thetvdb://75897/16/12?lang=en');
   154         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,17408,17400,'com.plexapp.agents.thetvdb://76808/2/16?lang=en');
   155         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,17984,17976,'com.plexapp.agents.thetvdb://77068/1/16?lang=en');
   156         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,18215,18207,'com.plexapp.agents.thetvdb://77259/1/1?lang=en');
   157         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,21251,21243,'com.plexapp.agents.thetvdb://78957/8/2?lang=en');
   158         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,24287,24279,'com.plexapp.agents.thetvdb://80337/5/8?lang=en');
   159         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,25513,25505,'com.plexapp.agents.thetvdb://82226/6?lang=en');
   160         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,25548,25540,'com.plexapp.agents.thetvdb://82339/2/10?lang=en');
   161         -  INSERT INTO sqlite_stat3 VALUES('items','i_guid',1,26770,26762,'com.plexapp.agents.thetvdb://86901/1/3?lang=en');
   162         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1524,0,0,'');
   163         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',2,3034,1391,'Attack of the Giant Squid');
   164         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',51,4742,2895,'Brad Sherwood');
   165         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',11,4912,2996,'Brian Williams');
   166         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',39,5847,3857,'Chip Esten');
   167         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,6071,4015,'Chuck Versus the DeLorean');
   168         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',12,7625,5436,'Denny Siegel');
   169         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',30,8924,6618,'Episode 1');
   170         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',29,9015,6629,'Episode 2');
   171         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',32,9082,6643,'Episode 3');
   172         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',28,9135,6654,'Episode 4');
   173         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',26,9183,6665,'Episode 5');
   174         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',27,9229,6677,'Episode 6');
   175         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',22,9266,6688,'Episode 7');
   176         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',20,9298,6699,'Episode 8');
   177         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',55,11750,8817,'Greg Proops');
   178         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,12143,9120,'Hardware Jungle');
   179         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',33,14712,11435,'Kathy Greenwood');
   180         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',3,15179,11840,'Last Call');
   181         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,18215,14601,'Nature or Nurture?');
   182         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',12,18241,14623,'Neil DeGrasse Tyson');
   183         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',68,19918,16144,'Pilot');
   184         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',7,21251,17298,'Reza Aslan');
   185         -  INSERT INTO sqlite_stat3 VALUES('items','i_title_sort',1,24287,20035,'Technoviking');
   186         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',1524,0,0,'');
   187         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,3035,1429,'Anderson Can''t Dance');
   188         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',51,4782,2991,'Brad Sherwood');
   189         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',11,4936,3079,'Brian Williams');
   190         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',39,5694,3783,'Chip Esten');
   191         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,6071,4100,'Clive Warren');
   192         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',12,7144,5078,'Denny Siegel');
   193         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',30,8249,6097,'Episode 1');
   194         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',29,8340,6108,'Episode 2');
   195         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',32,8407,6122,'Episode 3');
   196         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',28,8460,6133,'Episode 4');
   197         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',26,8508,6144,'Episode 5');
   198         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',27,8554,6156,'Episode 6');
   199         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',22,8591,6167,'Episode 7');
   200         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',20,8623,6178,'Episode 8');
   201         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,9107,6537,'Fat Albert and the Cosby Kids');
   202         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',55,10539,7843,'Greg Proops');
   203         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,12143,9276,'Iron Age Remains');
   204         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',33,13118,10143,'Kathy Greenwood');
   205         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,15179,11972,'Mink');
   206         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',68,17411,14035,'Pilot');
   207         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',2,18214,14727,'Reflections');
   208         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',4,21250,17481,'The Apartment');
   209         -  INSERT INTO sqlite_stat3 VALUES('items','i_title',1,24287,20283,'The Simpsons Already Did It');
   210         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',4315,95,2,1);
   211         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1553,4410,3,2);
   212         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1485,5963,4,3);
   213         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1414,7448,5,4);
   214         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1367,8862,6,5);
   215         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1328,10229,7,6);
   216         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1161,11557,8,7);
   217         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1108,12718,9,8);
   218         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1033,13826,10,9);
   219         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',1014,14859,11,10);
   220         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',929,15873,12,11);
   221         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',906,16802,13,12);
   222         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',844,17708,14,13);
   223         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',690,18552,15,14);
   224         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',655,19242,16,15);
   225         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',625,19897,17,16);
   226         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',579,20522,18,17);
   227         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',555,21101,19,18);
   228         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',526,21656,20,19);
   229         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',501,22182,21,20);
   230         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',459,22683,22,21);
   231         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',439,23142,23,22);
   232         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',315,23581,24,23);
   233         -  INSERT INTO sqlite_stat3 VALUES('items','i_index',192,24177,26,25);
   234         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1851,0,0,NULL);
   235         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',373,1857,2,'2011-10-22 14:54:39');
   236         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',595,2230,3,'2011-10-22 14:54:41');
   237         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',337,2825,4,'2011-10-22 14:54:43');
   238         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',361,3378,8,'2011-10-22 14:54:54');
   239         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',160,3739,9,'2011-10-22 14:54:56');
   240         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',315,4000,11,'2011-10-22 14:54:59');
   241         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',321,4334,13,'2011-10-22 14:55:02');
   242         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1292,4723,16,'2011-10-22 14:55:06');
   243         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',161,6015,17,'2011-10-22 14:55:07');
   244         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,9107,2677,'2012-09-04 18:07:50');
   245         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',313,9717,3270,'2012-10-18 16:50:21');
   246         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',450,10030,3271,'2012-10-18 16:50:22');
   247         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',389,10668,3275,'2012-10-18 16:50:26');
   248         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',796,11057,3276,'2012-10-18 16:51:06');
   249         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',161,12041,3280,'2012-10-19 19:52:37');
   250         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',135,13281,4186,'2013-02-19 00:56:10');
   251         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1063,13416,4187,'2013-02-19 00:56:11');
   252         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',797,14479,4188,'2013-02-19 00:56:13');
   253         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',147,15276,4189,'2013-02-19 00:56:15');
   254         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',346,15423,4190,'2013-02-19 00:56:16');
   255         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,18215,6436,'2013-05-05 14:09:54');
   256         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',2,21251,8122,'2013-05-24 15:25:45');
   257         -  INSERT INTO sqlite_stat3 VALUES('items','i_created_at',1,24287,11116,'2013-05-26 14:17:39');
   258         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',2560,0,0,NULL);
   259         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',18,3022,31,2350);
   260         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',10,6068,285,8150);
   261         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',158,6346,315,8949);
   262         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',34,9094,562,18831);
   263         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',20,12139,794,22838);
   264         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',134,14033,886,24739);
   265         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',159,14167,887,24740);
   266         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,14326,888,24741);
   267         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,14487,889,24742);
   268         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',124,14648,890,24743);
   269         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',157,14772,891,24744);
   270         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',126,15043,894,24747);
   271         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',40,15169,895,24748);
   272         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15243,898,24753);
   273         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',138,15404,899,24754);
   274         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',160,15542,900,24755);
   275         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15702,901,24756);
   276         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',161,15863,902,24757);
   277         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',124,16024,903,24758);
   278         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',155,16148,904,24759);
   279         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',26,18208,1043,29704);
   280         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',2,21251,1282,32952);
   281         -  INSERT INTO sqlite_stat3 VALUES('items','i_parent_id',13,24279,1583,36068);
   282         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid',25167,0,0,2);
   283         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid',736,25167,1,3);
   284         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid',15,25903,2,4);
   285         -  INSERT INTO sqlite_stat3 VALUES('items','i_secid',1398,25918,3,5);
   286         -  ANALYZE sqlite_master;
   287         -  
   288         -  explain query plan
   289         -  select items.title
   290         -    from items
   291         -         join items as child on child.parent_id=items.id
   292         -         join items as grandchild on grandchild.parent_id=child.id
   293         -         join settings
   294         -                    on settings.guid=grandchild.guid
   295         -                   and settings.account_id=1
   296         -   where items.metadata_type=2
   297         -     and items.secid=2
   298         -     and settings.last_viewed_at is not null
   299         -   group by items.id
   300         -   order by settings.last_viewed_at desc
   301         -   limit 10;
   302         -} [list \
   303         - 0 0 3 {SEARCH TABLE settings USING INDEX s_account_id (account_id=?)} \
   304         - 0 1 2 {SEARCH TABLE items AS grandchild USING INDEX i_guid (guid=?)} \
   305         - 0 2 1 {SEARCH TABLE items AS child USING INTEGER PRIMARY KEY (rowid=?)} \
   306         - 0 3 0 {SEARCH TABLE items USING INTEGER PRIMARY KEY (rowid=?)} \
   307         - 0 0 0 {USE TEMP B-TREE FOR GROUP BY} \
   308         - 0 0 0 {USE TEMP B-TREE FOR ORDER BY}]
   309         -
   310         -
   311         -finish_test

Changes to test/window6.test.

   364    364   } {
   365    365     fifteen fifteen 
   366    366     ten     fifteen.ten 
   367    367     thirty  fifteen.ten.thirty
   368    368   }
   369    369   
   370    370   finish_test
   371         -

Changes to test/window9.test.

   170    170       execsql "EXPLAIN QUERY PLAN $sql"
   171    171     } {~/ORDER/}
   172    172   }
   173    173   
   174    174   
   175    175   
   176    176   finish_test
   177         -

Changes to test/without_rowid1.test.

    98     98   
    99     99   # Verify that ANALYZE works
   100    100   #
   101    101   do_execsql_test without_rowid1-1.50 {
   102    102     ANALYZE;
   103    103     SELECT * FROM sqlite_stat1 ORDER BY idx;
   104    104   } {t1 t1 {4 2 1} t1 t1bd {4 2 2}}
   105         -ifcapable stat3 {
   106         -  do_execsql_test without_rowid1-1.51 {
   107         -    SELECT DISTINCT tbl, idx FROM sqlite_stat3 ORDER BY idx;
   108         -  } {t1 t1 t1 t1bd}
   109         -}
   110    105   ifcapable stat4 {
   111    106     do_execsql_test without_rowid1-1.52 {
   112    107       SELECT DISTINCT tbl, idx FROM sqlite_stat4 ORDER BY idx;
   113    108     } {t1 t1 t1 t1bd}
   114    109   }
   115    110   
   116    111   #----------