xref: /sqlite-3.40.0/ext/misc/explain.c (revision 7cff0e34)
1 /*
2 ** 2018-09-16
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 ** This file demonstrates an eponymous virtual table that returns the
14 ** EXPLAIN output from an SQL statement.
15 **
16 ** Usage example:
17 **
18 **     .load ./explain
19 **     SELECT p2 FROM explain('SELECT * FROM sqlite_schema')
20 **      WHERE opcode='OpenRead';
21 **
22 ** This module was originally written to help simplify SQLite testing,
23 ** by providing an easier means of verifying certain patterns in the
24 ** generated bytecode.
25 */
26 #if !defined(SQLITEINT_H)
27 #include "sqlite3ext.h"
28 #endif
29 SQLITE_EXTENSION_INIT1
30 #include <assert.h>
31 #include <string.h>
32 
33 #ifndef SQLITE_OMIT_VIRTUALTABLE
34 
35 /* explain_vtab is a subclass of sqlite3_vtab which will
36 ** serve as the underlying representation of a explain virtual table
37 */
38 typedef struct explain_vtab explain_vtab;
39 struct explain_vtab {
40   sqlite3_vtab base;  /* Base class - must be first */
41   sqlite3 *db;        /* Database connection for this explain vtab */
42 };
43 
44 /* explain_cursor is a subclass of sqlite3_vtab_cursor which will
45 ** serve as the underlying representation of a cursor that scans
46 ** over rows of the result from an EXPLAIN operation.
47 */
48 typedef struct explain_cursor explain_cursor;
49 struct explain_cursor {
50   sqlite3_vtab_cursor base;  /* Base class - must be first */
51   sqlite3 *db;               /* Database connection for this cursor */
52   char *zSql;                /* Value for the EXPLN_COLUMN_SQL column */
53   sqlite3_stmt *pExplain;    /* Statement being explained */
54   int rc;                    /* Result of last sqlite3_step() on pExplain */
55 };
56 
57 /*
58 ** The explainConnect() method is invoked to create a new
59 ** explain_vtab that describes the explain virtual table.
60 **
61 ** Think of this routine as the constructor for explain_vtab objects.
62 **
63 ** All this routine needs to do is:
64 **
65 **    (1) Allocate the explain_vtab object and initialize all fields.
66 **
67 **    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
68 **        result set of queries against explain will look like.
69 */
70 static int explainConnect(
71   sqlite3 *db,
72   void *pAux,
73   int argc, const char *const*argv,
74   sqlite3_vtab **ppVtab,
75   char **pzErr
76 ){
77   explain_vtab *pNew;
78   int rc;
79 
80 /* Column numbers */
81 #define EXPLN_COLUMN_ADDR     0   /* Instruction address */
82 #define EXPLN_COLUMN_OPCODE   1   /* Opcode */
83 #define EXPLN_COLUMN_P1       2   /* Operand 1 */
84 #define EXPLN_COLUMN_P2       3   /* Operand 2 */
85 #define EXPLN_COLUMN_P3       4   /* Operand 3 */
86 #define EXPLN_COLUMN_P4       5   /* Operand 4 */
87 #define EXPLN_COLUMN_P5       6   /* Operand 5 */
88 #define EXPLN_COLUMN_COMMENT  7   /* Comment */
89 #define EXPLN_COLUMN_SQL      8   /* SQL that is being explained */
90 
91 
92   rc = sqlite3_declare_vtab(db,
93      "CREATE TABLE x(addr,opcode,p1,p2,p3,p4,p5,comment,sql HIDDEN)");
94   if( rc==SQLITE_OK ){
95     pNew = sqlite3_malloc( sizeof(*pNew) );
96     *ppVtab = (sqlite3_vtab*)pNew;
97     if( pNew==0 ) return SQLITE_NOMEM;
98     memset(pNew, 0, sizeof(*pNew));
99     pNew->db = db;
100   }
101   return rc;
102 }
103 
104 /*
105 ** This method is the destructor for explain_cursor objects.
106 */
107 static int explainDisconnect(sqlite3_vtab *pVtab){
108   sqlite3_free(pVtab);
109   return SQLITE_OK;
110 }
111 
112 /*
113 ** Constructor for a new explain_cursor object.
114 */
115 static int explainOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
116   explain_cursor *pCur;
117   pCur = sqlite3_malloc( sizeof(*pCur) );
118   if( pCur==0 ) return SQLITE_NOMEM;
119   memset(pCur, 0, sizeof(*pCur));
120   pCur->db = ((explain_vtab*)p)->db;
121   *ppCursor = &pCur->base;
122   return SQLITE_OK;
123 }
124 
125 /*
126 ** Destructor for a explain_cursor.
127 */
128 static int explainClose(sqlite3_vtab_cursor *cur){
129   explain_cursor *pCur = (explain_cursor*)cur;
130   sqlite3_finalize(pCur->pExplain);
131   sqlite3_free(pCur->zSql);
132   sqlite3_free(pCur);
133   return SQLITE_OK;
134 }
135 
136 
137 /*
138 ** Advance a explain_cursor to its next row of output.
139 */
140 static int explainNext(sqlite3_vtab_cursor *cur){
141   explain_cursor *pCur = (explain_cursor*)cur;
142   pCur->rc = sqlite3_step(pCur->pExplain);
143   if( pCur->rc!=SQLITE_DONE && pCur->rc!=SQLITE_ROW ) return pCur->rc;
144   return SQLITE_OK;
145 }
146 
147 /*
148 ** Return values of columns for the row at which the explain_cursor
149 ** is currently pointing.
150 */
151 static int explainColumn(
152   sqlite3_vtab_cursor *cur,   /* The cursor */
153   sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
154   int i                       /* Which column to return */
155 ){
156   explain_cursor *pCur = (explain_cursor*)cur;
157   if( i==EXPLN_COLUMN_SQL ){
158     sqlite3_result_text(ctx, pCur->zSql, -1, SQLITE_TRANSIENT);
159   }else{
160     sqlite3_result_value(ctx, sqlite3_column_value(pCur->pExplain, i));
161   }
162   return SQLITE_OK;
163 }
164 
165 /*
166 ** Return the rowid for the current row.  In this implementation, the
167 ** rowid is the same as the output value.
168 */
169 static int explainRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
170   explain_cursor *pCur = (explain_cursor*)cur;
171   *pRowid = sqlite3_column_int64(pCur->pExplain, 0);
172   return SQLITE_OK;
173 }
174 
175 /*
176 ** Return TRUE if the cursor has been moved off of the last
177 ** row of output.
178 */
179 static int explainEof(sqlite3_vtab_cursor *cur){
180   explain_cursor *pCur = (explain_cursor*)cur;
181   return pCur->rc!=SQLITE_ROW;
182 }
183 
184 /*
185 ** This method is called to "rewind" the explain_cursor object back
186 ** to the first row of output.  This method is always called at least
187 ** once prior to any call to explainColumn() or explainRowid() or
188 ** explainEof().
189 **
190 ** The argv[0] is the SQL statement that is to be explained.
191 */
192 static int explainFilter(
193   sqlite3_vtab_cursor *pVtabCursor,
194   int idxNum, const char *idxStr,
195   int argc, sqlite3_value **argv
196 ){
197   explain_cursor *pCur = (explain_cursor *)pVtabCursor;
198   char *zSql = 0;
199   int rc;
200   sqlite3_finalize(pCur->pExplain);
201   pCur->pExplain = 0;
202   if( sqlite3_value_type(argv[0])!=SQLITE_TEXT ){
203     pCur->rc = SQLITE_DONE;
204     return SQLITE_OK;
205   }
206   sqlite3_free(pCur->zSql);
207   pCur->zSql = sqlite3_mprintf("%s", sqlite3_value_text(argv[0]));
208   if( pCur->zSql ){
209     zSql = sqlite3_mprintf("EXPLAIN %s", pCur->zSql);
210   }
211   if( zSql==0 ){
212     rc = SQLITE_NOMEM;
213   }else{
214     rc = sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pExplain, 0);
215     sqlite3_free(zSql);
216   }
217   if( rc ){
218     sqlite3_finalize(pCur->pExplain);
219     pCur->pExplain = 0;
220     sqlite3_free(pCur->zSql);
221     pCur->zSql = 0;
222   }else{
223     pCur->rc = sqlite3_step(pCur->pExplain);
224     rc = (pCur->rc==SQLITE_DONE || pCur->rc==SQLITE_ROW) ? SQLITE_OK : pCur->rc;
225   }
226   return rc;
227 }
228 
229 /*
230 ** SQLite will invoke this method one or more times while planning a query
231 ** that uses the explain virtual table.  This routine needs to create
232 ** a query plan for each invocation and compute an estimated cost for that
233 ** plan.
234 */
235 static int explainBestIndex(
236   sqlite3_vtab *tab,
237   sqlite3_index_info *pIdxInfo
238 ){
239   int i;                  /* Loop counter */
240   int idx = -1;           /* Index of a usable == constraint against SQL */
241   int unusable = 0;       /* True if there are unusable constraints on SQL */
242 
243   pIdxInfo->estimatedRows = 500;
244   for(i=0; i<pIdxInfo->nConstraint; i++){
245     struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
246     if( p->iColumn!=EXPLN_COLUMN_SQL ) continue;
247     if( !p->usable ){
248       unusable = 1;
249     }else if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
250       idx = i;
251     }
252   }
253   if( idx>=0 ){
254     /* There exists a usable == constraint against the SQL column */
255     pIdxInfo->estimatedCost = 10.0;
256     pIdxInfo->idxNum = 1;
257     pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
258     pIdxInfo->aConstraintUsage[idx].omit = 1;
259   }else if( unusable ){
260     /* There are unusable constraints against the SQL column.  Do not allow
261     ** this plan to continue forward. */
262     return SQLITE_CONSTRAINT;
263   }
264   return SQLITE_OK;
265 }
266 
267 /*
268 ** This following structure defines all the methods for the
269 ** explain virtual table.
270 */
271 static sqlite3_module explainModule = {
272   0,                         /* iVersion */
273   0,                         /* xCreate */
274   explainConnect,            /* xConnect */
275   explainBestIndex,          /* xBestIndex */
276   explainDisconnect,         /* xDisconnect */
277   0,                         /* xDestroy */
278   explainOpen,               /* xOpen - open a cursor */
279   explainClose,              /* xClose - close a cursor */
280   explainFilter,             /* xFilter - configure scan constraints */
281   explainNext,               /* xNext - advance a cursor */
282   explainEof,                /* xEof - check for end of scan */
283   explainColumn,             /* xColumn - read data */
284   explainRowid,              /* xRowid - read data */
285   0,                         /* xUpdate */
286   0,                         /* xBegin */
287   0,                         /* xSync */
288   0,                         /* xCommit */
289   0,                         /* xRollback */
290   0,                         /* xFindMethod */
291   0,                         /* xRename */
292   0,                         /* xSavepoint */
293   0,                         /* xRelease */
294   0,                         /* xRollbackTo */
295   0,                         /* xShadowName */
296 };
297 
298 #endif /* SQLITE_OMIT_VIRTUALTABLE */
299 
300 int sqlite3ExplainVtabInit(sqlite3 *db){
301   int rc = SQLITE_OK;
302 #ifndef SQLITE_OMIT_VIRTUALTABLE
303   rc = sqlite3_create_module(db, "explain", &explainModule, 0);
304 #endif
305   return rc;
306 }
307 
308 #ifdef _WIN32
309 __declspec(dllexport)
310 #endif
311 int sqlite3_explain_init(
312   sqlite3 *db,
313   char **pzErrMsg,
314   const sqlite3_api_routines *pApi
315 ){
316   int rc = SQLITE_OK;
317   SQLITE_EXTENSION_INIT2(pApi);
318 #ifndef SQLITE_OMIT_VIRTUALTABLE
319   rc = sqlite3ExplainVtabInit(db);
320 #endif
321   return rc;
322 }
323