4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
21 ** SELECT * FROM stmt;
23 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB)
24 #if !defined(SQLITEINT_H)
25 #include "sqlite3ext.h"
27 SQLITE_EXTENSION_INIT1
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
;
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
;
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(
70 int argc
, const char *const*argv
,
71 sqlite3_vtab
**ppVtab
,
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,"
95 pNew
= sqlite3_malloc( sizeof(*pNew
) );
96 *ppVtab
= (sqlite3_vtab
*)pNew
;
97 if( pNew
==0 ) return SQLITE_NOMEM
;
98 memset(pNew
, 0, sizeof(*pNew
));
105 ** This method is the destructor for stmt_cursor objects.
107 static int stmtDisconnect(sqlite3_vtab
*pVtab
){
113 ** Constructor for a new stmt_cursor object.
115 static int stmtOpen(sqlite3_vtab
*p
, sqlite3_vtab_cursor
**ppCursor
){
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
;
126 ** Destructor for a stmt_cursor.
128 static int stmtClose(sqlite3_vtab_cursor
*cur
){
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
;
140 pCur
->pStmt
= sqlite3_next_stmt(pCur
->db
, pCur
->pStmt
);
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
;
155 case STMT_COLUMN_SQL
: {
156 sqlite3_result_text(ctx
, sqlite3_sql(pCur
->pStmt
), -1, SQLITE_TRANSIENT
);
159 case STMT_COLUMN_NCOL
: {
160 sqlite3_result_int(ctx
, sqlite3_column_count(pCur
->pStmt
));
163 case STMT_COLUMN_RO
: {
164 sqlite3_result_int(ctx
, sqlite3_stmt_readonly(pCur
->pStmt
));
167 case STMT_COLUMN_BUSY
: {
168 sqlite3_result_int(ctx
, sqlite3_stmt_busy(pCur
->pStmt
));
171 case STMT_COLUMN_MEM
: {
172 i
= SQLITE_STMTSTATUS_MEMUSED
+
173 STMT_COLUMN_NSCAN
- SQLITE_STMTSTATUS_FULLSCAN_STEP
;
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));
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
;
201 ** Return TRUE if the cursor has been moved off of the last
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
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
;
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
232 static int stmtBestIndex(
234 sqlite3_index_info
*pIdxInfo
236 pIdxInfo
->estimatedCost
= (double)500;
237 pIdxInfo
->estimatedRows
= 500;
242 ** This following structure defines all the methods for the
243 ** stmt virtual table.
245 static sqlite3_module stmtModule
= {
248 stmtConnect
, /* xConnect */
249 stmtBestIndex
, /* xBestIndex */
250 stmtDisconnect
, /* xDisconnect */
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 */
271 #endif /* SQLITE_OMIT_VIRTUALTABLE */
273 int sqlite3StmtVtabInit(sqlite3
*db
){
275 #ifndef SQLITE_OMIT_VIRTUALTABLE
276 rc
= sqlite3_create_module(db
, "sqlite_stmt", &stmtModule
, 0);
283 __declspec(dllexport
)
285 int sqlite3_stmt_init(
288 const sqlite3_api_routines
*pApi
291 SQLITE_EXTENSION_INIT2(pApi
);
292 #ifndef SQLITE_OMIT_VIRTUALTABLE
293 rc
= sqlite3StmtVtabInit(db
);
297 #endif /* SQLITE_CORE */
298 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */