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