1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-12-24 14:17:58 +03:00

Add the ability to decode the headers of individual cells, byte-by-byte,

in the "showdb.exe" utility.

FossilOrigin-Name: 306b461d7c0643b6ac4df944759ecc9ce8581634
This commit is contained in:
drh
2014-06-19 23:38:53 +00:00
parent 267a13fd47
commit 6a30cd5a44
3 changed files with 159 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
C Add\sthe\s"LogEst"\sand\s"LogEst.exe"\starget\sto\sthe\smakefiles.
D 2014-06-18T18:10:12.200
C Add\sthe\sability\sto\sdecode\sthe\sheaders\sof\sindividual\scells,\sbyte-by-byte,\nin\sthe\s"showdb.exe"\sutility.
D 2014-06-19T23:38:53.722
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in b03432313a3aad96c706f8164fb9f5307eaf19f5
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -1158,7 +1158,7 @@ F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c 1f3fe634d6f690b8d39ab1b9fd34583d468921e1
F tool/showdb.c c080dea3addc8440191aef2c7cf222ee7959529c
F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5
F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
@@ -1179,7 +1179,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 5e514f6acebcfad4f18300d1a34f4917f1a746d9
R 608fed792452245bc29949099b24055c
P 7b91b0581d169a353462d96120a2e0d4dcc8e8ae
R 80dc9f5b1256cb0818cbd9270f47db96
U drh
Z 8ecf2902c498abf367d738a353cfaa20
Z ec7d321d3c2511a642cbe0539a129858

View File

@@ -1 +1 @@
7b91b0581d169a353462d96120a2e0d4dcc8e8ae
306b461d7c0643b6ac4df944759ecc9ce8581634

View File

@@ -129,6 +129,7 @@ static void print_page(int iPg){
free(aData);
}
/* Print a line of decode output showing a 4-byte integer.
*/
static void print_decode_line(
@@ -341,6 +342,120 @@ static int describeCell(
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
*/
@@ -356,6 +471,7 @@ static void decode_btree_page(
int iCellPtr;
int showCellContent = 0;
int showMap = 0;
int cellToDecode = -2;
char *zMap = 0;
switch( a[0] ){
case 2: zType = "index interior node"; break;
@@ -367,24 +483,39 @@ static void decode_btree_page(
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++;
}
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");
nCell = a[3]*256 + a[4];
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");
iCellPtr = 12;
}else{
iCellPtr = 8;
}
if( nCell>0 ){
printf(" key: lx=left-child n=payload-size r=rowid\n");
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);
@@ -409,14 +540,18 @@ static void decode_btree_page(
j = strlen(zBuf);
if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j);
}
printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
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);
}
}
}
/*
@@ -757,6 +892,7 @@ static void usage(const char *argv0){
" 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"