19f18e8a0Sdrh /*
29fecc546Sdrh ** 2005-07-08
39f18e8a0Sdrh **
49f18e8a0Sdrh ** The author disclaims copyright to this source code. In place of
59f18e8a0Sdrh ** a legal notice, here is a blessing:
69f18e8a0Sdrh **
79f18e8a0Sdrh ** May you do good and not evil.
89f18e8a0Sdrh ** May you find forgiveness for yourself and forgive others.
99f18e8a0Sdrh ** May you share freely, never taking more than you give.
109f18e8a0Sdrh **
119f18e8a0Sdrh *************************************************************************
129f18e8a0Sdrh ** This file contains code associated with the ANALYZE command.
13faacf17cSdrh **
14faacf17cSdrh ** The ANALYZE command gather statistics about the content of tables
15faacf17cSdrh ** and indices. These statistics are made available to the query planner
16faacf17cSdrh ** to help it make better decisions about how to perform queries.
17faacf17cSdrh **
18faacf17cSdrh ** The following system tables are or have been supported:
19faacf17cSdrh **
20faacf17cSdrh ** CREATE TABLE sqlite_stat1(tbl, idx, stat);
21faacf17cSdrh ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
22f404c86aSdrh ** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);
23c8af8504Sdrh ** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample);
24faacf17cSdrh **
25faacf17cSdrh ** Additional tables might be added in future releases of SQLite.
26faacf17cSdrh ** The sqlite_stat2 table is not created or used unless the SQLite version
27d3ed7340Sdrh ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
28faacf17cSdrh ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
29f7b5496eSdrh ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only
30175b8f06Sdrh ** created and used by SQLite versions 3.7.9 through 3.29.0 when
31c8af8504Sdrh ** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3
32175b8f06Sdrh ** is a superset of sqlite_stat2 and is also now deprecated. The
33175b8f06Sdrh ** sqlite_stat4 is an enhanced version of sqlite_stat3 and is only
34175b8f06Sdrh ** available when compiled with SQLITE_ENABLE_STAT4 and in SQLite
35175b8f06Sdrh ** versions 3.8.1 and later. STAT4 is the only variant that is still
36175b8f06Sdrh ** supported.
37c8af8504Sdrh **
3860ec914cSpeter.d.reid ** For most applications, sqlite_stat1 provides all the statistics required
39c8af8504Sdrh ** for the query planner to make good choices.
40faacf17cSdrh **
41faacf17cSdrh ** Format of sqlite_stat1:
42faacf17cSdrh **
43faacf17cSdrh ** There is normally one row per index, with the index identified by the
44faacf17cSdrh ** name in the idx column. The tbl column is the name of the table to
45faacf17cSdrh ** which the index belongs. In each such row, the stat column will be
46faacf17cSdrh ** a string consisting of a list of integers. The first integer in this
47c8af8504Sdrh ** list is the number of rows in the index. (This is the same as the
48c8af8504Sdrh ** number of rows in the table, except for partial indices.) The second
49faacf17cSdrh ** integer is the average number of rows in the index that have the same
50faacf17cSdrh ** value in the first column of the index. The third integer is the average
51faacf17cSdrh ** number of rows in the index that have the same value for the first two
52faacf17cSdrh ** columns. The N-th integer (for N>1) is the average number of rows in
53faacf17cSdrh ** the index which have the same value for the first N-1 columns. For
54faacf17cSdrh ** a K-column index, there will be K+1 integers in the stat column. If
55faacf17cSdrh ** the index is unique, then the last integer will be 1.
56faacf17cSdrh **
57faacf17cSdrh ** The list of integers in the stat column can optionally be followed
58faacf17cSdrh ** by the keyword "unordered". The "unordered" keyword, if it is present,
59faacf17cSdrh ** must be separated from the last integer by a single space. If the
60faacf17cSdrh ** "unordered" keyword is present, then the query planner assumes that
61faacf17cSdrh ** the index is unordered and will not use the index for a range query.
62faacf17cSdrh **
63faacf17cSdrh ** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat
64faacf17cSdrh ** column contains a single integer which is the (estimated) number of
65faacf17cSdrh ** rows in the table identified by sqlite_stat1.tbl.
66faacf17cSdrh **
67faacf17cSdrh ** Format of sqlite_stat2:
68faacf17cSdrh **
69faacf17cSdrh ** The sqlite_stat2 is only created and is only used if SQLite is compiled
70faacf17cSdrh ** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between
71d3ed7340Sdrh ** 3.6.18 and 3.7.8. The "stat2" table contains additional information
72faacf17cSdrh ** about the distribution of keys within an index. The index is identified by
73faacf17cSdrh ** the "idx" column and the "tbl" column is the name of the table to which
74faacf17cSdrh ** the index belongs. There are usually 10 rows in the sqlite_stat2
75faacf17cSdrh ** table for each index.
76faacf17cSdrh **
7723e7c4deSdan ** The sqlite_stat2 entries for an index that have sampleno between 0 and 9
78faacf17cSdrh ** inclusive are samples of the left-most key value in the index taken at
79faacf17cSdrh ** evenly spaced points along the index. Let the number of samples be S
80faacf17cSdrh ** (10 in the standard build) and let C be the number of rows in the index.
81faacf17cSdrh ** Then the sampled rows are given by:
82faacf17cSdrh **
83faacf17cSdrh ** rownumber = (i*C*2 + C)/(S*2)
84faacf17cSdrh **
85faacf17cSdrh ** For i between 0 and S-1. Conceptually, the index space is divided into
86faacf17cSdrh ** S uniform buckets and the samples are the middle row from each bucket.
87faacf17cSdrh **
88faacf17cSdrh ** The format for sqlite_stat2 is recorded here for legacy reference. This
89faacf17cSdrh ** version of SQLite does not support sqlite_stat2. It neither reads nor
90faacf17cSdrh ** writes the sqlite_stat2 table. This version of SQLite only supports
91faacf17cSdrh ** sqlite_stat3.
92faacf17cSdrh **
93faacf17cSdrh ** Format for sqlite_stat3:
94faacf17cSdrh **
95c8af8504Sdrh ** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the
96c8af8504Sdrh ** sqlite_stat4 format will be described first. Further information
97c8af8504Sdrh ** about sqlite_stat3 follows the sqlite_stat4 description.
98faacf17cSdrh **
99c8af8504Sdrh ** Format for sqlite_stat4:
100c8af8504Sdrh **
101c8af8504Sdrh ** As with sqlite_stat2, the sqlite_stat4 table contains histogram data
102c8af8504Sdrh ** to aid the query planner in choosing good indices based on the values
103c8af8504Sdrh ** that indexed columns are compared against in the WHERE clauses of
104c8af8504Sdrh ** queries.
105c8af8504Sdrh **
106c8af8504Sdrh ** The sqlite_stat4 table contains multiple entries for each index.
107d3ed7340Sdrh ** The idx column names the index and the tbl column is the table of the
108d3ed7340Sdrh ** index. If the idx and tbl columns are the same, then the sample is
109c8af8504Sdrh ** of the INTEGER PRIMARY KEY. The sample column is a blob which is the
1100ae4f14eSdrh ** binary encoding of a key from the index. The nEq column is a
1110ae4f14eSdrh ** list of integers. The first integer is the approximate number
1120ae4f14eSdrh ** of entries in the index whose left-most column exactly matches
1130ae4f14eSdrh ** the left-most column of the sample. The second integer in nEq
1140ae4f14eSdrh ** is the approximate number of entries in the index where the
1150ae4f14eSdrh ** first two columns match the first two columns of the sample.
11684d4fcc5Sdan ** And so forth. nLt is another list of integers that show the approximate
11784d4fcc5Sdan ** number of entries that are strictly less than the sample. The first
118c8af8504Sdrh ** integer in nLt contains the number of entries in the index where the
119c8af8504Sdrh ** left-most column is less than the left-most column of the sample.
120c8af8504Sdrh ** The K-th integer in the nLt entry is the number of index entries
121c8af8504Sdrh ** where the first K columns are less than the first K columns of the
122c8af8504Sdrh ** sample. The nDLt column is like nLt except that it contains the
123c8af8504Sdrh ** number of distinct entries in the index that are less than the
124c8af8504Sdrh ** sample.
125faacf17cSdrh **
126c8af8504Sdrh ** There can be an arbitrary number of sqlite_stat4 entries per index.
12784d4fcc5Sdan ** The ANALYZE command will typically generate sqlite_stat4 tables
128faacf17cSdrh ** that contain between 10 and 40 samples which are distributed across
129faacf17cSdrh ** the key space, though not uniformly, and which include samples with
130c8af8504Sdrh ** large nEq values.
131c8af8504Sdrh **
132c8af8504Sdrh ** Format for sqlite_stat3 redux:
133c8af8504Sdrh **
134c8af8504Sdrh ** The sqlite_stat3 table is like sqlite_stat4 except that it only
135c8af8504Sdrh ** looks at the left-most column of the index. The sqlite_stat3.sample
136c8af8504Sdrh ** column contains the actual value of the left-most column instead
137c8af8504Sdrh ** of a blob encoding of the complete index key as is found in
138c8af8504Sdrh ** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3
139c8af8504Sdrh ** all contain just a single integer which is the same as the first
140c8af8504Sdrh ** integer in the equivalent columns in sqlite_stat4.
1419f18e8a0Sdrh */
1429f18e8a0Sdrh #ifndef SQLITE_OMIT_ANALYZE
1439f18e8a0Sdrh #include "sqliteInt.h"
1449f18e8a0Sdrh
145f00e9025Sdan #if defined(SQLITE_ENABLE_STAT4)
146f00e9025Sdan # define IsStat4 1
147f00e9025Sdan #else
148f00e9025Sdan # define IsStat4 0
1499fecc546Sdrh # undef SQLITE_STAT4_SAMPLES
1509fecc546Sdrh # define SQLITE_STAT4_SAMPLES 1
1518ad169abSdan #endif
1528ad169abSdan
1539f18e8a0Sdrh /*
1549fecc546Sdrh ** This routine generates code that opens the sqlite_statN tables.
1559fecc546Sdrh ** The sqlite_stat1 table is always relevant. sqlite_stat2 is now
1569fecc546Sdrh ** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when
1579fecc546Sdrh ** appropriate compile-time options are provided.
158ff2d5ea4Sdrh **
1599fecc546Sdrh ** If the sqlite_statN tables do not previously exist, it is created.
16069188d9aSdan **
16169188d9aSdan ** Argument zWhere may be a pointer to a buffer containing a table name,
16269188d9aSdan ** or it may be a NULL pointer. If it is not NULL, then all entries in
1639fecc546Sdrh ** the sqlite_statN tables associated with the named table are deleted.
1649fecc546Sdrh ** If zWhere==0, then code is generated to delete all stat table entries.
165ff2d5ea4Sdrh */
openStatTable(Parse * pParse,int iDb,int iStatCur,const char * zWhere,const char * zWhereType)166ff2d5ea4Sdrh static void openStatTable(
167ff2d5ea4Sdrh Parse *pParse, /* Parsing context */
168ff2d5ea4Sdrh int iDb, /* The database we are looking in */
169ff2d5ea4Sdrh int iStatCur, /* Open the sqlite_stat1 table on this cursor */
170a071bc5dSdrh const char *zWhere, /* Delete entries for this table or index */
171a071bc5dSdrh const char *zWhereType /* Either "tbl" or "idx" */
172ff2d5ea4Sdrh ){
173558814f8Sdan static const struct {
17469188d9aSdan const char *zName;
17569188d9aSdan const char *zCols;
17669188d9aSdan } aTable[] = {
17769188d9aSdan { "sqlite_stat1", "tbl,idx,stat" },
1780106e378Sdan #if defined(SQLITE_ENABLE_STAT4)
179f52bb8d3Sdan { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" },
1809fecc546Sdrh #else
1819fecc546Sdrh { "sqlite_stat4", 0 },
182faacf17cSdrh #endif
183175b8f06Sdrh { "sqlite_stat3", 0 },
184faacf17cSdrh };
18502fa4696Sdan int i;
186ff2d5ea4Sdrh sqlite3 *db = pParse->db;
187ff2d5ea4Sdrh Db *pDb;
188ff2d5ea4Sdrh Vdbe *v = sqlite3GetVdbe(pParse);
189abc38158Sdrh u32 aRoot[ArraySize(aTable)];
1909fecc546Sdrh u8 aCreateTbl[ArraySize(aTable)];
1919d33d9e7Sdrh #ifdef SQLITE_ENABLE_STAT4
1929d33d9e7Sdrh const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
1939d33d9e7Sdrh #else
1949d33d9e7Sdrh const int nToOpen = 1;
1959d33d9e7Sdrh #endif
1969fecc546Sdrh
197cf1be45fSdrh if( v==0 ) return;
1981fee73e7Sdrh assert( sqlite3BtreeHoldsAllMutexes(db) );
1991fee73e7Sdrh assert( sqlite3VdbeDb(v)==db );
200ff2d5ea4Sdrh pDb = &db->aDb[iDb];
20102fa4696Sdan
202faacf17cSdrh /* Create new statistic tables if they do not exist, or clear them
203faacf17cSdrh ** if they do already exist.
204faacf17cSdrh */
20569188d9aSdan for(i=0; i<ArraySize(aTable); i++){
20669188d9aSdan const char *zTab = aTable[i].zName;
20702fa4696Sdan Table *pStat;
2089d33d9e7Sdrh aCreateTbl[i] = 0;
20969c33826Sdrh if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
2109d33d9e7Sdrh if( i<nToOpen ){
2119fecc546Sdrh /* The sqlite_statN table does not exist. Create it. Note that a
21202fa4696Sdan ** side-effect of the CREATE TABLE statement is to leave the rootpage
21302fa4696Sdan ** of the new table in register pParse->regRoot. This is important
21402fa4696Sdan ** because the OpenWrite opcode below will be needing it. */
215ff2d5ea4Sdrh sqlite3NestedParse(pParse,
21669c33826Sdrh "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
217ff2d5ea4Sdrh );
218abc38158Sdrh aRoot[i] = (u32)pParse->regRoot;
219428c218cSdan aCreateTbl[i] = OPFLAG_P2ISREG;
2208ad169abSdan }
221ff2d5ea4Sdrh }else{
22202fa4696Sdan /* The table already exists. If zWhere is not NULL, delete all entries
22302fa4696Sdan ** associated with the table zWhere. If zWhere is NULL, delete the
22402fa4696Sdan ** entire contents of the table. */
22502fa4696Sdan aRoot[i] = pStat->tnum;
22669188d9aSdan sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
22702fa4696Sdan if( zWhere ){
22802fa4696Sdan sqlite3NestedParse(pParse,
2291435a9a1Sdrh "DELETE FROM %Q.%s WHERE %s=%Q",
23069c33826Sdrh pDb->zDbSName, zTab, zWhereType, zWhere
23102fa4696Sdan );
232614efe2bSdan #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
233614efe2bSdan }else if( db->xPreUpdateCallback ){
234614efe2bSdan sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
235614efe2bSdan #endif
23602fa4696Sdan }else{
2378ad169abSdan /* The sqlite_stat[134] table already exists. Delete all rows. */
238abc38158Sdrh sqlite3VdbeAddOp2(v, OP_Clear, (int)aRoot[i], iDb);
23902fa4696Sdan }
24002fa4696Sdan }
241ff2d5ea4Sdrh }
242ff2d5ea4Sdrh
243f00e9025Sdan /* Open the sqlite_stat[134] tables for writing. */
2449d33d9e7Sdrh for(i=0; i<nToOpen; i++){
2451435a9a1Sdrh assert( i<ArraySize(aTable) );
246abc38158Sdrh sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, (int)aRoot[i], iDb, 3);
24702fa4696Sdan sqlite3VdbeChangeP5(v, aCreateTbl[i]);
248ec9e55d3Sdrh VdbeComment((v, aTable[i].zName));
24902fa4696Sdan }
250ff2d5ea4Sdrh }
251ff2d5ea4Sdrh
252ff2d5ea4Sdrh /*
253f52bb8d3Sdan ** Recommended number of samples for sqlite_stat4
254faacf17cSdrh */
255f52bb8d3Sdan #ifndef SQLITE_STAT4_SAMPLES
256f52bb8d3Sdan # define SQLITE_STAT4_SAMPLES 24
257faacf17cSdrh #endif
258faacf17cSdrh
259faacf17cSdrh /*
260f00e9025Sdan ** Three SQL functions - stat_init(), stat_push(), and stat_get() -
261ade3addfSdrh ** share an instance of the following structure to hold their state
262ade3addfSdrh ** information.
263ade3addfSdrh */
264afa1ecacSdrh typedef struct StatAccum StatAccum;
265afa1ecacSdrh typedef struct StatSample StatSample;
266afa1ecacSdrh struct StatSample {
267f52bb8d3Sdan tRowcnt *anEq; /* sqlite_stat4.nEq */
268f52bb8d3Sdan tRowcnt *anDLt; /* sqlite_stat4.nDLt */
269175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
2709fecc546Sdrh tRowcnt *anLt; /* sqlite_stat4.nLt */
271da475b8dSdrh union {
2729fecc546Sdrh i64 iRowid; /* Rowid in main table of the key */
273ebe25af1Sdrh u8 *aRowid; /* Key for WITHOUT ROWID tables */
274da475b8dSdrh } u;
275da475b8dSdrh u32 nRowid; /* Sizeof aRowid[] */
276ade3addfSdrh u8 isPSample; /* True if a periodic sample */
277f00e9025Sdan int iCol; /* If !isPSample, the reason for inclusion */
278ade3addfSdrh u32 iHash; /* Tiebreaker hash */
2799fecc546Sdrh #endif
280f00e9025Sdan };
281afa1ecacSdrh struct StatAccum {
282afa1ecacSdrh sqlite3 *db; /* Database connection, for malloc() */
2839f274636Sdrh tRowcnt nEst; /* Estimated number of rows */
2849f274636Sdrh tRowcnt nRow; /* Number of rows visited so far */
28549a76a8fSdrh int nLimit; /* Analysis row-scan limit */
286ec9e55d3Sdrh int nCol; /* Number of columns in index + pk/rowid */
287ec9e55d3Sdrh int nKeyCol; /* Number of index columns w/o the pk/rowid */
28859a8cb79Sdrh u8 nSkipAhead; /* Number of times of skip-ahead */
289afa1ecacSdrh StatSample current; /* Current row as a StatSample */
290afa1ecacSdrh #ifdef SQLITE_ENABLE_STAT4
291afa1ecacSdrh tRowcnt nPSample; /* How often to do a periodic sample */
292f00e9025Sdan int mxSample; /* Maximum number of samples to accumulate */
293f00e9025Sdan u32 iPrn; /* Pseudo-random number used for sampling */
294afa1ecacSdrh StatSample *aBest; /* Array of nCol best samples */
295f00e9025Sdan int iMin; /* Index in a[] of entry with minimum score */
296f00e9025Sdan int nSample; /* Current number of samples */
297bd1d270eSdan int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
298f00e9025Sdan int iGet; /* Index of current sample accessed by stat_get() */
299afa1ecacSdrh StatSample *a; /* Array of mxSample StatSample objects */
300afa1ecacSdrh #endif
301ade3addfSdrh };
302ade3addfSdrh
303afa1ecacSdrh /* Reclaim memory used by a StatSample
304ebe25af1Sdrh */
305175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
sampleClear(sqlite3 * db,StatSample * p)306afa1ecacSdrh static void sampleClear(sqlite3 *db, StatSample *p){
307da475b8dSdrh assert( db!=0 );
308da475b8dSdrh if( p->nRowid ){
309da475b8dSdrh sqlite3DbFree(db, p->u.aRowid);
310ebe25af1Sdrh p->nRowid = 0;
311ebe25af1Sdrh }
312da475b8dSdrh }
313ebe25af1Sdrh #endif
314ebe25af1Sdrh
315da475b8dSdrh /* Initialize the BLOB value of a ROWID
316ebe25af1Sdrh */
317175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
sampleSetRowid(sqlite3 * db,StatSample * p,int n,const u8 * pData)318afa1ecacSdrh static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){
319da475b8dSdrh assert( db!=0 );
320da475b8dSdrh if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
321575fad65Sdrh p->u.aRowid = sqlite3DbMallocRawNN(db, n);
322da475b8dSdrh if( p->u.aRowid ){
323da475b8dSdrh p->nRowid = n;
324da475b8dSdrh memcpy(p->u.aRowid, pData, n);
325da475b8dSdrh }else{
326da475b8dSdrh p->nRowid = 0;
327ebe25af1Sdrh }
328ebe25af1Sdrh }
329da475b8dSdrh #endif
330da475b8dSdrh
331da475b8dSdrh /* Initialize the INTEGER value of a ROWID.
332da475b8dSdrh */
333175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
sampleSetRowidInt64(sqlite3 * db,StatSample * p,i64 iRowid)334afa1ecacSdrh static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){
335da475b8dSdrh assert( db!=0 );
336da475b8dSdrh if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
337da475b8dSdrh p->nRowid = 0;
338da475b8dSdrh p->u.iRowid = iRowid;
339da475b8dSdrh }
340da475b8dSdrh #endif
341da475b8dSdrh
342da475b8dSdrh
343da475b8dSdrh /*
344da475b8dSdrh ** Copy the contents of object (*pFrom) into (*pTo).
345da475b8dSdrh */
346175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
sampleCopy(StatAccum * p,StatSample * pTo,StatSample * pFrom)347afa1ecacSdrh static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
348da475b8dSdrh pTo->isPSample = pFrom->isPSample;
349da475b8dSdrh pTo->iCol = pFrom->iCol;
350da475b8dSdrh pTo->iHash = pFrom->iHash;
351da475b8dSdrh memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol);
352da475b8dSdrh memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol);
353da475b8dSdrh memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol);
354da475b8dSdrh if( pFrom->nRowid ){
355da475b8dSdrh sampleSetRowid(p->db, pTo, pFrom->nRowid, pFrom->u.aRowid);
356da475b8dSdrh }else{
357da475b8dSdrh sampleSetRowidInt64(p->db, pTo, pFrom->u.iRowid);
358da475b8dSdrh }
359ebe25af1Sdrh }
360ebe25af1Sdrh #endif
361ebe25af1Sdrh
362ebe25af1Sdrh /*
363afa1ecacSdrh ** Reclaim all memory of a StatAccum structure.
364ebe25af1Sdrh */
statAccumDestructor(void * pOld)365afa1ecacSdrh static void statAccumDestructor(void *pOld){
366afa1ecacSdrh StatAccum *p = (StatAccum*)pOld;
367175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
3689d33d9e7Sdrh if( p->mxSample ){
369ebe25af1Sdrh int i;
370ebe25af1Sdrh for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
371ebe25af1Sdrh for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
372da475b8dSdrh sampleClear(p->db, &p->current);
3739d33d9e7Sdrh }
374ebe25af1Sdrh #endif
375ebe25af1Sdrh sqlite3DbFree(p->db, p);
376ebe25af1Sdrh }
377ebe25af1Sdrh
378ade3addfSdrh /*
37949a76a8fSdrh ** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
380ec9e55d3Sdrh ** are:
381553818a0Sdrh ** N: The number of columns in the index including the rowid/pk (note 1)
382553818a0Sdrh ** K: The number of columns in the index excluding the rowid/pk.
3839f274636Sdrh ** C: Estimated number of rows in the index
38449a76a8fSdrh ** L: A limit on the number of rows to scan, or 0 for no-limit
385ec9e55d3Sdrh **
386553818a0Sdrh ** Note 1: In the special case of the covering index that implements a
387553818a0Sdrh ** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
388553818a0Sdrh ** total number of columns in the table.
389ec9e55d3Sdrh **
390553818a0Sdrh ** For indexes on ordinary rowid tables, N==K+1. But for indexes on
391553818a0Sdrh ** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
392553818a0Sdrh ** PRIMARY KEY of the table. The covering index that implements the
393553818a0Sdrh ** original WITHOUT ROWID table as N==K as a special case.
394ade3addfSdrh **
395afa1ecacSdrh ** This routine allocates the StatAccum object in heap memory. The return
396afa1ecacSdrh ** value is a pointer to the StatAccum object. The datatype of the
397afa1ecacSdrh ** return value is BLOB, but it is really just a pointer to the StatAccum
398f8ede57aSdrh ** object.
399ade3addfSdrh */
statInit(sqlite3_context * context,int argc,sqlite3_value ** argv)400f00e9025Sdan static void statInit(
401ade3addfSdrh sqlite3_context *context,
402ade3addfSdrh int argc,
403ade3addfSdrh sqlite3_value **argv
404ade3addfSdrh ){
405afa1ecacSdrh StatAccum *p;
406f52bb8d3Sdan int nCol; /* Number of columns in index being sampled */
407ec9e55d3Sdrh int nKeyCol; /* Number of key columns */
4089fecc546Sdrh int nColUp; /* nCol rounded up for alignment */
409f52bb8d3Sdan int n; /* Bytes of space to allocate */
41059a8cb79Sdrh sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
411175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
412e50478d7Sdrh /* Maximum number of samples. 0 if STAT4 data is not collected */
41359a8cb79Sdrh int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
4149fecc546Sdrh #endif
415ade3addfSdrh
416f52bb8d3Sdan /* Decode the three function arguments */
41768257196Sdrh UNUSED_PARAMETER(argc);
4189fecc546Sdrh nCol = sqlite3_value_int(argv[0]);
419ec9e55d3Sdrh assert( nCol>0 );
4209fecc546Sdrh nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
421ec9e55d3Sdrh nKeyCol = sqlite3_value_int(argv[1]);
422ec9e55d3Sdrh assert( nKeyCol<=nCol );
423ec9e55d3Sdrh assert( nKeyCol>0 );
424f52bb8d3Sdan
425afa1ecacSdrh /* Allocate the space required for the StatAccum object */
426f00e9025Sdan n = sizeof(*p)
427afa1ecacSdrh + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
428e50478d7Sdrh + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
429175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
430e50478d7Sdrh if( mxSample ){
431e50478d7Sdrh n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
432afa1ecacSdrh + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
433e50478d7Sdrh + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
434e50478d7Sdrh }
4359fecc546Sdrh #endif
436ebe25af1Sdrh p = sqlite3DbMallocZero(db, n);
437ade3addfSdrh if( p==0 ){
438ade3addfSdrh sqlite3_result_error_nomem(context);
439ade3addfSdrh return;
440ade3addfSdrh }
441f52bb8d3Sdan
442ebe25af1Sdrh p->db = db;
4439f274636Sdrh p->nEst = sqlite3_value_int64(argv[2]);
4449fecc546Sdrh p->nRow = 0;
44549a76a8fSdrh p->nLimit = sqlite3_value_int64(argv[3]);
446f52bb8d3Sdan p->nCol = nCol;
447ec9e55d3Sdrh p->nKeyCol = nKeyCol;
44859a8cb79Sdrh p->nSkipAhead = 0;
449f00e9025Sdan p->current.anDLt = (tRowcnt*)&p[1];
4509fecc546Sdrh p->current.anEq = &p->current.anDLt[nColUp];
4519fecc546Sdrh
452175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
45331e3744eSdrh p->mxSample = p->nLimit==0 ? mxSample : 0;
4549d33d9e7Sdrh if( mxSample ){
4559fecc546Sdrh u8 *pSpace; /* Allocated space not yet assigned */
4569fecc546Sdrh int i; /* Used to iterate through p->aSample[] */
4579fecc546Sdrh
4589fecc546Sdrh p->iGet = -1;
4599f274636Sdrh p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
4609fecc546Sdrh p->current.anLt = &p->current.anEq[nColUp];
4614081d5daSdrh p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
462f00e9025Sdan
463afa1ecacSdrh /* Set up the StatAccum.a[] and aBest[] arrays */
464afa1ecacSdrh p->a = (struct StatSample*)&p->current.anLt[nColUp];
465f00e9025Sdan p->aBest = &p->a[mxSample];
466f00e9025Sdan pSpace = (u8*)(&p->a[mxSample+nCol]);
467f00e9025Sdan for(i=0; i<(mxSample+nCol); i++){
4689fecc546Sdrh p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
4699fecc546Sdrh p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
4709fecc546Sdrh p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp);
471f52bb8d3Sdan }
472f52bb8d3Sdan assert( (pSpace - (u8*)p)==n );
473f52bb8d3Sdan
474f00e9025Sdan for(i=0; i<nCol; i++){
475f00e9025Sdan p->aBest[i].iCol = i;
476f00e9025Sdan }
4779fecc546Sdrh }
4789fecc546Sdrh #endif
479f00e9025Sdan
480f8ede57aSdrh /* Return a pointer to the allocated object to the caller. Note that
481f8ede57aSdrh ** only the pointer (the 2nd parameter) matters. The size of the object
482f8ede57aSdrh ** (given by the 3rd parameter) is never used and can be any positive
483f8ede57aSdrh ** value. */
484afa1ecacSdrh sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
485ade3addfSdrh }
486f00e9025Sdan static const FuncDef statInitFuncdef = {
48731e3744eSdrh 4, /* nArg */
488d36e1041Sdrh SQLITE_UTF8, /* funcFlags */
489ade3addfSdrh 0, /* pUserData */
490ade3addfSdrh 0, /* pNext */
4912d80151fSdrh statInit, /* xSFunc */
492ade3addfSdrh 0, /* xFinalize */
493980cf25bSdan 0, 0, /* xValue, xInverse */
494f00e9025Sdan "stat_init", /* zName */
49580738d9cSdrh {0}
496ade3addfSdrh };
497ade3addfSdrh
498b13af4c5Sdan #ifdef SQLITE_ENABLE_STAT4
499b13af4c5Sdan /*
500b13af4c5Sdan ** pNew and pOld are both candidate non-periodic samples selected for
501b13af4c5Sdan ** the same column (pNew->iCol==pOld->iCol). Ignoring this column and
502b13af4c5Sdan ** considering only any trailing columns and the sample hash value, this
503b13af4c5Sdan ** function returns true if sample pNew is to be preferred over pOld.
504b13af4c5Sdan ** In other words, if we assume that the cardinalities of the selected
505b13af4c5Sdan ** column for pNew and pOld are equal, is pNew to be preferred over pOld.
506b13af4c5Sdan **
507b13af4c5Sdan ** This function assumes that for each argument sample, the contents of
508b13af4c5Sdan ** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid.
509b13af4c5Sdan */
sampleIsBetterPost(StatAccum * pAccum,StatSample * pNew,StatSample * pOld)510b13af4c5Sdan static int sampleIsBetterPost(
511afa1ecacSdrh StatAccum *pAccum,
512afa1ecacSdrh StatSample *pNew,
513afa1ecacSdrh StatSample *pOld
514b13af4c5Sdan ){
515b13af4c5Sdan int nCol = pAccum->nCol;
516b13af4c5Sdan int i;
517b13af4c5Sdan assert( pNew->iCol==pOld->iCol );
518b13af4c5Sdan for(i=pNew->iCol+1; i<nCol; i++){
519b13af4c5Sdan if( pNew->anEq[i]>pOld->anEq[i] ) return 1;
520b13af4c5Sdan if( pNew->anEq[i]<pOld->anEq[i] ) return 0;
521b13af4c5Sdan }
522b13af4c5Sdan if( pNew->iHash>pOld->iHash ) return 1;
523b13af4c5Sdan return 0;
524b13af4c5Sdan }
525b13af4c5Sdan #endif
526b13af4c5Sdan
527175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
528f00e9025Sdan /*
529f00e9025Sdan ** Return true if pNew is to be preferred over pOld.
530b13af4c5Sdan **
531b13af4c5Sdan ** This function assumes that for each argument sample, the contents of
532b13af4c5Sdan ** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid.
533f00e9025Sdan */
sampleIsBetter(StatAccum * pAccum,StatSample * pNew,StatSample * pOld)534b13af4c5Sdan static int sampleIsBetter(
535afa1ecacSdrh StatAccum *pAccum,
536afa1ecacSdrh StatSample *pNew,
537afa1ecacSdrh StatSample *pOld
538b13af4c5Sdan ){
539f00e9025Sdan tRowcnt nEqNew = pNew->anEq[pNew->iCol];
540f00e9025Sdan tRowcnt nEqOld = pOld->anEq[pOld->iCol];
541f00e9025Sdan
542f00e9025Sdan assert( pOld->isPSample==0 && pNew->isPSample==0 );
543f00e9025Sdan assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) );
544f00e9025Sdan
545b13af4c5Sdan if( (nEqNew>nEqOld) ) return 1;
546b13af4c5Sdan if( nEqNew==nEqOld ){
547b13af4c5Sdan if( pNew->iCol<pOld->iCol ) return 1;
548b13af4c5Sdan return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld));
549f00e9025Sdan }
550f00e9025Sdan return 0;
551f00e9025Sdan }
552ade3addfSdrh
553ade3addfSdrh /*
554f00e9025Sdan ** Copy the contents of sample *pNew into the p->a[] array. If necessary,
555f00e9025Sdan ** remove the least desirable sample from p->a[] to make room.
556f00e9025Sdan */
sampleInsert(StatAccum * p,StatSample * pNew,int nEqZero)557afa1ecacSdrh static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){
558afa1ecacSdrh StatSample *pSample = 0;
559f52bb8d3Sdan int i;
560f52bb8d3Sdan
561f00e9025Sdan assert( IsStat4 || nEqZero==0 );
562f52bb8d3Sdan
563afa1ecacSdrh /* StatAccum.nMaxEqZero is set to the maximum number of leading 0
564afa1ecacSdrh ** values in the anEq[] array of any sample in StatAccum.a[]. In
565bd1d270eSdan ** other words, if nMaxEqZero is n, then it is guaranteed that there
566afa1ecacSdrh ** are no samples with StatSample.anEq[m]==0 for (m>=n). */
567bd1d270eSdan if( nEqZero>p->nMaxEqZero ){
568bd1d270eSdan p->nMaxEqZero = nEqZero;
569bd1d270eSdan }
570f00e9025Sdan if( pNew->isPSample==0 ){
571afa1ecacSdrh StatSample *pUpgrade = 0;
572f00e9025Sdan assert( pNew->anEq[pNew->iCol]>0 );
573ade3addfSdrh
574f00e9025Sdan /* This sample is being added because the prefix that ends in column
575f00e9025Sdan ** iCol occurs many times in the table. However, if we have already
576f00e9025Sdan ** added a sample that shares this prefix, there is no need to add
5771f616ad8Sdan ** this one. Instead, upgrade the priority of the highest priority
5781f616ad8Sdan ** existing sample that shares this prefix. */
579f00e9025Sdan for(i=p->nSample-1; i>=0; i--){
580afa1ecacSdrh StatSample *pOld = &p->a[i];
581f00e9025Sdan if( pOld->anEq[pNew->iCol]==0 ){
5821f616ad8Sdan if( pOld->isPSample ) return;
583b13af4c5Sdan assert( pOld->iCol>pNew->iCol );
584b13af4c5Sdan assert( sampleIsBetter(p, pNew, pOld) );
585b13af4c5Sdan if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){
5861f616ad8Sdan pUpgrade = pOld;
5878ad169abSdan }
5881f616ad8Sdan }
5891f616ad8Sdan }
5901f616ad8Sdan if( pUpgrade ){
5911f616ad8Sdan pUpgrade->iCol = pNew->iCol;
5921f616ad8Sdan pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol];
593f00e9025Sdan goto find_new_min;
5941f28eaddSdan }
5951f28eaddSdan }
596f52bb8d3Sdan
597f00e9025Sdan /* If necessary, remove sample iMin to make room for the new sample. */
598f00e9025Sdan if( p->nSample>=p->mxSample ){
599afa1ecacSdrh StatSample *pMin = &p->a[p->iMin];
600c55521a6Sdan tRowcnt *anEq = pMin->anEq;
601c55521a6Sdan tRowcnt *anLt = pMin->anLt;
602f00e9025Sdan tRowcnt *anDLt = pMin->anDLt;
603da475b8dSdrh sampleClear(p->db, pMin);
604f00e9025Sdan memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1));
605f404c86aSdrh pSample = &p->a[p->nSample-1];
606d269461cSdrh pSample->nRowid = 0;
607c55521a6Sdan pSample->anEq = anEq;
608c55521a6Sdan pSample->anDLt = anDLt;
609c55521a6Sdan pSample->anLt = anLt;
610f00e9025Sdan p->nSample = p->mxSample-1;
611f52bb8d3Sdan }
612ade3addfSdrh
613b49d1047Sdan /* The "rows less-than" for the rowid column must be greater than that
614b49d1047Sdan ** for the last sample in the p->a[] array. Otherwise, the samples would
615b49d1047Sdan ** be out of order. */
616b49d1047Sdan assert( p->nSample==0
617b49d1047Sdan || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] );
618b49d1047Sdan
619b49d1047Sdan /* Insert the new sample */
620b49d1047Sdan pSample = &p->a[p->nSample];
621b49d1047Sdan sampleCopy(p, pSample, pNew);
622b49d1047Sdan p->nSample++;
623b49d1047Sdan
624f00e9025Sdan /* Zero the first nEqZero entries in the anEq[] array. */
625f00e9025Sdan memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero);
626f00e9025Sdan
627f00e9025Sdan find_new_min:
628f00e9025Sdan if( p->nSample>=p->mxSample ){
629f00e9025Sdan int iMin = -1;
630f52bb8d3Sdan for(i=0; i<p->mxSample; i++){
631f52bb8d3Sdan if( p->a[i].isPSample ) continue;
632b13af4c5Sdan if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){
633ade3addfSdrh iMin = i;
634ade3addfSdrh }
635ade3addfSdrh }
636f52bb8d3Sdan assert( iMin>=0 );
637ade3addfSdrh p->iMin = iMin;
638ade3addfSdrh }
639ade3addfSdrh }
640175b8f06Sdrh #endif /* SQLITE_ENABLE_STAT4 */
641f00e9025Sdan
642afa1ecacSdrh #ifdef SQLITE_ENABLE_STAT4
643f00e9025Sdan /*
644f00e9025Sdan ** Field iChng of the index being scanned has changed. So at this point
645f00e9025Sdan ** p->current contains a sample that reflects the previous row of the
646f00e9025Sdan ** index. The value of anEq[iChng] and subsequent anEq[] elements are
647f00e9025Sdan ** correct at this point.
648f00e9025Sdan */
samplePushPrevious(StatAccum * p,int iChng)649afa1ecacSdrh static void samplePushPrevious(StatAccum *p, int iChng){
650f00e9025Sdan int i;
651f00e9025Sdan
652f00e9025Sdan /* Check if any samples from the aBest[] array should be pushed
653f00e9025Sdan ** into IndexSample.a[] at this point. */
654f00e9025Sdan for(i=(p->nCol-2); i>=iChng; i--){
655afa1ecacSdrh StatSample *pBest = &p->aBest[i];
656b13af4c5Sdan pBest->anEq[i] = p->current.anEq[i];
657b13af4c5Sdan if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
658f00e9025Sdan sampleInsert(p, pBest, i);
659f00e9025Sdan }
660f00e9025Sdan }
661f00e9025Sdan
662bd1d270eSdan /* Check that no sample contains an anEq[] entry with an index of
663bd1d270eSdan ** p->nMaxEqZero or greater set to zero. */
664bd1d270eSdan for(i=p->nSample-1; i>=0; i--){
665bd1d270eSdan int j;
666bd1d270eSdan for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
667bd1d270eSdan }
668bd1d270eSdan
669f00e9025Sdan /* Update the anEq[] fields of any samples already collected. */
670bd1d270eSdan if( iChng<p->nMaxEqZero ){
671f00e9025Sdan for(i=p->nSample-1; i>=0; i--){
672f00e9025Sdan int j;
673f00e9025Sdan for(j=iChng; j<p->nCol; j++){
674f00e9025Sdan if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
675f00e9025Sdan }
676f00e9025Sdan }
677bd1d270eSdan p->nMaxEqZero = iChng;
678bd1d270eSdan }
679f00e9025Sdan }
680afa1ecacSdrh #endif /* SQLITE_ENABLE_STAT4 */
681f00e9025Sdan
682f00e9025Sdan /*
683ebe25af1Sdrh ** Implementation of the stat_push SQL function: stat_push(P,C,R)
6849fecc546Sdrh ** Arguments:
685f00e9025Sdan **
686afa1ecacSdrh ** P Pointer to the StatAccum object created by stat_init()
6879fecc546Sdrh ** C Index of left-most column to differ from previous row
688ebe25af1Sdrh ** R Rowid for the current row. Might be a key record for
689ebe25af1Sdrh ** WITHOUT ROWID tables.
690f00e9025Sdan **
69159a8cb79Sdrh ** The purpose of this routine is to collect statistical data and/or
69259a8cb79Sdrh ** samples from the index being analyzed into the StatAccum object.
69359a8cb79Sdrh ** The stat_get() SQL function will be used afterwards to
69459a8cb79Sdrh ** retrieve the information gathered.
69559a8cb79Sdrh **
69659a8cb79Sdrh ** This SQL function usually returns NULL, but might return an integer
69759a8cb79Sdrh ** if it wants the byte-code to do special processing.
6989fecc546Sdrh **
699175b8f06Sdrh ** The R parameter is only used for STAT4
700f00e9025Sdan */
statPush(sqlite3_context * context,int argc,sqlite3_value ** argv)701f00e9025Sdan static void statPush(
702f00e9025Sdan sqlite3_context *context,
703f00e9025Sdan int argc,
704f00e9025Sdan sqlite3_value **argv
705f00e9025Sdan ){
706f00e9025Sdan int i;
707f00e9025Sdan
708f00e9025Sdan /* The three function arguments */
709afa1ecacSdrh StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
7109fecc546Sdrh int iChng = sqlite3_value_int(argv[1]);
711f00e9025Sdan
7124f991890Sdrh UNUSED_PARAMETER( argc );
7134f991890Sdrh UNUSED_PARAMETER( context );
714ec9e55d3Sdrh assert( p->nCol>0 );
715f00e9025Sdan assert( iChng<p->nCol );
716f00e9025Sdan
7179fecc546Sdrh if( p->nRow==0 ){
718b49d1047Sdan /* This is the first call to this function. Do initialization. */
7199fecc546Sdrh for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
7209fecc546Sdrh }else{
7219fecc546Sdrh /* Second and subsequent calls get processed here */
722afa1ecacSdrh #ifdef SQLITE_ENABLE_STAT4
7239d33d9e7Sdrh if( p->mxSample ) samplePushPrevious(p, iChng);
724afa1ecacSdrh #endif
725f00e9025Sdan
726f00e9025Sdan /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
727f00e9025Sdan ** to the current row of the index. */
728f00e9025Sdan for(i=0; i<iChng; i++){
729f00e9025Sdan p->current.anEq[i]++;
730f00e9025Sdan }
731f00e9025Sdan for(i=iChng; i<p->nCol; i++){
732f00e9025Sdan p->current.anDLt[i]++;
733175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
7349d33d9e7Sdrh if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
7359fecc546Sdrh #endif
736f00e9025Sdan p->current.anEq[i] = 1;
737f00e9025Sdan }
738f00e9025Sdan }
73959a8cb79Sdrh
7409fecc546Sdrh p->nRow++;
741175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
7429d33d9e7Sdrh if( p->mxSample ){
7439d33d9e7Sdrh tRowcnt nLt;
744ebe25af1Sdrh if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
745da475b8dSdrh sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
746ebe25af1Sdrh }else{
747da475b8dSdrh sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
748da475b8dSdrh sqlite3_value_blob(argv[2]));
749ebe25af1Sdrh }
750f00e9025Sdan p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
751f00e9025Sdan
7529d33d9e7Sdrh nLt = p->current.anLt[p->nCol-1];
753f00e9025Sdan /* Check if this is to be a periodic sample. If so, add it. */
754f00e9025Sdan if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
755f00e9025Sdan p->current.isPSample = 1;
756f00e9025Sdan p->current.iCol = 0;
757f00e9025Sdan sampleInsert(p, &p->current, p->nCol-1);
758f00e9025Sdan p->current.isPSample = 0;
759f00e9025Sdan }
760f00e9025Sdan
761f00e9025Sdan /* Update the aBest[] array. */
762f00e9025Sdan for(i=0; i<(p->nCol-1); i++){
763f00e9025Sdan p->current.iCol = i;
764b13af4c5Sdan if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){
765f00e9025Sdan sampleCopy(p, &p->aBest[i], &p->current);
766f00e9025Sdan }
767f00e9025Sdan }
76859a8cb79Sdrh }else
76959a8cb79Sdrh #endif
7703d42fb78Sdrh if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
77159a8cb79Sdrh p->nSkipAhead++;
77259a8cb79Sdrh sqlite3_result_int(context, p->current.anDLt[0]>0);
773f00e9025Sdan }
774f00e9025Sdan }
77559a8cb79Sdrh
776f00e9025Sdan static const FuncDef statPushFuncdef = {
777175b8f06Sdrh 2+IsStat4, /* nArg */
778d36e1041Sdrh SQLITE_UTF8, /* funcFlags */
779ade3addfSdrh 0, /* pUserData */
780ade3addfSdrh 0, /* pNext */
7812d80151fSdrh statPush, /* xSFunc */
782ade3addfSdrh 0, /* xFinalize */
783980cf25bSdan 0, 0, /* xValue, xInverse */
784f00e9025Sdan "stat_push", /* zName */
78580738d9cSdrh {0}
786ade3addfSdrh };
787ade3addfSdrh
788f00e9025Sdan #define STAT_GET_STAT1 0 /* "stat" column of stat1 table */
789f00e9025Sdan #define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */
790f00e9025Sdan #define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */
791f00e9025Sdan #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */
792f00e9025Sdan #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */
793f00e9025Sdan
794ade3addfSdrh /*
79592707acfSdrh ** Implementation of the stat_get(P,J) SQL function. This routine is
796553818a0Sdrh ** used to query statistical information that has been gathered into
797afa1ecacSdrh ** the StatAccum object by prior calls to stat_push(). The P parameter
798afa1ecacSdrh ** has type BLOB but it is really just a pointer to the StatAccum object.
799553818a0Sdrh ** The content to returned is determined by the parameter J
80092707acfSdrh ** which is one of the STAT_GET_xxxx values defined above.
801ade3addfSdrh **
80235497fccSdrh ** The stat_get(P,J) function is not available to generic SQL. It is
80335497fccSdrh ** inserted as part of a manually constructed bytecode program. (See
80435497fccSdrh ** the callStatGet() routine below.) It is guaranteed that the P
805afa1ecacSdrh ** parameter will always be a pointer to a StatAccum object, never a
80635497fccSdrh ** NULL.
80735497fccSdrh **
808175b8f06Sdrh ** If STAT4 is not enabled, then J is always
80992707acfSdrh ** STAT_GET_STAT1 and is hence omitted and this routine becomes
81092707acfSdrh ** a one-parameter function, stat_get(P), that always returns the
81192707acfSdrh ** stat1 table entry information.
812ade3addfSdrh */
statGet(sqlite3_context * context,int argc,sqlite3_value ** argv)813f00e9025Sdan static void statGet(
814ade3addfSdrh sqlite3_context *context,
815ade3addfSdrh int argc,
816ade3addfSdrh sqlite3_value **argv
817ade3addfSdrh ){
818afa1ecacSdrh StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
819175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
820175b8f06Sdrh /* STAT4 has a parameter on this routine. */
821f00e9025Sdan int eCall = sqlite3_value_int(argv[1]);
82292707acfSdrh assert( argc==2 );
823f00e9025Sdan assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ
824f00e9025Sdan || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
825f00e9025Sdan || eCall==STAT_GET_NDLT
826f00e9025Sdan );
8279d33d9e7Sdrh assert( eCall==STAT_GET_STAT1 || p->mxSample );
82892707acfSdrh if( eCall==STAT_GET_STAT1 )
82992707acfSdrh #else
83092707acfSdrh assert( argc==1 );
83192707acfSdrh #endif
83292707acfSdrh {
833f00e9025Sdan /* Return the value to store in the "stat" column of the sqlite_stat1
834f00e9025Sdan ** table for this index.
835f00e9025Sdan **
836f00e9025Sdan ** The value is a string composed of a list of integers describing
837f00e9025Sdan ** the index. The first integer in the list is the total number of
838f00e9025Sdan ** entries in the index. There is one additional integer in the list
839f00e9025Sdan ** for each indexed column. This additional integer is an estimate of
840afa1ecacSdrh ** the number of rows matched by a equality query on the index using
841f00e9025Sdan ** a key with the corresponding number of fields. In other words,
842f00e9025Sdan ** if the index is on columns (a,b) and the sqlite_stat1 value is
843f00e9025Sdan ** "100 10 2", then SQLite estimates that:
844f00e9025Sdan **
845f00e9025Sdan ** * the index contains 100 rows,
846f00e9025Sdan ** * "WHERE a=?" matches 10 rows, and
847f00e9025Sdan ** * "WHERE a=? AND b=?" matches 2 rows.
848f00e9025Sdan **
849f00e9025Sdan ** If D is the count of distinct values and K is the total number of
85060995928Sdrh ** rows, then each estimate is usually computed as:
851f00e9025Sdan **
852f00e9025Sdan ** I = (K+D-1)/D
85360995928Sdrh **
85460995928Sdrh ** In other words, I is K/D rounded up to the next whole integer.
85560995928Sdrh ** However, if I is between 1.0 and 1.1 (in other words if I is
85660995928Sdrh ** close to 1.0 but just a little larger) then do not round up but
85760995928Sdrh ** instead keep the I value at 1.0.
858f00e9025Sdan */
8595bf4715eSdrh sqlite3_str sStat; /* Text of the constructed "stat" line */
8605bf4715eSdrh int i; /* Loop counter */
861f52bb8d3Sdan
8625bf4715eSdrh sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100);
8635bf4715eSdrh sqlite3_str_appendf(&sStat, "%llu",
86459a8cb79Sdrh p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
865ec9e55d3Sdrh for(i=0; i<p->nKeyCol; i++){
86626586e77Sdrh u64 nDistinct = p->current.anDLt[i] + 1;
86726586e77Sdrh u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
86860995928Sdrh if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1;
8695bf4715eSdrh sqlite3_str_appendf(&sStat, " %llu", iVal);
870f00e9025Sdan assert( p->current.anEq[i] );
871f00e9025Sdan }
8725bf4715eSdrh sqlite3ResultStrAccum(context, &sStat);
87392707acfSdrh }
874175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
87592707acfSdrh else if( eCall==STAT_GET_ROWID ){
876f00e9025Sdan if( p->iGet<0 ){
877f00e9025Sdan samplePushPrevious(p, 0);
878f00e9025Sdan p->iGet = 0;
879f00e9025Sdan }
880f00e9025Sdan if( p->iGet<p->nSample ){
881afa1ecacSdrh StatSample *pS = p->a + p->iGet;
882ebe25af1Sdrh if( pS->nRowid==0 ){
883da475b8dSdrh sqlite3_result_int64(context, pS->u.iRowid);
884ebe25af1Sdrh }else{
885da475b8dSdrh sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
886da475b8dSdrh SQLITE_TRANSIENT);
887ebe25af1Sdrh }
888f00e9025Sdan }
889f00e9025Sdan }else{
890f00e9025Sdan tRowcnt *aCnt = 0;
8915bf4715eSdrh sqlite3_str sStat;
8925bf4715eSdrh int i;
893f00e9025Sdan
894f00e9025Sdan assert( p->iGet<p->nSample );
895f00e9025Sdan switch( eCall ){
896f00e9025Sdan case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break;
897f00e9025Sdan case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break;
898f00e9025Sdan default: {
899f00e9025Sdan aCnt = p->a[p->iGet].anDLt;
900f00e9025Sdan p->iGet++;
901f00e9025Sdan break;
902f00e9025Sdan }
903f52bb8d3Sdan }
9045bf4715eSdrh sqlite3StrAccumInit(&sStat, 0, 0, 0, p->nCol*100);
905f52bb8d3Sdan for(i=0; i<p->nCol; i++){
9065bf4715eSdrh sqlite3_str_appendf(&sStat, "%llu ", (u64)aCnt[i]);
907f52bb8d3Sdan }
9085bf4715eSdrh if( sStat.nChar ) sStat.nChar--;
9095bf4715eSdrh sqlite3ResultStrAccum(context, &sStat);
910f52bb8d3Sdan }
911175b8f06Sdrh #endif /* SQLITE_ENABLE_STAT4 */
9124f991890Sdrh #ifndef SQLITE_DEBUG
9134f991890Sdrh UNUSED_PARAMETER( argc );
9144f991890Sdrh #endif
9158ad169abSdan }
916f00e9025Sdan static const FuncDef statGetFuncdef = {
917175b8f06Sdrh 1+IsStat4, /* nArg */
918d36e1041Sdrh SQLITE_UTF8, /* funcFlags */
919ade3addfSdrh 0, /* pUserData */
920ade3addfSdrh 0, /* pNext */
9212d80151fSdrh statGet, /* xSFunc */
922ade3addfSdrh 0, /* xFinalize */
923980cf25bSdan 0, 0, /* xValue, xInverse */
924f00e9025Sdan "stat_get", /* zName */
92580738d9cSdrh {0}
926ade3addfSdrh };
927ade3addfSdrh
callStatGet(Parse * pParse,int regStat,int iParam,int regOut)9289f274636Sdrh static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
929175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
9309f274636Sdrh sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
9314f991890Sdrh #elif SQLITE_DEBUG
93292707acfSdrh assert( iParam==STAT_GET_STAT1 );
9334f991890Sdrh #else
9344f991890Sdrh UNUSED_PARAMETER( iParam );
93592707acfSdrh #endif
9369f274636Sdrh assert( regOut!=regStat && regOut!=regStat+1 );
9379f274636Sdrh sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
938920cf596Sdrh &statGetFuncdef, 0);
939f00e9025Sdan }
940ade3addfSdrh
941e557b015Sdrh #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
942e557b015Sdrh /* Add a comment to the most recent VDBE opcode that is the name
943e557b015Sdrh ** of the k-th column of the pIdx index.
944e557b015Sdrh */
analyzeVdbeCommentIndexWithColumnName(Vdbe * v,Index * pIdx,int k)945e557b015Sdrh static void analyzeVdbeCommentIndexWithColumnName(
946e557b015Sdrh Vdbe *v, /* Prepared statement under construction */
947e557b015Sdrh Index *pIdx, /* Index whose column is being loaded */
948e557b015Sdrh int k /* Which column index */
949e557b015Sdrh ){
950e557b015Sdrh int i; /* Index of column in the table */
951e557b015Sdrh assert( k>=0 && k<pIdx->nColumn );
952e557b015Sdrh i = pIdx->aiColumn[k];
953e557b015Sdrh if( NEVER(i==XN_ROWID) ){
954e557b015Sdrh VdbeComment((v,"%s.rowid",pIdx->zName));
955e557b015Sdrh }else if( i==XN_EXPR ){
956*4bc1cc18Sdrh assert( pIdx->bHasExpr );
957e557b015Sdrh VdbeComment((v,"%s.expr(%d)",pIdx->zName, k));
958e557b015Sdrh }else{
959cf9d36d1Sdrh VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName));
960e557b015Sdrh }
961e557b015Sdrh }
962e557b015Sdrh #else
963e557b015Sdrh # define analyzeVdbeCommentIndexWithColumnName(a,b,c)
964e557b015Sdrh #endif /* SQLITE_DEBUG */
965e557b015Sdrh
966ade3addfSdrh /*
967ff2d5ea4Sdrh ** Generate code to do an analysis of all indices associated with
968ff2d5ea4Sdrh ** a single table.
969ff2d5ea4Sdrh */
analyzeOneTable(Parse * pParse,Table * pTab,Index * pOnlyIdx,int iStatCur,int iMem,int iTab)970ff2d5ea4Sdrh static void analyzeOneTable(
971ff2d5ea4Sdrh Parse *pParse, /* Parser context */
972ff2d5ea4Sdrh Table *pTab, /* Table whose indices are to be analyzed */
973a071bc5dSdrh Index *pOnlyIdx, /* If not NULL, only analyze this one index */
974dfe88eceSdrh int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */
975c612970cSdan int iMem, /* Available memory locations begin here */
9764a54bb57Sdrh int iTab /* Next available cursor */
977ff2d5ea4Sdrh ){
9780f9a34eaSdan sqlite3 *db = pParse->db; /* Database handle */
979ff2d5ea4Sdrh Index *pIdx; /* An index to being analyzed */
98069188d9aSdan int iIdxCur; /* Cursor open on index being analyzed */
981c612970cSdan int iTabCur; /* Table cursor */
982ff2d5ea4Sdrh Vdbe *v; /* The virtual machine being built up */
983ff2d5ea4Sdrh int i; /* Loop counter */
984f6cf1ffbSdrh int jZeroRows = -1; /* Jump from here if number of rows is zero */
985da184236Sdanielk1977 int iDb; /* Index of database containing pTab */
986721dfcf5Sdrh u8 needTableCnt = 1; /* True to count the table */
987f00e9025Sdan int regNewRowid = iMem++; /* Rowid for the inserted record */
9889f274636Sdrh int regStat = iMem++; /* Register to hold StatAccum object */
989f00e9025Sdan int regChng = iMem++; /* Index of changed index field */
9909fecc546Sdrh int regRowid = iMem++; /* Rowid argument passed to stat_push() */
991f00e9025Sdan int regTemp = iMem++; /* Temporary use register */
99249a76a8fSdrh int regTemp2 = iMem++; /* Second temporary use register */
993e275dc3fSdan int regTabname = iMem++; /* Register containing table name */
994e275dc3fSdan int regIdxname = iMem++; /* Register containing index name */
995f00e9025Sdan int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
996f00e9025Sdan int regPrev = iMem; /* MUST BE LAST (see below) */
997614efe2bSdan #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
998614efe2bSdan Table *pStat1 = 0;
999614efe2bSdan #endif
100068c4dbbdSdan
1001f0459fc4Sdrh pParse->nMem = MAX(pParse->nMem, iMem);
1002ff2d5ea4Sdrh v = sqlite3GetVdbe(pParse);
100315564055Sdrh if( v==0 || NEVER(pTab==0) ){
100415564055Sdrh return;
100515564055Sdrh }
10069966621dSdrh if( !IsOrdinaryTable(pTab) ){
1007f39d29c0Sdrh /* Do not gather statistics on views or virtual tables */
100815564055Sdrh return;
100915564055Sdrh }
1010cedfecf9Sdrh if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){
101115564055Sdrh /* Do not gather statistics on system tables */
1012ff2d5ea4Sdrh return;
1013ff2d5ea4Sdrh }
10140f9a34eaSdan assert( sqlite3BtreeHoldsAllMutexes(db) );
10150f9a34eaSdan iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
1016da184236Sdanielk1977 assert( iDb>=0 );
10172120608eSdrh assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
1018e6e04969Sdrh #ifndef SQLITE_OMIT_AUTHORIZATION
1019e6e04969Sdrh if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
102069c33826Sdrh db->aDb[iDb].zDbSName ) ){
1021e6e04969Sdrh return;
1022e6e04969Sdrh }
1023e6e04969Sdrh #endif
1024e6e04969Sdrh
1025614efe2bSdan #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
1026614efe2bSdan if( db->xPreUpdateCallback ){
1027614efe2bSdan pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
1028614efe2bSdan if( pStat1==0 ) return;
1029614efe2bSdan pStat1->zName = (char*)&pStat1[1];
1030614efe2bSdan memcpy(pStat1->zName, "sqlite_stat1", 13);
1031614efe2bSdan pStat1->nCol = 3;
1032614efe2bSdan pStat1->iPKey = -1;
1033c45924ebSdrh sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC);
1034614efe2bSdan }
1035614efe2bSdan #endif
1036614efe2bSdan
1037e043201dSdan /* Establish a read-lock on the table at the shared-cache level.
1038f00e9025Sdan ** Open a read-only cursor on the table. Also allocate a cursor number
1039f00e9025Sdan ** to use for scanning indexes (iIdxCur). No index cursor is opened at
1040f00e9025Sdan ** this time though. */
1041c00da105Sdanielk1977 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
1042c612970cSdan iTabCur = iTab++;
1043f00e9025Sdan iIdxCur = iTab++;
1044c612970cSdan pParse->nTab = MAX(pParse->nTab, iTab);
1045e043201dSdan sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
1046076e85f5Sdrh sqlite3VdbeLoadString(v, regTabname, pTab->zName);
1047e043201dSdan
1048ff2d5ea4Sdrh for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
1049553818a0Sdrh int nCol; /* Number of columns in pIdx. "N" */
1050f00e9025Sdan int addrRewind; /* Address of "OP_Rewind iIdxCur" */
1051f00e9025Sdan int addrNextRow; /* Address of "next_row:" */
1052ce95d119Sdrh const char *zIdxName; /* Name of the index */
1053553818a0Sdrh int nColTest; /* Number of columns to test for changes */
1054f52bb8d3Sdan
1055a071bc5dSdrh if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
1056721dfcf5Sdrh if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
1057ec9e55d3Sdrh if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){
1058bbbdc83bSdrh nCol = pIdx->nKeyCol;
1059ec9e55d3Sdrh zIdxName = pTab->zName;
1060553818a0Sdrh nColTest = nCol - 1;
1061ec9e55d3Sdrh }else{
1062ec9e55d3Sdrh nCol = pIdx->nColumn;
1063ec9e55d3Sdrh zIdxName = pIdx->zName;
10646861b8a1Sdrh nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1;
1065ec9e55d3Sdrh }
1066e275dc3fSdan
106715564055Sdrh /* Populate the register containing the index name. */
1068076e85f5Sdrh sqlite3VdbeLoadString(v, regIdxname, zIdxName);
1069ec9e55d3Sdrh VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
107069188d9aSdan
1071e043201dSdan /*
1072f00e9025Sdan ** Pseudo-code for loop that calls stat_push():
1073e043201dSdan **
1074f00e9025Sdan ** Rewind csr
1075f00e9025Sdan ** if eof(csr) goto end_of_scan;
1076f00e9025Sdan ** regChng = 0
1077f00e9025Sdan ** goto chng_addr_0;
1078e043201dSdan **
1079dd6e1f19Sdan ** next_row:
1080f00e9025Sdan ** regChng = 0
1081f00e9025Sdan ** if( idx(0) != regPrev(0) ) goto chng_addr_0
1082f00e9025Sdan ** regChng = 1
1083f00e9025Sdan ** if( idx(1) != regPrev(1) ) goto chng_addr_1
1084f00e9025Sdan ** ...
1085f00e9025Sdan ** regChng = N
1086f00e9025Sdan ** goto chng_addr_N
1087e043201dSdan **
1088f00e9025Sdan ** chng_addr_0:
1089f00e9025Sdan ** regPrev(0) = idx(0)
1090f00e9025Sdan ** chng_addr_1:
1091f00e9025Sdan ** regPrev(1) = idx(1)
1092f00e9025Sdan ** ...
1093e043201dSdan **
10949d793325Sdrh ** endDistinctTest:
1095f00e9025Sdan ** regRowid = idx(rowid)
10969fecc546Sdrh ** stat_push(P, regChng, regRowid)
1097f00e9025Sdan ** Next csr
1098f00e9025Sdan ** if !eof(csr) goto next_row;
1099e043201dSdan **
1100f00e9025Sdan ** end_of_scan:
1101e043201dSdan */
1102f00e9025Sdan
1103f00e9025Sdan /* Make sure there are enough memory cells allocated to accommodate
1104f00e9025Sdan ** the regPrev array and a trailing rowid (the rowid slot is required
1105f00e9025Sdan ** when building a record to insert into the sample column of
1106f00e9025Sdan ** the sqlite_stat4 table. */
1107553818a0Sdrh pParse->nMem = MAX(pParse->nMem, regPrev+nColTest);
110802fa4696Sdan
1109f00e9025Sdan /* Open a read-only cursor on the index being analyzed. */
1110e043201dSdan assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
1111f00e9025Sdan sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb);
11122ec2fb22Sdrh sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
1113e043201dSdan VdbeComment((v, "%s", pIdx->zName));
1114e043201dSdan
1115f00e9025Sdan /* Invoke the stat_init() function. The arguments are:
1116f52bb8d3Sdan **
1117553818a0Sdrh ** (1) the number of columns in the index including the rowid
1118553818a0Sdrh ** (or for a WITHOUT ROWID table, the number of PK columns),
1119553818a0Sdrh ** (2) the number of columns in the key without the rowid/pk
11209f274636Sdrh ** (3) estimated number of rows in the index,
1121f52bb8d3Sdan */
11229f274636Sdrh sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
11239f274636Sdrh assert( regRowid==regStat+2 );
11249f274636Sdrh sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
1125175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
11269d33d9e7Sdrh if( OptimizationEnabled(db, SQLITE_Stat4) ){
11279f274636Sdrh sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
11289f274636Sdrh addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
11299f274636Sdrh VdbeCoverage(v);
11309f274636Sdrh }else
11319fecc546Sdrh #endif
11329f274636Sdrh {
11339f274636Sdrh addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
11349f274636Sdrh VdbeCoverage(v);
11359f274636Sdrh sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
11369f274636Sdrh }
113749a76a8fSdrh assert( regTemp2==regStat+4 );
113849a76a8fSdrh sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
113949a76a8fSdrh sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
1140920cf596Sdrh &statInitFuncdef, 0);
1141f52bb8d3Sdan
1142f00e9025Sdan /* Implementation of the following:
1143e043201dSdan **
1144f00e9025Sdan ** Rewind csr
1145f00e9025Sdan ** if eof(csr) goto end_of_scan;
1146f00e9025Sdan ** regChng = 0
1147f00e9025Sdan ** goto next_push_0;
1148f00e9025Sdan **
1149e043201dSdan */
1150f00e9025Sdan sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
1151553818a0Sdrh addrNextRow = sqlite3VdbeCurrentAddr(v);
1152e043201dSdan
1153553818a0Sdrh if( nColTest>0 ){
1154ec4ccdbcSdrh int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
1155b12879fdSdrh int *aGotoChng; /* Array of jump instruction addresses */
1156575fad65Sdrh aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
1157b12879fdSdrh if( aGotoChng==0 ) continue;
1158e043201dSdan
1159f00e9025Sdan /*
1160dd6e1f19Sdan ** next_row:
1161f00e9025Sdan ** regChng = 0
1162f00e9025Sdan ** if( idx(0) != regPrev(0) ) goto chng_addr_0
1163f00e9025Sdan ** regChng = 1
1164f00e9025Sdan ** if( idx(1) != regPrev(1) ) goto chng_addr_1
1165f00e9025Sdan ** ...
1166f00e9025Sdan ** regChng = N
11679d793325Sdrh ** goto endDistinctTest
1168dd6e1f19Sdan */
1169553818a0Sdrh sqlite3VdbeAddOp0(v, OP_Goto);
1170f00e9025Sdan addrNextRow = sqlite3VdbeCurrentAddr(v);
11715f1d1d9cSdrh if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){
11729d793325Sdrh /* For a single-column UNIQUE index, once we have found a non-NULL
11739d793325Sdrh ** row, we know that all the rest will be distinct, so skip
11749d793325Sdrh ** subsequent distinctness tests. */
11759d793325Sdrh sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest);
11769d793325Sdrh VdbeCoverage(v);
11779d793325Sdrh }
1178553818a0Sdrh for(i=0; i<nColTest; i++){
1179e043201dSdan char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
1180f00e9025Sdan sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
1181f00e9025Sdan sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
1182e557b015Sdrh analyzeVdbeCommentIndexWithColumnName(v,pIdx,i);
1183f00e9025Sdan aGotoChng[i] =
1184f00e9025Sdan sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
1185e043201dSdan sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
1186688852abSdrh VdbeCoverage(v);
1187ff2d5ea4Sdrh }
1188553818a0Sdrh sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng);
1189076e85f5Sdrh sqlite3VdbeGoto(v, endDistinctTest);
1190553818a0Sdrh
119102fa4696Sdan
1192f00e9025Sdan /*
1193f00e9025Sdan ** chng_addr_0:
1194f00e9025Sdan ** regPrev(0) = idx(0)
1195f00e9025Sdan ** chng_addr_1:
1196f00e9025Sdan ** regPrev(1) = idx(1)
1197f00e9025Sdan ** ...
1198f00e9025Sdan */
1199553818a0Sdrh sqlite3VdbeJumpHere(v, addrNextRow-1);
1200553818a0Sdrh for(i=0; i<nColTest; i++){
1201f00e9025Sdan sqlite3VdbeJumpHere(v, aGotoChng[i]);
1202f00e9025Sdan sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
1203e557b015Sdrh analyzeVdbeCommentIndexWithColumnName(v,pIdx,i);
1204f52bb8d3Sdan }
12059d793325Sdrh sqlite3VdbeResolveLabel(v, endDistinctTest);
1206b12879fdSdrh sqlite3DbFree(db, aGotoChng);
1207553818a0Sdrh }
1208f00e9025Sdan
1209f00e9025Sdan /*
1210f00e9025Sdan ** chng_addr_N:
1211175b8f06Sdrh ** regRowid = idx(rowid) // STAT4 only
1212175b8f06Sdrh ** stat_push(P, regChng, regRowid) // 3rd parameter STAT4 only
1213f00e9025Sdan ** Next csr
1214f00e9025Sdan ** if !eof(csr) goto next_row;
1215f00e9025Sdan */
1216175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
12179d33d9e7Sdrh if( OptimizationEnabled(db, SQLITE_Stat4) ){
12189f274636Sdrh assert( regRowid==(regStat+2) );
1219ebe25af1Sdrh if( HasRowid(pTab) ){
1220ebe25af1Sdrh sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
1221ebe25af1Sdrh }else{
1222ebe25af1Sdrh Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
1223ebe25af1Sdrh int j, k, regKey;
1224ebe25af1Sdrh regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
1225ebe25af1Sdrh for(j=0; j<pPk->nKeyCol; j++){
1226b9bcf7caSdrh k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
122749297c86Sdrh assert( k>=0 && k<pIdx->nColumn );
1228ebe25af1Sdrh sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
1229e557b015Sdrh analyzeVdbeCommentIndexWithColumnName(v,pIdx,k);
1230ebe25af1Sdrh }
1231ebe25af1Sdrh sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
1232ebe25af1Sdrh sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
1233ebe25af1Sdrh }
12349d33d9e7Sdrh }
12359fecc546Sdrh #endif
12369f274636Sdrh assert( regChng==(regStat+1) );
123759a8cb79Sdrh {
12389f274636Sdrh sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
1239920cf596Sdrh &statPushFuncdef, 0);
124049a76a8fSdrh if( db->nAnalysisLimit ){
124149a76a8fSdrh int j1, j2, j3;
124249a76a8fSdrh j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
124349a76a8fSdrh j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
124459a8cb79Sdrh j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
1245f72981f2Sdrh VdbeCoverage(v);
124659a8cb79Sdrh sqlite3VdbeJumpHere(v, j1);
1247688852abSdrh sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
124859a8cb79Sdrh sqlite3VdbeJumpHere(v, j2);
124959a8cb79Sdrh sqlite3VdbeJumpHere(v, j3);
125049a76a8fSdrh }else{
125149a76a8fSdrh sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
125249a76a8fSdrh }
125359a8cb79Sdrh }
1254f00e9025Sdan
1255f00e9025Sdan /* Add the entry to the stat1 table. */
12569f274636Sdrh callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
12574583c37cSdrh assert( "BBB"[0]==SQLITE_AFF_TEXT );
12584583c37cSdrh sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
1259f00e9025Sdan sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
1260f00e9025Sdan sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
1261614efe2bSdan #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
1262614efe2bSdan sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
1263614efe2bSdan #endif
1264f00e9025Sdan sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
1265f00e9025Sdan
1266175b8f06Sdrh /* Add the entries to the stat4 table. */
1267175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
126831e3744eSdrh if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
1269f00e9025Sdan int regEq = regStat1;
1270f00e9025Sdan int regLt = regStat1+1;
1271f00e9025Sdan int regDLt = regStat1+2;
1272f00e9025Sdan int regSample = regStat1+3;
1273f00e9025Sdan int regCol = regStat1+4;
1274f00e9025Sdan int regSampleRowid = regCol + nCol;
1275f00e9025Sdan int addrNext;
1276f00e9025Sdan int addrIsNull;
1277ebe25af1Sdrh u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
1278f00e9025Sdan
1279ec9e55d3Sdrh pParse->nMem = MAX(pParse->nMem, regCol+nCol);
1280f00e9025Sdan
1281f00e9025Sdan addrNext = sqlite3VdbeCurrentAddr(v);
12829f274636Sdrh callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
1283f00e9025Sdan addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
1284688852abSdrh VdbeCoverage(v);
12859f274636Sdrh callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
12869f274636Sdrh callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
12879f274636Sdrh callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
1288ebe25af1Sdrh sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
12896ccbd278Sdrh VdbeCoverage(v);
1290ec9e55d3Sdrh for(i=0; i<nCol; i++){
12911f9ca2c8Sdrh sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i);
1292ff2d5ea4Sdrh }
1293ec9e55d3Sdrh sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
129457bf4a8eSdrh sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
1295f00e9025Sdan sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
1296f00e9025Sdan sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
1297fe70510aSdrh sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
1298f00e9025Sdan sqlite3VdbeJumpHere(v, addrIsNull);
1299f00e9025Sdan }
1300175b8f06Sdrh #endif /* SQLITE_ENABLE_STAT4 */
1301f00e9025Sdan
13029fecc546Sdrh /* End of analysis */
1303f00e9025Sdan sqlite3VdbeJumpHere(v, addrRewind);
1304f00e9025Sdan }
1305f00e9025Sdan
1306f00e9025Sdan
1307721dfcf5Sdrh /* Create a single sqlite_stat1 entry containing NULL as the index
1308721dfcf5Sdrh ** name and the row count as the content.
130915564055Sdrh */
1310721dfcf5Sdrh if( pOnlyIdx==0 && needTableCnt ){
131115564055Sdrh VdbeComment((v, "%s", pTab->zName));
1312e043201dSdan sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
1313688852abSdrh jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v);
131415564055Sdrh sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
13154583c37cSdrh assert( "BBB"[0]==SQLITE_AFF_TEXT );
13164583c37cSdrh sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
1317ade3addfSdrh sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
1318f00e9025Sdan sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
131915564055Sdrh sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
13203739f298Sdan #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
13213739f298Sdan sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
13223739f298Sdan #endif
1323f6cf1ffbSdrh sqlite3VdbeJumpHere(v, jZeroRows);
1324ff2d5ea4Sdrh }
1325721dfcf5Sdrh }
1326ff2d5ea4Sdrh
13274a54bb57Sdrh
1328497e446dSdrh /*
13294a54bb57Sdrh ** Generate code that will cause the most recent index analysis to
13304a54bb57Sdrh ** be loaded into internal hash tables where is can be used.
1331ff2d5ea4Sdrh */
loadAnalysis(Parse * pParse,int iDb)13324a54bb57Sdrh static void loadAnalysis(Parse *pParse, int iDb){
1333182e84c1Sdrh Vdbe *v = sqlite3GetVdbe(pParse);
13344a54bb57Sdrh if( v ){
13354a54bb57Sdrh sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb);
133672052a73Sdrh }
13374a54bb57Sdrh }
13384a54bb57Sdrh
13394a54bb57Sdrh /*
13404a54bb57Sdrh ** Generate code that will do an analysis of an entire database
13414a54bb57Sdrh */
analyzeDatabase(Parse * pParse,int iDb)13424a54bb57Sdrh static void analyzeDatabase(Parse *pParse, int iDb){
13434a54bb57Sdrh sqlite3 *db = pParse->db;
13444a54bb57Sdrh Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */
13454a54bb57Sdrh HashElem *k;
13464a54bb57Sdrh int iStatCur;
13474a54bb57Sdrh int iMem;
13484a54bb57Sdrh int iTab;
13494a54bb57Sdrh
13504a54bb57Sdrh sqlite3BeginWriteOperation(pParse, 0, iDb);
13514a54bb57Sdrh iStatCur = pParse->nTab;
13524a54bb57Sdrh pParse->nTab += 3;
13534a54bb57Sdrh openStatTable(pParse, iDb, iStatCur, 0, 0);
13544a54bb57Sdrh iMem = pParse->nMem+1;
13554a54bb57Sdrh iTab = pParse->nTab;
135672052a73Sdrh assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
135772052a73Sdrh for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
135872052a73Sdrh Table *pTab = (Table*)sqliteHashData(k);
13594a54bb57Sdrh analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab);
1360182e84c1Sdrh }
13614a54bb57Sdrh loadAnalysis(pParse, iDb);
1362ff2d5ea4Sdrh }
1363ff2d5ea4Sdrh
1364ff2d5ea4Sdrh /*
1365ff2d5ea4Sdrh ** Generate code that will do an analysis of a single table in
1366a071bc5dSdrh ** a database. If pOnlyIdx is not NULL then it is a single index
1367a071bc5dSdrh ** in pTab that should be analyzed.
1368ff2d5ea4Sdrh */
analyzeTable(Parse * pParse,Table * pTab,Index * pOnlyIdx)1369a071bc5dSdrh static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){
1370ff2d5ea4Sdrh int iDb;
1371ff2d5ea4Sdrh int iStatCur;
1372ff2d5ea4Sdrh
1373ff2d5ea4Sdrh assert( pTab!=0 );
13741fee73e7Sdrh assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
1375da184236Sdanielk1977 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
1376ff2d5ea4Sdrh sqlite3BeginWriteOperation(pParse, 0, iDb);
137702fa4696Sdan iStatCur = pParse->nTab;
1378ade3addfSdrh pParse->nTab += 3;
1379a071bc5dSdrh if( pOnlyIdx ){
1380a071bc5dSdrh openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
1381a071bc5dSdrh }else{
1382a071bc5dSdrh openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
1383a071bc5dSdrh }
13844a54bb57Sdrh analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab);
13854a54bb57Sdrh loadAnalysis(pParse, iDb);
1386ff2d5ea4Sdrh }
1387ff2d5ea4Sdrh
1388ff2d5ea4Sdrh /*
1389ff2d5ea4Sdrh ** Generate code for the ANALYZE command. The parser calls this routine
1390ff2d5ea4Sdrh ** when it recognizes an ANALYZE command.
13919f18e8a0Sdrh **
13929f18e8a0Sdrh ** ANALYZE -- 1
13939f18e8a0Sdrh ** ANALYZE <database> -- 2
13949f18e8a0Sdrh ** ANALYZE ?<database>.?<tablename> -- 3
13959f18e8a0Sdrh **
13969f18e8a0Sdrh ** Form 1 causes all indices in all attached databases to be analyzed.
13979f18e8a0Sdrh ** Form 2 analyzes all indices the single database named.
13989f18e8a0Sdrh ** Form 3 analyzes all indices associated with the named table.
13999f18e8a0Sdrh */
sqlite3Analyze(Parse * pParse,Token * pName1,Token * pName2)1400182e84c1Sdrh void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
1401ff2d5ea4Sdrh sqlite3 *db = pParse->db;
1402ff2d5ea4Sdrh int iDb;
14034a54bb57Sdrh int i;
1404ff2d5ea4Sdrh char *z, *zDb;
1405ff2d5ea4Sdrh Table *pTab;
1406a071bc5dSdrh Index *pIdx;
1407ff2d5ea4Sdrh Token *pTableName;
14084a54bb57Sdrh Vdbe *v;
1409ff2d5ea4Sdrh
1410ff2d5ea4Sdrh /* Read the database schema. If an error occurs, leave an error message
1411ff2d5ea4Sdrh ** and code in pParse and return NULL. */
14121fee73e7Sdrh assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
1413ff2d5ea4Sdrh if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
1414ff2d5ea4Sdrh return;
14159f18e8a0Sdrh }
14169f18e8a0Sdrh
141705800a1dSdrh assert( pName2!=0 || pName1==0 );
1418ff2d5ea4Sdrh if( pName1==0 ){
1419ff2d5ea4Sdrh /* Form 1: Analyze everything */
14204a54bb57Sdrh for(i=0; i<db->nDb; i++){
14214a54bb57Sdrh if( i==1 ) continue; /* Do not analyze the TEMP database */
14224a54bb57Sdrh analyzeDatabase(pParse, i);
14234a54bb57Sdrh }
1424bce04148Sdrh }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
1425bce04148Sdrh /* Analyze the schema named as the argument */
14264a54bb57Sdrh analyzeDatabase(pParse, iDb);
1427e6e04969Sdrh }else{
1428bce04148Sdrh /* Form 3: Analyze the table or index named as an argument */
1429ff2d5ea4Sdrh iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
1430ff2d5ea4Sdrh if( iDb>=0 ){
1431bce04148Sdrh zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
143217435752Sdrh z = sqlite3NameFromToken(db, pTableName);
1433cf1be45fSdrh if( z ){
1434a071bc5dSdrh if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
1435a071bc5dSdrh analyzeTable(pParse, pIdx->pTable, pIdx);
1436a071bc5dSdrh }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){
1437a071bc5dSdrh analyzeTable(pParse, pTab, 0);
1438ff2d5ea4Sdrh }
1439a071bc5dSdrh sqlite3DbFree(db, z);
1440ff2d5ea4Sdrh }
1441ff2d5ea4Sdrh }
1442ff2d5ea4Sdrh }
1443bce04148Sdrh if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
1444bce04148Sdrh sqlite3VdbeAddOp0(v, OP_Expire);
1445bce04148Sdrh }
144672052a73Sdrh }
1447ff2d5ea4Sdrh
1448497e446dSdrh /*
1449497e446dSdrh ** Used to pass information from the analyzer reader through to the
1450497e446dSdrh ** callback routine.
1451497e446dSdrh */
1452497e446dSdrh typedef struct analysisInfo analysisInfo;
1453497e446dSdrh struct analysisInfo {
1454497e446dSdrh sqlite3 *db;
1455497e446dSdrh const char *zDatabase;
1456497e446dSdrh };
1457497e446dSdrh
1458497e446dSdrh /*
1459f52bb8d3Sdan ** The first argument points to a nul-terminated string containing a
1460f52bb8d3Sdan ** list of space separated integers. Read the first nOut of these into
1461f52bb8d3Sdan ** the array aOut[].
1462f52bb8d3Sdan */
decodeIntArray(char * zIntArray,int nOut,tRowcnt * aOut,LogEst * aLog,Index * pIndex)1463f52bb8d3Sdan static void decodeIntArray(
1464c28c4e50Sdrh char *zIntArray, /* String containing int array to decode */
1465c28c4e50Sdrh int nOut, /* Number of slots in aOut[] */
1466c28c4e50Sdrh tRowcnt *aOut, /* Store integers here */
1467cfc9df76Sdan LogEst *aLog, /* Or, if aOut==0, here */
1468c28c4e50Sdrh Index *pIndex /* Handle extra flags for this index, if not NULL */
1469f52bb8d3Sdan ){
1470f52bb8d3Sdan char *z = zIntArray;
1471f52bb8d3Sdan int c;
1472f52bb8d3Sdan int i;
1473f52bb8d3Sdan tRowcnt v;
1474f52bb8d3Sdan
1475175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
14766d57bbfeSdrh if( z==0 ) z = "";
14776d57bbfeSdrh #else
147885d117bcSdrh assert( z!=0 );
14796d57bbfeSdrh #endif
1480f52bb8d3Sdan for(i=0; *z && i<nOut; i++){
1481f52bb8d3Sdan v = 0;
1482f52bb8d3Sdan while( (c=z[0])>='0' && c<='9' ){
1483f52bb8d3Sdan v = v*10 + c - '0';
1484f52bb8d3Sdan z++;
1485f52bb8d3Sdan }
1486175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
148785d117bcSdrh if( aOut ) aOut[i] = v;
148885d117bcSdrh if( aLog ) aLog[i] = sqlite3LogEst(v);
1489c5f246ebSdrh #else
1490c5f246ebSdrh assert( aOut==0 );
1491c5f246ebSdrh UNUSED_PARAMETER(aOut);
149285d117bcSdrh assert( aLog!=0 );
1493cfc9df76Sdan aLog[i] = sqlite3LogEst(v);
149485d117bcSdrh #endif
1495f52bb8d3Sdan if( *z==' ' ) z++;
1496f52bb8d3Sdan }
1497175b8f06Sdrh #ifndef SQLITE_ENABLE_STAT4
14980da10d32Sdrh assert( pIndex!=0 ); {
14991f1fc0c2Sdrh #else
15000da10d32Sdrh if( pIndex ){
15011f1fc0c2Sdrh #endif
15020da10d32Sdrh pIndex->bUnordered = 0;
15030da10d32Sdrh pIndex->noSkipScan = 0;
150425df48d9Sdrh while( z[0] ){
150525df48d9Sdrh if( sqlite3_strglob("unordered*", z)==0 ){
1506c28c4e50Sdrh pIndex->bUnordered = 1;
1507e13e9f54Sdrh }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
1508725dd724Sdrh int sz = sqlite3Atoi(z+3);
1509725dd724Sdrh if( sz<2 ) sz = 2;
1510725dd724Sdrh pIndex->szIdxRow = sqlite3LogEst(sz);
1511f9df2fbdSdrh }else if( sqlite3_strglob("noskipscan*", z)==0 ){
1512f9df2fbdSdrh pIndex->noSkipScan = 1;
1513c28c4e50Sdrh }
1514dbd9486dSdrh #ifdef SQLITE_ENABLE_COSTMULT
1515dbd9486dSdrh else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
1516dbd9486dSdrh pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
1517dbd9486dSdrh }
1518dbd9486dSdrh #endif
151925df48d9Sdrh while( z[0]!=0 && z[0]!=' ' ) z++;
152025df48d9Sdrh while( z[0]==' ' ) z++;
1521f52bb8d3Sdan }
1522f52bb8d3Sdan }
15230da10d32Sdrh }
1524f52bb8d3Sdan
1525f52bb8d3Sdan /*
1526497e446dSdrh ** This callback is invoked once for each index when reading the
1527497e446dSdrh ** sqlite_stat1 table.
1528497e446dSdrh **
152915564055Sdrh ** argv[0] = name of the table
153015564055Sdrh ** argv[1] = name of the index (might be NULL)
153115564055Sdrh ** argv[2] = results of analysis - on integer for each column
153215564055Sdrh **
153315564055Sdrh ** Entries for which argv[1]==NULL simply record the number of rows in
153415564055Sdrh ** the table.
1535497e446dSdrh */
153662c14b34Sdanielk1977 static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
1537497e446dSdrh analysisInfo *pInfo = (analysisInfo*)pData;
1538497e446dSdrh Index *pIndex;
153915564055Sdrh Table *pTable;
1540497e446dSdrh const char *z;
1541497e446dSdrh
154215564055Sdrh assert( argc==3 );
1543f3d3c27aSdanielk1977 UNUSED_PARAMETER2(NotUsed, argc);
1544f3d3c27aSdanielk1977
154515564055Sdrh if( argv==0 || argv[0]==0 || argv[2]==0 ){
1546497e446dSdrh return 0;
1547497e446dSdrh }
154815564055Sdrh pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
154915564055Sdrh if( pTable==0 ){
1550497e446dSdrh return 0;
1551497e446dSdrh }
1552c2b23e7aSdrh if( argv[1]==0 ){
155315564055Sdrh pIndex = 0;
1554c2b23e7aSdrh }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){
1555c2b23e7aSdrh pIndex = sqlite3PrimaryKeyIndex(pTable);
1556c2b23e7aSdrh }else{
1557c2b23e7aSdrh pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase);
155815564055Sdrh }
155915564055Sdrh z = argv[2];
1560f52bb8d3Sdan
1561f52bb8d3Sdan if( pIndex ){
15624eed0534Sdan tRowcnt *aiRowEst = 0;
156343085d74Sdan int nCol = pIndex->nKeyCol+1;
1564175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
15654eed0534Sdan /* Index.aiRowEst may already be set here if there are duplicate
15664eed0534Sdan ** sqlite_stat1 entries for this index. In that case just clobber
15674eed0534Sdan ** the old data with the new instead of allocating a new array. */
15684eed0534Sdan if( pIndex->aiRowEst==0 ){
15694eed0534Sdan pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
15704a642b60Sdrh if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db);
15714eed0534Sdan }
15724eed0534Sdan aiRowEst = pIndex->aiRowEst;
157343085d74Sdan #endif
157425df48d9Sdrh pIndex->bUnordered = 0;
157543085d74Sdan decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
157633bec3f5Sdrh pIndex->hasStat1 = 1;
157733bec3f5Sdrh if( pIndex->pPartIdxWhere==0 ){
157833bec3f5Sdrh pTable->nRowLogEst = pIndex->aiRowLogEst[0];
157933bec3f5Sdrh pTable->tabFlags |= TF_HasStat1;
158033bec3f5Sdrh }
1581f52bb8d3Sdan }else{
158252f6c916Sdrh Index fakeIdx;
158352f6c916Sdrh fakeIdx.szIdxRow = pTable->szTabRow;
1584dbd9486dSdrh #ifdef SQLITE_ENABLE_COSTMULT
1585dbd9486dSdrh fakeIdx.pTable = pTable;
1586dbd9486dSdrh #endif
1587cfc9df76Sdan decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
158852f6c916Sdrh pTable->szTabRow = fakeIdx.szIdxRow;
158933bec3f5Sdrh pTable->tabFlags |= TF_HasStat1;
1590497e446dSdrh }
1591f52bb8d3Sdan
1592497e446dSdrh return 0;
1593497e446dSdrh }
1594497e446dSdrh
1595497e446dSdrh /*
159685c165caSdan ** If the Index.aSample variable is not NULL, delete the aSample[] array
159785c165caSdan ** and its contents.
159885c165caSdan */
1599d46def77Sdan void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
1600175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
160185c165caSdan if( pIdx->aSample ){
160285c165caSdan int j;
1603faacf17cSdrh for(j=0; j<pIdx->nSample; j++){
160485c165caSdan IndexSample *p = &pIdx->aSample[j];
1605f52bb8d3Sdan sqlite3DbFree(db, p->p);
160685c165caSdan }
16078e3937ffSdrh sqlite3DbFree(db, pIdx->aSample);
160885c165caSdan }
16098e3937ffSdrh if( db && db->pnBytesFreed==0 ){
1610faacf17cSdrh pIdx->nSample = 0;
1611faacf17cSdrh pIdx->aSample = 0;
16128e3937ffSdrh }
1613cea72b2dSshane #else
161443b18e1eSdrh UNUSED_PARAMETER(db);
1615cea72b2dSshane UNUSED_PARAMETER(pIdx);
1616175b8f06Sdrh #endif /* SQLITE_ENABLE_STAT4 */
161785c165caSdan }
161885c165caSdan
1619175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
16200adbed8aSdan /*
16210adbed8aSdan ** Populate the pIdx->aAvgEq[] array based on the samples currently
16220adbed8aSdan ** stored in pIdx->aSample[].
16230adbed8aSdan */
16240adbed8aSdan static void initAvgEq(Index *pIdx){
16250adbed8aSdan if( pIdx ){
16260adbed8aSdan IndexSample *aSample = pIdx->aSample;
16270adbed8aSdan IndexSample *pFinal = &aSample[pIdx->nSample-1];
16280adbed8aSdan int iCol;
162939caccf8Sdan int nCol = 1;
163039caccf8Sdan if( pIdx->nSampleCol>1 ){
163139caccf8Sdan /* If this is stat4 data, then calculate aAvgEq[] values for all
163239caccf8Sdan ** sample columns except the last. The last is always set to 1, as
163339caccf8Sdan ** once the trailing PK fields are considered all index keys are
163439caccf8Sdan ** unique. */
163539caccf8Sdan nCol = pIdx->nSampleCol-1;
163639caccf8Sdan pIdx->aAvgEq[nCol] = 1;
163739caccf8Sdan }
163839caccf8Sdan for(iCol=0; iCol<nCol; iCol++){
163943085d74Sdan int nSample = pIdx->nSample;
16400adbed8aSdan int i; /* Used to iterate through samples */
16410adbed8aSdan tRowcnt sumEq = 0; /* Sum of the nEq values */
16420adbed8aSdan tRowcnt avgEq = 0;
164343085d74Sdan tRowcnt nRow; /* Number of rows in index */
164443085d74Sdan i64 nSum100 = 0; /* Number of terms contributing to sumEq */
164543085d74Sdan i64 nDist100; /* Number of distinct values in index */
164643085d74Sdan
16475cca94eaSdan if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){
164843085d74Sdan nRow = pFinal->anLt[iCol];
164943085d74Sdan nDist100 = (i64)100 * pFinal->anDLt[iCol];
165043085d74Sdan nSample--;
165143085d74Sdan }else{
165243085d74Sdan nRow = pIdx->aiRowEst[0];
165343085d74Sdan nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
165443085d74Sdan }
16559f07cf7bSdrh pIdx->nRowEst0 = nRow;
16560adbed8aSdan
16570adbed8aSdan /* Set nSum to the number of distinct (iCol+1) field prefixes that
165843085d74Sdan ** occur in the stat4 table for this index. Set sumEq to the sum of
165943085d74Sdan ** the nEq values for column iCol for the same set (adding the value
166043085d74Sdan ** only once where there exist duplicate prefixes). */
166143085d74Sdan for(i=0; i<nSample; i++){
166243085d74Sdan if( i==(pIdx->nSample-1)
166343085d74Sdan || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol]
166443085d74Sdan ){
16650adbed8aSdan sumEq += aSample[i].anEq[iCol];
166643085d74Sdan nSum100 += 100;
16670adbed8aSdan }
16680adbed8aSdan }
166943085d74Sdan
1670785d8ed0Sdrh if( nDist100>nSum100 && sumEq<nRow ){
167143085d74Sdan avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
16720adbed8aSdan }
16730adbed8aSdan if( avgEq==0 ) avgEq = 1;
16740adbed8aSdan pIdx->aAvgEq[iCol] = avgEq;
16750adbed8aSdan }
16760adbed8aSdan }
16770adbed8aSdan }
16780adbed8aSdan
16790106e378Sdan /*
1680ce95d119Sdrh ** Look up an index by name. Or, if the name of a WITHOUT ROWID table
1681ce95d119Sdrh ** is supplied instead, find the PRIMARY KEY index for that table.
1682ce95d119Sdrh */
1683ce95d119Sdrh static Index *findIndexOrPrimaryKey(
1684ce95d119Sdrh sqlite3 *db,
1685ce95d119Sdrh const char *zName,
1686ce95d119Sdrh const char *zDb
1687ce95d119Sdrh ){
1688ce95d119Sdrh Index *pIdx = sqlite3FindIndex(db, zName, zDb);
1689ce95d119Sdrh if( pIdx==0 ){
1690ce95d119Sdrh Table *pTab = sqlite3FindTable(db, zName, zDb);
1691ce95d119Sdrh if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
1692ce95d119Sdrh }
1693ce95d119Sdrh return pIdx;
1694ce95d119Sdrh }
1695ce95d119Sdrh
1696ce95d119Sdrh /*
1697175b8f06Sdrh ** Load the content from either the sqlite_stat4
16980106e378Sdan ** into the relevant Index.aSample[] arrays.
16990106e378Sdan **
17000106e378Sdan ** Arguments zSql1 and zSql2 must point to SQL statements that return
1701175b8f06Sdrh ** data equivalent to the following:
17020106e378Sdan **
17030106e378Sdan ** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx
17040106e378Sdan ** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4
17050106e378Sdan **
17060106e378Sdan ** where %Q is replaced with the database name before the SQL is executed.
17070106e378Sdan */
17080106e378Sdan static int loadStatTbl(
17090106e378Sdan sqlite3 *db, /* Database handle */
17100106e378Sdan const char *zSql1, /* SQL statement 1 (see above) */
17110106e378Sdan const char *zSql2, /* SQL statement 2 (see above) */
17120106e378Sdan const char *zDb /* Database name (e.g. "main") */
17130106e378Sdan ){
1714faacf17cSdrh int rc; /* Result codes from subroutines */
1715faacf17cSdrh sqlite3_stmt *pStmt = 0; /* An SQL statement being run */
1716faacf17cSdrh char *zSql; /* Text of the SQL statement */
1717faacf17cSdrh Index *pPrevIdx = 0; /* Previous index in the loop */
1718faacf17cSdrh IndexSample *pSample; /* A slot in pIdx->aSample[] */
1719faacf17cSdrh
17204a642b60Sdrh assert( db->lookaside.bDisable );
17210106e378Sdan zSql = sqlite3MPrintf(db, zSql1, zDb);
1722faacf17cSdrh if( !zSql ){
1723fad3039cSmistachkin return SQLITE_NOMEM_BKPT;
1724faacf17cSdrh }
1725faacf17cSdrh rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
1726faacf17cSdrh sqlite3DbFree(db, zSql);
1727faacf17cSdrh if( rc ) return rc;
1728faacf17cSdrh
1729faacf17cSdrh while( sqlite3_step(pStmt)==SQLITE_ROW ){
17300106e378Sdan int nIdxCol = 1; /* Number of columns in stat4 records */
17310106e378Sdan
1732faacf17cSdrh char *zIndex; /* Index name */
1733faacf17cSdrh Index *pIdx; /* Pointer to the index object */
1734faacf17cSdrh int nSample; /* Number of samples */
1735f52bb8d3Sdan int nByte; /* Bytes of space required */
1736f52bb8d3Sdan int i; /* Bytes of space required */
1737f52bb8d3Sdan tRowcnt *pSpace;
1738faacf17cSdrh
1739faacf17cSdrh zIndex = (char *)sqlite3_column_text(pStmt, 0);
1740faacf17cSdrh if( zIndex==0 ) continue;
1741faacf17cSdrh nSample = sqlite3_column_int(pStmt, 1);
1742ce95d119Sdrh pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
1743175b8f06Sdrh assert( pIdx==0 || pIdx->nSample==0 );
17445eae1d1bSdrh if( pIdx==0 ) continue;
174539caccf8Sdan assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
174639caccf8Sdan if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
174739caccf8Sdan nIdxCol = pIdx->nKeyCol;
174839caccf8Sdan }else{
174939caccf8Sdan nIdxCol = pIdx->nColumn;
175039caccf8Sdan }
17518ad169abSdan pIdx->nSampleCol = nIdxCol;
1752f52bb8d3Sdan nByte = sizeof(IndexSample) * nSample;
17530106e378Sdan nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
175439caccf8Sdan nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
1755f52bb8d3Sdan
1756f52bb8d3Sdan pIdx->aSample = sqlite3DbMallocZero(db, nByte);
1757faacf17cSdrh if( pIdx->aSample==0 ){
1758faacf17cSdrh sqlite3_finalize(pStmt);
1759fad3039cSmistachkin return SQLITE_NOMEM_BKPT;
1760faacf17cSdrh }
1761f52bb8d3Sdan pSpace = (tRowcnt*)&pIdx->aSample[nSample];
176239caccf8Sdan pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
176340386968Sdrh pIdx->pTable->tabFlags |= TF_HasStat4;
17640adbed8aSdan for(i=0; i<nSample; i++){
17650106e378Sdan pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
17660106e378Sdan pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
17670106e378Sdan pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
1768f52bb8d3Sdan }
1769f52bb8d3Sdan assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) );
1770faacf17cSdrh }
17718e3937ffSdrh rc = sqlite3_finalize(pStmt);
17728e3937ffSdrh if( rc ) return rc;
1773faacf17cSdrh
17740106e378Sdan zSql = sqlite3MPrintf(db, zSql2, zDb);
1775faacf17cSdrh if( !zSql ){
1776fad3039cSmistachkin return SQLITE_NOMEM_BKPT;
1777faacf17cSdrh }
1778faacf17cSdrh rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
1779faacf17cSdrh sqlite3DbFree(db, zSql);
1780faacf17cSdrh if( rc ) return rc;
1781faacf17cSdrh
1782faacf17cSdrh while( sqlite3_step(pStmt)==SQLITE_ROW ){
1783faacf17cSdrh char *zIndex; /* Index name */
1784faacf17cSdrh Index *pIdx; /* Pointer to the index object */
17850106e378Sdan int nCol = 1; /* Number of columns in index */
1786faacf17cSdrh
1787faacf17cSdrh zIndex = (char *)sqlite3_column_text(pStmt, 0);
1788faacf17cSdrh if( zIndex==0 ) continue;
1789ce95d119Sdrh pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
1790faacf17cSdrh if( pIdx==0 ) continue;
179186f69d98Sdan /* This next condition is true if data has already been loaded from
1792175b8f06Sdrh ** the sqlite_stat4 table. */
17930adbed8aSdan nCol = pIdx->nSampleCol;
17940adbed8aSdan if( pIdx!=pPrevIdx ){
17950adbed8aSdan initAvgEq(pPrevIdx);
17960adbed8aSdan pPrevIdx = pIdx;
17970106e378Sdan }
1798c367d4c0Sdan pSample = &pIdx->aSample[pIdx->nSample];
1799cfc9df76Sdan decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0);
1800cfc9df76Sdan decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0);
1801cfc9df76Sdan decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0);
1802f52bb8d3Sdan
1803c367d4c0Sdan /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer.
1804c367d4c0Sdan ** This is in case the sample record is corrupted. In that case, the
1805c367d4c0Sdan ** sqlite3VdbeRecordCompare() may read up to two varints past the
1806c367d4c0Sdan ** end of the allocated buffer before it realizes it is dealing with
1807c367d4c0Sdan ** a corrupt record. Adding the two 0x00 bytes prevents this from causing
1808c367d4c0Sdan ** a buffer overread. */
1809f52bb8d3Sdan pSample->n = sqlite3_column_bytes(pStmt, 4);
1810c367d4c0Sdan pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
1811f52bb8d3Sdan if( pSample->p==0 ){
1812faacf17cSdrh sqlite3_finalize(pStmt);
1813fad3039cSmistachkin return SQLITE_NOMEM_BKPT;
1814faacf17cSdrh }
1815895decf6Sdan if( pSample->n ){
1816f52bb8d3Sdan memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
1817895decf6Sdan }
1818c367d4c0Sdan pIdx->nSample++;
1819faacf17cSdrh }
182061b34406Sdrh rc = sqlite3_finalize(pStmt);
182161b34406Sdrh if( rc==SQLITE_OK ) initAvgEq(pPrevIdx);
182261b34406Sdrh return rc;
1823faacf17cSdrh }
18240106e378Sdan
18250106e378Sdan /*
1826175b8f06Sdrh ** Load content from the sqlite_stat4 table into
18270106e378Sdan ** the Index.aSample[] arrays of all indices.
18280106e378Sdan */
18290106e378Sdan static int loadStat4(sqlite3 *db, const char *zDb){
18300106e378Sdan int rc = SQLITE_OK; /* Result codes from subroutines */
1831ebd1ff62Sdrh const Table *pStat4;
18320106e378Sdan
18334a642b60Sdrh assert( db->lookaside.bDisable );
1834ebd1ff62Sdrh if( (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0
1835ebd1ff62Sdrh && IsOrdinaryTable(pStat4)
1836ebd1ff62Sdrh ){
1837175b8f06Sdrh rc = loadStatTbl(db,
18380106e378Sdan "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx",
18390106e378Sdan "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
18400106e378Sdan zDb
18410106e378Sdan );
18420106e378Sdan }
18430106e378Sdan return rc;
18440106e378Sdan }
1845175b8f06Sdrh #endif /* SQLITE_ENABLE_STAT4 */
1846faacf17cSdrh
1847faacf17cSdrh /*
1848175b8f06Sdrh ** Load the content of the sqlite_stat1 and sqlite_stat4 tables. The
184985c165caSdan ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
1850175b8f06Sdrh ** arrays. The contents of sqlite_stat4 are used to populate the
185185c165caSdan ** Index.aSample[] arrays.
185285c165caSdan **
185385c165caSdan ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
1854175b8f06Sdrh ** is returned. In this case, even if SQLITE_ENABLE_STAT4 was defined
1855175b8f06Sdrh ** during compilation and the sqlite_stat4 table is present, no data is
185685c165caSdan ** read from it.
185785c165caSdan **
1858175b8f06Sdrh ** If SQLITE_ENABLE_STAT4 was defined during compilation and the
1859f52bb8d3Sdan ** sqlite_stat4 table is not present in the database, SQLITE_ERROR is
186085c165caSdan ** returned. However, in this case, data is read from the sqlite_stat1
186185c165caSdan ** table (if it is present) before returning.
186285c165caSdan **
186385c165caSdan ** If an OOM error occurs, this function always sets db->mallocFailed.
186485c165caSdan ** This means if the caller does not care about other errors, the return
186585c165caSdan ** code may be ignored.
1866497e446dSdrh */
1867cf1be45fSdrh int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
1868497e446dSdrh analysisInfo sInfo;
1869497e446dSdrh HashElem *i;
1870497e446dSdrh char *zSql;
187151b55a3eSdrh int rc = SQLITE_OK;
187233bec3f5Sdrh Schema *pSchema = db->aDb[iDb].pSchema;
1873ebd1ff62Sdrh const Table *pStat1;
1874497e446dSdrh
1875ff0587c6Sdrh assert( iDb>=0 && iDb<db->nDb );
1876ff0587c6Sdrh assert( db->aDb[iDb].pBt!=0 );
18771fee73e7Sdrh
1878497e446dSdrh /* Clear any prior statistics */
18792120608eSdrh assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
188033bec3f5Sdrh for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
188133bec3f5Sdrh Table *pTab = sqliteHashData(i);
188233bec3f5Sdrh pTab->tabFlags &= ~TF_HasStat1;
188333bec3f5Sdrh }
188433bec3f5Sdrh for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
1885497e446dSdrh Index *pIdx = sqliteHashData(i);
188633bec3f5Sdrh pIdx->hasStat1 = 0;
1887175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
1888d46def77Sdan sqlite3DeleteIndexSamples(db, pIdx);
1889d46def77Sdan pIdx->aSample = 0;
1890faacf17cSdrh #endif
1891497e446dSdrh }
1892497e446dSdrh
1893f6661a88Sdrh /* Load new statistics out of the sqlite_stat1 table */
1894497e446dSdrh sInfo.db = db;
189569c33826Sdrh sInfo.zDatabase = db->aDb[iDb].zDbSName;
1896ebd1ff62Sdrh if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase))
1897ebd1ff62Sdrh && IsOrdinaryTable(pStat1)
1898ebd1ff62Sdrh ){
189985c165caSdan zSql = sqlite3MPrintf(db,
190015564055Sdrh "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
1901f16ce3bcSdrh if( zSql==0 ){
1902fad3039cSmistachkin rc = SQLITE_NOMEM_BKPT;
1903f16ce3bcSdrh }else{
1904cf1be45fSdrh rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
1905633e6d57Sdrh sqlite3DbFree(db, zSql);
1906f16ce3bcSdrh }
1907f6661a88Sdrh }
190802fa4696Sdan
1909f6661a88Sdrh /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
1910f6661a88Sdrh assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
191133bec3f5Sdrh for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
1912f6661a88Sdrh Index *pIdx = sqliteHashData(i);
191333bec3f5Sdrh if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
1914f6661a88Sdrh }
191585c165caSdan
1916f52bb8d3Sdan /* Load the statistics from the sqlite_stat4 table. */
1917175b8f06Sdrh #ifdef SQLITE_ENABLE_STAT4
191872d03a64Sdrh if( rc==SQLITE_OK ){
191931f69626Sdrh DisableLookaside;
1920f52bb8d3Sdan rc = loadStat4(db, sInfo.zDatabase);
192131f69626Sdrh EnableLookaside;
192285c165caSdan }
192333bec3f5Sdrh for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
192443085d74Sdan Index *pIdx = sqliteHashData(i);
192575b170b1Sdrh sqlite3_free(pIdx->aiRowEst);
192643085d74Sdan pIdx->aiRowEst = 0;
192743085d74Sdan }
192869188d9aSdan #endif
1929e275dc3fSdan
1930e275dc3fSdan if( rc==SQLITE_NOMEM ){
19314a642b60Sdrh sqlite3OomFault(db);
1932e275dc3fSdan }
1933cf1be45fSdrh return rc;
1934497e446dSdrh }
1935ff2d5ea4Sdrh
19369f18e8a0Sdrh
19379f18e8a0Sdrh #endif /* SQLITE_OMIT_ANALYZE */
1938