1 /* 2 ** 2017-05-31 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 information 14 ** about all prepared statements for the database connection. 15 ** 16 ** Usage example: 17 ** 18 ** .load ./stmt 19 ** .mode line 20 ** .header on 21 ** SELECT * FROM stmt; 22 */ 23 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) 24 #if !defined(SQLITEINT_H) 25 #include "sqlite3ext.h" 26 #endif 27 SQLITE_EXTENSION_INIT1 28 #include <assert.h> 29 #include <string.h> 30 31 #ifndef SQLITE_OMIT_VIRTUALTABLE 32 33 /* 34 ** The following macros are used to cast pointers to integers. 35 ** The way you do this varies from one compiler 36 ** to the next, so we have developed the following set of #if statements 37 ** to generate appropriate macros for a wide range of compilers. 38 */ 39 #if defined(__PTRDIFF_TYPE__) /* This case should work for GCC */ 40 # define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(__PTRDIFF_TYPE__)(X)) 41 #elif !defined(__GNUC__) /* Works for compilers other than LLVM */ 42 # define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(((char*)X)-(char*)0)) 43 #elif defined(HAVE_STDINT_H) /* Use this case if we have ANSI headers */ 44 # define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(intptr_t)(X)) 45 #else /* Generates a warning - but it always works */ 46 # define SQLITE_PTR_TO_INT64(X) ((sqlite3_int64)(X)) 47 #endif 48 49 50 /* stmt_vtab is a subclass of sqlite3_vtab which will 51 ** serve as the underlying representation of a stmt virtual table 52 */ 53 typedef struct stmt_vtab stmt_vtab; 54 struct stmt_vtab { 55 sqlite3_vtab base; /* Base class - must be first */ 56 sqlite3 *db; /* Database connection for this stmt vtab */ 57 }; 58 59 /* stmt_cursor is a subclass of sqlite3_vtab_cursor which will 60 ** serve as the underlying representation of a cursor that scans 61 ** over rows of the result 62 */ 63 typedef struct stmt_cursor stmt_cursor; 64 struct stmt_cursor { 65 sqlite3_vtab_cursor base; /* Base class - must be first */ 66 sqlite3 *db; /* Database connection for this cursor */ 67 sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */ 68 sqlite3_int64 iRowid; /* The rowid */ 69 }; 70 71 /* 72 ** The stmtConnect() method is invoked to create a new 73 ** stmt_vtab that describes the generate_stmt virtual table. 74 ** 75 ** Think of this routine as the constructor for stmt_vtab objects. 76 ** 77 ** All this routine needs to do is: 78 ** 79 ** (1) Allocate the stmt_vtab object and initialize all fields. 80 ** 81 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the 82 ** result set of queries against generate_stmt will look like. 83 */ 84 static int stmtConnect( 85 sqlite3 *db, 86 void *pAux, 87 int argc, const char *const*argv, 88 sqlite3_vtab **ppVtab, 89 char **pzErr 90 ){ 91 stmt_vtab *pNew; 92 int rc; 93 94 /* Column numbers */ 95 #define STMT_COLUMN_PTR 0 /* Numeric value of the statement pointer */ 96 #define STMT_COLUMN_SQL 1 /* SQL for the statement */ 97 #define STMT_COLUMN_NCOL 2 /* Number of result columns */ 98 #define STMT_COLUMN_RO 3 /* True if read-only */ 99 #define STMT_COLUMN_BUSY 4 /* True if currently busy */ 100 #define STMT_COLUMN_NSCAN 5 /* SQLITE_STMTSTATUS_FULLSCAN_STEP */ 101 #define STMT_COLUMN_NSORT 6 /* SQLITE_STMTSTATUS_SORT */ 102 #define STMT_COLUMN_NAIDX 7 /* SQLITE_STMTSTATUS_AUTOINDEX */ 103 #define STMT_COLUMN_NSTEP 8 /* SQLITE_STMTSTATUS_VM_STEP */ 104 #define STMT_COLUMN_REPREP 9 /* SQLITE_STMTSTATUS_REPREPARE */ 105 #define STMT_COLUMN_RUN 10 /* SQLITE_STMTSTATUS_RUN */ 106 #define STMT_COLUMN_MEM 11 /* SQLITE_STMTSTATUS_MEMUSED */ 107 108 109 rc = sqlite3_declare_vtab(db, 110 "CREATE TABLE x(ptr,sql,ncol,ro,busy,nscan,nsort,naidx,nstep," 111 "reprep,run,mem)"); 112 if( rc==SQLITE_OK ){ 113 pNew = sqlite3_malloc( sizeof(*pNew) ); 114 *ppVtab = (sqlite3_vtab*)pNew; 115 if( pNew==0 ) return SQLITE_NOMEM; 116 memset(pNew, 0, sizeof(*pNew)); 117 pNew->db = db; 118 } 119 return rc; 120 } 121 122 /* 123 ** This method is the destructor for stmt_cursor objects. 124 */ 125 static int stmtDisconnect(sqlite3_vtab *pVtab){ 126 sqlite3_free(pVtab); 127 return SQLITE_OK; 128 } 129 130 /* 131 ** Constructor for a new stmt_cursor object. 132 */ 133 static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ 134 stmt_cursor *pCur; 135 pCur = sqlite3_malloc( sizeof(*pCur) ); 136 if( pCur==0 ) return SQLITE_NOMEM; 137 memset(pCur, 0, sizeof(*pCur)); 138 pCur->db = ((stmt_vtab*)p)->db; 139 *ppCursor = &pCur->base; 140 return SQLITE_OK; 141 } 142 143 /* 144 ** Destructor for a stmt_cursor. 145 */ 146 static int stmtClose(sqlite3_vtab_cursor *cur){ 147 sqlite3_free(cur); 148 return SQLITE_OK; 149 } 150 151 152 /* 153 ** Advance a stmt_cursor to its next row of output. 154 */ 155 static int stmtNext(sqlite3_vtab_cursor *cur){ 156 stmt_cursor *pCur = (stmt_cursor*)cur; 157 pCur->iRowid++; 158 pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt); 159 return SQLITE_OK; 160 } 161 162 /* 163 ** Return values of columns for the row at which the stmt_cursor 164 ** is currently pointing. 165 */ 166 static int stmtColumn( 167 sqlite3_vtab_cursor *cur, /* The cursor */ 168 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ 169 int i /* Which column to return */ 170 ){ 171 stmt_cursor *pCur = (stmt_cursor*)cur; 172 switch( i ){ 173 case STMT_COLUMN_PTR: { 174 sqlite3_result_int64(ctx, SQLITE_PTR_TO_INT64(pCur->pStmt)); 175 break; 176 } 177 case STMT_COLUMN_SQL: { 178 sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT); 179 break; 180 } 181 case STMT_COLUMN_NCOL: { 182 sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt)); 183 break; 184 } 185 case STMT_COLUMN_RO: { 186 sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt)); 187 break; 188 } 189 case STMT_COLUMN_BUSY: { 190 sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt)); 191 break; 192 } 193 case STMT_COLUMN_MEM: { 194 i = SQLITE_STMTSTATUS_MEMUSED + 195 STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP; 196 /* Fall thru */ 197 } 198 case STMT_COLUMN_NSCAN: 199 case STMT_COLUMN_NSORT: 200 case STMT_COLUMN_NAIDX: 201 case STMT_COLUMN_NSTEP: 202 case STMT_COLUMN_REPREP: 203 case STMT_COLUMN_RUN: { 204 sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt, 205 i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0)); 206 break; 207 } 208 } 209 return SQLITE_OK; 210 } 211 212 /* 213 ** Return the rowid for the current row. In this implementation, the 214 ** rowid is the same as the output value. 215 */ 216 static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ 217 stmt_cursor *pCur = (stmt_cursor*)cur; 218 *pRowid = pCur->iRowid; 219 return SQLITE_OK; 220 } 221 222 /* 223 ** Return TRUE if the cursor has been moved off of the last 224 ** row of output. 225 */ 226 static int stmtEof(sqlite3_vtab_cursor *cur){ 227 stmt_cursor *pCur = (stmt_cursor*)cur; 228 return pCur->pStmt==0; 229 } 230 231 /* 232 ** This method is called to "rewind" the stmt_cursor object back 233 ** to the first row of output. This method is always called at least 234 ** once prior to any call to stmtColumn() or stmtRowid() or 235 ** stmtEof(). 236 */ 237 static int stmtFilter( 238 sqlite3_vtab_cursor *pVtabCursor, 239 int idxNum, const char *idxStr, 240 int argc, sqlite3_value **argv 241 ){ 242 stmt_cursor *pCur = (stmt_cursor *)pVtabCursor; 243 pCur->pStmt = 0; 244 pCur->iRowid = 0; 245 return stmtNext(pVtabCursor); 246 } 247 248 /* 249 ** SQLite will invoke this method one or more times while planning a query 250 ** that uses the generate_stmt virtual table. This routine needs to create 251 ** a query plan for each invocation and compute an estimated cost for that 252 ** plan. 253 */ 254 static int stmtBestIndex( 255 sqlite3_vtab *tab, 256 sqlite3_index_info *pIdxInfo 257 ){ 258 pIdxInfo->estimatedCost = (double)500; 259 pIdxInfo->estimatedRows = 500; 260 return SQLITE_OK; 261 } 262 263 /* 264 ** This following structure defines all the methods for the 265 ** generate_stmt virtual table. 266 */ 267 static sqlite3_module stmtModule = { 268 0, /* iVersion */ 269 0, /* xCreate */ 270 stmtConnect, /* xConnect */ 271 stmtBestIndex, /* xBestIndex */ 272 stmtDisconnect, /* xDisconnect */ 273 0, /* xDestroy */ 274 stmtOpen, /* xOpen - open a cursor */ 275 stmtClose, /* xClose - close a cursor */ 276 stmtFilter, /* xFilter - configure scan constraints */ 277 stmtNext, /* xNext - advance a cursor */ 278 stmtEof, /* xEof - check for end of scan */ 279 stmtColumn, /* xColumn - read data */ 280 stmtRowid, /* xRowid - read data */ 281 0, /* xUpdate */ 282 0, /* xBegin */ 283 0, /* xSync */ 284 0, /* xCommit */ 285 0, /* xRollback */ 286 0, /* xFindMethod */ 287 0, /* xRename */ 288 }; 289 290 #endif /* SQLITE_OMIT_VIRTUALTABLE */ 291 292 int sqlite3StmtVtabInit(sqlite3 *db){ 293 int rc = SQLITE_OK; 294 #ifndef SQLITE_OMIT_VIRTUALTABLE 295 rc = sqlite3_create_module(db, "stmt", &stmtModule, 0); 296 #endif 297 return rc; 298 } 299 300 #ifndef SQLITE_CORE 301 #ifdef _WIN32 302 __declspec(dllexport) 303 #endif 304 int sqlite3_stmt_init( 305 sqlite3 *db, 306 char **pzErrMsg, 307 const sqlite3_api_routines *pApi 308 ){ 309 int rc = SQLITE_OK; 310 SQLITE_EXTENSION_INIT2(pApi); 311 #ifndef SQLITE_OMIT_VIRTUALTABLE 312 rc = sqlite3StmtVtabInit(db); 313 #endif 314 return rc; 315 } 316 #endif /* SQLITE_CORE */ 317 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ 318