xref: /sqlite-3.40.0/ext/expert/sqlite3expert.c (revision bd0f1dbd)
1 /*
2 ** 2017 April 09
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 */
13 #include "sqlite3expert.h"
14 #include <assert.h>
15 #include <string.h>
16 #include <stdio.h>
17 
18 typedef sqlite3_int64 i64;
19 typedef sqlite3_uint64 u64;
20 
21 typedef struct IdxColumn IdxColumn;
22 typedef struct IdxConstraint IdxConstraint;
23 typedef struct IdxScan IdxScan;
24 typedef struct IdxStatement IdxStatement;
25 typedef struct IdxTable IdxTable;
26 typedef struct IdxWrite IdxWrite;
27 
28 #define STRLEN  (int)strlen
29 
30 /*
31 ** A temp table name that we assume no user database will actually use.
32 ** If this assumption proves incorrect triggers on the table with the
33 ** conflicting name will be ignored.
34 */
35 #define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776"
36 
37 /*
38 ** A single constraint. Equivalent to either "col = ?" or "col < ?" (or
39 ** any other type of single-ended range constraint on a column).
40 **
41 ** pLink:
42 **   Used to temporarily link IdxConstraint objects into lists while
43 **   creating candidate indexes.
44 */
45 struct IdxConstraint {
46   char *zColl;                    /* Collation sequence */
47   int bRange;                     /* True for range, false for eq */
48   int iCol;                       /* Constrained table column */
49   int bFlag;                      /* Used by idxFindCompatible() */
50   int bDesc;                      /* True if ORDER BY <expr> DESC */
51   IdxConstraint *pNext;           /* Next constraint in pEq or pRange list */
52   IdxConstraint *pLink;           /* See above */
53 };
54 
55 /*
56 ** A single scan of a single table.
57 */
58 struct IdxScan {
59   IdxTable *pTab;                 /* Associated table object */
60   int iDb;                        /* Database containing table zTable */
61   i64 covering;                   /* Mask of columns required for cov. index */
62   IdxConstraint *pOrder;          /* ORDER BY columns */
63   IdxConstraint *pEq;             /* List of == constraints */
64   IdxConstraint *pRange;          /* List of < constraints */
65   IdxScan *pNextScan;             /* Next IdxScan object for same analysis */
66 };
67 
68 /*
69 ** Information regarding a single database table. Extracted from
70 ** "PRAGMA table_info" by function idxGetTableInfo().
71 */
72 struct IdxColumn {
73   char *zName;
74   char *zColl;
75   int iPk;
76 };
77 struct IdxTable {
78   int nCol;
79   char *zName;                    /* Table name */
80   IdxColumn *aCol;
81   IdxTable *pNext;                /* Next table in linked list of all tables */
82 };
83 
84 /*
85 ** An object of the following type is created for each unique table/write-op
86 ** seen. The objects are stored in a singly-linked list beginning at
87 ** sqlite3expert.pWrite.
88 */
89 struct IdxWrite {
90   IdxTable *pTab;
91   int eOp;                        /* SQLITE_UPDATE, DELETE or INSERT */
92   IdxWrite *pNext;
93 };
94 
95 /*
96 ** Each statement being analyzed is represented by an instance of this
97 ** structure.
98 */
99 struct IdxStatement {
100   int iId;                        /* Statement number */
101   char *zSql;                     /* SQL statement */
102   char *zIdx;                     /* Indexes */
103   char *zEQP;                     /* Plan */
104   IdxStatement *pNext;
105 };
106 
107 
108 /*
109 ** A hash table for storing strings. With space for a payload string
110 ** with each entry. Methods are:
111 **
112 **   idxHashInit()
113 **   idxHashClear()
114 **   idxHashAdd()
115 **   idxHashSearch()
116 */
117 #define IDX_HASH_SIZE 1023
118 typedef struct IdxHashEntry IdxHashEntry;
119 typedef struct IdxHash IdxHash;
120 struct IdxHashEntry {
121   char *zKey;                     /* nul-terminated key */
122   char *zVal;                     /* nul-terminated value string */
123   char *zVal2;                    /* nul-terminated value string 2 */
124   IdxHashEntry *pHashNext;        /* Next entry in same hash bucket */
125   IdxHashEntry *pNext;            /* Next entry in hash */
126 };
127 struct IdxHash {
128   IdxHashEntry *pFirst;
129   IdxHashEntry *aHash[IDX_HASH_SIZE];
130 };
131 
132 /*
133 ** sqlite3expert object.
134 */
135 struct sqlite3expert {
136   int iSample;                    /* Percentage of tables to sample for stat1 */
137   sqlite3 *db;                    /* User database */
138   sqlite3 *dbm;                   /* In-memory db for this analysis */
139   sqlite3 *dbv;                   /* Vtab schema for this analysis */
140   IdxTable *pTable;               /* List of all IdxTable objects */
141   IdxScan *pScan;                 /* List of scan objects */
142   IdxWrite *pWrite;               /* List of write objects */
143   IdxStatement *pStatement;       /* List of IdxStatement objects */
144   int bRun;                       /* True once analysis has run */
145   char **pzErrmsg;
146   int rc;                         /* Error code from whereinfo hook */
147   IdxHash hIdx;                   /* Hash containing all candidate indexes */
148   char *zCandidates;              /* For EXPERT_REPORT_CANDIDATES */
149 };
150 
151 
152 /*
153 ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc().
154 ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
155 */
156 static void *idxMalloc(int *pRc, int nByte){
157   void *pRet;
158   assert( *pRc==SQLITE_OK );
159   assert( nByte>0 );
160   pRet = sqlite3_malloc(nByte);
161   if( pRet ){
162     memset(pRet, 0, nByte);
163   }else{
164     *pRc = SQLITE_NOMEM;
165   }
166   return pRet;
167 }
168 
169 /*
170 ** Initialize an IdxHash hash table.
171 */
172 static void idxHashInit(IdxHash *pHash){
173   memset(pHash, 0, sizeof(IdxHash));
174 }
175 
176 /*
177 ** Reset an IdxHash hash table.
178 */
179 static void idxHashClear(IdxHash *pHash){
180   int i;
181   for(i=0; i<IDX_HASH_SIZE; i++){
182     IdxHashEntry *pEntry;
183     IdxHashEntry *pNext;
184     for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){
185       pNext = pEntry->pHashNext;
186       sqlite3_free(pEntry->zVal2);
187       sqlite3_free(pEntry);
188     }
189   }
190   memset(pHash, 0, sizeof(IdxHash));
191 }
192 
193 /*
194 ** Return the index of the hash bucket that the string specified by the
195 ** arguments to this function belongs.
196 */
197 static int idxHashString(const char *z, int n){
198   unsigned int ret = 0;
199   int i;
200   for(i=0; i<n; i++){
201     ret += (ret<<3) + (unsigned char)(z[i]);
202   }
203   return (int)(ret % IDX_HASH_SIZE);
204 }
205 
206 /*
207 ** If zKey is already present in the hash table, return non-zero and do
208 ** nothing. Otherwise, add an entry with key zKey and payload string zVal to
209 ** the hash table passed as the second argument.
210 */
211 static int idxHashAdd(
212   int *pRc,
213   IdxHash *pHash,
214   const char *zKey,
215   const char *zVal
216 ){
217   int nKey = STRLEN(zKey);
218   int iHash = idxHashString(zKey, nKey);
219   int nVal = (zVal ? STRLEN(zVal) : 0);
220   IdxHashEntry *pEntry;
221   assert( iHash>=0 );
222   for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
223     if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
224       return 1;
225     }
226   }
227   pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
228   if( pEntry ){
229     pEntry->zKey = (char*)&pEntry[1];
230     memcpy(pEntry->zKey, zKey, nKey);
231     if( zVal ){
232       pEntry->zVal = &pEntry->zKey[nKey+1];
233       memcpy(pEntry->zVal, zVal, nVal);
234     }
235     pEntry->pHashNext = pHash->aHash[iHash];
236     pHash->aHash[iHash] = pEntry;
237 
238     pEntry->pNext = pHash->pFirst;
239     pHash->pFirst = pEntry;
240   }
241   return 0;
242 }
243 
244 /*
245 ** If zKey/nKey is present in the hash table, return a pointer to the
246 ** hash-entry object.
247 */
248 static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){
249   int iHash;
250   IdxHashEntry *pEntry;
251   if( nKey<0 ) nKey = STRLEN(zKey);
252   iHash = idxHashString(zKey, nKey);
253   assert( iHash>=0 );
254   for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
255     if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
256       return pEntry;
257     }
258   }
259   return 0;
260 }
261 
262 /*
263 ** If the hash table contains an entry with a key equal to the string
264 ** passed as the final two arguments to this function, return a pointer
265 ** to the payload string. Otherwise, if zKey/nKey is not present in the
266 ** hash table, return NULL.
267 */
268 static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){
269   IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey);
270   if( pEntry ) return pEntry->zVal;
271   return 0;
272 }
273 
274 /*
275 ** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl
276 ** variable to point to a copy of nul-terminated string zColl.
277 */
278 static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
279   IdxConstraint *pNew;
280   int nColl = STRLEN(zColl);
281 
282   assert( *pRc==SQLITE_OK );
283   pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1);
284   if( pNew ){
285     pNew->zColl = (char*)&pNew[1];
286     memcpy(pNew->zColl, zColl, nColl+1);
287   }
288   return pNew;
289 }
290 
291 /*
292 ** An error associated with database handle db has just occurred. Pass
293 ** the error message to callback function xOut.
294 */
295 static void idxDatabaseError(
296   sqlite3 *db,                    /* Database handle */
297   char **pzErrmsg                 /* Write error here */
298 ){
299   *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
300 }
301 
302 /*
303 ** Prepare an SQL statement.
304 */
305 static int idxPrepareStmt(
306   sqlite3 *db,                    /* Database handle to compile against */
307   sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
308   char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
309   const char *zSql                /* SQL statement to compile */
310 ){
311   int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
312   if( rc!=SQLITE_OK ){
313     *ppStmt = 0;
314     idxDatabaseError(db, pzErrmsg);
315   }
316   return rc;
317 }
318 
319 /*
320 ** Prepare an SQL statement using the results of a printf() formatting.
321 */
322 static int idxPrintfPrepareStmt(
323   sqlite3 *db,                    /* Database handle to compile against */
324   sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
325   char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
326   const char *zFmt,               /* printf() format of SQL statement */
327   ...                             /* Trailing printf() arguments */
328 ){
329   va_list ap;
330   int rc;
331   char *zSql;
332   va_start(ap, zFmt);
333   zSql = sqlite3_vmprintf(zFmt, ap);
334   if( zSql==0 ){
335     rc = SQLITE_NOMEM;
336   }else{
337     rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql);
338     sqlite3_free(zSql);
339   }
340   va_end(ap);
341   return rc;
342 }
343 
344 
345 /*************************************************************************
346 ** Beginning of virtual table implementation.
347 */
348 typedef struct ExpertVtab ExpertVtab;
349 struct ExpertVtab {
350   sqlite3_vtab base;
351   IdxTable *pTab;
352   sqlite3expert *pExpert;
353 };
354 
355 typedef struct ExpertCsr ExpertCsr;
356 struct ExpertCsr {
357   sqlite3_vtab_cursor base;
358   sqlite3_stmt *pData;
359 };
360 
361 static char *expertDequote(const char *zIn){
362   int n = STRLEN(zIn);
363   char *zRet = sqlite3_malloc(n);
364 
365   assert( zIn[0]=='\'' );
366   assert( zIn[n-1]=='\'' );
367 
368   if( zRet ){
369     int iOut = 0;
370     int iIn = 0;
371     for(iIn=1; iIn<(n-1); iIn++){
372       if( zIn[iIn]=='\'' ){
373         assert( zIn[iIn+1]=='\'' );
374         iIn++;
375       }
376       zRet[iOut++] = zIn[iIn];
377     }
378     zRet[iOut] = '\0';
379   }
380 
381   return zRet;
382 }
383 
384 /*
385 ** This function is the implementation of both the xConnect and xCreate
386 ** methods of the r-tree virtual table.
387 **
388 **   argv[0]   -> module name
389 **   argv[1]   -> database name
390 **   argv[2]   -> table name
391 **   argv[...] -> column names...
392 */
393 static int expertConnect(
394   sqlite3 *db,
395   void *pAux,
396   int argc, const char *const*argv,
397   sqlite3_vtab **ppVtab,
398   char **pzErr
399 ){
400   sqlite3expert *pExpert = (sqlite3expert*)pAux;
401   ExpertVtab *p = 0;
402   int rc;
403 
404   if( argc!=4 ){
405     *pzErr = sqlite3_mprintf("internal error!");
406     rc = SQLITE_ERROR;
407   }else{
408     char *zCreateTable = expertDequote(argv[3]);
409     if( zCreateTable ){
410       rc = sqlite3_declare_vtab(db, zCreateTable);
411       if( rc==SQLITE_OK ){
412         p = idxMalloc(&rc, sizeof(ExpertVtab));
413       }
414       if( rc==SQLITE_OK ){
415         p->pExpert = pExpert;
416         p->pTab = pExpert->pTable;
417         assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 );
418       }
419       sqlite3_free(zCreateTable);
420     }else{
421       rc = SQLITE_NOMEM;
422     }
423   }
424 
425   *ppVtab = (sqlite3_vtab*)p;
426   return rc;
427 }
428 
429 static int expertDisconnect(sqlite3_vtab *pVtab){
430   ExpertVtab *p = (ExpertVtab*)pVtab;
431   sqlite3_free(p);
432   return SQLITE_OK;
433 }
434 
435 static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){
436   ExpertVtab *p = (ExpertVtab*)pVtab;
437   sqlite3 *dbv = p->pExpert->dbv;
438   int rc = SQLITE_OK;
439   int n = 0;
440   IdxScan *pScan;
441   const int opmask =
442     SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT |
443     SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE |
444     SQLITE_INDEX_CONSTRAINT_LE;
445 
446   pScan = idxMalloc(&rc, sizeof(IdxScan));
447   if( pScan ){
448     int i;
449 
450     /* Link the new scan object into the list */
451     pScan->pTab = p->pTab;
452     pScan->pNextScan = p->pExpert->pScan;
453     p->pExpert->pScan = pScan;
454 
455     /* Add the constraints to the IdxScan object */
456     for(i=0; i<pIdxInfo->nConstraint; i++){
457       struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
458       if( pCons->usable
459        && pCons->iColumn>=0
460        && p->pTab->aCol[pCons->iColumn].iPk==0
461        && (pCons->op & opmask)
462       ){
463         IdxConstraint *pNew;
464         const char *zColl = sqlite3_vtab_collation(dbv, i);
465         pNew = idxNewConstraint(&rc, zColl);
466         if( pNew ){
467           pNew->iCol = pCons->iColumn;
468           if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
469             pNew->pNext = pScan->pEq;
470             pScan->pEq = pNew;
471           }else{
472             pNew->bRange = 1;
473             pNew->pNext = pScan->pRange;
474             pScan->pRange = pNew;
475           }
476         }
477         n++;
478         pIdxInfo->aConstraintUsage[i].argvIndex = n;
479       }
480     }
481 
482     /* Add the ORDER BY to the IdxScan object */
483     for(i=pIdxInfo->nOrderBy-1; i>=0; i--){
484       int iCol = pIdxInfo->aOrderBy[i].iColumn;
485       if( iCol>=0 ){
486         IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl);
487         if( pNew ){
488           pNew->iCol = iCol;
489           pNew->bDesc = pIdxInfo->aOrderBy[i].desc;
490           pNew->pNext = pScan->pOrder;
491           pNew->pLink = pScan->pOrder;
492           pScan->pOrder = pNew;
493           n++;
494         }
495       }
496     }
497   }
498 
499   pIdxInfo->estimatedCost = 1000000.0 / n;
500   return rc;
501 }
502 
503 static int expertUpdate(
504   sqlite3_vtab *pVtab,
505   int nData,
506   sqlite3_value **azData,
507   sqlite_int64 *pRowid
508 ){
509   return SQLITE_OK;
510 }
511 
512 /*
513 ** Virtual table module xOpen method.
514 */
515 static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
516   int rc = SQLITE_OK;
517   ExpertCsr *pCsr;
518   pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
519   *ppCursor = (sqlite3_vtab_cursor*)pCsr;
520   return rc;
521 }
522 
523 /*
524 ** Virtual table module xClose method.
525 */
526 static int expertClose(sqlite3_vtab_cursor *cur){
527   ExpertCsr *pCsr = (ExpertCsr*)cur;
528   sqlite3_finalize(pCsr->pData);
529   sqlite3_free(pCsr);
530   return SQLITE_OK;
531 }
532 
533 /*
534 ** Virtual table module xEof method.
535 **
536 ** Return non-zero if the cursor does not currently point to a valid
537 ** record (i.e if the scan has finished), or zero otherwise.
538 */
539 static int expertEof(sqlite3_vtab_cursor *cur){
540   ExpertCsr *pCsr = (ExpertCsr*)cur;
541   return pCsr->pData==0;
542 }
543 
544 /*
545 ** Virtual table module xNext method.
546 */
547 static int expertNext(sqlite3_vtab_cursor *cur){
548   ExpertCsr *pCsr = (ExpertCsr*)cur;
549   int rc = SQLITE_OK;
550 
551   assert( pCsr->pData );
552   rc = sqlite3_step(pCsr->pData);
553   if( rc!=SQLITE_ROW ){
554     rc = sqlite3_finalize(pCsr->pData);
555     pCsr->pData = 0;
556   }else{
557     rc = SQLITE_OK;
558   }
559 
560   return rc;
561 }
562 
563 /*
564 ** Virtual table module xRowid method.
565 */
566 static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
567   *pRowid = 0;
568   return SQLITE_OK;
569 }
570 
571 /*
572 ** Virtual table module xColumn method.
573 */
574 static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
575   ExpertCsr *pCsr = (ExpertCsr*)cur;
576   sqlite3_value *pVal;
577   pVal = sqlite3_column_value(pCsr->pData, i);
578   if( pVal ){
579     sqlite3_result_value(ctx, pVal);
580   }
581   return SQLITE_OK;
582 }
583 
584 /*
585 ** Virtual table module xFilter method.
586 */
587 static int expertFilter(
588   sqlite3_vtab_cursor *cur,
589   int idxNum, const char *idxStr,
590   int argc, sqlite3_value **argv
591 ){
592   ExpertCsr *pCsr = (ExpertCsr*)cur;
593   ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab);
594   sqlite3expert *pExpert = pVtab->pExpert;
595   int rc;
596 
597   rc = sqlite3_finalize(pCsr->pData);
598   pCsr->pData = 0;
599   if( rc==SQLITE_OK ){
600     rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
601         "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
602     );
603   }
604 
605   if( rc==SQLITE_OK ){
606     rc = expertNext(cur);
607   }
608   return rc;
609 }
610 
611 static int idxRegisterVtab(sqlite3expert *p){
612   static sqlite3_module expertModule = {
613     2,                            /* iVersion */
614     expertConnect,                /* xCreate - create a table */
615     expertConnect,                /* xConnect - connect to an existing table */
616     expertBestIndex,              /* xBestIndex - Determine search strategy */
617     expertDisconnect,             /* xDisconnect - Disconnect from a table */
618     expertDisconnect,             /* xDestroy - Drop a table */
619     expertOpen,                   /* xOpen - open a cursor */
620     expertClose,                  /* xClose - close a cursor */
621     expertFilter,                 /* xFilter - configure scan constraints */
622     expertNext,                   /* xNext - advance a cursor */
623     expertEof,                    /* xEof */
624     expertColumn,                 /* xColumn - read data */
625     expertRowid,                  /* xRowid - read data */
626     expertUpdate,                 /* xUpdate - write data */
627     0,                            /* xBegin - begin transaction */
628     0,                            /* xSync - sync transaction */
629     0,                            /* xCommit - commit transaction */
630     0,                            /* xRollback - rollback transaction */
631     0,                            /* xFindFunction - function overloading */
632     0,                            /* xRename - rename the table */
633     0,                            /* xSavepoint */
634     0,                            /* xRelease */
635     0,                            /* xRollbackTo */
636   };
637 
638   return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
639 }
640 /*
641 ** End of virtual table implementation.
642 *************************************************************************/
643 /*
644 ** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function
645 ** is called, set it to the return value of sqlite3_finalize() before
646 ** returning. Otherwise, discard the sqlite3_finalize() return value.
647 */
648 static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){
649   int rc = sqlite3_finalize(pStmt);
650   if( *pRc==SQLITE_OK ) *pRc = rc;
651 }
652 
653 /*
654 ** Attempt to allocate an IdxTable structure corresponding to table zTab
655 ** in the main database of connection db. If successful, set (*ppOut) to
656 ** point to the new object and return SQLITE_OK. Otherwise, return an
657 ** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be
658 ** set to point to an error string.
659 **
660 ** It is the responsibility of the caller to eventually free either the
661 ** IdxTable object or error message using sqlite3_free().
662 */
663 static int idxGetTableInfo(
664   sqlite3 *db,                    /* Database connection to read details from */
665   const char *zTab,               /* Table name */
666   IdxTable **ppOut,               /* OUT: New object (if successful) */
667   char **pzErrmsg                 /* OUT: Error message (if not) */
668 ){
669   sqlite3_stmt *p1 = 0;
670   int nCol = 0;
671   int nTab = STRLEN(zTab);
672   int nByte = sizeof(IdxTable) + nTab + 1;
673   IdxTable *pNew = 0;
674   int rc, rc2;
675   char *pCsr = 0;
676 
677   rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
678   while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
679     const char *zCol = (const char*)sqlite3_column_text(p1, 1);
680     nByte += 1 + STRLEN(zCol);
681     rc = sqlite3_table_column_metadata(
682         db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
683     );
684     nByte += 1 + STRLEN(zCol);
685     nCol++;
686   }
687   rc2 = sqlite3_reset(p1);
688   if( rc==SQLITE_OK ) rc = rc2;
689 
690   nByte += sizeof(IdxColumn) * nCol;
691   if( rc==SQLITE_OK ){
692     pNew = idxMalloc(&rc, nByte);
693   }
694   if( rc==SQLITE_OK ){
695     pNew->aCol = (IdxColumn*)&pNew[1];
696     pNew->nCol = nCol;
697     pCsr = (char*)&pNew->aCol[nCol];
698   }
699 
700   nCol = 0;
701   while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
702     const char *zCol = (const char*)sqlite3_column_text(p1, 1);
703     int nCopy = STRLEN(zCol) + 1;
704     pNew->aCol[nCol].zName = pCsr;
705     pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
706     memcpy(pCsr, zCol, nCopy);
707     pCsr += nCopy;
708 
709     rc = sqlite3_table_column_metadata(
710         db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
711     );
712     if( rc==SQLITE_OK ){
713       nCopy = STRLEN(zCol) + 1;
714       pNew->aCol[nCol].zColl = pCsr;
715       memcpy(pCsr, zCol, nCopy);
716       pCsr += nCopy;
717     }
718 
719     nCol++;
720   }
721   idxFinalize(&rc, p1);
722 
723   if( rc!=SQLITE_OK ){
724     sqlite3_free(pNew);
725     pNew = 0;
726   }else{
727     pNew->zName = pCsr;
728     memcpy(pNew->zName, zTab, nTab+1);
729   }
730 
731   *ppOut = pNew;
732   return rc;
733 }
734 
735 /*
736 ** This function is a no-op if *pRc is set to anything other than
737 ** SQLITE_OK when it is called.
738 **
739 ** If *pRc is initially set to SQLITE_OK, then the text specified by
740 ** the printf() style arguments is appended to zIn and the result returned
741 ** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on
742 ** zIn before returning.
743 */
744 static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
745   va_list ap;
746   char *zAppend = 0;
747   char *zRet = 0;
748   int nIn = zIn ? STRLEN(zIn) : 0;
749   int nAppend = 0;
750   va_start(ap, zFmt);
751   if( *pRc==SQLITE_OK ){
752     zAppend = sqlite3_vmprintf(zFmt, ap);
753     if( zAppend ){
754       nAppend = STRLEN(zAppend);
755       zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
756     }
757     if( zAppend && zRet ){
758       memcpy(zRet, zIn, nIn);
759       memcpy(&zRet[nIn], zAppend, nAppend+1);
760     }else{
761       sqlite3_free(zRet);
762       zRet = 0;
763       *pRc = SQLITE_NOMEM;
764     }
765     sqlite3_free(zAppend);
766     sqlite3_free(zIn);
767   }
768   va_end(ap);
769   return zRet;
770 }
771 
772 /*
773 ** Return true if zId must be quoted in order to use it as an SQL
774 ** identifier, or false otherwise.
775 */
776 static int idxIdentifierRequiresQuotes(const char *zId){
777   int i;
778   for(i=0; zId[i]; i++){
779     if( !(zId[i]=='_')
780      && !(zId[i]>='0' && zId[i]<='9')
781      && !(zId[i]>='a' && zId[i]<='z')
782      && !(zId[i]>='A' && zId[i]<='Z')
783     ){
784       return 1;
785     }
786   }
787   return 0;
788 }
789 
790 /*
791 ** This function appends an index column definition suitable for constraint
792 ** pCons to the string passed as zIn and returns the result.
793 */
794 static char *idxAppendColDefn(
795   int *pRc,                       /* IN/OUT: Error code */
796   char *zIn,                      /* Column defn accumulated so far */
797   IdxTable *pTab,                 /* Table index will be created on */
798   IdxConstraint *pCons
799 ){
800   char *zRet = zIn;
801   IdxColumn *p = &pTab->aCol[pCons->iCol];
802   if( zRet ) zRet = idxAppendText(pRc, zRet, ", ");
803 
804   if( idxIdentifierRequiresQuotes(p->zName) ){
805     zRet = idxAppendText(pRc, zRet, "%Q", p->zName);
806   }else{
807     zRet = idxAppendText(pRc, zRet, "%s", p->zName);
808   }
809 
810   if( sqlite3_stricmp(p->zColl, pCons->zColl) ){
811     if( idxIdentifierRequiresQuotes(pCons->zColl) ){
812       zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl);
813     }else{
814       zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl);
815     }
816   }
817 
818   if( pCons->bDesc ){
819     zRet = idxAppendText(pRc, zRet, " DESC");
820   }
821   return zRet;
822 }
823 
824 /*
825 ** Search database dbm for an index compatible with the one idxCreateFromCons()
826 ** would create from arguments pScan, pEq and pTail. If no error occurs and
827 ** such an index is found, return non-zero. Or, if no such index is found,
828 ** return zero.
829 **
830 ** If an error occurs, set *pRc to an SQLite error code and return zero.
831 */
832 static int idxFindCompatible(
833   int *pRc,                       /* OUT: Error code */
834   sqlite3* dbm,                   /* Database to search */
835   IdxScan *pScan,                 /* Scan for table to search for index on */
836   IdxConstraint *pEq,             /* List of == constraints */
837   IdxConstraint *pTail            /* List of range constraints */
838 ){
839   const char *zTbl = pScan->pTab->zName;
840   sqlite3_stmt *pIdxList = 0;
841   IdxConstraint *pIter;
842   int nEq = 0;                    /* Number of elements in pEq */
843   int rc;
844 
845   /* Count the elements in list pEq */
846   for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++;
847 
848   rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
849   while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
850     int bMatch = 1;
851     IdxConstraint *pT = pTail;
852     sqlite3_stmt *pInfo = 0;
853     const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
854 
855     /* Zero the IdxConstraint.bFlag values in the pEq list */
856     for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
857 
858     rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
859     while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
860       int iIdx = sqlite3_column_int(pInfo, 0);
861       int iCol = sqlite3_column_int(pInfo, 1);
862       const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
863 
864       if( iIdx<nEq ){
865         for(pIter=pEq; pIter; pIter=pIter->pLink){
866           if( pIter->bFlag ) continue;
867           if( pIter->iCol!=iCol ) continue;
868           if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
869           pIter->bFlag = 1;
870           break;
871         }
872         if( pIter==0 ){
873           bMatch = 0;
874           break;
875         }
876       }else{
877         if( pT ){
878           if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){
879             bMatch = 0;
880             break;
881           }
882           pT = pT->pLink;
883         }
884       }
885     }
886     idxFinalize(&rc, pInfo);
887 
888     if( rc==SQLITE_OK && bMatch ){
889       sqlite3_finalize(pIdxList);
890       return 1;
891     }
892   }
893   idxFinalize(&rc, pIdxList);
894 
895   *pRc = rc;
896   return 0;
897 }
898 
899 static int idxCreateFromCons(
900   sqlite3expert *p,
901   IdxScan *pScan,
902   IdxConstraint *pEq,
903   IdxConstraint *pTail
904 ){
905   sqlite3 *dbm = p->dbm;
906   int rc = SQLITE_OK;
907   if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
908     IdxTable *pTab = pScan->pTab;
909     char *zCols = 0;
910     char *zIdx = 0;
911     IdxConstraint *pCons;
912     int h = 0;
913     const char *zFmt;
914 
915     for(pCons=pEq; pCons; pCons=pCons->pLink){
916       zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
917     }
918     for(pCons=pTail; pCons; pCons=pCons->pLink){
919       zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
920     }
921 
922     if( rc==SQLITE_OK ){
923       /* Hash the list of columns to come up with a name for the index */
924       const char *zTable = pScan->pTab->zName;
925       char *zName;                /* Index name */
926       int i;
927       for(i=0; zCols[i]; i++){
928         h += ((h<<3) + zCols[i]);
929       }
930       zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
931       if( zName==0 ){
932         rc = SQLITE_NOMEM;
933       }else{
934         if( idxIdentifierRequiresQuotes(zTable) ){
935           zFmt = "CREATE INDEX '%q' ON %Q(%s)";
936         }else{
937           zFmt = "CREATE INDEX %s ON %s(%s)";
938         }
939         zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
940         if( !zIdx ){
941           rc = SQLITE_NOMEM;
942         }else{
943           rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
944           idxHashAdd(&rc, &p->hIdx, zName, zIdx);
945         }
946         sqlite3_free(zName);
947         sqlite3_free(zIdx);
948       }
949     }
950 
951     sqlite3_free(zCols);
952   }
953   return rc;
954 }
955 
956 /*
957 ** Return true if list pList (linked by IdxConstraint.pLink) contains
958 ** a constraint compatible with *p. Otherwise return false.
959 */
960 static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){
961   IdxConstraint *pCmp;
962   for(pCmp=pList; pCmp; pCmp=pCmp->pLink){
963     if( p->iCol==pCmp->iCol ) return 1;
964   }
965   return 0;
966 }
967 
968 static int idxCreateFromWhere(
969   sqlite3expert *p,
970   IdxScan *pScan,                 /* Create indexes for this scan */
971   IdxConstraint *pTail            /* range/ORDER BY constraints for inclusion */
972 ){
973   IdxConstraint *p1 = 0;
974   IdxConstraint *pCon;
975   int rc;
976 
977   /* Gather up all the == constraints. */
978   for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){
979     if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
980       pCon->pLink = p1;
981       p1 = pCon;
982     }
983   }
984 
985   /* Create an index using the == constraints collected above. And the
986   ** range constraint/ORDER BY terms passed in by the caller, if any. */
987   rc = idxCreateFromCons(p, pScan, p1, pTail);
988 
989   /* If no range/ORDER BY passed by the caller, create a version of the
990   ** index for each range constraint.  */
991   if( pTail==0 ){
992     for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
993       assert( pCon->pLink==0 );
994       if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
995         rc = idxCreateFromCons(p, pScan, p1, pCon);
996       }
997     }
998   }
999 
1000   return rc;
1001 }
1002 
1003 /*
1004 ** Create candidate indexes in database [dbm] based on the data in
1005 ** linked-list pScan.
1006 */
1007 static int idxCreateCandidates(sqlite3expert *p, char **pzErr){
1008   int rc = SQLITE_OK;
1009   IdxScan *pIter;
1010 
1011   for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
1012     rc = idxCreateFromWhere(p, pIter, 0);
1013     if( rc==SQLITE_OK && pIter->pOrder ){
1014       rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
1015     }
1016   }
1017 
1018   return rc;
1019 }
1020 
1021 /*
1022 ** Free all elements of the linked list starting at pConstraint.
1023 */
1024 static void idxConstraintFree(IdxConstraint *pConstraint){
1025   IdxConstraint *pNext;
1026   IdxConstraint *p;
1027 
1028   for(p=pConstraint; p; p=pNext){
1029     pNext = p->pNext;
1030     sqlite3_free(p);
1031   }
1032 }
1033 
1034 /*
1035 ** Free all elements of the linked list starting from pScan up until pLast
1036 ** (pLast is not freed).
1037 */
1038 static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
1039   IdxScan *p;
1040   IdxScan *pNext;
1041   for(p=pScan; p!=pLast; p=pNext){
1042     pNext = p->pNextScan;
1043     idxConstraintFree(p->pOrder);
1044     idxConstraintFree(p->pEq);
1045     idxConstraintFree(p->pRange);
1046     sqlite3_free(p);
1047   }
1048 }
1049 
1050 /*
1051 ** Free all elements of the linked list starting from pStatement up
1052 ** until pLast (pLast is not freed).
1053 */
1054 static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){
1055   IdxStatement *p;
1056   IdxStatement *pNext;
1057   for(p=pStatement; p!=pLast; p=pNext){
1058     pNext = p->pNext;
1059     sqlite3_free(p->zEQP);
1060     sqlite3_free(p->zIdx);
1061     sqlite3_free(p);
1062   }
1063 }
1064 
1065 /*
1066 ** Free the linked list of IdxTable objects starting at pTab.
1067 */
1068 static void idxTableFree(IdxTable *pTab){
1069   IdxTable *pIter;
1070   IdxTable *pNext;
1071   for(pIter=pTab; pIter; pIter=pNext){
1072     pNext = pIter->pNext;
1073     sqlite3_free(pIter);
1074   }
1075 }
1076 
1077 /*
1078 ** Free the linked list of IdxWrite objects starting at pTab.
1079 */
1080 static void idxWriteFree(IdxWrite *pTab){
1081   IdxWrite *pIter;
1082   IdxWrite *pNext;
1083   for(pIter=pTab; pIter; pIter=pNext){
1084     pNext = pIter->pNext;
1085     sqlite3_free(pIter);
1086   }
1087 }
1088 
1089 
1090 
1091 /*
1092 ** This function is called after candidate indexes have been created. It
1093 ** runs all the queries to see which indexes they prefer, and populates
1094 ** IdxStatement.zIdx and IdxStatement.zEQP with the results.
1095 */
1096 int idxFindIndexes(
1097   sqlite3expert *p,
1098   char **pzErr                         /* OUT: Error message (sqlite3_malloc) */
1099 ){
1100   IdxStatement *pStmt;
1101   sqlite3 *dbm = p->dbm;
1102   int rc = SQLITE_OK;
1103 
1104   IdxHash hIdx;
1105   idxHashInit(&hIdx);
1106 
1107   for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){
1108     IdxHashEntry *pEntry;
1109     sqlite3_stmt *pExplain = 0;
1110     idxHashClear(&hIdx);
1111     rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,
1112         "EXPLAIN QUERY PLAN %s", pStmt->zSql
1113     );
1114     while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
1115       int iSelectid = sqlite3_column_int(pExplain, 0);
1116       int iOrder = sqlite3_column_int(pExplain, 1);
1117       int iFrom = sqlite3_column_int(pExplain, 2);
1118       const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
1119       int nDetail = STRLEN(zDetail);
1120       int i;
1121 
1122       for(i=0; i<nDetail; i++){
1123         const char *zIdx = 0;
1124         if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
1125           zIdx = &zDetail[i+13];
1126         }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
1127           zIdx = &zDetail[i+22];
1128         }
1129         if( zIdx ){
1130           const char *zSql;
1131           int nIdx = 0;
1132           while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){
1133             nIdx++;
1134           }
1135           zSql = idxHashSearch(&p->hIdx, zIdx, nIdx);
1136           if( zSql ){
1137             idxHashAdd(&rc, &hIdx, zSql, 0);
1138             if( rc ) goto find_indexes_out;
1139           }
1140           break;
1141         }
1142       }
1143 
1144       pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%d|%d|%d|%s\n",
1145           iSelectid, iOrder, iFrom, zDetail
1146       );
1147     }
1148 
1149     for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
1150       pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey);
1151     }
1152 
1153     idxFinalize(&rc, pExplain);
1154   }
1155 
1156  find_indexes_out:
1157   idxHashClear(&hIdx);
1158   return rc;
1159 }
1160 
1161 static int idxAuthCallback(
1162   void *pCtx,
1163   int eOp,
1164   const char *z3,
1165   const char *z4,
1166   const char *zDb,
1167   const char *zTrigger
1168 ){
1169   int rc = SQLITE_OK;
1170   if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
1171     if( sqlite3_stricmp(zDb, "main")==0 ){
1172       sqlite3expert *p = (sqlite3expert*)pCtx;
1173       IdxTable *pTab;
1174       for(pTab=p->pTable; pTab; pTab=pTab->pNext){
1175         if( 0==sqlite3_stricmp(z3, pTab->zName) ) break;
1176       }
1177       if( pTab ){
1178         IdxWrite *pWrite;
1179         for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){
1180           if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break;
1181         }
1182         if( pWrite==0 ){
1183           pWrite = idxMalloc(&rc, sizeof(IdxWrite));
1184           if( rc==SQLITE_OK ){
1185             pWrite->pTab = pTab;
1186             pWrite->eOp = eOp;
1187             pWrite->pNext = p->pWrite;
1188             p->pWrite = pWrite;
1189           }
1190         }
1191       }
1192     }
1193   }
1194   return rc;
1195 }
1196 
1197 static int idxProcessOneTrigger(
1198   sqlite3expert *p,
1199   IdxWrite *pWrite,
1200   char **pzErr
1201 ){
1202   static const char *zInt = UNIQUE_TABLE_NAME;
1203   static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME;
1204   IdxTable *pTab = pWrite->pTab;
1205   const char *zTab = pTab->zName;
1206   const char *zSql =
1207     "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master "
1208     "WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
1209     "ORDER BY type;";
1210   sqlite3_stmt *pSelect = 0;
1211   int rc = SQLITE_OK;
1212   char *zWrite = 0;
1213 
1214   /* Create the table and its triggers in the temp schema */
1215   rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
1216   while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
1217     const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
1218     rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
1219   }
1220   idxFinalize(&rc, pSelect);
1221 
1222   /* Rename the table in the temp schema to zInt */
1223   if( rc==SQLITE_OK ){
1224     char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt);
1225     if( z==0 ){
1226       rc = SQLITE_NOMEM;
1227     }else{
1228       rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr);
1229       sqlite3_free(z);
1230     }
1231   }
1232 
1233   switch( pWrite->eOp ){
1234     case SQLITE_INSERT: {
1235       int i;
1236       zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt);
1237       for(i=0; i<pTab->nCol; i++){
1238         zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", ");
1239       }
1240       zWrite = idxAppendText(&rc, zWrite, ")");
1241       break;
1242     }
1243     case SQLITE_UPDATE: {
1244       int i;
1245       zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt);
1246       for(i=0; i<pTab->nCol; i++){
1247         zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ",
1248             pTab->aCol[i].zName
1249         );
1250       }
1251       break;
1252     }
1253     default: {
1254       assert( pWrite->eOp==SQLITE_DELETE );
1255       if( rc==SQLITE_OK ){
1256         zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt);
1257         if( zWrite==0 ) rc = SQLITE_NOMEM;
1258       }
1259     }
1260   }
1261 
1262   if( rc==SQLITE_OK ){
1263     sqlite3_stmt *pX = 0;
1264     rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0);
1265     idxFinalize(&rc, pX);
1266     if( rc!=SQLITE_OK ){
1267       idxDatabaseError(p->dbv, pzErr);
1268     }
1269   }
1270   sqlite3_free(zWrite);
1271 
1272   if( rc==SQLITE_OK ){
1273     rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr);
1274   }
1275 
1276   return rc;
1277 }
1278 
1279 static int idxProcessTriggers(sqlite3expert *p, char **pzErr){
1280   int rc = SQLITE_OK;
1281   IdxWrite *pEnd = 0;
1282   IdxWrite *pFirst = p->pWrite;
1283 
1284   while( rc==SQLITE_OK && pFirst!=pEnd ){
1285     IdxWrite *pIter;
1286     for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){
1287       rc = idxProcessOneTrigger(p, pIter, pzErr);
1288     }
1289     pEnd = pFirst;
1290     pFirst = p->pWrite;
1291   }
1292 
1293   return rc;
1294 }
1295 
1296 
1297 static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
1298   int rc = idxRegisterVtab(p);
1299   sqlite3_stmt *pSchema = 0;
1300 
1301   /* For each table in the main db schema:
1302   **
1303   **   1) Add an entry to the p->pTable list, and
1304   **   2) Create the equivalent virtual table in dbv.
1305   */
1306   rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
1307       "SELECT type, name, sql, 1 FROM sqlite_master "
1308       "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
1309       " UNION ALL "
1310       "SELECT type, name, sql, 2 FROM sqlite_master "
1311       "WHERE type = 'trigger'"
1312       "  AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') "
1313       "ORDER BY 4, 1"
1314   );
1315   while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
1316     const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
1317     const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
1318     const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
1319 
1320     if( zType[0]=='v' || zType[1]=='r' ){
1321       rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
1322     }else{
1323       IdxTable *pTab;
1324       rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
1325       if( rc==SQLITE_OK ){
1326         int i;
1327         char *zInner = 0;
1328         char *zOuter = 0;
1329         pTab->pNext = p->pTable;
1330         p->pTable = pTab;
1331 
1332         /* The statement the vtab will pass to sqlite3_declare_vtab() */
1333         zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
1334         for(i=0; i<pTab->nCol; i++){
1335           zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s",
1336               (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
1337           );
1338         }
1339         zInner = idxAppendText(&rc, zInner, ")");
1340 
1341         /* The CVT statement to create the vtab */
1342         zOuter = idxAppendText(&rc, 0,
1343             "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner
1344         );
1345         if( rc==SQLITE_OK ){
1346           rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg);
1347         }
1348         sqlite3_free(zInner);
1349         sqlite3_free(zOuter);
1350       }
1351     }
1352   }
1353   idxFinalize(&rc, pSchema);
1354   return rc;
1355 }
1356 
1357 struct IdxSampleCtx {
1358   int iTarget;
1359   double target;                  /* Target nRet/nRow value */
1360   double nRow;                    /* Number of rows seen */
1361   double nRet;                    /* Number of rows returned */
1362 };
1363 
1364 static void idxSampleFunc(
1365   sqlite3_context *pCtx,
1366   int argc,
1367   sqlite3_value **argv
1368 ){
1369   struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
1370   int bRet;
1371 
1372   assert( argc==0 );
1373   if( p->nRow==0.0 ){
1374     bRet = 1;
1375   }else{
1376     bRet = (p->nRet / p->nRow) <= p->target;
1377     if( bRet==0 ){
1378       unsigned short rnd;
1379       sqlite3_randomness(2, (void*)&rnd);
1380       bRet = ((int)rnd % 100) <= p->iTarget;
1381     }
1382   }
1383 
1384   sqlite3_result_int(pCtx, bRet);
1385   p->nRow += 1.0;
1386   p->nRet += (double)bRet;
1387 }
1388 
1389 struct IdxRemCtx {
1390   int nSlot;
1391   struct IdxRemSlot {
1392     int eType;                    /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
1393     i64 iVal;                     /* SQLITE_INTEGER value */
1394     double rVal;                  /* SQLITE_FLOAT value */
1395     int nByte;                    /* Bytes of space allocated at z */
1396     int n;                        /* Size of buffer z */
1397     char *z;                      /* SQLITE_TEXT/BLOB value */
1398   } aSlot[1];
1399 };
1400 
1401 /*
1402 ** Implementation of scalar function rem().
1403 */
1404 static void idxRemFunc(
1405   sqlite3_context *pCtx,
1406   int argc,
1407   sqlite3_value **argv
1408 ){
1409   struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx);
1410   struct IdxRemSlot *pSlot;
1411   int iSlot;
1412   assert( argc==2 );
1413 
1414   iSlot = sqlite3_value_int(argv[0]);
1415   assert( iSlot<=p->nSlot );
1416   pSlot = &p->aSlot[iSlot];
1417 
1418   switch( pSlot->eType ){
1419     case SQLITE_NULL:
1420       /* no-op */
1421       break;
1422 
1423     case SQLITE_INTEGER:
1424       sqlite3_result_int64(pCtx, pSlot->iVal);
1425       break;
1426 
1427     case SQLITE_FLOAT:
1428       sqlite3_result_double(pCtx, pSlot->rVal);
1429       break;
1430 
1431     case SQLITE_BLOB:
1432       sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
1433       break;
1434 
1435     case SQLITE_TEXT:
1436       sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
1437       break;
1438   }
1439 
1440   pSlot->eType = sqlite3_value_type(argv[1]);
1441   switch( pSlot->eType ){
1442     case SQLITE_NULL:
1443       /* no-op */
1444       break;
1445 
1446     case SQLITE_INTEGER:
1447       pSlot->iVal = sqlite3_value_int64(argv[1]);
1448       break;
1449 
1450     case SQLITE_FLOAT:
1451       pSlot->rVal = sqlite3_value_double(argv[1]);
1452       break;
1453 
1454     case SQLITE_BLOB:
1455     case SQLITE_TEXT: {
1456       int nByte = sqlite3_value_bytes(argv[1]);
1457       if( nByte>pSlot->nByte ){
1458         char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
1459         if( zNew==0 ){
1460           sqlite3_result_error_nomem(pCtx);
1461           return;
1462         }
1463         pSlot->nByte = nByte*2;
1464         pSlot->z = zNew;
1465       }
1466       pSlot->n = nByte;
1467       if( pSlot->eType==SQLITE_BLOB ){
1468         memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte);
1469       }else{
1470         memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte);
1471       }
1472       break;
1473     }
1474   }
1475 }
1476 
1477 static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
1478   int rc = SQLITE_OK;
1479   const char *zMax =
1480     "SELECT max(i.seqno) FROM "
1481     "  sqlite_master AS s, "
1482     "  pragma_index_list(s.name) AS l, "
1483     "  pragma_index_info(l.name) AS i "
1484     "WHERE s.type = 'table'";
1485   sqlite3_stmt *pMax = 0;
1486 
1487   *pnMax = 0;
1488   rc = idxPrepareStmt(db, &pMax, pzErr, zMax);
1489   if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
1490     *pnMax = sqlite3_column_int(pMax, 0) + 1;
1491   }
1492   idxFinalize(&rc, pMax);
1493 
1494   return rc;
1495 }
1496 
1497 static int idxPopulateOneStat1(
1498   sqlite3expert *p,
1499   sqlite3_stmt *pIndexXInfo,
1500   sqlite3_stmt *pWriteStat,
1501   const char *zTab,
1502   const char *zIdx,
1503   char **pzErr
1504 ){
1505   char *zCols = 0;
1506   char *zOrder = 0;
1507   char *zQuery = 0;
1508   int nCol = 0;
1509   int i;
1510   sqlite3_stmt *pQuery = 0;
1511   int *aStat = 0;
1512   int rc = SQLITE_OK;
1513 
1514   assert( p->iSample>0 );
1515 
1516   /* Formulate the query text */
1517   sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC);
1518   while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){
1519     const char *zComma = zCols==0 ? "" : ", ";
1520     const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
1521     const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
1522     zCols = idxAppendText(&rc, zCols,
1523         "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
1524     );
1525     zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
1526   }
1527   if( rc==SQLITE_OK ){
1528     if( p->iSample==100 ){
1529       zQuery = sqlite3_mprintf(
1530           "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder
1531       );
1532     }else{
1533       zQuery = sqlite3_mprintf(
1534           "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder
1535       );
1536     }
1537   }
1538   sqlite3_free(zCols);
1539   sqlite3_free(zOrder);
1540 
1541   /* Formulate the query text */
1542   if( rc==SQLITE_OK ){
1543     sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
1544     rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
1545   }
1546   sqlite3_free(zQuery);
1547 
1548   if( rc==SQLITE_OK ){
1549     aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
1550   }
1551   if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
1552     IdxHashEntry *pEntry;
1553     char *zStat = 0;
1554     for(i=0; i<=nCol; i++) aStat[i] = 1;
1555     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
1556       aStat[0]++;
1557       for(i=0; i<nCol; i++){
1558         if( sqlite3_column_int(pQuery, i)==0 ) break;
1559       }
1560       for(/*no-op*/; i<nCol; i++){
1561         aStat[i+1]++;
1562       }
1563     }
1564 
1565     if( rc==SQLITE_OK ){
1566       int s0 = aStat[0];
1567       zStat = sqlite3_mprintf("%d", s0);
1568       if( zStat==0 ) rc = SQLITE_NOMEM;
1569       for(i=1; rc==SQLITE_OK && i<=nCol; i++){
1570         zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
1571       }
1572     }
1573 
1574     if( rc==SQLITE_OK ){
1575       sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
1576       sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC);
1577       sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC);
1578       sqlite3_step(pWriteStat);
1579       rc = sqlite3_reset(pWriteStat);
1580     }
1581 
1582     pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx));
1583     if( pEntry ){
1584       assert( pEntry->zVal2==0 );
1585       pEntry->zVal2 = zStat;
1586     }else{
1587       sqlite3_free(zStat);
1588     }
1589   }
1590   sqlite3_free(aStat);
1591   idxFinalize(&rc, pQuery);
1592 
1593   return rc;
1594 }
1595 
1596 static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){
1597   int rc;
1598   char *zSql;
1599 
1600   rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
1601   if( rc!=SQLITE_OK ) return rc;
1602 
1603   zSql = sqlite3_mprintf(
1604       "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab
1605   );
1606   if( zSql==0 ) return SQLITE_NOMEM;
1607   rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0);
1608   sqlite3_free(zSql);
1609 
1610   return rc;
1611 }
1612 
1613 /*
1614 ** This function is called as part of sqlite3_expert_analyze(). Candidate
1615 ** indexes have already been created in database sqlite3expert.dbm, this
1616 ** function populates sqlite_stat1 table in the same database.
1617 **
1618 ** The stat1 data is generated by querying the
1619 */
1620 static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
1621   int rc = SQLITE_OK;
1622   int nMax =0;
1623   struct IdxRemCtx *pCtx = 0;
1624   struct IdxSampleCtx samplectx;
1625   int i;
1626   i64 iPrev = -100000;
1627   sqlite3_stmt *pAllIndex = 0;
1628   sqlite3_stmt *pIndexXInfo = 0;
1629   sqlite3_stmt *pWrite = 0;
1630 
1631   const char *zAllIndex =
1632     "SELECT s.rowid, s.name, l.name FROM "
1633     "  sqlite_master AS s, "
1634     "  pragma_index_list(s.name) AS l "
1635     "WHERE s.type = 'table'";
1636   const char *zIndexXInfo =
1637     "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key";
1638   const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)";
1639 
1640   /* If iSample==0, no sqlite_stat1 data is required. */
1641   if( p->iSample==0 ) return SQLITE_OK;
1642 
1643   rc = idxLargestIndex(p->dbm, &nMax, pzErr);
1644   if( nMax<=0 || rc!=SQLITE_OK ) return rc;
1645 
1646   rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
1647 
1648   if( rc==SQLITE_OK ){
1649     int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
1650     pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
1651   }
1652 
1653   if( rc==SQLITE_OK ){
1654     sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
1655     rc = sqlite3_create_function(
1656         dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
1657     );
1658   }
1659   if( rc==SQLITE_OK ){
1660     rc = sqlite3_create_function(
1661         p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
1662     );
1663   }
1664 
1665   if( rc==SQLITE_OK ){
1666     pCtx->nSlot = nMax+1;
1667     rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
1668   }
1669   if( rc==SQLITE_OK ){
1670     rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
1671   }
1672   if( rc==SQLITE_OK ){
1673     rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite);
1674   }
1675 
1676   while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){
1677     i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
1678     const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
1679     const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
1680     if( p->iSample<100 && iPrev!=iRowid ){
1681       samplectx.target = (double)p->iSample / 100.0;
1682       samplectx.iTarget = p->iSample;
1683       samplectx.nRow = 0.0;
1684       samplectx.nRet = 0.0;
1685       rc = idxBuildSampleTable(p, zTab);
1686       if( rc!=SQLITE_OK ) break;
1687     }
1688     rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr);
1689     iPrev = iRowid;
1690   }
1691   if( rc==SQLITE_OK && p->iSample<100 ){
1692     rc = sqlite3_exec(p->dbv,
1693         "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0
1694     );
1695   }
1696 
1697   idxFinalize(&rc, pAllIndex);
1698   idxFinalize(&rc, pIndexXInfo);
1699   idxFinalize(&rc, pWrite);
1700 
1701   for(i=0; i<pCtx->nSlot; i++){
1702     sqlite3_free(pCtx->aSlot[i].z);
1703   }
1704   sqlite3_free(pCtx);
1705 
1706   if( rc==SQLITE_OK ){
1707     rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0);
1708   }
1709 
1710   sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
1711   return rc;
1712 }
1713 
1714 /*
1715 ** Allocate a new sqlite3expert object.
1716 */
1717 sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
1718   int rc = SQLITE_OK;
1719   sqlite3expert *pNew;
1720 
1721   pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert));
1722 
1723   /* Open two in-memory databases to work with. The "vtab database" (dbv)
1724   ** will contain a virtual table corresponding to each real table in
1725   ** the user database schema, and a copy of each view. It is used to
1726   ** collect information regarding the WHERE, ORDER BY and other clauses
1727   ** of the user's query.
1728   */
1729   if( rc==SQLITE_OK ){
1730     pNew->db = db;
1731     pNew->iSample = 100;
1732     rc = sqlite3_open(":memory:", &pNew->dbv);
1733   }
1734   if( rc==SQLITE_OK ){
1735     rc = sqlite3_open(":memory:", &pNew->dbm);
1736     if( rc==SQLITE_OK ){
1737       sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_FULL_EQP, 1, (int*)0);
1738     }
1739   }
1740 
1741 
1742   /* Copy the entire schema of database [db] into [dbm]. */
1743   if( rc==SQLITE_OK ){
1744     sqlite3_stmt *pSql;
1745     rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg,
1746         "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'"
1747         " AND sql NOT LIKE 'CREATE VIRTUAL %%'"
1748     );
1749     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
1750       const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
1751       rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
1752     }
1753     idxFinalize(&rc, pSql);
1754   }
1755 
1756   /* Create the vtab schema */
1757   if( rc==SQLITE_OK ){
1758     rc = idxCreateVtabSchema(pNew, pzErrmsg);
1759   }
1760 
1761   /* Register the auth callback with dbv */
1762   if( rc==SQLITE_OK ){
1763     sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
1764   }
1765 
1766   /* If an error has occurred, free the new object and reutrn NULL. Otherwise,
1767   ** return the new sqlite3expert handle.  */
1768   if( rc!=SQLITE_OK ){
1769     sqlite3_expert_destroy(pNew);
1770     pNew = 0;
1771   }
1772   return pNew;
1773 }
1774 
1775 /*
1776 ** Configure an sqlite3expert object.
1777 */
1778 int sqlite3_expert_config(sqlite3expert *p, int op, ...){
1779   int rc = SQLITE_OK;
1780   va_list ap;
1781   va_start(ap, op);
1782   switch( op ){
1783     case EXPERT_CONFIG_SAMPLE: {
1784       int iVal = va_arg(ap, int);
1785       if( iVal<0 ) iVal = 0;
1786       if( iVal>100 ) iVal = 100;
1787       p->iSample = iVal;
1788       break;
1789     }
1790     default:
1791       rc = SQLITE_NOTFOUND;
1792       break;
1793   }
1794 
1795   va_end(ap);
1796   return rc;
1797 }
1798 
1799 /*
1800 ** Add an SQL statement to the analysis.
1801 */
1802 int sqlite3_expert_sql(
1803   sqlite3expert *p,               /* From sqlite3_expert_new() */
1804   const char *zSql,               /* SQL statement to add */
1805   char **pzErr                    /* OUT: Error message (if any) */
1806 ){
1807   IdxScan *pScanOrig = p->pScan;
1808   IdxStatement *pStmtOrig = p->pStatement;
1809   int rc = SQLITE_OK;
1810   const char *zStmt = zSql;
1811 
1812   if( p->bRun ) return SQLITE_MISUSE;
1813 
1814   while( rc==SQLITE_OK && zStmt && zStmt[0] ){
1815     sqlite3_stmt *pStmt = 0;
1816     rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
1817     if( rc==SQLITE_OK ){
1818       if( pStmt ){
1819         IdxStatement *pNew;
1820         const char *z = sqlite3_sql(pStmt);
1821         int n = STRLEN(z);
1822         pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
1823         if( rc==SQLITE_OK ){
1824           pNew->zSql = (char*)&pNew[1];
1825           memcpy(pNew->zSql, z, n+1);
1826           pNew->pNext = p->pStatement;
1827           if( p->pStatement ) pNew->iId = p->pStatement->iId+1;
1828           p->pStatement = pNew;
1829         }
1830         sqlite3_finalize(pStmt);
1831       }
1832     }else{
1833       idxDatabaseError(p->dbv, pzErr);
1834     }
1835   }
1836 
1837   if( rc!=SQLITE_OK ){
1838     idxScanFree(p->pScan, pScanOrig);
1839     idxStatementFree(p->pStatement, pStmtOrig);
1840     p->pScan = pScanOrig;
1841     p->pStatement = pStmtOrig;
1842   }
1843 
1844   return rc;
1845 }
1846 
1847 int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
1848   int rc;
1849   IdxHashEntry *pEntry;
1850 
1851   /* Do trigger processing to collect any extra IdxScan structures */
1852   rc = idxProcessTriggers(p, pzErr);
1853 
1854   /* Create candidate indexes within the in-memory database file */
1855   if( rc==SQLITE_OK ){
1856     rc = idxCreateCandidates(p, pzErr);
1857   }
1858 
1859   /* Generate the stat1 data */
1860   if( rc==SQLITE_OK ){
1861     rc = idxPopulateStat1(p, pzErr);
1862   }
1863 
1864   /* Formulate the EXPERT_REPORT_CANDIDATES text */
1865   for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
1866     p->zCandidates = idxAppendText(&rc, p->zCandidates,
1867         "%s;%s%s\n", pEntry->zVal,
1868         pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2
1869     );
1870   }
1871 
1872   /* Figure out which of the candidate indexes are preferred by the query
1873   ** planner and report the results to the user.  */
1874   if( rc==SQLITE_OK ){
1875     rc = idxFindIndexes(p, pzErr);
1876   }
1877 
1878   if( rc==SQLITE_OK ){
1879     p->bRun = 1;
1880   }
1881   return rc;
1882 }
1883 
1884 /*
1885 ** Return the total number of statements that have been added to this
1886 ** sqlite3expert using sqlite3_expert_sql().
1887 */
1888 int sqlite3_expert_count(sqlite3expert *p){
1889   int nRet = 0;
1890   if( p->pStatement ) nRet = p->pStatement->iId+1;
1891   return nRet;
1892 }
1893 
1894 /*
1895 ** Return a component of the report.
1896 */
1897 const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){
1898   const char *zRet = 0;
1899   IdxStatement *pStmt;
1900 
1901   if( p->bRun==0 ) return 0;
1902   for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext);
1903   switch( eReport ){
1904     case EXPERT_REPORT_SQL:
1905       if( pStmt ) zRet = pStmt->zSql;
1906       break;
1907     case EXPERT_REPORT_INDEXES:
1908       if( pStmt ) zRet = pStmt->zIdx;
1909       break;
1910     case EXPERT_REPORT_PLAN:
1911       if( pStmt ) zRet = pStmt->zEQP;
1912       break;
1913     case EXPERT_REPORT_CANDIDATES:
1914       zRet = p->zCandidates;
1915       break;
1916   }
1917   return zRet;
1918 }
1919 
1920 /*
1921 ** Free an sqlite3expert object.
1922 */
1923 void sqlite3_expert_destroy(sqlite3expert *p){
1924   if( p ){
1925     sqlite3_close(p->dbm);
1926     sqlite3_close(p->dbv);
1927     idxScanFree(p->pScan, 0);
1928     idxStatementFree(p->pStatement, 0);
1929     idxTableFree(p->pTable);
1930     idxWriteFree(p->pWrite);
1931     idxHashClear(&p->hIdx);
1932     sqlite3_free(p->zCandidates);
1933     sqlite3_free(p);
1934   }
1935 }
1936