From 569c6676a6ddb0ff73821d7693b5e18ddef809b9 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 16 Oct 2014 22:51:35 -0400 Subject: Imported Upstream version 3.2.0 --- tool/showdb.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 238 insertions(+), 41 deletions(-) (limited to 'tool/showdb.c') diff --git a/tool/showdb.c b/tool/showdb.c index 27424e0..1a51e9d 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -9,6 +9,8 @@ #if !defined(_MSC_VER) #include +#else +#include #endif #include @@ -66,7 +68,7 @@ static unsigned char *getContent(int ofst, int nByte){ if( aData==0 ) out_of_memory(); memset(aData, 0, nByte+32); lseek(db, ofst, SEEK_SET); - read(db, aData, nByte); + if( read(db, aData, nByte)=nByte ){ sprintf(&zBuf[i], " "); @@ -148,7 +151,7 @@ static print_decode_line( sprintf(&zBuf[i], " %02x", aData[ofst+j]); val = val*256 + aData[ofst+j]; } - i += strlen(&zBuf[i]); + i += (int)strlen(&zBuf[i]); } sprintf(&zBuf[i], " %9d", val); printf("%s %s\n", zBuf, zMsg); @@ -189,14 +192,14 @@ static void print_db_header(void){ /* ** Describe cell content. */ -static int describeContent( +static i64 describeContent( unsigned char *a, /* Cell content */ - int nLocal, /* Bytes in a[] */ + i64 nLocal, /* Bytes in a[] */ char *zDesc /* Write description here */ ){ - int nDesc = 0; - int n, i, j; - i64 x, v; + i64 nDesc = 0; + int n, j; + i64 i, x, v; const unsigned char *pData; const unsigned char *pLimit; char sep = ' '; @@ -236,15 +239,15 @@ static int describeContent( }else if( x==9 ){ sprintf(zDesc, "1"); }else if( x>=12 ){ - int size = (x-12)/2; + i64 size = (x-12)/2; if( (x&1)==0 ){ - sprintf(zDesc, "blob(%d)", size); + sprintf(zDesc, "blob(%lld)", size); }else{ - sprintf(zDesc, "txt(%d)", size); + sprintf(zDesc, "txt(%lld)", size); } pData += size; } - j = strlen(zDesc); + j = (int)strlen(zDesc); zDesc += j; nDesc += j; } @@ -255,11 +258,11 @@ static int describeContent( ** Compute the local payload size given the total payload size and ** the page size. */ -static int localPayload(i64 nPayload, char cType){ - int maxLocal; - int minLocal; - int surplus; - int nLocal; +static i64 localPayload(i64 nPayload, char cType){ + i64 maxLocal; + i64 minLocal; + i64 surplus; + i64 nLocal; if( cType==13 ){ /* Table leaf */ maxLocal = pagesize-35; @@ -287,19 +290,19 @@ static int localPayload(i64 nPayload, char cType){ ** ** The return value is the local cell size. */ -static int describeCell( +static i64 describeCell( unsigned char cType, /* Page type */ unsigned char *a, /* Cell content */ int showCellContent, /* Show cell content if true */ char **pzDesc /* Store description here */ ){ int i; - int nDesc = 0; + i64 nDesc = 0; int n = 0; int leftChild; i64 nPayload; i64 rowid; - int nLocal; + i64 nLocal; static char zDesc[1000]; i = 0; if( cType<=5 ){ @@ -341,6 +344,180 @@ 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; + int leftChild; + i64 k; + i64 nPayload; + i64 rowid; + i64 nHdr; + i64 iType; + i64 nLocal; + unsigned char *x = a + ofst; + unsigned char *end; + unsigned char cType = a[0]; + int nCol = 0; + int szCol[2000]; + int ofstCol[2000]; + int typeCol[2000]; + + printf("Cell[%d]:\n", iCell); + 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); + if( nLocal==nPayload ){ + printf("payload-size: %lld\n", nPayload); + }else{ + printf("payload-size: %lld (%lld local, %lld overflow)\n", + nPayload, nLocal, 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; + nCol = 0; + k = nHdr; + while( x+j=nCell ){ + printf("Page %d has only %d cells\n", pgno, nCell); + return; + } + printf("Header on 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 ){ + if( cellToDecode==(-2) && nCell>0 ){ printf(" key: lx=left-child n=payload-size r=rowid\n"); } if( showMap ){ @@ -396,27 +588,32 @@ static void decode_btree_page( for(i=0; i0 ){ a = getContent((pgno-1)*pagesize, pagesize); @@ -495,11 +692,10 @@ static void page_usage_cell( int cellno /* Index of the cell on the page */ ){ int i; - int nDesc = 0; int n = 0; i64 nPayload; i64 rowid; - int nLocal; + i64 nLocal; i = 0; if( cType<=5 ){ a += 4; @@ -677,7 +873,7 @@ static void page_usage_report(const char *zDbName){ if( rc==SQLITE_OK ){ while( sqlite3_step(pStmt)==SQLITE_ROW ){ int pgno = sqlite3_column_int(pStmt, 2); - page_usage_btree(pgno, 0, 0, sqlite3_column_text(pStmt, 1)); + page_usage_btree(pgno, 0, 0, (const char*)sqlite3_column_text(pStmt,1)); } }else{ printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db)); @@ -700,12 +896,12 @@ static void page_usage_report(const char *zDbName){ ** Try to figure out how every page in the database file is being used. */ static void ptrmap_coverage_report(const char *zDbName){ - unsigned int pgno; + int pgno; unsigned char *aHdr; unsigned char *a; int usable; int perPage; - unsigned int i; + int i; /* Avoid the pathological case */ if( mxPage<1 ){ @@ -758,6 +954,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" @@ -779,7 +976,7 @@ int main(int argc, char **argv){ zPgSz[0] = 0; zPgSz[1] = 0; lseek(db, 16, SEEK_SET); - read(db, zPgSz, 2); + if( read(db, zPgSz, 2)<2 ) memset(zPgSz, 0, 2); pagesize = zPgSz[0]*256 + zPgSz[1]*65536; if( pagesize==0 ) pagesize = 1024; printf("Pagesize: %d\n", pagesize); @@ -835,7 +1032,6 @@ int main(int argc, char **argv){ free(a); continue; }else if( zLeft && zLeft[0]=='t' ){ - unsigned char *a; int detail = 0; int recursive = 0; int i; @@ -861,4 +1057,5 @@ int main(int argc, char **argv){ } } close(db); + return 0; } -- cgit v1.2.3