Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the ability to decode the headers of individual cells, byte-by-byte, in the "showdb.exe" utility. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
306b461d7c0643b6ac4df944759ecc9c |
User & Date: | drh 2014-06-19 23:38:53.722 |
Context
2014-06-20
| ||
01:32 | In the showdb.exe utility, for the "NNNbd" command, also show data fields in addition to header fields on each record decoded. Improvements to formatting. (check-in: b451fe0cb9 user: drh tags: trunk) | |
2014-06-19
| ||
23:38 | Add the ability to decode the headers of individual cells, byte-by-byte, in the "showdb.exe" utility. (check-in: 306b461d7c user: drh tags: trunk) | |
2014-06-18
| ||
18:10 | Add the "LogEst" and "LogEst.exe" target to the makefiles. (check-in: 7b91b0581d user: drh tags: trunk) | |
Changes
Changes to tool/showdb.c.
︙ | ︙ | |||
124 125 126 127 128 129 130 131 132 133 134 135 136 137 | unsigned char *aData; iStart = (iPg-1)*pagesize; fprintf(stdout, "Page %d: (offsets 0x%x..0x%x)\n", iPg, iStart, iStart+pagesize-1); aData = print_byte_range(iStart, pagesize, 0); free(aData); } /* Print a line of decode output showing a 4-byte integer. */ static void print_decode_line( unsigned char *aData, /* Content being decoded */ int ofst, int nByte, /* Start and size of decode */ const char *zMsg /* Message to append */ | > | 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | unsigned char *aData; iStart = (iPg-1)*pagesize; fprintf(stdout, "Page %d: (offsets 0x%x..0x%x)\n", iPg, iStart, iStart+pagesize-1); aData = print_byte_range(iStart, pagesize, 0); free(aData); } /* Print a line of decode output showing a 4-byte integer. */ static void print_decode_line( unsigned char *aData, /* Content being decoded */ int ofst, int nByte, /* Start and size of decode */ const char *zMsg /* Message to append */ |
︙ | ︙ | |||
336 337 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 | } if( showCellContent && cType!=5 ){ nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]); } *pzDesc = zDesc; return nLocal+n; } /* ** Decode a btree page */ static void decode_btree_page( unsigned char *a, /* Page content */ int pgno, /* Page number */ int hdrSize, /* Size of the page header. 0 or 100 */ char *zArgs /* Flags to control formatting */ ){ const char *zType = "unknown"; int nCell; int i, j; int iCellPtr; int showCellContent = 0; int showMap = 0; char *zMap = 0; switch( a[0] ){ case 2: zType = "index interior node"; break; case 5: zType = "table interior node"; break; case 10: zType = "index leaf"; break; case 13: zType = "table leaf"; break; } while( zArgs[0] ){ switch( zArgs[0] ){ case 'c': showCellContent = 1; break; case 'm': showMap = 1; break; } zArgs++; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | < | | | | < < < | | | > > > > | 337 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 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | } if( showCellContent && cType!=5 ){ nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]); } *pzDesc = zDesc; return nLocal+n; } /* Print an offset followed by nByte bytes. Add extra white-space ** at the end so that subsequent text is aligned. */ static void printBytes( unsigned char *aData, /* Content being decoded */ unsigned char *aStart, /* Start of content to be printed */ int nByte /* Number of bytes to print */ ){ int j; printf(" %03x: ", (int)(aStart-aData)); for(j=0; j<9; j++){ if( j>=nByte ){ printf(" "); }else{ printf("%02x ", aStart[j]); } } } /* ** Write a full decode on stdout for the cell at a[ofst]. ** Assume the page contains a header of size szPgHdr bytes. */ static void decodeCell( unsigned char *a, /* Page content (without the page-1 header) */ unsigned pgno, /* Page number */ int iCell, /* Cell index */ int szPgHdr, /* Size of the page header. 0 or 100 */ int ofst /* Cell begins at a[ofst] */ ){ int i, j, k; int leftChild; i64 nPayload; i64 rowid; i64 nHdr; i64 iType; int nLocal; unsigned char *x = a + ofst; unsigned char *end; unsigned char cType = a[0]; printf("Decode cell[%d] on page %d offset %04x....\n", iCell, pgno, szPgHdr+ofst); if( cType<=5 ){ leftChild = ((x[0]*256 + x[1])*256 + x[2])*256 + x[3]; printBytes(a, x, 4); printf("left child page:: %d\n", leftChild); x += 4; } if( cType!=5 ){ i = decodeVarint(x, &nPayload); printBytes(a, x, i); nLocal = localPayload(nPayload, cType); printf("bytes of payload: %d (local: %d)\n", (int)nPayload, nLocal); x += i; }else{ nPayload = nLocal = 0; } end = x + nLocal; if( cType==5 || cType==13 ){ i = decodeVarint(x, &rowid); printBytes(a, x, i); printf("rowid: %lld\n", rowid); x += i; } if( nLocal>0 ){ i = decodeVarint(x, &nHdr); printBytes(a, x, i); printf("record header size: %d\n", (int)nHdr); j = i; k = 0; while( x+j<end && j<nHdr ){ const char *zTypeName; int sz = 0; char zNm[30]; i = decodeVarint(x+j, &iType); printBytes(a, x+j, i); printf("column[%d] type code: %d - ", k++, (int)iType); switch( iType ){ case 0: zTypeName = "NULL"; sz = 0; break; case 1: zTypeName = "int8"; sz = 1; break; case 2: zTypeName = "int16"; sz = 2; break; case 3: zTypeName = "int24"; sz = 3; break; case 4: zTypeName = "int32"; sz = 4; break; case 5: zTypeName = "int48"; sz = 6; break; case 6: zTypeName = "int64"; sz = 8; break; case 7: zTypeName = "double"; sz = 8; break; case 8: zTypeName = "zero"; sz = 0; break; case 9: zTypeName = "one"; sz = 0; break; case 10: case 11: zTypeName = "error"; sz = 0; break; default: { sz = (int)(iType-12)/2; sprintf(zNm, (iType&1)==0 ? "blob(%d)" : "text(%d)", sz); zTypeName = zNm; break; } } printf("%s\n", zTypeName); j += i; } } if( j<nLocal ){ printBytes(a, x+j, 0); printf("%d bytes of content\n", nLocal-j); } if( nLocal<nPayload ){ printBytes(a, x+nLocal, 4); printf("first overflow page: %d\n", decodeInt32(x+nLocal)); } } /* ** Decode a btree page */ static void decode_btree_page( unsigned char *a, /* Page content */ int pgno, /* Page number */ int hdrSize, /* Size of the page header. 0 or 100 */ char *zArgs /* Flags to control formatting */ ){ const char *zType = "unknown"; int nCell; int i, j; int iCellPtr; int showCellContent = 0; int showMap = 0; int cellToDecode = -2; char *zMap = 0; switch( a[0] ){ case 2: zType = "index interior node"; break; case 5: zType = "table interior node"; break; case 10: zType = "index leaf"; break; case 13: zType = "table leaf"; break; } while( zArgs[0] ){ switch( zArgs[0] ){ case 'c': showCellContent = 1; break; case 'm': showMap = 1; break; case 'd': { if( !isdigit(zArgs[1]) ){ cellToDecode = -1; }else{ cellToDecode = 0; while( isdigit(zArgs[1]) ){ zArgs++; cellToDecode = cellToDecode*10 + zArgs[0] - '0'; } } break; } } zArgs++; } nCell = a[3]*256 + a[4]; iCellPtr = (a[0]==2 || a[0]==5) ? 12 : 8; if( cellToDecode==(-2) ){ printf("Decode of btree page %d:\n", pgno); print_decode_line(a, 0, 1, zType); print_decode_line(a, 1, 2, "Offset to first freeblock"); print_decode_line(a, 3, 2, "Number of cells on this page"); print_decode_line(a, 5, 2, "Offset to cell content area"); print_decode_line(a, 7, 1, "Fragmented byte count"); if( a[0]==2 || a[0]==5 ){ print_decode_line(a, 8, 4, "Right child"); } if( nCell>0 ){ printf(" key: lx=left-child n=payload-size r=rowid\n"); } }else if( cellToDecode>=nCell ){ printf("Page %d has only %d cells\n", pgno, nCell); return; } if( showMap ){ zMap = malloc(pagesize); memset(zMap, '.', pagesize); memset(zMap, '1', hdrSize); memset(&zMap[hdrSize], 'H', iCellPtr); memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell); |
︙ | ︙ | |||
405 406 407 408 409 410 411 | memset(&zMap[cofst], '*', n); zMap[cofst] = '['; zMap[cofst+n-1] = ']'; sprintf(zBuf, "%d", i); j = strlen(zBuf); if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j); } | > | > > > | | 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | memset(&zMap[cofst], '*', n); zMap[cofst] = '['; zMap[cofst+n-1] = ']'; sprintf(zBuf, "%d", i); j = strlen(zBuf); if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j); } if( cellToDecode==(-2) ){ printf(" %03x: cell[%d] %s\n", cofst, i, zDesc); }else if( cellToDecode==(-1) || cellToDecode==i ){ decodeCell(a, pgno, i, hdrSize, cofst-hdrSize); } } if( showMap ){ for(i=0; i<pagesize; i+=64){ printf(" %03x: %.64s\n", i, &zMap[i]); } free(zMap); } } /* ** Decode a freelist trunk page. */ static void decode_trunk_page( int pgno, /* The page number */ |
︙ | ︙ | |||
753 754 755 756 757 758 759 760 761 762 763 764 765 766 | " pgidx Index of how each page is used\n" " ptrmap Show all PTRMAP page content\n" " NNN..MMM Show hex of pages NNN through MMM\n" " NNN..end Show hex of pages NNN through end of file\n" " NNNb Decode btree page NNN\n" " NNNbc Decode btree page NNN and show content\n" " NNNbm Decode btree page NNN and show a layout map\n" " NNNt Decode freelist trunk page NNN\n" " NNNtd Show leaf freelist pages on the decode\n" " NNNtr Recurisvely decode freelist starting at NNN\n" ); } int main(int argc, char **argv){ | > | 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 | " pgidx Index of how each page is used\n" " ptrmap Show all PTRMAP page content\n" " NNN..MMM Show hex of pages NNN through MMM\n" " NNN..end Show hex of pages NNN through end of file\n" " NNNb Decode btree page NNN\n" " NNNbc Decode btree page NNN and show content\n" " NNNbm Decode btree page NNN and show a layout map\n" " NNNbdCCC Decode cell CCC on btree page NNN\n" " NNNt Decode freelist trunk page NNN\n" " NNNtd Show leaf freelist pages on the decode\n" " NNNtr Recurisvely decode freelist starting at NNN\n" ); } int main(int argc, char **argv){ |
︙ | ︙ |