1 /*
2 ** 2019-04-17
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 contains an implementation of two eponymous virtual tables,
14 ** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
15 ** "sqlite_dbpage" eponymous virtual table be available.
16 **
17 ** SQLITE_DBDATA:
18 **   sqlite_dbdata is used to extract data directly from a database b-tree
19 **   page and its associated overflow pages, bypassing the b-tree layer.
20 **   The table schema is equivalent to:
21 **
22 **     CREATE TABLE sqlite_dbdata(
23 **       pgno INTEGER,
24 **       cell INTEGER,
25 **       field INTEGER,
26 **       value ANY,
27 **       schema TEXT HIDDEN
28 **     );
29 **
30 **   IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
31 **   FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
32 **   "schema".
33 **
34 **   Each page of the database is inspected. If it cannot be interpreted as
35 **   a b-tree page, or if it is a b-tree page containing 0 entries, the
36 **   sqlite_dbdata table contains no rows for that page.  Otherwise, the
37 **   table contains one row for each field in the record associated with
38 **   each cell on the page. For intkey b-trees, the key value is stored in
39 **   field -1.
40 **
41 **   For example, for the database:
42 **
43 **     CREATE TABLE t1(a, b);     -- root page is page 2
44 **     INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
45 **     INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
46 **
47 **   the sqlite_dbdata table contains, as well as from entries related to
48 **   page 1, content equivalent to:
49 **
50 **     INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
51 **         (2, 0, -1, 5     ),
52 **         (2, 0,  0, 'v'   ),
53 **         (2, 0,  1, 'five'),
54 **         (2, 1, -1, 10    ),
55 **         (2, 1,  0, 'x'   ),
56 **         (2, 1,  1, 'ten' );
57 **
58 **   If database corruption is encountered, this module does not report an
59 **   error. Instead, it attempts to extract as much data as possible and
60 **   ignores the corruption.
61 **
62 ** SQLITE_DBPTR:
63 **   The sqlite_dbptr table has the following schema:
64 **
65 **     CREATE TABLE sqlite_dbptr(
66 **       pgno INTEGER,
67 **       child INTEGER,
68 **       schema TEXT HIDDEN
69 **     );
70 **
71 **   It contains one entry for each b-tree pointer between a parent and
72 **   child page in the database.
73 */
74 #if !defined(SQLITEINT_H)
75 #include "sqlite3ext.h"
76 
77 typedef unsigned char u8;
78 
79 #endif
80 SQLITE_EXTENSION_INIT1
81 #include <string.h>
82 #include <assert.h>
83 
84 #define DBDATA_PADDING_BYTES 100
85 
86 typedef struct DbdataTable DbdataTable;
87 typedef struct DbdataCursor DbdataCursor;
88 
89 /* Cursor object */
90 struct DbdataCursor {
91   sqlite3_vtab_cursor base;       /* Base class.  Must be first */
92   sqlite3_stmt *pStmt;            /* For fetching database pages */
93 
94   int iPgno;                      /* Current page number */
95   u8 *aPage;                      /* Buffer containing page */
96   int nPage;                      /* Size of aPage[] in bytes */
97   int nCell;                      /* Number of cells on aPage[] */
98   int iCell;                      /* Current cell number */
99   int bOnePage;                   /* True to stop after one page */
100   int szDb;
101   sqlite3_int64 iRowid;
102 
103   /* Only for the sqlite_dbdata table */
104   u8 *pRec;                       /* Buffer containing current record */
105   int nRec;                       /* Size of pRec[] in bytes */
106   int nHdr;                       /* Size of header in bytes */
107   int iField;                     /* Current field number */
108   u8 *pHdrPtr;
109   u8 *pPtr;
110 
111   sqlite3_int64 iIntkey;          /* Integer key value */
112 };
113 
114 /* Table object */
115 struct DbdataTable {
116   sqlite3_vtab base;              /* Base class.  Must be first */
117   sqlite3 *db;                    /* The database connection */
118   sqlite3_stmt *pStmt;            /* For fetching database pages */
119   int bPtr;                       /* True for sqlite3_dbptr table */
120 };
121 
122 /* Column and schema definitions for sqlite_dbdata */
123 #define DBDATA_COLUMN_PGNO        0
124 #define DBDATA_COLUMN_CELL        1
125 #define DBDATA_COLUMN_FIELD       2
126 #define DBDATA_COLUMN_VALUE       3
127 #define DBDATA_COLUMN_SCHEMA      4
128 #define DBDATA_SCHEMA             \
129       "CREATE TABLE x("           \
130       "  pgno INTEGER,"           \
131       "  cell INTEGER,"           \
132       "  field INTEGER,"          \
133       "  value ANY,"              \
134       "  schema TEXT HIDDEN"      \
135       ")"
136 
137 /* Column and schema definitions for sqlite_dbptr */
138 #define DBPTR_COLUMN_PGNO         0
139 #define DBPTR_COLUMN_CHILD        1
140 #define DBPTR_COLUMN_SCHEMA       2
141 #define DBPTR_SCHEMA              \
142       "CREATE TABLE x("           \
143       "  pgno INTEGER,"           \
144       "  child INTEGER,"          \
145       "  schema TEXT HIDDEN"      \
146       ")"
147 
148 /*
149 ** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual
150 ** table.
151 */
dbdataConnect(sqlite3 * db,void * pAux,int argc,const char * const * argv,sqlite3_vtab ** ppVtab,char ** pzErr)152 static int dbdataConnect(
153   sqlite3 *db,
154   void *pAux,
155   int argc, const char *const*argv,
156   sqlite3_vtab **ppVtab,
157   char **pzErr
158 ){
159   DbdataTable *pTab = 0;
160   int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
161 
162   if( rc==SQLITE_OK ){
163     pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
164     if( pTab==0 ){
165       rc = SQLITE_NOMEM;
166     }else{
167       memset(pTab, 0, sizeof(DbdataTable));
168       pTab->db = db;
169       pTab->bPtr = (pAux!=0);
170     }
171   }
172 
173   *ppVtab = (sqlite3_vtab*)pTab;
174   return rc;
175 }
176 
177 /*
178 ** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
179 */
dbdataDisconnect(sqlite3_vtab * pVtab)180 static int dbdataDisconnect(sqlite3_vtab *pVtab){
181   DbdataTable *pTab = (DbdataTable*)pVtab;
182   if( pTab ){
183     sqlite3_finalize(pTab->pStmt);
184     sqlite3_free(pVtab);
185   }
186   return SQLITE_OK;
187 }
188 
189 /*
190 ** This function interprets two types of constraints:
191 **
192 **       schema=?
193 **       pgno=?
194 **
195 ** If neither are present, idxNum is set to 0. If schema=? is present,
196 ** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
197 ** in idxNum is set.
198 **
199 ** If both parameters are present, schema is in position 0 and pgno in
200 ** position 1.
201 */
dbdataBestIndex(sqlite3_vtab * tab,sqlite3_index_info * pIdx)202 static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
203   DbdataTable *pTab = (DbdataTable*)tab;
204   int i;
205   int iSchema = -1;
206   int iPgno = -1;
207   int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
208 
209   for(i=0; i<pIdx->nConstraint; i++){
210     struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
211     if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
212       if( p->iColumn==colSchema ){
213         if( p->usable==0 ) return SQLITE_CONSTRAINT;
214         iSchema = i;
215       }
216       if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
217         iPgno = i;
218       }
219     }
220   }
221 
222   if( iSchema>=0 ){
223     pIdx->aConstraintUsage[iSchema].argvIndex = 1;
224     pIdx->aConstraintUsage[iSchema].omit = 1;
225   }
226   if( iPgno>=0 ){
227     pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
228     pIdx->aConstraintUsage[iPgno].omit = 1;
229     pIdx->estimatedCost = 100;
230     pIdx->estimatedRows =  50;
231 
232     if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
233       int iCol = pIdx->aOrderBy[0].iColumn;
234       if( pIdx->nOrderBy==1 ){
235         pIdx->orderByConsumed = (iCol==0 || iCol==1);
236       }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
237         pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
238       }
239     }
240 
241   }else{
242     pIdx->estimatedCost = 100000000;
243     pIdx->estimatedRows = 1000000000;
244   }
245   pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
246   return SQLITE_OK;
247 }
248 
249 /*
250 ** Open a new sqlite_dbdata or sqlite_dbptr cursor.
251 */
dbdataOpen(sqlite3_vtab * pVTab,sqlite3_vtab_cursor ** ppCursor)252 static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
253   DbdataCursor *pCsr;
254 
255   pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
256   if( pCsr==0 ){
257     return SQLITE_NOMEM;
258   }else{
259     memset(pCsr, 0, sizeof(DbdataCursor));
260     pCsr->base.pVtab = pVTab;
261   }
262 
263   *ppCursor = (sqlite3_vtab_cursor *)pCsr;
264   return SQLITE_OK;
265 }
266 
267 /*
268 ** Restore a cursor object to the state it was in when first allocated
269 ** by dbdataOpen().
270 */
dbdataResetCursor(DbdataCursor * pCsr)271 static void dbdataResetCursor(DbdataCursor *pCsr){
272   DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
273   if( pTab->pStmt==0 ){
274     pTab->pStmt = pCsr->pStmt;
275   }else{
276     sqlite3_finalize(pCsr->pStmt);
277   }
278   pCsr->pStmt = 0;
279   pCsr->iPgno = 1;
280   pCsr->iCell = 0;
281   pCsr->iField = 0;
282   pCsr->bOnePage = 0;
283   sqlite3_free(pCsr->aPage);
284   sqlite3_free(pCsr->pRec);
285   pCsr->pRec = 0;
286   pCsr->aPage = 0;
287 }
288 
289 /*
290 ** Close an sqlite_dbdata or sqlite_dbptr cursor.
291 */
dbdataClose(sqlite3_vtab_cursor * pCursor)292 static int dbdataClose(sqlite3_vtab_cursor *pCursor){
293   DbdataCursor *pCsr = (DbdataCursor*)pCursor;
294   dbdataResetCursor(pCsr);
295   sqlite3_free(pCsr);
296   return SQLITE_OK;
297 }
298 
299 /*
300 ** Utility methods to decode 16 and 32-bit big-endian unsigned integers.
301 */
get_uint16(unsigned char * a)302 static unsigned int get_uint16(unsigned char *a){
303   return (a[0]<<8)|a[1];
304 }
get_uint32(unsigned char * a)305 static unsigned int get_uint32(unsigned char *a){
306   return ((unsigned int)a[0]<<24)
307        | ((unsigned int)a[1]<<16)
308        | ((unsigned int)a[2]<<8)
309        | ((unsigned int)a[3]);
310 }
311 
312 /*
313 ** Load page pgno from the database via the sqlite_dbpage virtual table.
314 ** If successful, set (*ppPage) to point to a buffer containing the page
315 ** data, (*pnPage) to the size of that buffer in bytes and return
316 ** SQLITE_OK. In this case it is the responsibility of the caller to
317 ** eventually free the buffer using sqlite3_free().
318 **
319 ** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
320 ** return an SQLite error code.
321 */
dbdataLoadPage(DbdataCursor * pCsr,unsigned int pgno,u8 ** ppPage,int * pnPage)322 static int dbdataLoadPage(
323   DbdataCursor *pCsr,             /* Cursor object */
324   unsigned int pgno,              /* Page number of page to load */
325   u8 **ppPage,                    /* OUT: pointer to page buffer */
326   int *pnPage                     /* OUT: Size of (*ppPage) in bytes */
327 ){
328   int rc2;
329   int rc = SQLITE_OK;
330   sqlite3_stmt *pStmt = pCsr->pStmt;
331 
332   *ppPage = 0;
333   *pnPage = 0;
334   sqlite3_bind_int64(pStmt, 2, pgno);
335   if( SQLITE_ROW==sqlite3_step(pStmt) ){
336     int nCopy = sqlite3_column_bytes(pStmt, 0);
337     if( nCopy>0 ){
338       u8 *pPage;
339       pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
340       if( pPage==0 ){
341         rc = SQLITE_NOMEM;
342       }else{
343         const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
344         memcpy(pPage, pCopy, nCopy);
345         memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
346       }
347       *ppPage = pPage;
348       *pnPage = nCopy;
349     }
350   }
351   rc2 = sqlite3_reset(pStmt);
352   if( rc==SQLITE_OK ) rc = rc2;
353 
354   return rc;
355 }
356 
357 /*
358 ** Read a varint.  Put the value in *pVal and return the number of bytes.
359 */
dbdataGetVarint(const u8 * z,sqlite3_int64 * pVal)360 static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
361   sqlite3_int64 v = 0;
362   int i;
363   for(i=0; i<8; i++){
364     v = (v<<7) + (z[i]&0x7f);
365     if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
366   }
367   v = (v<<8) + (z[i]&0xff);
368   *pVal = v;
369   return 9;
370 }
371 
372 /*
373 ** Return the number of bytes of space used by an SQLite value of type
374 ** eType.
375 */
dbdataValueBytes(int eType)376 static int dbdataValueBytes(int eType){
377   switch( eType ){
378     case 0: case 8: case 9:
379     case 10: case 11:
380       return 0;
381     case 1:
382       return 1;
383     case 2:
384       return 2;
385     case 3:
386       return 3;
387     case 4:
388       return 4;
389     case 5:
390       return 6;
391     case 6:
392     case 7:
393       return 8;
394     default:
395       if( eType>0 ){
396         return ((eType-12) / 2);
397       }
398       return 0;
399   }
400 }
401 
402 /*
403 ** Load a value of type eType from buffer pData and use it to set the
404 ** result of context object pCtx.
405 */
dbdataValue(sqlite3_context * pCtx,int eType,u8 * pData,int nData)406 static void dbdataValue(
407   sqlite3_context *pCtx,
408   int eType,
409   u8 *pData,
410   int nData
411 ){
412   if( eType>=0 && dbdataValueBytes(eType)<=nData ){
413     switch( eType ){
414       case 0:
415       case 10:
416       case 11:
417         sqlite3_result_null(pCtx);
418         break;
419 
420       case 8:
421         sqlite3_result_int(pCtx, 0);
422         break;
423       case 9:
424         sqlite3_result_int(pCtx, 1);
425         break;
426 
427       case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
428         sqlite3_uint64 v = (signed char)pData[0];
429         pData++;
430         switch( eType ){
431           case 7:
432           case 6:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
433           case 5:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
434           case 4:  v = (v<<8) + pData[0];  pData++;
435           case 3:  v = (v<<8) + pData[0];  pData++;
436           case 2:  v = (v<<8) + pData[0];  pData++;
437         }
438 
439         if( eType==7 ){
440           double r;
441           memcpy(&r, &v, sizeof(r));
442           sqlite3_result_double(pCtx, r);
443         }else{
444           sqlite3_result_int64(pCtx, (sqlite3_int64)v);
445         }
446         break;
447       }
448 
449       default: {
450         int n = ((eType-12) / 2);
451         if( eType % 2 ){
452           sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT);
453         }else{
454           sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
455         }
456       }
457     }
458   }
459 }
460 
461 /*
462 ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
463 */
dbdataNext(sqlite3_vtab_cursor * pCursor)464 static int dbdataNext(sqlite3_vtab_cursor *pCursor){
465   DbdataCursor *pCsr = (DbdataCursor*)pCursor;
466   DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
467 
468   pCsr->iRowid++;
469   while( 1 ){
470     int rc;
471     int iOff = (pCsr->iPgno==1 ? 100 : 0);
472     int bNextPage = 0;
473 
474     if( pCsr->aPage==0 ){
475       while( 1 ){
476         if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
477         rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
478         if( rc!=SQLITE_OK ) return rc;
479         if( pCsr->aPage ) break;
480         pCsr->iPgno++;
481       }
482       pCsr->iCell = pTab->bPtr ? -2 : 0;
483       pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
484     }
485 
486     if( pTab->bPtr ){
487       if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
488         pCsr->iCell = pCsr->nCell;
489       }
490       pCsr->iCell++;
491       if( pCsr->iCell>=pCsr->nCell ){
492         sqlite3_free(pCsr->aPage);
493         pCsr->aPage = 0;
494         if( pCsr->bOnePage ) return SQLITE_OK;
495         pCsr->iPgno++;
496       }else{
497         return SQLITE_OK;
498       }
499     }else{
500       /* If there is no record loaded, load it now. */
501       if( pCsr->pRec==0 ){
502         int bHasRowid = 0;
503         int nPointer = 0;
504         sqlite3_int64 nPayload = 0;
505         sqlite3_int64 nHdr = 0;
506         int iHdr;
507         int U, X;
508         int nLocal;
509 
510         switch( pCsr->aPage[iOff] ){
511           case 0x02:
512             nPointer = 4;
513             break;
514           case 0x0a:
515             break;
516           case 0x0d:
517             bHasRowid = 1;
518             break;
519           default:
520             /* This is not a b-tree page with records on it. Continue. */
521             pCsr->iCell = pCsr->nCell;
522             break;
523         }
524 
525         if( pCsr->iCell>=pCsr->nCell ){
526           bNextPage = 1;
527         }else{
528 
529           iOff += 8 + nPointer + pCsr->iCell*2;
530           if( iOff>pCsr->nPage ){
531             bNextPage = 1;
532           }else{
533             iOff = get_uint16(&pCsr->aPage[iOff]);
534           }
535 
536           /* For an interior node cell, skip past the child-page number */
537           iOff += nPointer;
538 
539           /* Load the "byte of payload including overflow" field */
540           if( bNextPage || iOff>pCsr->nPage ){
541             bNextPage = 1;
542           }else{
543             iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload);
544           }
545 
546           /* If this is a leaf intkey cell, load the rowid */
547           if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
548             iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
549           }
550 
551           /* Figure out how much data to read from the local page */
552           U = pCsr->nPage;
553           if( bHasRowid ){
554             X = U-35;
555           }else{
556             X = ((U-12)*64/255)-23;
557           }
558           if( nPayload<=X ){
559             nLocal = nPayload;
560           }else{
561             int M, K;
562             M = ((U-12)*32/255)-23;
563             K = M+((nPayload-M)%(U-4));
564             if( K<=X ){
565               nLocal = K;
566             }else{
567               nLocal = M;
568             }
569           }
570 
571           if( bNextPage || nLocal+iOff>pCsr->nPage ){
572             bNextPage = 1;
573           }else{
574 
575             /* Allocate space for payload. And a bit more to catch small buffer
576             ** overruns caused by attempting to read a varint or similar from
577             ** near the end of a corrupt record.  */
578             pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
579             if( pCsr->pRec==0 ) return SQLITE_NOMEM;
580             memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
581             pCsr->nRec = nPayload;
582 
583             /* Load the nLocal bytes of payload */
584             memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
585             iOff += nLocal;
586 
587             /* Load content from overflow pages */
588             if( nPayload>nLocal ){
589               sqlite3_int64 nRem = nPayload - nLocal;
590               unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
591               while( nRem>0 ){
592                 u8 *aOvfl = 0;
593                 int nOvfl = 0;
594                 int nCopy;
595                 rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
596                 assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
597                 if( rc!=SQLITE_OK ) return rc;
598                 if( aOvfl==0 ) break;
599 
600                 nCopy = U-4;
601                 if( nCopy>nRem ) nCopy = nRem;
602                 memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
603                 nRem -= nCopy;
604 
605                 pgnoOvfl = get_uint32(aOvfl);
606                 sqlite3_free(aOvfl);
607               }
608             }
609 
610             iHdr = dbdataGetVarint(pCsr->pRec, &nHdr);
611             pCsr->nHdr = nHdr;
612             pCsr->pHdrPtr = &pCsr->pRec[iHdr];
613             pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
614             pCsr->iField = (bHasRowid ? -1 : 0);
615           }
616         }
617       }else{
618         pCsr->iField++;
619         if( pCsr->iField>0 ){
620           sqlite3_int64 iType;
621           if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
622             bNextPage = 1;
623           }else{
624             pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType);
625             pCsr->pPtr += dbdataValueBytes(iType);
626           }
627         }
628       }
629 
630       if( bNextPage ){
631         sqlite3_free(pCsr->aPage);
632         sqlite3_free(pCsr->pRec);
633         pCsr->aPage = 0;
634         pCsr->pRec = 0;
635         if( pCsr->bOnePage ) return SQLITE_OK;
636         pCsr->iPgno++;
637       }else{
638         if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
639           return SQLITE_OK;
640         }
641 
642         /* Advance to the next cell. The next iteration of the loop will load
643         ** the record and so on. */
644         sqlite3_free(pCsr->pRec);
645         pCsr->pRec = 0;
646         pCsr->iCell++;
647       }
648     }
649   }
650 
651   assert( !"can't get here" );
652   return SQLITE_OK;
653 }
654 
655 /*
656 ** Return true if the cursor is at EOF.
657 */
dbdataEof(sqlite3_vtab_cursor * pCursor)658 static int dbdataEof(sqlite3_vtab_cursor *pCursor){
659   DbdataCursor *pCsr = (DbdataCursor*)pCursor;
660   return pCsr->aPage==0;
661 }
662 
663 /*
664 ** Determine the size in pages of database zSchema (where zSchema is
665 ** "main", "temp" or the name of an attached database) and set
666 ** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
667 ** an SQLite error code.
668 */
dbdataDbsize(DbdataCursor * pCsr,const char * zSchema)669 static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
670   DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
671   char *zSql = 0;
672   int rc, rc2;
673   sqlite3_stmt *pStmt = 0;
674 
675   zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
676   if( zSql==0 ) return SQLITE_NOMEM;
677   rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
678   sqlite3_free(zSql);
679   if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
680     pCsr->szDb = sqlite3_column_int(pStmt, 0);
681   }
682   rc2 = sqlite3_finalize(pStmt);
683   if( rc==SQLITE_OK ) rc = rc2;
684   return rc;
685 }
686 
687 /*
688 ** xFilter method for sqlite_dbdata and sqlite_dbptr.
689 */
dbdataFilter(sqlite3_vtab_cursor * pCursor,int idxNum,const char * idxStr,int argc,sqlite3_value ** argv)690 static int dbdataFilter(
691   sqlite3_vtab_cursor *pCursor,
692   int idxNum, const char *idxStr,
693   int argc, sqlite3_value **argv
694 ){
695   DbdataCursor *pCsr = (DbdataCursor*)pCursor;
696   DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
697   int rc = SQLITE_OK;
698   const char *zSchema = "main";
699 
700   dbdataResetCursor(pCsr);
701   assert( pCsr->iPgno==1 );
702   if( idxNum & 0x01 ){
703     zSchema = (const char*)sqlite3_value_text(argv[0]);
704   }
705   if( idxNum & 0x02 ){
706     pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
707     pCsr->bOnePage = 1;
708   }else{
709     pCsr->nPage = dbdataDbsize(pCsr, zSchema);
710     rc = dbdataDbsize(pCsr, zSchema);
711   }
712 
713   if( rc==SQLITE_OK ){
714     if( pTab->pStmt ){
715       pCsr->pStmt = pTab->pStmt;
716       pTab->pStmt = 0;
717     }else{
718       rc = sqlite3_prepare_v2(pTab->db,
719           "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
720           &pCsr->pStmt, 0
721       );
722     }
723   }
724   if( rc==SQLITE_OK ){
725     rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
726   }else{
727     pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
728   }
729   if( rc==SQLITE_OK ){
730     rc = dbdataNext(pCursor);
731   }
732   return rc;
733 }
734 
735 /*
736 ** Return a column for the sqlite_dbdata or sqlite_dbptr table.
737 */
dbdataColumn(sqlite3_vtab_cursor * pCursor,sqlite3_context * ctx,int i)738 static int dbdataColumn(
739   sqlite3_vtab_cursor *pCursor,
740   sqlite3_context *ctx,
741   int i
742 ){
743   DbdataCursor *pCsr = (DbdataCursor*)pCursor;
744   DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
745   if( pTab->bPtr ){
746     switch( i ){
747       case DBPTR_COLUMN_PGNO:
748         sqlite3_result_int64(ctx, pCsr->iPgno);
749         break;
750       case DBPTR_COLUMN_CHILD: {
751         int iOff = pCsr->iPgno==1 ? 100 : 0;
752         if( pCsr->iCell<0 ){
753           iOff += 8;
754         }else{
755           iOff += 12 + pCsr->iCell*2;
756           if( iOff>pCsr->nPage ) return SQLITE_OK;
757           iOff = get_uint16(&pCsr->aPage[iOff]);
758         }
759         if( iOff<=pCsr->nPage ){
760           sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
761         }
762         break;
763       }
764     }
765   }else{
766     switch( i ){
767       case DBDATA_COLUMN_PGNO:
768         sqlite3_result_int64(ctx, pCsr->iPgno);
769         break;
770       case DBDATA_COLUMN_CELL:
771         sqlite3_result_int(ctx, pCsr->iCell);
772         break;
773       case DBDATA_COLUMN_FIELD:
774         sqlite3_result_int(ctx, pCsr->iField);
775         break;
776       case DBDATA_COLUMN_VALUE: {
777         if( pCsr->iField<0 ){
778           sqlite3_result_int64(ctx, pCsr->iIntkey);
779         }else{
780           sqlite3_int64 iType;
781           dbdataGetVarint(pCsr->pHdrPtr, &iType);
782           dbdataValue(
783               ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
784           );
785         }
786         break;
787       }
788     }
789   }
790   return SQLITE_OK;
791 }
792 
793 /*
794 ** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
795 */
dbdataRowid(sqlite3_vtab_cursor * pCursor,sqlite_int64 * pRowid)796 static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
797   DbdataCursor *pCsr = (DbdataCursor*)pCursor;
798   *pRowid = pCsr->iRowid;
799   return SQLITE_OK;
800 }
801 
802 
803 /*
804 ** Invoke this routine to register the "sqlite_dbdata" virtual table module
805 */
sqlite3DbdataRegister(sqlite3 * db)806 static int sqlite3DbdataRegister(sqlite3 *db){
807   static sqlite3_module dbdata_module = {
808     0,                            /* iVersion */
809     0,                            /* xCreate */
810     dbdataConnect,                /* xConnect */
811     dbdataBestIndex,              /* xBestIndex */
812     dbdataDisconnect,             /* xDisconnect */
813     0,                            /* xDestroy */
814     dbdataOpen,                   /* xOpen - open a cursor */
815     dbdataClose,                  /* xClose - close a cursor */
816     dbdataFilter,                 /* xFilter - configure scan constraints */
817     dbdataNext,                   /* xNext - advance a cursor */
818     dbdataEof,                    /* xEof - check for end of scan */
819     dbdataColumn,                 /* xColumn - read data */
820     dbdataRowid,                  /* xRowid - read data */
821     0,                            /* xUpdate */
822     0,                            /* xBegin */
823     0,                            /* xSync */
824     0,                            /* xCommit */
825     0,                            /* xRollback */
826     0,                            /* xFindMethod */
827     0,                            /* xRename */
828     0,                            /* xSavepoint */
829     0,                            /* xRelease */
830     0,                            /* xRollbackTo */
831     0                             /* xShadowName */
832   };
833 
834   int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
835   if( rc==SQLITE_OK ){
836     rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
837   }
838   return rc;
839 }
840 
841 #ifdef _WIN32
842 __declspec(dllexport)
843 #endif
sqlite3_dbdata_init(sqlite3 * db,char ** pzErrMsg,const sqlite3_api_routines * pApi)844 int sqlite3_dbdata_init(
845   sqlite3 *db,
846   char **pzErrMsg,
847   const sqlite3_api_routines *pApi
848 ){
849   SQLITE_EXTENSION_INIT2(pApi);
850   return sqlite3DbdataRegister(db);
851 }
852