extensions/sqlite/sqlite-source/analyze.c
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 30 07:00:22 2008 +0000 (2008-03-30)
changeset 1952 b7aa2b626807
permissions -rw-r--r--
Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile
ds@1952
     1
/*
ds@1952
     2
** 2005 July 8
ds@1952
     3
**
ds@1952
     4
** The author disclaims copyright to this source code.  In place of
ds@1952
     5
** a legal notice, here is a blessing:
ds@1952
     6
**
ds@1952
     7
**    May you do good and not evil.
ds@1952
     8
**    May you find forgiveness for yourself and forgive others.
ds@1952
     9
**    May you share freely, never taking more than you give.
ds@1952
    10
**
ds@1952
    11
*************************************************************************
ds@1952
    12
** This file contains code associated with the ANALYZE command.
ds@1952
    13
**
ds@1952
    14
** @(#) $Id$
ds@1952
    15
*/
ds@1952
    16
#ifndef SQLITE_OMIT_ANALYZE
ds@1952
    17
#include "sqliteInt.h"
ds@1952
    18
ds@1952
    19
/*
ds@1952
    20
** This routine generates code that opens the sqlite_stat1 table on cursor
ds@1952
    21
** iStatCur.
ds@1952
    22
**
ds@1952
    23
** If the sqlite_stat1 tables does not previously exist, it is created.
ds@1952
    24
** If it does previously exist, all entires associated with table zWhere
ds@1952
    25
** are removed.  If zWhere==0 then all entries are removed.
ds@1952
    26
*/
ds@1952
    27
static void openStatTable(
ds@1952
    28
  Parse *pParse,          /* Parsing context */
ds@1952
    29
  int iDb,                /* The database we are looking in */
ds@1952
    30
  int iStatCur,           /* Open the sqlite_stat1 table on this cursor */
ds@1952
    31
  const char *zWhere      /* Delete entries associated with this table */
ds@1952
    32
){
ds@1952
    33
  sqlite3 *db = pParse->db;
ds@1952
    34
  Db *pDb;
ds@1952
    35
  int iRootPage;
ds@1952
    36
  Table *pStat;
ds@1952
    37
  Vdbe *v = sqlite3GetVdbe(pParse);
ds@1952
    38
ds@1952
    39
  if( v==0 ) return;
ds@1952
    40
  assert( sqlite3BtreeHoldsAllMutexes(db) );
ds@1952
    41
  assert( sqlite3VdbeDb(v)==db );
ds@1952
    42
  pDb = &db->aDb[iDb];
ds@1952
    43
  if( (pStat = sqlite3FindTable(db, "sqlite_stat1", pDb->zName))==0 ){
ds@1952
    44
    /* The sqlite_stat1 tables does not exist.  Create it.  
ds@1952
    45
    ** Note that a side-effect of the CREATE TABLE statement is to leave
ds@1952
    46
    ** the rootpage of the new table on the top of the stack.  This is
ds@1952
    47
    ** important because the OpenWrite opcode below will be needing it. */
ds@1952
    48
    sqlite3NestedParse(pParse,
ds@1952
    49
      "CREATE TABLE %Q.sqlite_stat1(tbl,idx,stat)",
ds@1952
    50
      pDb->zName
ds@1952
    51
    );
ds@1952
    52
    iRootPage = 0;  /* Cause rootpage to be taken from top of stack */
ds@1952
    53
  }else if( zWhere ){
ds@1952
    54
    /* The sqlite_stat1 table exists.  Delete all entries associated with
ds@1952
    55
    ** the table zWhere. */
ds@1952
    56
    sqlite3NestedParse(pParse,
ds@1952
    57
       "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q",
ds@1952
    58
       pDb->zName, zWhere
ds@1952
    59
    );
ds@1952
    60
    iRootPage = pStat->tnum;
ds@1952
    61
  }else{
ds@1952
    62
    /* The sqlite_stat1 table already exists.  Delete all rows. */
ds@1952
    63
    iRootPage = pStat->tnum;
ds@1952
    64
    sqlite3VdbeAddOp(v, OP_Clear, pStat->tnum, iDb);
ds@1952
    65
  }
ds@1952
    66
ds@1952
    67
  /* Open the sqlite_stat1 table for writing. Unless it was created
ds@1952
    68
  ** by this vdbe program, lock it for writing at the shared-cache level. 
ds@1952
    69
  ** If this vdbe did create the sqlite_stat1 table, then it must have 
ds@1952
    70
  ** already obtained a schema-lock, making the write-lock redundant.
ds@1952
    71
  */
ds@1952
    72
  if( iRootPage>0 ){
ds@1952
    73
    sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1");
ds@1952
    74
  }
ds@1952
    75
  sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
ds@1952
    76
  sqlite3VdbeAddOp(v, OP_OpenWrite, iStatCur, iRootPage);
ds@1952
    77
  sqlite3VdbeAddOp(v, OP_SetNumColumns, iStatCur, 3);
ds@1952
    78
}
ds@1952
    79
