xref: /sqlite-3.40.0/src/vdbevtab.c (revision a8e41eca)
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.
10 **
11 *************************************************************************
12 **
13 ** This file implements virtual-tables for examining the bytecode content
14 ** of a prepared statement.
15 */
16 #ifdef SQLITE_ENABLE_BYTECODE_VTAB
17 #include "sqliteInt.h"
18 #include "vdbeInt.h"
19 
20 /* An instance of the bytecode() table-valued function.
21 */
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(). */
27 };
28 
29 /* A cursor for scanning through the bytecode
30 */
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 */
45 };
46 
47 /*
48 ** Create a new bytecode() table-valued function.
49 */
50 static int bytecodevtabConnect(
51   sqlite3 *db,
52   void *pAux,
53   int argc, const char *const*argv,
54   sqlite3_vtab **ppVtab,
55   char **pzErr
56 ){
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       "stmt HIDDEN"
73     ");",
74 
75     /* Tables_used() schema */
76     "CREATE TABLE x("
77       "type TEXT,"
78       "schema TEXT,"
79       "name TEXT,"
80       "wr INT,"
81       "subprog TEXT,"
82       "stmt HIDDEN"
83    ");"
84   };
85 
86   rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
87   if( rc==SQLITE_OK ){
88     pNew = sqlite3_malloc( sizeof(*pNew) );
89     *ppVtab = (sqlite3_vtab*)pNew;
90     if( pNew==0 ) return SQLITE_NOMEM;
91     memset(pNew, 0, sizeof(*pNew));
92     pNew->db = db;
93     pNew->bTablesUsed = isTabUsed*2;
94   }
95   return rc;
96 }
97 
98 /*
99 ** This method is the destructor for bytecodevtab objects.
100 */
101 static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
102   bytecodevtab *p = (bytecodevtab*)pVtab;
103   sqlite3_free(p);
104   return SQLITE_OK;
105 }
106 
107 /*
108 ** Constructor for a new bytecodevtab_cursor object.
109 */
110 static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
111   bytecodevtab *pVTab = (bytecodevtab*)p;
112   bytecodevtab_cursor *pCur;
113   pCur = sqlite3_malloc( sizeof(*pCur) );
114   if( pCur==0 ) return SQLITE_NOMEM;
115   memset(pCur, 0, sizeof(*pCur));
116   sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
117   *ppCursor = &pCur->base;
118   return SQLITE_OK;
119 }
120 
121 /*
122 ** Clear all internal content from a bytecodevtab cursor.
123 */
124 static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
125   sqlite3_free(pCur->zP4);
126   pCur->zP4 = 0;
127   sqlite3VdbeMemRelease(&pCur->sub);
128   sqlite3VdbeMemSetNull(&pCur->sub);
129   if( pCur->needFinalize ){
130     sqlite3_finalize(pCur->pStmt);
131   }
132   pCur->pStmt = 0;
133   pCur->needFinalize = 0;
134   pCur->zType = 0;
135   pCur->zSchema = 0;
136   pCur->zName = 0;
137 }
138 
139 /*
140 ** Destructor for a bytecodevtab_cursor.
141 */
142 static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
143   bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
144   bytecodevtabCursorClear(pCur);
145   sqlite3_free(pCur);
146   return SQLITE_OK;
147 }
148 
149 
150 /*
151 ** Advance a bytecodevtab_cursor to its next row of output.
152 */
153 static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
154   bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
155   bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
156   int rc;
157   if( pCur->zP4 ){
158     sqlite3_free(pCur->zP4);
159     pCur->zP4 = 0;
160   }
161   if( pCur->zName ){
162     pCur->zName = 0;
163     pCur->zType = 0;
164     pCur->zSchema = 0;
165   }
166   rc = sqlite3VdbeNextOpcode(
167            (Vdbe*)pCur->pStmt,
168            pCur->showSubprograms ? &pCur->sub : 0,
169            pTab->bTablesUsed,
170            &pCur->iRowid,
171            &pCur->iAddr,
172            &pCur->aOp);
173   if( rc!=SQLITE_OK ){
174     sqlite3VdbeMemSetNull(&pCur->sub);
175     pCur->aOp = 0;
176   }
177   return SQLITE_OK;
178 }
179 
180 /*
181 ** Return TRUE if the cursor has been moved off of the last
182 ** row of output.
183 */
184 static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
185   bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
186   return pCur->aOp==0;
187 }
188 
189 /*
190 ** Return values of columns for the row at which the bytecodevtab_cursor
191 ** is currently pointing.
192 */
193 static int bytecodevtabColumn(
194   sqlite3_vtab_cursor *cur,   /* The cursor */
195   sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
196   int i                       /* Which column to return */
197 ){
198   bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
199   bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
200   Op *pOp = pCur->aOp + pCur->iAddr;
201   if( pVTab->bTablesUsed ){
202     if( i==4 ){
203       i = 8;
204     }else{
205       if( i<=2 && pCur->zType==0 ){
206         Schema *pSchema;
207         HashElem *k;
208         int iDb = pOp->p3;
209         int iRoot = pOp->p2;
210         sqlite3 *db = pVTab->db;
211         pSchema = db->aDb[iDb].pSchema;
212         pCur->zSchema = db->aDb[iDb].zDbSName;
213         for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
214           Table *pTab = (Table*)sqliteHashData(k);
215           if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
216             pCur->zName = pTab->zName;
217             pCur->zType = "table";
218             break;
219           }
220         }
221         if( pCur->zName==0 ){
222           for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
223             Index *pIdx = (Index*)sqliteHashData(k);
224             if( pIdx->tnum==iRoot ){
225               pCur->zName = pIdx->zName;
226               pCur->zType = "index";
227             }
228           }
229         }
230       }
231       i += 10;
232     }
233   }
234   switch( i ){
235     case 0:   /* addr */
236       sqlite3_result_int(ctx, pCur->iAddr);
237       break;
238     case 1:   /* opcode */
239       sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
240                           -1, SQLITE_STATIC);
241       break;
242     case 2:   /* p1 */
243       sqlite3_result_int(ctx, pOp->p1);
244       break;
245     case 3:   /* p2 */
246       sqlite3_result_int(ctx, pOp->p2);
247       break;
248     case 4:   /* p3 */
249       sqlite3_result_int(ctx, pOp->p3);
250       break;
251     case 5:   /* p4 */
252     case 7:   /* comment */
253       if( pCur->zP4==0 ){
254         pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
255       }
256       if( i==5 ){
257         sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
258       }else{
259 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
260         char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
261         sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
262 #endif
263       }
264       break;
265     case 6:     /* p5 */
266       sqlite3_result_int(ctx, pOp->p5);
267       break;
268     case 8: {   /* subprog */
269       Op *aOp = pCur->aOp;
270       assert( aOp[0].opcode==OP_Init );
271       assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
272       if( pCur->iRowid==pCur->iAddr+1 ){
273         break;  /* Result is NULL for the main program */
274       }else if( aOp[0].p4.z!=0 ){
275          sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
276       }else{
277          sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
278       }
279       break;
280     }
281     case 10:  /* tables_used.type */
282       sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
283       break;
284     case 11:  /* tables_used.schema */
285       sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
286       break;
287     case 12:  /* tables_used.name */
288       sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
289       break;
290     case 13:  /* tables_used.wr */
291       sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
292       break;
293   }
294   return SQLITE_OK;
295 }
296 
297 /*
298 ** Return the rowid for the current row.  In this implementation, the
299 ** rowid is the same as the output value.
300 */
301 static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
302   bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
303   *pRowid = pCur->iRowid;
304   return SQLITE_OK;
305 }
306 
307 /*
308 ** Initialize a cursor.
309 **
310 **    idxNum==0     means show all subprograms
311 **    idxNum==1     means show only the main bytecode and omit subprograms.
312 */
313 static int bytecodevtabFilter(
314   sqlite3_vtab_cursor *pVtabCursor,
315   int idxNum, const char *idxStr,
316   int argc, sqlite3_value **argv
317 ){
318   bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
319   bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
320   int rc = SQLITE_OK;
321 
322   bytecodevtabCursorClear(pCur);
323   pCur->iRowid = 0;
324   pCur->iAddr = 0;
325   pCur->showSubprograms = idxNum==0;
326   assert( argc==1 );
327   if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
328     const char *zSql = (const char*)sqlite3_value_text(argv[0]);
329     if( zSql==0 ){
330       rc = SQLITE_NOMEM;
331     }else{
332       rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
333       pCur->needFinalize = 1;
334     }
335   }else{
336     pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
337   }
338   if( pCur->pStmt==0 ){
339     pVTab->base.zErrMsg = sqlite3_mprintf(
340        "argument to %s() is not a valid SQL statement",
341        pVTab->bTablesUsed ? "tables_used" : "bytecode"
342     );
343     rc = SQLITE_ERROR;
344   }else{
345     bytecodevtabNext(pVtabCursor);
346   }
347   return rc;
348 }
349 
350 /*
351 ** We must have a single stmt=? constraint that will be passed through
352 ** into the xFilter method.  If there is no valid stmt=? constraint,
353 ** then return an SQLITE_CONSTRAINT error.
354 */
355 static int bytecodevtabBestIndex(
356   sqlite3_vtab *tab,
357   sqlite3_index_info *pIdxInfo
358 ){
359   int i;
360   int rc = SQLITE_CONSTRAINT;
361   struct sqlite3_index_constraint *p;
362   bytecodevtab *pVTab = (bytecodevtab*)tab;
363   int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
364   pIdxInfo->estimatedCost = (double)100;
365   pIdxInfo->estimatedRows = 100;
366   pIdxInfo->idxNum = 0;
367   for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
368     if( p->usable==0 ) continue;
369     if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
370       rc = SQLITE_OK;
371       pIdxInfo->aConstraintUsage[i].omit = 1;
372       pIdxInfo->aConstraintUsage[i].argvIndex = 1;
373     }
374     if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
375       pIdxInfo->aConstraintUsage[i].omit = 1;
376       pIdxInfo->idxNum = 1;
377     }
378   }
379   return rc;
380 }
381 
382 /*
383 ** This following structure defines all the methods for the
384 ** virtual table.
385 */
386 static sqlite3_module bytecodevtabModule = {
387   /* iVersion    */ 0,
388   /* xCreate     */ 0,
389   /* xConnect    */ bytecodevtabConnect,
390   /* xBestIndex  */ bytecodevtabBestIndex,
391   /* xDisconnect */ bytecodevtabDisconnect,
392   /* xDestroy    */ 0,
393   /* xOpen       */ bytecodevtabOpen,
394   /* xClose      */ bytecodevtabClose,
395   /* xFilter     */ bytecodevtabFilter,
396   /* xNext       */ bytecodevtabNext,
397   /* xEof        */ bytecodevtabEof,
398   /* xColumn     */ bytecodevtabColumn,
399   /* xRowid      */ bytecodevtabRowid,
400   /* xUpdate     */ 0,
401   /* xBegin      */ 0,
402   /* xSync       */ 0,
403   /* xCommit     */ 0,
404   /* xRollback   */ 0,
405   /* xFindMethod */ 0,
406   /* xRename     */ 0,
407   /* xSavepoint  */ 0,
408   /* xRelease    */ 0,
409   /* xRollbackTo */ 0,
410   /* xShadowName */ 0
411 };
412 
413 
414 int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
415   int rc;
416   rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
417   if( rc==SQLITE_OK ){
418     rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
419   }
420   return rc;
421 }
422 #endif /* SQLITE_ENABLE_BYTECODE_VTAB */
423