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