ds@1952
    80
/*
ds@1952
    81
** Generate code to do an analysis of all indices associated with
ds@1952
    82
** a single table.
ds@1952
    83
*/
ds@1952
    84
static void analyzeOneTable(
ds@1952
    85
  Parse *pParse,   /* Parser context */
ds@1952
    86
  Table *pTab,     /* Table whose indices are to be analyzed */
ds@1952
    87
  int iStatCur,    /* Cursor that writes to the sqlite_stat1 table */
ds@1952
    88
  int iMem         /* Available memory locations begin here */
ds@1952
    89
){
ds@1952
    90
  Index *pIdx;     /* An index to being analyzed */
ds@1952
    91
  int iIdxCur;     /* Cursor number for index being analyzed */
ds@1952
    92
  int nCol;        /* Number of columns in the index */
ds@1952
    93
  Vdbe *v;         /* The virtual machine being built up */
ds@1952
    94
  int i;           /* Loop counter */
ds@1952
    95
  int topOfLoop;   /* The top of the loop */
ds@1952
    96
  int endOfLoop;   /* The end of the loop */
ds@1952
    97
  int addr;        /* The address of an instruction */
ds@1952
    98
  int iDb;         /* Index of database containing pTab */
ds@1952
    99
ds@1952
   100
  v = sqlite3GetVdbe(pParse);
ds@1952
   101
  if( v==0 || pTab==0 || pTab->pIndex==0 ){
ds@1952
   102
    /* Do no analysis for tables that have no indices */
ds@1952
   103
    return;
ds@1952
   104
  }
ds@1952
   105
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
ds@1952
   106
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
ds@1952
   107
  assert( iDb>=0 );
ds@1952
   108
#ifndef SQLITE_OMIT_AUTHORIZATION
ds@1952
   109
  if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
ds@1952
   110
      pParse->db->aDb[iDb].zName ) ){
ds@1952
   111
    return;
ds@1952
   112
  }
ds@1952
   113
#endif
ds@1952
   114
ds@1952
   115
  /* Establish a read-lock on the table at the shared-cache level. */
ds@1952
   116
  sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
ds@1952
   117
ds@1952
   118
  iIdxCur = pParse->nTab;
ds@1952
   119
  for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
ds@1952
   120
    KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
ds@1952
   121
ds@1952
   122
    /* Open a cursor to the index to be analyzed
ds@1952
   123
    */
ds@1952
   124
    assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) );
ds@1952
   125
    sqlite3VdbeAddOp(v, OP_Integer, iDb, 0);
ds@1952
   126
    VdbeComment((v, "# %s", pIdx->zName));
ds@1952
   127
    sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum,
ds@1952
   128
        (char *)pKey, P3_KEYINFO_HANDOFF);
ds@1952
   129
    nCol = pIdx->nColumn;
ds@1952
   130
    if( iMem+nCol*2>=pParse->nMem ){
ds@1952
   131
      pParse->nMem = iMem+nCol*2+1;
ds@1952
   132
    }
ds@1952
   133
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, nCol+1);
ds@1952
   134
