15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2005 July 8
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains code associated with the ANALYZE command.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_ANALYZE
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This routine generates code that opens the sqlite_stat1 table for
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** writing with cursor iStatCur. If the library was built with the
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_ENABLE_STAT2 macro defined, then the sqlite_stat2 table is
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** opened for writing using cursor (iStatCur+1)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the sqlite_stat1 tables does not previously exist, it is created.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Similarly, if the sqlite_stat2 table does not exist and the library
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is compiled with SQLITE_ENABLE_STAT2 defined, it is created.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Argument zWhere may be a pointer to a buffer containing a table name,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** or it may be a NULL pointer. If it is not NULL, then all entries in
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the sqlite_stat1 and (if applicable) sqlite_stat2 tables associated
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** with the named table are deleted. If zWhere==0, then code is generated
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to delete all stat table entries.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void openStatTable(
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,          /* Parsing context */
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iDb,                /* The database we are looking in */
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zWhere,     /* Delete entries for this table or index */
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zWhereType  /* Either "tbl" or "idx" */
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *zName;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *zCols;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aTable[] = {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "sqlite_stat1", "tbl,idx,stat" },
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "sqlite_stat2", "tbl,idx,sampleno,sample" },
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int aRoot[] = {0, 0};
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u8 aCreateTbl[] = {0, 0};
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = pParse->db;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Db *pDb;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Vdbe *v = sqlite3GetVdbe(pParse);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( v==0 ) return;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3BtreeHoldsAllMutexes(db) );
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3VdbeDb(v)==db );
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pDb = &db->aDb[iDb];
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<ArraySize(aTable); i++){
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char *zTab = aTable[i].zName;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Table *pStat;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* The sqlite_stat[12] table does not exist. Create it. Note that a
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** side-effect of the CREATE TABLE statement is to leave the rootpage
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** of the new table in register pParse->regRoot. This is important
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** because the OpenWrite opcode below will be needing it. */
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3NestedParse(pParse,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      );
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aRoot[i] = pParse->regRoot;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aCreateTbl[i] = 1;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* The table already exists. If zWhere is not NULL, delete all entries
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** associated with the table zWhere. If zWhere is NULL, delete the
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** entire contents of the table. */
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aRoot[i] = pStat->tnum;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( zWhere ){
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3NestedParse(pParse,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        );
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }else{
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* The sqlite_stat[12] table already exists.  Delete all rows. */
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Open the sqlite_stat[12] tables for writing. */
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<ArraySize(aTable); i++){
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeChangeP5(v, aCreateTbl[i]);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code to do an analysis of all indices associated with
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a single table.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void analyzeOneTable(
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,   /* Parser context */
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTab,     /* Table whose indices are to be analyzed */
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index *pOnlyIdx, /* If not NULL, only analyze this one index */
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iStatCur,    /* Index of VdbeCursor that writes the sqlite_stat1 table */
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iMem         /* Available memory locations begin here */
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = pParse->db;    /* Database handle */
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index *pIdx;                 /* An index to being analyzed */
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iIdxCur;                 /* Cursor open on index being analyzed */
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Vdbe *v;                     /* The virtual machine being built up */
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;                       /* Loop counter */
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int topOfLoop;               /* The top of the loop */
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int endOfLoop;               /* The end of the loop */
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int jZeroRows = -1;          /* Jump from here if number of rows is zero */
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iDb;                     /* Index of database containing pTab */
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regTabname = iMem++;     /* Register containing table name */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regIdxname = iMem++;     /* Register containing index name */
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regSampleno = iMem++;    /* Register containing next sample number */
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regCol = iMem++;         /* Content of a column analyzed table */
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regRec = iMem++;         /* Register holding completed record */
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regTemp = iMem++;        /* Temporary use register */
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regRowid = iMem++;       /* Rowid for the inserted record */
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int addr = 0;                /* Instruction address */
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regTemp2 = iMem++;       /* Temporary use register */
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regSamplerecno = iMem++; /* Index of next sample to record */
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regRecno = iMem++;       /* Current sample index */
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regLast = iMem++;        /* Index of last sample to record */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regFirst = iMem++;       /* Index of first sample to record */
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v = sqlite3GetVdbe(pParse);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( v==0 || NEVER(pTab==0) ){
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pTab->tnum==0 ){
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Do not gather statistics on views or virtual tables */
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==0 ){
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Do not gather statistics on system tables */
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3BtreeHoldsAllMutexes(db) );
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( iDb>=0 );
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTHORIZATION
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      db->aDb[iDb].zName ) ){
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Establish a read-lock on the table at the shared-cache level. */
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iIdxCur = pParse->nTab++;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nCol;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    KeyInfo *pKey;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    nCol = pIdx->nColumn;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pKey = sqlite3IndexKeyinfo(pParse, pIdx);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( iMem+1+(nCol*2)>pParse->nMem ){
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pParse->nMem = iMem+1+(nCol*2);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Open a cursor to the index to be analyzed. */
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (char *)pKey, P4_KEYINFO_HANDOFF);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VdbeComment((v, "%s", pIdx->zName));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Populate the register containing the index name. */
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* If this iteration of the loop is generating code to analyze the
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** first index in the pTab->pIndex list, then register regLast has
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** not been populated. In this case populate it now.  */
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pTab->pIndex==pIdx ){
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Divide,  regTemp2, regLast, regLast);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeJumpHere(v, addr);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Zero the regSampleno and regRecno registers. */
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* The block of memory cells initialized here is used as follows.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **    iMem:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **        The total number of rows in the table.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **    iMem+1 .. iMem+nCol:
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **        Number of distinct entries in index considering the
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **        left-most N columns only, where N is between 1 and nCol,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **        inclusive.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **    iMem+nCol+1 .. Mem+2*nCol:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **        Previous value of indexed columns, from left to right.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** Cells iMem through iMem+nCol are initialized to 0. The others are
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** initialized to contain an SQL NULL.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(i=0; i<=nCol; i++){
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(i=0; i<nCol; i++){
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Start the analysis loop. This loop runs through all the entries in
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** the index b-tree.  */
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    endOfLoop = sqlite3VdbeMakeLabel(v);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    topOfLoop = sqlite3VdbeCurrentAddr(v);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(i=0; i<nCol; i++){
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CollSeq *pColl;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( i==0 ){
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Check if the record that cursor iIdxCur points to contains a
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ** value that should be stored in the sqlite_stat2 table. If so,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ** store it.  */
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert( regTabname+1==regIdxname
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             && regTabname+2==regSampleno
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             && regTabname+3==regCol
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        );
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 4, regRec, "aaab", 0);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Calculate new values for regSamplerecno and regSampleno.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **   sampleno = sampleno + 1
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        **   samplerecno = samplerecno+(remaining records)/(remaining samples)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        */
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp3(v, OP_Subtract, regRecno, regLast, regTemp);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regTemp2);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp3(v, OP_Subtract, regSampleno, regTemp2, regTemp2);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regTemp, regTemp);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp3(v, OP_Add, regSamplerecno, regTemp, regSamplerecno);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeJumpHere(v, ne);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Always record the very first row */
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert( pIdx->azColl!=0 );
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      assert( pIdx->azColl[i]!=0 );
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       (char*)pColl, P4_COLLSEQ);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( db->mallocFailed ){
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      /* If a malloc failure has occurred, then the result of the expression
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** passed as the second argument to the call to sqlite3VdbeJumpHere()
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** below may be negative. Which causes an assert() to fail (or an
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ** out-of-bounds write if SQLITE_DEBUG is not defined).  */
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(i=0; i<nCol; i++){
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int addr2 = sqlite3VdbeCurrentAddr(v) - (nCol*2);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( i==0 ){
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3VdbeJumpHere(v, addr2-1);  /* Set jump dest for the OP_IfNot */
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeJumpHere(v, addr2);      /* Set jump dest for the OP_Ne */
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* End of the analysis loop. */
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeResolveLabel(v, endOfLoop);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Store the results in sqlite_stat1.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** The result is a single row of the sqlite_stat1 table.  The first
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** two columns are the names of the table and index.  The third column
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** is a string composed of a list of integer statistics about the
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** index.  The first integer in the list is the total number of entries
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** in the index.  There is one additional integer in the list for each
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** column of the table.  This additional integer is a guess of how many
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** rows of the table the index will select.  If D is the count of distinct
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** values and K is the total number of rows, then the integer is computed
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** as:
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **        I = (K+D-1)/D
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    **
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** If K==0 then no entry is made into the sqlite_stat1 table.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** If K>0 then it is always the case the D>0 so division by zero
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** is never possible.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( jZeroRows<0 ){
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(i=0; i<nCol; i++){
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* If the table has no indices, create a single sqlite_stat1 entry
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** containing NULL as the index name and the row count as the content.
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pTab->pIndex==0 ){
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VdbeComment((v, "%s", pTab->zName));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regSampleno);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regSampleno);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeJumpHere(v, jZeroRows);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pParse->nMem<regRec ) pParse->nMem = regRec;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3VdbeJumpHere(v, jZeroRows);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code that will cause the most recent index analysis to
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** be loaded into internal hash tables where is can be used.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void loadAnalysis(Parse *pParse, int iDb){
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Vdbe *v = sqlite3GetVdbe(pParse);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( v ){
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code that will do an analysis of an entire database
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void analyzeDatabase(Parse *pParse, int iDb){
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = pParse->db;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HashElem *k;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iStatCur;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iMem;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3BeginWriteOperation(pParse, 0, iDb);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iStatCur = pParse->nTab;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pParse->nTab += 2;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  openStatTable(pParse, iDb, iStatCur, 0, 0);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iMem = pParse->nMem+1;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Table *pTab = (Table*)sqliteHashData(k);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    analyzeOneTable(pParse, pTab, 0, iStatCur, iMem);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  loadAnalysis(pParse, iDb);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code that will do an analysis of a single table in
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a database.  If pOnlyIdx is not NULL then it is a single index
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in pTab that should be analyzed.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iDb;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iStatCur;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( pTab!=0 );
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3BeginWriteOperation(pParse, 0, iDb);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iStatCur = pParse->nTab;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pParse->nTab += 2;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pOnlyIdx ){
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  loadAnalysis(pParse, iDb);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Generate code for the ANALYZE command.  The parser calls this routine
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** when it recognizes an ANALYZE command.
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**        ANALYZE                            -- 1
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**        ANALYZE  <database>                -- 2
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**        ANALYZE  ?<database>.?<tablename>  -- 3
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Form 1 causes all indices in all attached databases to be analyzed.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Form 2 analyzes all indices the single database named.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Form 3 analyzes all indices associated with the named table.
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = pParse->db;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iDb;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *z, *zDb;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTab;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index *pIdx;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Token *pTableName;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Read the database schema. If an error occurs, leave an error message
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** and code in pParse and return NULL. */
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( pName2!=0 || pName1==0 );
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pName1==0 ){
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Form 1:  Analyze everything */
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(i=0; i<db->nDb; i++){
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( i==1 ) continue;  /* Do not analyze the TEMP database */
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      analyzeDatabase(pParse, i);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( pName2->n==0 ){
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Form 2:  Analyze the database or table named */
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iDb = sqlite3FindDb(db, pName1);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( iDb>=0 ){
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      analyzeDatabase(pParse, iDb);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      z = sqlite3NameFromToken(db, pName1);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( z ){
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          analyzeTable(pParse, pIdx->pTable, pIdx);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          analyzeTable(pParse, pTab, 0);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3DbFree(db, z);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Form 3: Analyze the fully qualified table name */
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( iDb>=0 ){
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zDb = db->aDb[iDb].zName;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      z = sqlite3NameFromToken(db, pTableName);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( z ){
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          analyzeTable(pParse, pIdx->pTable, pIdx);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          analyzeTable(pParse, pTab, 0);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3DbFree(db, z);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Used to pass information from the analyzer reader through to the
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** callback routine.
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct analysisInfo analysisInfo;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct analysisInfo {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zDatabase;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This callback is invoked once for each index when reading the
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite_stat1 table.
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     argv[0] = name of the table
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     argv[1] = name of the index (might be NULL)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     argv[2] = results of analysis - on integer for each column
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Entries for which argv[1]==NULL simply record the number of rows in
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the table.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  analysisInfo *pInfo = (analysisInfo*)pData;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Index *pIndex;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Table *pTable;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i, c, n;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int v;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *z;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( argc==3 );
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNUSED_PARAMETER2(NotUsed, argc);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argv==0 || argv[0]==0 || argv[2]==0 ){
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pTable==0 ){
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argv[1] ){
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pIndex = 0;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  n = pIndex ? pIndex->nColumn : 0;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  z = argv[2];
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; *z && i<=n; i++){
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v = 0;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while( (c=z[0])>='0' && c<='9' ){
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      v = v*10 + c - '0';
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      z++;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( i==0 ) pTable->nRowEst = v;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pIndex==0 ) break;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pIndex->aiRowEst[i] = v;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( *z==' ' ) z++;
551b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if( strcmp(z, "unordered")==0 ){
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pIndex->bUnordered = 1;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the Index.aSample variable is not NULL, delete the aSample[] array
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and its contents.
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pIdx->aSample ){
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int j;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for(j=0; j<SQLITE_INDEX_SAMPLES; j++){
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IndexSample *p = &pIdx->aSample[j];
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3DbFree(db, p->u.z);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3DbFree(db, pIdx->aSample);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNUSED_PARAMETER(db);
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNUSED_PARAMETER(pIdx);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** arrays. The contents of sqlite_stat2 are used to populate the
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Index.aSample[] arrays.
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** during compilation and the sqlite_stat2 table is present, no data is
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** read from it.
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If SQLITE_ENABLE_STAT2 was defined during compilation and the
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite_stat2 table is not present in the database, SQLITE_ERROR is
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** returned. However, in this case, data is read from the sqlite_stat1
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** table (if it is present) before returning.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If an OOM error occurs, this function always sets db->mallocFailed.
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This means if the caller does not care about other errors, the return
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** code may be ignored.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  analysisInfo sInfo;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HashElem *i;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zSql;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( iDb>=0 && iDb<db->nDb );
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( db->aDb[iDb].pBt!=0 );
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Clear any prior statistics */
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Index *pIdx = sqliteHashData(i);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3DefaultRowEst(pIdx);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3DeleteIndexSamples(db, pIdx);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pIdx->aSample = 0;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Check to make sure the sqlite_stat1 table exists */
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sInfo.db = db;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sInfo.zDatabase = db->aDb[iDb].zName;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SQLITE_ERROR;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Load new statistics out of the sqlite_stat1 table */
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zSql = sqlite3MPrintf(db,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zSql==0 ){
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = SQLITE_NOMEM;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3DbFree(db, zSql);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Load the statistics from the sqlite_stat2 table. */
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_ENABLE_STAT2
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK && !sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase) ){
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = SQLITE_ERROR;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_stmt *pStmt = 0;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zSql = sqlite3MPrintf(db,
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( !zSql ){
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc = SQLITE_NOMEM;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3DbFree(db, zSql);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( rc==SQLITE_OK ){
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      while( sqlite3_step(pStmt)==SQLITE_ROW ){
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        char *zIndex;   /* Index name */
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Index *pIdx;    /* Pointer to the index object */
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zIndex = (char *)sqlite3_column_text(pStmt, 0);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        pIdx = zIndex ? sqlite3FindIndex(db, zIndex, sInfo.zDatabase) : 0;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( pIdx ){
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int iSample = sqlite3_column_int(pStmt, 1);
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            int eType = sqlite3_column_type(pStmt, 2);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if( pIdx->aSample==0 ){
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              if( pIdx->aSample==0 ){
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                db->mallocFailed = 1;
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                break;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              }
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	      memset(pIdx->aSample, 0, sz);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            assert( pIdx->aSample );
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              IndexSample *pSample = &pIdx->aSample[iSample];
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              pSample->eType = (u8)eType;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                pSample->u.r = sqlite3_column_double(pStmt, 2);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const char *z = (const char *)(
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    (eType==SQLITE_BLOB) ?
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    sqlite3_column_blob(pStmt, 2):
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    sqlite3_column_text(pStmt, 2)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                );
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int n = sqlite3_column_bytes(pStmt, 2);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if( n>24 ){
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  n = 24;
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                pSample->nByte = (u8)n;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if( n < 1){
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  pSample->u.z = 0;
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }else{
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  pSample->u.z = sqlite3DbStrNDup(0, z, n);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  if( pSample->u.z==0 ){
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    db->mallocFailed = 1;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    break;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  }
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              }
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc = sqlite3_finalize(pStmt);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_NOMEM ){
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    db->mallocFailed = 1;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_ANALYZE */
720