Fix a problem causing the recovery extension to use excessive memory and CPU time...
[sqlite.git] / src / vdbevtab.c
blob1c9909a1aa98357c7c471e03a8bd5bfa81e00422
1 /*
2 ** 2020-03-23
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 implements virtual-tables for examining the bytecode content
14 ** of a prepared statement.
16 #include "sqliteInt.h"
17 #if defined(SQLITE_ENABLE_BYTECODE_VTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
18 #include "vdbeInt.h"
20 /* An instance of the bytecode() table-valued function.
22 typedef struct bytecodevtab bytecodevtab;
23 struct bytecodevtab {
24 sqlite3_vtab base; /* Base class - must be first */
25 sqlite3 *db; /* Database connection */
26 int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */
29 /* A cursor for scanning through the bytecode
31 typedef struct bytecodevtab_cursor bytecodevtab_cursor;
32 struct bytecodevtab_cursor {
33 sqlite3_vtab_cursor base; /* Base class - must be first */
34 sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */
35 int iRowid; /* The rowid of the output table */
36 int iAddr; /* Address */
37 int needFinalize; /* Cursors owns pStmt and must finalize it */
38 int showSubprograms; /* Provide a listing of subprograms */
39 Op *aOp; /* Operand array */
40 char *zP4; /* Rendered P4 value */
41 const char *zType; /* tables_used.type */
42 const char *zSchema; /* tables_used.schema */
43 const char *zName; /* tables_used.name */
44 Mem sub; /* Subprograms */
48 ** Create a new bytecode() table-valued function.
50 static int bytecodevtabConnect(
51 sqlite3 *db,
52 void *pAux,
53 int argc, const char *const*argv,
54 sqlite3_vtab **ppVtab,
55 char **pzErr
57 bytecodevtab *pNew;
58 int rc;
59 int isTabUsed = pAux!=0;
60 const char *azSchema[2] = {
61 /* bytecode() schema */
62 "CREATE TABLE x("
63 "addr INT,"
64 "opcode TEXT,"
65 "p1 INT,"
66 "p2 INT,"
67 "p3 INT,"
68 "p4 TEXT,"
69 "p5 INT,"
70 "comment TEXT,"
71 "subprog TEXT,"
72 "nexec INT,"
73 "ncycle INT,"
74 "stmt HIDDEN"
75 ");",
77 /* Tables_used() schema */
78 "CREATE TABLE x("
79 "type TEXT,"
80 "schema TEXT,"
81 "name TEXT,"
82 "wr INT,"
83 "subprog TEXT,"
84 "stmt HIDDEN"
85 ");"
88 (void)argc;
89 (void)argv;
90 (void)pzErr;
91 rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
92 if( rc==SQLITE_OK ){
93 pNew = sqlite3_malloc( sizeof(*pNew) );
94 *ppVtab = (sqlite3_vtab*)pNew;
95 if( pNew==0 ) return SQLITE_NOMEM;
96 memset(pNew, 0, sizeof(*pNew));
97 pNew->db = db;
98 pNew->bTablesUsed = isTabUsed*2;
100 return rc;
104 ** This method is the destructor for bytecodevtab objects.
106 static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
107 bytecodevtab *p = (bytecodevtab*)pVtab;
108 sqlite3_free(p);
109 return SQLITE_OK;
113 ** Constructor for a new bytecodevtab_cursor object.
115 static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
116 bytecodevtab *pVTab = (bytecodevtab*)p;
117 bytecodevtab_cursor *pCur;
118 pCur = sqlite3_malloc( sizeof(*pCur) );
119 if( pCur==0 ) return SQLITE_NOMEM;
120 memset(pCur, 0, sizeof(*pCur));
121 sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
122 *ppCursor = &pCur->base;
123 return SQLITE_OK;
127 ** Clear all internal content from a bytecodevtab cursor.
129 static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
130 sqlite3_free(pCur->zP4);
131 pCur->zP4 = 0;
132 sqlite3VdbeMemRelease(&pCur->sub);
133 sqlite3VdbeMemSetNull(&pCur->sub);
134 if( pCur->needFinalize ){
135 sqlite3_finalize(pCur->pStmt);
137 pCur->pStmt = 0;
138 pCur->needFinalize = 0;
139 pCur->zType = 0;
140 pCur->zSchema = 0;
141 pCur->zName = 0;
145 ** Destructor for a bytecodevtab_cursor.
147 static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
148 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
149 bytecodevtabCursorClear(pCur);
150 sqlite3_free(pCur);
151 return SQLITE_OK;
156 ** Advance a bytecodevtab_cursor to its next row of output.
158 static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
159 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
160 bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
161 int rc;
162 if( pCur->zP4 ){
163 sqlite3_free(pCur->zP4);
164 pCur->zP4 = 0;
166 if( pCur->zName ){
167 pCur->zName = 0;
168 pCur->zType = 0;
169 pCur->zSchema = 0;
171 rc = sqlite3VdbeNextOpcode(
172 (Vdbe*)pCur->pStmt,
173 pCur->showSubprograms ? &pCur->sub : 0,
174 pTab->bTablesUsed,
175 &pCur->iRowid,
176 &pCur->iAddr,
177 &pCur->aOp);
178 if( rc!=SQLITE_OK ){
179 sqlite3VdbeMemSetNull(&pCur->sub);
180 pCur->aOp = 0;
182 return SQLITE_OK;
186 ** Return TRUE if the cursor has been moved off of the last
187 ** row of output.
189 static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
190 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
191 return pCur->aOp==0;
195 ** Return values of columns for the row at which the bytecodevtab_cursor
196 ** is currently pointing.
198 static int bytecodevtabColumn(
199 sqlite3_vtab_cursor *cur, /* The cursor */
200 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
201 int i /* Which column to return */
203 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
204 bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
205 Op *pOp = pCur->aOp + pCur->iAddr;
206 if( pVTab->bTablesUsed ){
207 if( i==4 ){
208 i = 8;
209 }else{
210 if( i<=2 && pCur->zType==0 ){
211 Schema *pSchema;
212 HashElem *k;
213 int iDb = pOp->p3;
214 Pgno iRoot = (Pgno)pOp->p2;
215 sqlite3 *db = pVTab->db;
216 pSchema = db->aDb[iDb].pSchema;
217 pCur->zSchema = db->aDb[iDb].zDbSName;
218 for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
219 Table *pTab = (Table*)sqliteHashData(k);
220 if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
221 pCur->zName = pTab->zName;
222 pCur->zType = "table";
223 break;
226 if( pCur->zName==0 ){
227 for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
228 Index *pIdx = (Index*)sqliteHashData(k);
229 if( pIdx->tnum==iRoot ){
230 pCur->zName = pIdx->zName;
231 pCur->zType = "index";
236 i += 20;
239 switch( i ){
240 case 0: /* addr */
241 sqlite3_result_int(ctx, pCur->iAddr);
242 break;
243 case 1: /* opcode */
244 sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
245 -1, SQLITE_STATIC);
246 break;
247 case 2: /* p1 */
248 sqlite3_result_int(ctx, pOp->p1);
249 break;
250 case 3: /* p2 */
251 sqlite3_result_int(ctx, pOp->p2);
252 break;
253 case 4: /* p3 */
254 sqlite3_result_int(ctx, pOp->p3);
255 break;
256 case 5: /* p4 */
257 case 7: /* comment */
258 if( pCur->zP4==0 ){
259 pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
261 if( i==5 ){
262 sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
263 }else{
264 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
265 char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
266 sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
267 #endif
269 break;
270 case 6: /* p5 */
271 sqlite3_result_int(ctx, pOp->p5);
272 break;
273 case 8: { /* subprog */
274 Op *aOp = pCur->aOp;
275 assert( aOp[0].opcode==OP_Init );
276 assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
277 if( pCur->iRowid==pCur->iAddr+1 ){
278 break; /* Result is NULL for the main program */
279 }else if( aOp[0].p4.z!=0 ){
280 sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
281 }else{
282 sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
284 break;
287 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
288 case 9: /* nexec */
289 sqlite3_result_int64(ctx, pOp->nExec);
290 break;
291 case 10: /* ncycle */
292 sqlite3_result_int64(ctx, pOp->nCycle);
293 break;
294 #else
295 case 9: /* nexec */
296 case 10: /* ncycle */
297 sqlite3_result_int(ctx, 0);
298 break;
299 #endif
301 case 20: /* tables_used.type */
302 sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
303 break;
304 case 21: /* tables_used.schema */
305 sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
306 break;
307 case 22: /* tables_used.name */
308 sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
309 break;
310 case 23: /* tables_used.wr */
311 sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
312 break;
314 return SQLITE_OK;
318 ** Return the rowid for the current row. In this implementation, the
319 ** rowid is the same as the output value.
321 static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
322 bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
323 *pRowid = pCur->iRowid;
324 return SQLITE_OK;
328 ** Initialize a cursor.
330 ** idxNum==0 means show all subprograms
331 ** idxNum==1 means show only the main bytecode and omit subprograms.
333 static int bytecodevtabFilter(
334 sqlite3_vtab_cursor *pVtabCursor,
335 int idxNum, const char *idxStr,
336 int argc, sqlite3_value **argv
338 bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
339 bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
340 int rc = SQLITE_OK;
341 (void)idxStr;
343 bytecodevtabCursorClear(pCur);
344 pCur->iRowid = 0;
345 pCur->iAddr = 0;
346 pCur->showSubprograms = idxNum==0;
347 assert( argc==1 );
348 if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
349 const char *zSql = (const char*)sqlite3_value_text(argv[0]);
350 if( zSql==0 ){
351 rc = SQLITE_NOMEM;
352 }else{
353 rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
354 pCur->needFinalize = 1;
356 }else{
357 pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
359 if( pCur->pStmt==0 ){
360 pVTab->base.zErrMsg = sqlite3_mprintf(
361 "argument to %s() is not a valid SQL statement",
362 pVTab->bTablesUsed ? "tables_used" : "bytecode"
364 rc = SQLITE_ERROR;
365 }else{
366 bytecodevtabNext(pVtabCursor);
368 return rc;
372 ** We must have a single stmt=? constraint that will be passed through
373 ** into the xFilter method. If there is no valid stmt=? constraint,
374 ** then return an SQLITE_CONSTRAINT error.
376 static int bytecodevtabBestIndex(
377 sqlite3_vtab *tab,
378 sqlite3_index_info *pIdxInfo
380 int i;
381 int rc = SQLITE_CONSTRAINT;
382 struct sqlite3_index_constraint *p;
383 bytecodevtab *pVTab = (bytecodevtab*)tab;
384 int iBaseCol = pVTab->bTablesUsed ? 4 : 10;
385 pIdxInfo->estimatedCost = (double)100;
386 pIdxInfo->estimatedRows = 100;
387 pIdxInfo->idxNum = 0;
388 for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
389 if( p->usable==0 ) continue;
390 if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
391 rc = SQLITE_OK;
392 pIdxInfo->aConstraintUsage[i].omit = 1;
393 pIdxInfo->aConstraintUsage[i].argvIndex = 1;
395 if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
396 pIdxInfo->aConstraintUsage[i].omit = 1;
397 pIdxInfo->idxNum = 1;
400 return rc;
404 ** This following structure defines all the methods for the
405 ** virtual table.
407 static sqlite3_module bytecodevtabModule = {
408 /* iVersion */ 0,
409 /* xCreate */ 0,
410 /* xConnect */ bytecodevtabConnect,
411 /* xBestIndex */ bytecodevtabBestIndex,
412 /* xDisconnect */ bytecodevtabDisconnect,
413 /* xDestroy */ 0,
414 /* xOpen */ bytecodevtabOpen,
415 /* xClose */ bytecodevtabClose,
416 /* xFilter */ bytecodevtabFilter,
417 /* xNext */ bytecodevtabNext,
418 /* xEof */ bytecodevtabEof,
419 /* xColumn */ bytecodevtabColumn,
420 /* xRowid */ bytecodevtabRowid,
421 /* xUpdate */ 0,
422 /* xBegin */ 0,
423 /* xSync */ 0,
424 /* xCommit */ 0,
425 /* xRollback */ 0,
426 /* xFindMethod */ 0,
427 /* xRename */ 0,
428 /* xSavepoint */ 0,
429 /* xRelease */ 0,
430 /* xRollbackTo */ 0,
431 /* xShadowName */ 0,
432 /* xIntegrity */ 0
436 int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
437 int rc;
438 rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
439 if( rc==SQLITE_OK ){
440 rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
442 return rc;
444 #elif defined(SQLITE_ENABLE_BYTECODE_VTAB)
445 int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
446 #endif /* SQLITE_ENABLE_BYTECODE_VTAB */