ds@1952
   135
    /* Memory cells are used as follows:
ds@1952
   136
    **
ds@1952
   137
    **    mem[iMem]:             The total number of rows in the table.
ds@1952
   138
    **    mem[iMem+1]:           Number of distinct values in column 1
ds@1952
   139
    **    ...
ds@1952
   140
    **    mem[iMem+nCol]:        Number of distinct values in column N
ds@1952
   141
    **    mem[iMem+nCol+1]       Last observed value of column 1
ds@1952
   142
    **    ...
ds@1952
   143
    **    mem[iMem+nCol+nCol]:   Last observed value of column N
ds@1952
   144
    **
ds@1952
   145
    ** Cells iMem through iMem+nCol are initialized to 0.  The others
ds@1952
   146
    ** are initialized to NULL.
ds@1952
   147
    */
ds@1952
   148
    for(i=0; i<=nCol; i++){
ds@1952
   149
      sqlite3VdbeAddOp(v, OP_MemInt, 0, iMem+i);
ds@1952
   150
    }
ds@1952
   151
    for(i=0; i<nCol; i++){
ds@1952
   152
      sqlite3VdbeAddOp(v, OP_MemNull, iMem+nCol+i+1, 0);
ds@1952
   153
    }
ds@1952
   154
ds@1952
   155
    /* Do the analysis.
ds@1952
   156
    */
ds@1952
   157
    endOfLoop = sqlite3VdbeMakeLabel(v);
ds@1952
   158
    sqlite3VdbeAddOp(v, OP_Rewind, iIdxCur, endOfLoop);
ds@1952
   159
    topOfLoop = sqlite3VdbeCurrentAddr(v);
ds@1952
   160
    sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem);
ds@1952
   161
    for(i=0; i<nCol; i++){
ds@1952
   162
      sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
ds@1952
   163
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem+nCol+i+1, 0);
ds@1952
   164
      sqlite3VdbeAddOp(v, OP_Ne, 0x100, 0);
ds@1952
   165
    }
ds@1952
   166
    sqlite3VdbeAddOp(v, OP_Goto, 0, endOfLoop);
ds@1952
   167
    for(i=0; i<nCol; i++){
ds@1952
   168
      addr = sqlite3VdbeAddOp(v, OP_MemIncr, 1, iMem+i+1);
ds@1952
   169
      sqlite3VdbeChangeP2(v, topOfLoop + 3*i + 3, addr);
ds@1952
   170
      sqlite3VdbeAddOp(v, OP_Column, iIdxCur, i);
ds@1952
   171
      sqlite3VdbeAddOp(v, OP_MemStore, iMem+nCol+i+1, 1);
ds@1952
   172
    }
ds@1952
   173
    sqlite3VdbeResolveLabel(v, endOfLoop);
ds@1952
   174
    sqlite3VdbeAddOp(v, OP_Next, iIdxCur, topOfLoop);
ds@1952
   175
    sqlite3VdbeAddOp(v, OP_Close, iIdxCur, 0);
ds@1952
   176
ds@1952
   177
    /* Store the results.  
ds@1952
   178
    **
ds@1952
   179
    ** The result is a single row of the sqlite_stat1 table.  The first
ds@1952
   180
    ** two columns are the names of the table and index.  The third column
ds@1952
   181
    ** is a string composed of a list of integer statistics about the
ds@1952
   182
    ** index.  The first integer in the list is the total number of entires
ds@1952
   183
    ** in the index.  There is one additional integer in the list for each
ds@1952
   184
    ** column of the table.  This additional integer is a guess of how many
ds@1952
   185
    ** rows of the table the index will select.  If D is the count of distinct
ds@1952
   186
    ** values and K is the total number of rows, then the integer is computed
ds@1952
   187
    ** as:
ds@1952
   188
    **
ds@1952
   189
    **        I = (K+D-1)/D
ds@1952
   190
    **
ds@1952
   191
    ** If K==0 then no entry is made into the sqlite_stat1 table.  
ds@1952
   192
    ** If K>0 then it is always the case the D>0 so division by zero
ds@1952
   193
    ** is never possible.
ds@1952
   194
    */
