Enhance the command-line completion extension to return the names of
[sqlite.git] / ext / misc / stmt.c
blobdbaa0bd64dcca28774412492cd6138fecd0fcf9d
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.
11 *************************************************************************
13 ** This file demonstrates an eponymous virtual table that returns information
14 ** about all prepared statements for the database connection.
16 ** Usage example:
18 ** .load ./stmt
19 ** .mode line
20 ** .header on
21 ** SELECT * FROM stmt;
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>
31 #ifndef SQLITE_OMIT_VIRTUALTABLE
33 /* stmt_vtab is a subclass of sqlite3_vtab which will
34 ** serve as the underlying representation of a stmt virtual table
36 typedef struct stmt_vtab stmt_vtab;
37 struct stmt_vtab {
38 sqlite3_vtab base; /* Base class - must be first */
39 sqlite3 *db; /* Database connection for this stmt vtab */
42 /* stmt_cursor is a subclass of sqlite3_vtab_cursor which will
43 ** serve as the underlying representation of a cursor that scans
44 ** over rows of the result
46 typedef struct stmt_cursor stmt_cursor;
47 struct stmt_cursor {
48 sqlite3_vtab_cursor base; /* Base class - must be first */
49 sqlite3 *db; /* Database connection for this cursor */
50 sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */
51 sqlite3_int64 iRowid; /* The rowid */
55 ** The stmtConnect() method is invoked to create a new
56 ** stmt_vtab that describes the stmt virtual table.
58 ** Think of this routine as the constructor for stmt_vtab objects.
60 ** All this routine needs to do is:
62 ** (1) Allocate the stmt_vtab object and initialize all fields.
64 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
65 ** result set of queries against stmt will look like.
67 static int stmtConnect(
68 sqlite3 *db,
69 void *pAux,
70 int argc, const char *const*argv,
71 sqlite3_vtab **ppVtab,
72 char **pzErr
74 stmt_vtab *pNew;
75 int rc;
77 /* Column numbers */
78 #define STMT_COLUMN_SQL 0 /* SQL for the statement */
79 #define STMT_COLUMN_NCOL 1 /* Number of result columns */
80 #define STMT_COLUMN_RO 2 /* True if read-only */
81 #define STMT_COLUMN_BUSY 3 /* True if currently busy */
82 #define STMT_COLUMN_NSCAN 4 /* SQLITE_STMTSTATUS_FULLSCAN_STEP */
83 #define STMT_COLUMN_NSORT 5 /* SQLITE_STMTSTATUS_SORT */
84 #define STMT_COLUMN_NAIDX 6 /* SQLITE_STMTSTATUS_AUTOINDEX */
85 #define STMT_COLUMN_NSTEP 7 /* SQLITE_STMTSTATUS_VM_STEP */
86 #define STMT_COLUMN_REPREP 8 /* SQLITE_STMTSTATUS_REPREPARE */
87 #define STMT_COLUMN_RUN 9 /* SQLITE_STMTSTATUS_RUN */
88 #define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */
91 rc = sqlite3_declare_vtab(db,
92 "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
93 "reprep,run,mem)");
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;
101 return rc;
105 ** This method is the destructor for stmt_cursor objects.
107 static int stmtDisconnect(sqlite3_vtab *pVtab){
108 sqlite3_free(pVtab);
109 return SQLITE_OK;
113 ** Constructor for a new stmt_cursor object.
115 static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
116 stmt_cursor *pCur;
117 pCur = sqlite3_malloc( sizeof(*pCur) );
118 if( pCur==0 ) return SQLITE_NOMEM;
119 memset(pCur, 0, sizeof(*pCur));
120 pCur->db = ((stmt_vtab*)p)->db;
121 *ppCursor = &pCur->base;
122 return SQLITE_OK;
126 ** Destructor for a stmt_cursor.
128 static int stmtClose(sqlite3_vtab_cursor *cur){
129 sqlite3_free(cur);
130 return SQLITE_OK;
135 ** Advance a stmt_cursor to its next row of output.
137 static int stmtNext(sqlite3_vtab_cursor *cur){
138 stmt_cursor *pCur = (stmt_cursor*)cur;
139 pCur->iRowid++;
140 pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
141 return SQLITE_OK;
145 ** Return values of columns for the row at which the stmt_cursor
146 ** is currently pointing.
148 static int stmtColumn(
149 sqlite3_vtab_cursor *cur, /* The cursor */
150 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
151 int i /* Which column to return */
153 stmt_cursor *pCur = (stmt_cursor*)cur;
154 switch( i ){
155 case STMT_COLUMN_SQL: {
156 sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
157 break;
159 case STMT_COLUMN_NCOL: {
160 sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
161 break;
163 case STMT_COLUMN_RO: {
164 sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
165 break;
167 case STMT_COLUMN_BUSY: {
168 sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
169 break;
171 case STMT_COLUMN_MEM: {
172 i = SQLITE_STMTSTATUS_MEMUSED +
173 STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
174 /* Fall thru */
176 case STMT_COLUMN_NSCAN:
177 case STMT_COLUMN_NSORT:
178 case STMT_COLUMN_NAIDX:
179 case STMT_COLUMN_NSTEP:
180 case STMT_COLUMN_REPREP:
181 case STMT_COLUMN_RUN: {
182 sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
183 i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
184 break;
187 return SQLITE_OK;
191 ** Return the rowid for the current row. In this implementation, the
192 ** rowid is the same as the output value.
194 static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
195 stmt_cursor *pCur = (stmt_cursor*)cur;
196 *pRowid = pCur->iRowid;
197 return SQLITE_OK;
201 ** Return TRUE if the cursor has been moved off of the last
202 ** row of output.
204 static int stmtEof(sqlite3_vtab_cursor *cur){
205 stmt_cursor *pCur = (stmt_cursor*)cur;
206 return pCur->pStmt==0;
210 ** This method is called to "rewind" the stmt_cursor object back
211 ** to the first row of output. This method is always called at least
212 ** once prior to any call to stmtColumn() or stmtRowid() or
213 ** stmtEof().
215 static int stmtFilter(
216 sqlite3_vtab_cursor *pVtabCursor,
217 int idxNum, const char *idxStr,
218 int argc, sqlite3_value **argv
220 stmt_cursor *pCur = (stmt_cursor *)pVtabCursor;
221 pCur->pStmt = 0;
222 pCur->iRowid = 0;
223 return stmtNext(pVtabCursor);
227 ** SQLite will invoke this method one or more times while planning a query
228 ** that uses the stmt virtual table. This routine needs to create
229 ** a query plan for each invocation and compute an estimated cost for that
230 ** plan.
232 static int stmtBestIndex(
233 sqlite3_vtab *tab,
234 sqlite3_index_info *pIdxInfo
236 pIdxInfo->estimatedCost = (double)500;
237 pIdxInfo->estimatedRows = 500;
238 return SQLITE_OK;
242 ** This following structure defines all the methods for the
243 ** stmt virtual table.
245 static sqlite3_module stmtModule = {
246 0, /* iVersion */
247 0, /* xCreate */
248 stmtConnect, /* xConnect */
249 stmtBestIndex, /* xBestIndex */
250 stmtDisconnect, /* xDisconnect */
251 0, /* xDestroy */
252 stmtOpen, /* xOpen - open a cursor */
253 stmtClose, /* xClose - close a cursor */
254 stmtFilter, /* xFilter - configure scan constraints */
255 stmtNext, /* xNext - advance a cursor */
256 stmtEof, /* xEof - check for end of scan */
257 stmtColumn, /* xColumn - read data */
258 stmtRowid, /* xRowid - read data */
259 0, /* xUpdate */
260 0, /* xBegin */
261 0, /* xSync */
262 0, /* xCommit */
263 0, /* xRollback */
264 0, /* xFindMethod */
265 0, /* xRename */
266 0, /* xSavepoint */
267 0, /* xRelease */
268 0, /* xRollbackTo */
271 #endif /* SQLITE_OMIT_VIRTUALTABLE */
273 int sqlite3StmtVtabInit(sqlite3 *db){
274 int rc = SQLITE_OK;
275 #ifndef SQLITE_OMIT_VIRTUALTABLE
276 rc = sqlite3_create_module(db, "sqlite_stmt", &stmtModule, 0);
277 #endif
278 return rc;
281 #ifndef SQLITE_CORE
282 #ifdef _WIN32
283 __declspec(dllexport)
284 #endif
285 int sqlite3_stmt_init(
286 sqlite3 *db,
287 char **pzErrMsg,
288 const sqlite3_api_routines *pApi
290 int rc = SQLITE_OK;
291 SQLITE_EXTENSION_INIT2(pApi);
292 #ifndef SQLITE_OMIT_VIRTUALTABLE
293 rc = sqlite3StmtVtabInit(db);
294 #endif
295 return rc;
297 #endif /* SQLITE_CORE */
298 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */