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