ds@1952
   195
    sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
ds@1952
   196
    addr = sqlite3VdbeAddOp(v, OP_IfNot, 0, 0);
ds@1952
   197
    sqlite3VdbeAddOp(v, OP_NewRowid, iStatCur, 0);
ds@1952
   198
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0);
ds@1952
   199
    sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0);
ds@1952
   200
    sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
ds@1952
   201
    sqlite3VdbeOp3(v, OP_String8, 0, 0, " ", 0);
ds@1952
   202
    for(i=0; i<nCol; i++){
ds@1952
   203
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem, 0);
ds@1952
   204
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
ds@1952
   205
      sqlite3VdbeAddOp(v, OP_Add, 0, 0);
ds@1952
   206
      sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);
ds@1952
   207
      sqlite3VdbeAddOp(v, OP_MemLoad, iMem+i+1, 0);
ds@1952
   208
      sqlite3VdbeAddOp(v, OP_Divide, 0, 0);
ds@1952
   209
      sqlite3VdbeAddOp(v, OP_ToInt, 0, 0);
ds@1952
   210
      if( i==nCol-1 ){
ds@1952
   211
        sqlite3VdbeAddOp(v, OP_Concat, nCol*2-1, 0);
ds@1952
   212
      }else{
ds@1952
   213
        sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
ds@1952
   214
      }
ds@1952
   215
    }
ds@1952
   216
    sqlite3VdbeOp3(v, OP_MakeRecord, 3, 0, "aaa", 0);
ds@1952
   217
    sqlite3VdbeAddOp(v, OP_Insert, iStatCur, OPFLAG_APPEND);
ds@1952
   218
    sqlite3VdbeJumpHere(v, addr);
ds@1952
   219
  }
ds@1952
   220
}
ds@1952
   221
ds@1952
   222
/*
ds@1952
   223
** Generate code that will cause the most recent index analysis to
ds@1952
   224
** be laoded into internal hash tables where is can be used.
ds@1952
   225
*/
ds@1952
   226
static void loadAnalysis(Parse *pParse, int iDb){
ds@1952
   227
  Vdbe *v = sqlite3GetVdbe(pParse);
ds@1952
   228
  if( v ){
ds@1952
   229
    sqlite3VdbeAddOp(v, OP_LoadAnalysis, iDb, 0);
ds@1952
   230
  }
ds@1952
   231
}
ds@1952
   232
ds@1952
   233
/*
ds@1952
   234
** Generate code that will do an analysis of an entire database
ds@1952
   235
*/
ds@1952
   236
static void analyzeDatabase(Parse *pParse, int iDb){
ds@1952
   237
  sqlite3 *db = pParse->db;
ds@1952
   238
  Schema *pSchema = db->aDb[iDb].pSchema;    /* Schema of database iDb */
ds@1952
   239
  HashElem *k;
ds@1952
   240
  int iStatCur;
ds@1952
   241
  int iMem;
ds@1952
   242
ds@1952
   243
  sqlite3BeginWriteOperation(pParse, 0, iDb);
ds@1952
   244
  iStatCur = pParse->nTab++;
ds@1952
   245
  openStatTable(pParse, iDb, iStatCur, 0);
ds@1952
   246
  iMem = pParse->nMem;
ds@1952
   247
  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
ds@1952
   248
    Table *pTab = (Table*)sqliteHashData(k);
ds@1952
   249
    analyzeOneTable(pParse, pTab, iStatCur, iMem);
ds@1952
   250
  }
ds@1952
   251
  loadAnalysis(pParse, iDb);
ds@1952
   252
}
ds@1952
   253
ds@1952
   254
/*
ds@1952
   255
** Generate code that will do an analysis of a single table in
ds@1952
   256
** a database.
ds@1952
   257
*/
ds@1952
   258
