Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add "PRAGMA bt_page_dump" to access a specific bt xControl() command. This is probably a temporary solution. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d00d7c08d195d21f0846411537da6a14 |
User & Date: | dan 2013-10-22 19:04:17.847 |
Context
2013-10-23
| ||
19:31 | Progress on reading and writing frames from and to the log file. check-in: 5ba2ff0701 user: dan tags: trunk | |
2013-10-22
| ||
19:04 | Add "PRAGMA bt_page_dump" to access a specific bt xControl() command. This is probably a temporary solution. check-in: d00d7c08d1 user: dan tags: trunk | |
16:20 | More logging code. check-in: 94016fe5e8 user: dan tags: trunk | |
Changes
Changes to src/bt.h.
︙ | ︙ | |||
114 115 116 117 118 119 120 121 | int sqlite4BtCsrData(bt_cursor *pCsr, int, int, const void **ppV, int *pnV); int sqlite4BtReplace(bt_db*, const void *pK, int nK, const void *pV, int nV); int sqlite4BtDelete(bt_cursor*); int sqlite4BtSetCookie(bt_db*, unsigned int iVal); int sqlite4BtGetCookie(bt_db*, unsigned int *piVal); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | int sqlite4BtCsrData(bt_cursor *pCsr, int, int, const void **ppV, int *pnV); int sqlite4BtReplace(bt_db*, const void *pK, int nK, const void *pV, int nV); int sqlite4BtDelete(bt_cursor*); int sqlite4BtSetCookie(bt_db*, unsigned int iVal); int sqlite4BtGetCookie(bt_db*, unsigned int *piVal); /* ** Append a human readable representation of the b-tree page passed via ** arguments a+n to the buffer passed as the first argument. If argument ** pgno is non-zero it is included in the output. */ int sqlite4BtDebugPage(sqlite4_buffer*, unsigned int pgno, char *a, int n); /* ** kvstore xControl() method. ** ** BT_CONTROL_INFO: ** If the second argument to sqlite4BtControl() is BT_CONTROL_INFO, then ** the third is expected to be a pointer to an instance of type bt_info. ** The "output" buffer must already be initialized. Before ** sqlite4BtControl() returns it appends debugging information to the ** buffer. The specific information appended depends on the eType and ** pgno member variables. */ int sqlite4BtControl(bt_db*, int op, void *pArg); #define BT_CONTROL_INFO 7706389 typedef struct bt_info bt_info; struct bt_info { int eType; unsigned int pgno; sqlite4_buffer output; }; |
Changes to src/bt_main.c.
︙ | ︙ | |||
28 29 30 31 32 33 34 | #ifndef MIN # define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef MAX # define MAX(a,b) (((a)>(b))?(a):(b)) #endif | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #ifndef MIN # define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef MAX # define MAX(a,b) (((a)>(b))?(a):(b)) #endif #define BT_STDERR_DEBUG 1 struct bt_db { sqlite4_env *pEnv; /* SQLite environment */ BtPager *pPager; /* Underlying page-based database */ bt_cursor *pAllCsr; /* List of all open cursors */ }; |
︙ | ︙ | |||
338 339 340 341 342 343 344 | return pgno; } /* **************************************************************************/ | > > > | > > > | > > > > > > > > | > | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | return pgno; } /* **************************************************************************/ static void btBufPrintf(sqlite4_buffer *pBuf, const char *zFormat, ...){ char *zAppend; va_list ap; va_start(ap, zFormat); zAppend = sqlite4_vmprintf(0, zFormat, ap); va_end(ap); sqlite4_buffer_append(pBuf, zAppend, strlen(zAppend)); sqlite4_free(0, zAppend); } /* ** Append a human-readable interpretation of the b-tree page in aData/nData ** to buffer pBuf. */ static void btPageToAscii(u32 pgno, u8 *aData, int nData, sqlite4_buffer *pBuf){ int i; int nCell = (int)btCellCount(aData, nData); btBufPrintf(pBuf, "Page %d: ", pgno); btBufPrintf(pBuf, "nCell=%d ", nCell); btBufPrintf(pBuf, "iFree=%d ", (int)btFreeOffset(aData, nData)); btBufPrintf(pBuf, "flags=%d ", (int)btFlags(aData)); if( btFlags(aData) & BT_PGFLAGS_INTERNAL ){ btBufPrintf(pBuf, "rchild=%d ", (int)btGetU32(&aData[1])); } btBufPrintf(pBuf, "cell-offsets=("); for(i=0; i<nCell; i++){ u8 *ptr = btCellPtrFind(aData, nData, i); btBufPrintf(pBuf, "%s%d", i==0?"":" ", (int)btGetU16(ptr)); } btBufPrintf(pBuf, ")\n"); for(i=0; i<nCell; i++){ int nKey; int j; u8 *pCell = btCellFind(aData, nData, i); btBufPrintf(pBuf, " Key %d: ", i); pCell += sqlite4BtVarintGet32(pCell, &nKey); for(j=0; j<nKey; j++){ btBufPrintf(pBuf, "%02X", (int)pCell[j]); } if( btFlags(aData) & BT_PGFLAGS_INTERNAL ){ btBufPrintf(pBuf, " child=%d ", (int)btGetU32(&pCell[j])); } btBufPrintf(pBuf, "\n"); } } int sqlite4BtDebugPage(sqlite4_buffer *pBuf, u32 pgno, char *aData, int nData){ btPageToAscii(pgno, (u8*)aData, nData, pBuf); return SQLITE4_OK; } #ifndef NDEBUG #include <stdio.h> static void printPage(FILE *f, u32 pgno, u8 *aData, int nData){ sqlite4_buffer buf; sqlite4_buffer_init(&buf, 0); btPageToAscii(pgno, aData, nData, &buf); sqlite4_buffer_append(&buf, "", 1); fprintf(f, "%s", (char*)buf.p); sqlite4_buffer_clear(&buf); } int printPgdataToStderr(u32 pgno, u8 *aData, int nData){ printPage(stderr, pgno, aData, nData); return 0; } int printPgToStderr(BtPage *pPg){ printPage(stderr, sqlite4BtPagePgno(pPg), sqlite4BtPageData(pPg), 1024); |
︙ | ︙ | |||
911 912 913 914 915 916 917 | const int pgsz = sqlite4BtPagerPagesize(pPager); u8 *aData; u8 *pCell; u8 *pOvfl = 0; int iCell = pCsr->aiCell[pCsr->nPg-1]; int n; int rc = SQLITE4_OK; | < | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 | const int pgsz = sqlite4BtPagerPagesize(pPager); u8 *aData; u8 *pCell; u8 *pOvfl = 0; int iCell = pCsr->aiCell[pCsr->nPg-1]; int n; int rc = SQLITE4_OK; aData = (u8*)sqlite4BtPageData(pCsr->apPage[pCsr->nPg-1]); assert( btCellCount(aData, pgsz)>iCell ); pCell = btCellFind(aData, pgsz, iCell); pCell += sqlite4BtVarintGet32(pCell, &n); if( n==0 ){ |
︙ | ︙ | |||
2310 2311 2312 2313 2314 2315 2316 2317 | int sqlite4BtSetCookie(bt_db *db, unsigned int iVal){ return sqlite4BtPagerSetCookie(db->pPager, iVal); } int sqlite4BtGetCookie(bt_db *db, unsigned int *piVal){ return sqlite4BtPagerGetCookie(db->pPager, piVal); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 | int sqlite4BtSetCookie(bt_db *db, unsigned int iVal){ return sqlite4BtPagerSetCookie(db->pPager, iVal); } int sqlite4BtGetCookie(bt_db *db, unsigned int *piVal){ return sqlite4BtPagerGetCookie(db->pPager, piVal); } int sqlite4BtControl(bt_db *db, int op, void *pArg){ int rc = SQLITE4_OK; switch( op ){ case BT_CONTROL_INFO: { bt_info *pInfo = (bt_info*)pArg; int iTrans = sqlite4BtTransactionLevel(db); if( iTrans==0 ) rc = sqlite4BtBegin(db, 1); if( rc==SQLITE4_OK ){ BtPage *pPg = 0; rc = sqlite4BtPageGet(db->pPager, pInfo->pgno, &pPg); if( rc==SQLITE4_OK ){ u8 *aData; int nData; aData = sqlite4BtPageData(pPg); nData = sqlite4BtPagerPagesize(db->pPager); btPageToAscii(pInfo->pgno, aData, nData, &pInfo->output); sqlite4_buffer_append(&pInfo->output, "", 1); sqlite4BtPageRelease(pPg); } if( iTrans==0 ) rc = sqlite4BtCommit(db, 0); } } } return rc; } |
Changes to src/kvbt.c.
︙ | ︙ | |||
215 216 217 218 219 220 221 | */ static int btClose(KVStore *pKVStore){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtClose(p->pDb); } static int btControl(KVStore *pKVStore, int op, void *pArg){ | > | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | */ static int btClose(KVStore *pKVStore){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtClose(p->pDb); } static int btControl(KVStore *pKVStore, int op, void *pArg){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtControl(p->pDb, op, pArg); } static int btGetMeta(KVStore *pKVStore, unsigned int *piVal){ KVBt *p = (KVBt *)pKVStore; return sqlite4BtGetCookie(p->pDb, piVal); } |
︙ | ︙ |
Changes to src/pragma.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. */ #include "sqliteInt.h" /* ** Interpret the given string as a boolean value. */ u8 sqlite4GetBoolean(const char *z){ /* 123456789 12345 */ static const char zText[] = "onoffalseyestrue"; | > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. */ #include "sqliteInt.h" #include "bt.h" /* ** Interpret the given string as a boolean value. */ u8 sqlite4GetBoolean(const char *z){ /* 123456789 12345 */ static const char zText[] = "onoffalseyestrue"; |
︙ | ︙ | |||
661 662 663 664 665 666 667 | sqlite4VdbeAddOp4(v, OP_HaltIfNull, SQLITE4_CONSTRAINT, OE_Abort, r2, "value may not be null", P4_STATIC); sqlite4VdbeAddOp1(v, OP_ToBlob, r2); sqlite4VdbeAddOp0(v, OP_OpenWrite); sqlite4VdbeAddOp3(v, OP_Insert, 0, r2, r1); sqlite4VdbeAddOp0(v, OP_Halt); }else | | | 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | sqlite4VdbeAddOp4(v, OP_HaltIfNull, SQLITE4_CONSTRAINT, OE_Abort, r2, "value may not be null", P4_STATIC); sqlite4VdbeAddOp1(v, OP_ToBlob, r2); sqlite4VdbeAddOp0(v, OP_OpenWrite); sqlite4VdbeAddOp3(v, OP_Insert, 0, r2, r1); sqlite4VdbeAddOp0(v, OP_Halt); }else #endif /* SQLITE4_DEBUG */ /* ** PRAGMA integrity_check ** ** Check that for each table, the content of any auxilliary indexes are ** consistent with the primary key index. */ |
︙ | ︙ | |||
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 | sqlite4VdbeChangeP1(v, addr, iDb); sqlite4VdbeChangeP1(v, addr+1, iDb); sqlite4VdbeSetNumCols(v, 1); sqlite4VdbeSetColName(v, 0, COLNAME_NAME, zPragma, SQLITE4_TRANSIENT); } }else {/* Empty ELSE clause */} pragma_out: sqlite4DbFree(db, zPragma); /* sqlite4DbFree(db, zRight); */ sqlite4ExprListDelete(db, pList); } #endif /* SQLITE4_OMIT_PRAGMA */ | > > > > > > > > > > > > > > > > > > > > > | 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 | sqlite4VdbeChangeP1(v, addr, iDb); sqlite4VdbeChangeP1(v, addr+1, iDb); sqlite4VdbeSetNumCols(v, 1); sqlite4VdbeSetColName(v, 0, COLNAME_NAME, zPragma, SQLITE4_TRANSIENT); } }else /* ** TODO: This is temporary. There should be some generic way to ** pass PRAGMA commands through to KV stores. */ if( sqlite4_stricmp(zPragma, "bt_page_dump")==0 && zRight ){ bt_info info; memset(&info, 0, sizeof(info)); info.pgno = sqlite4Atoi(zRight); sqlite4_buffer_init(&info.output, sqlite4_db_env(db)->pMM); rc = sqlite4_kvstore_control(db, zDb, BT_CONTROL_INFO, (void*)&info); if( rc==SQLITE4_OK ){ sqlite4VdbeSetNumCols(v, 1); sqlite4VdbeSetColName(v, 0, COLNAME_NAME, "info", SQLITE4_STATIC); sqlite4VdbeAddOp2(v, OP_String8, 0, 1); sqlite4VdbeChangeP4(v, -1, (char*)info.output.p, P4_TRANSIENT); sqlite4VdbeAddOp2(v, OP_ResultRow, 1, 1); } sqlite4_buffer_clear(&info.output); }else {/* Empty ELSE clause */} pragma_out: sqlite4DbFree(db, zPragma); /* sqlite4DbFree(db, zRight); */ sqlite4ExprListDelete(db, pList); } #endif /* SQLITE4_OMIT_PRAGMA */ |