static void analyzeTable(Parse *pParse, Table *pTab){
ds@1952
   259
  int iDb;
ds@1952
   260
  int iStatCur;
ds@1952
   261
ds@1952
   262
  assert( pTab!=0 );
ds@1952
   263
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
ds@1952
   264
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
ds@1952
   265
  sqlite3BeginWriteOperation(pParse, 0, iDb);
ds@1952
   266
  iStatCur = pParse->nTab++;
ds@1952
   267
  openStatTable(pParse, iDb, iStatCur, pTab->zName);
ds@1952
   268
  analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem);
ds@1952
   269
  loadAnalysis(pParse, iDb);
ds@1952
   270
}
ds@1952
   271
ds@1952
   272
/*
ds@1952
   273
** Generate code for the ANALYZE command.  The parser calls this routine
ds@1952
   274
** when it recognizes an ANALYZE command.
ds@1952
   275
**
ds@1952
   276
**        ANALYZE                            -- 1
ds@1952
   277
**        ANALYZE  <database>                -- 2
ds@1952
   278
**        ANALYZE  ?<database>.?<tablename>  -- 3
ds@1952
   279
**
ds@1952
   280
** Form 1 causes all indices in all attached databases to be analyzed.
ds@1952
   281
** Form 2 analyzes all indices the single database named.
ds@1952
   282
** Form 3 analyzes all indices associated with the named table.
ds@1952
   283
*/
ds@1952
   284
void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
ds@1952
   285
  sqlite3 *db = pParse->db;
ds@1952
   286
  int iDb;
ds@1952
   287
  int i;
ds@1952
   288
  char *z, *zDb;
ds@1952
   289
  Table *pTab;
ds@1952
   290
  Token *pTableName;
ds@1952
   291
ds@1952
   292
  /* Read the database schema. If an error occurs, leave an error message
ds@1952
   293
  ** and code in pParse and return NULL. */
ds@1952
   294
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
ds@1952
   295
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
ds@1952
   296
    return;
ds@1952
   297
  }
ds@1952
   298
ds@1952
   299
  if( pName1==0 ){
ds@1952
   300
    /* Form 1:  Analyze everything */
ds@1952
   301
    for(i=0; i<db->nDb; i++){
ds@1952
   302
      if( i==1 ) continue;  /* Do not analyze the TEMP database */
ds@1952
   303
      analyzeDatabase(pParse, i);
ds@1952
   304
    }
ds@1952
   305
  }else if( pName2==0 || pName2->n==0 ){
ds@1952
   306
    /* Form 2:  Analyze the database or table named */
ds@1952
   307
    iDb = sqlite3FindDb(db, pName1);
ds@1952
   308
    if( iDb>=0 ){
ds@1952
   309
      analyzeDatabase(pParse, iDb);
ds@1952
   310
    }else{
ds@1952
   311
      z = sqlite3NameFromToken(db, pName1);
ds@1952
   312
      pTab = sqlite3LocateTable(pParse, z, 0);
ds@1952
   313
      sqlite3_free(z);
ds@1952
   314
      if( pTab ){
ds@1952
   315
        analyzeTable(pParse, pTab);
ds@1952
   316
      }
ds@1952
   317
    }
ds@1952
   318
  }else{
ds@1952
   319
    /* Form 3: Analyze the fully qualified table name */
ds@1952
   320
    iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
ds@1952
   321
    if( iDb>=0 ){
ds@1952
   322
      zDb = db->aDb[iDb].zName;
ds@1952
   323
      z = sqlite3NameFromToken(db, pTableName);
ds@1952
   324
      if( z ){
ds@1952
   325
        pTab = sqlite3LocateTable(pParse, z, zDb);
ds@1952
   326
        sqlite3_free(z);
ds@1952
   327
        if( pTab ){
ds@1952
   328
          analyzeTable(pParse, pTab);
ds@1952
   329
        }
ds@1952
   330
      }
ds@1952
   331
    }   
ds@1952
   332
  }
ds@1952
   333
}
ds@1952
   334
ds@1952
   335
/*
ds@1952
   336
** Used to pass information from the analyzer reader through to the
ds@1952
   337
** callback routine.
ds@1952
   338
*/
ds@1952
   339
typedef struct analysisInfo analysisInfo;
ds@1952
   340
struct analysisInfo {
ds@1952
   341
  sqlite3 *db;
ds@1952
   342
  const char *zDatabase;
ds@1952
   343
};
ds@1952
   344
ds@1952
   345
/*
ds@1952
   346
** This callback is invoked once for each index when reading the
ds@1952
   347
** sqlite_stat1 table.  
ds@1952
   348
**
ds@1952
   349
**     argv[0] = name of the index
ds@1952
   350
**     argv[1] = results of analysis - on integer for each column
ds@1952
   351
*/
ds@1952
   352
static int analysisLoader(void *pData, int argc, char **argv, char **azNotUsed){
ds@1952
   353
  analysisInfo *pInfo = (analysisInfo*)pData;
ds@1952
   354
  Index *pIndex;
ds@1952
   355
  int i, c;
ds@1952
   356
  unsigned int v;
ds@1952
   357
  const char *z;
ds@1952
   358
ds@1952
   359
  assert( argc==2 );
ds@1952
   360
  if( argv==0 || argv[0]==0 || argv[1]==0 ){
ds@1952
   361
    return 0;
ds@1952
   362
  }
ds@1952
   363
  pIndex = sqlite3FindIndex(pInfo->db, argv[0], pInfo->zDatabase);
ds@1952
   364
  if( pIndex==0 ){
ds@1952
   365
    return 0;
ds@1952
   366
  }
ds@1952
   367
  z = argv[1];
ds@1952
   368
  for(i=0; *z && i<=pIndex->nColumn; i++){
ds@1952
   369
    v = 0;
ds@1952
   370
    while( (c=z[0])>='0' && c<='9' ){
ds@1952
   371
      v = v*10 + c - '0';
ds@1952
   372
      z++;
ds@1952
   373
    }
ds@1952
   374
    pIndex->aiRowEst[i] = v;
ds@1952
   375
    if( *z==' ' ) z++;
ds@1952
   376
  }
ds@1952
   377
  return 0;
ds@1952
   378
}
ds@1952
   379
ds@1952
   380
/*
ds@1952
   381
** Load the content of the sqlite_stat1 table into the index hash tables.
ds@1952
   382
*/
ds@1952
   383
int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
ds@1952
   384
  analysisInfo sInfo;
ds@1952
   385
  HashElem *i;
ds@1952
   386
  char *zSql;
ds@1952
   387
  int rc;
ds@1952
   388
ds@1952
   389
  assert( iDb>=0 && iDb<db->nDb );
ds@1952
   390
  assert( db->aDb[iDb].pBt!=0 );
ds@1952
   391
  assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
ds@1952
   392
ds@1952
   393
  /* Clear any prior statistics */
ds@1952
   394
  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
ds@1952
   395
    Index *pIdx = sqliteHashData(i);
ds@1952
   396
    sqlite3DefaultRowEst(pIdx);
ds@1952
   397
  }
ds@1952
   398
ds@1952
   399
  /* Check to make sure the sqlite_stat1 table existss */
ds@1952
   400
  sInfo.db = db;
ds@1952
   401
  sInfo.zDatabase = db->aDb[iDb].zName;
ds@1952
   402
  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){
ds@1952
   403
     return SQLITE_ERROR;
ds@1952
   404
  }
ds@1952
   405
ds@1952
   406
ds@1952
   407
  /* Load new statistics out of the sqlite_stat1 table */
ds@1952
   408
  zSql = sqlite3MPrintf(db, "SELECT idx, stat FROM %Q.sqlite_stat1",
ds@1952
   409
                        sInfo.zDatabase);
ds@1952
   410
  sqlite3SafetyOff(db);
ds@1952
   411
  rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
ds@1952
   412
  sqlite3SafetyOn(db);
ds@1952
   413
  sqlite3_free(zSql);
ds@1952
   414
  return rc;
ds@1952
   415
}
ds@1952
   416
ds@1952
   417
ds@1952
   418
#endif /* SQLITE_OMIT_ANALYZE */