Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(691)

Unified Diff: third_party/sqlite/sqlite-src-3080704/tool/showwal.c

Issue 883353008: [sql] Import reference version of SQLite 3.8.7.4. (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hold back encoding change which is messing up patch. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/sqlite/sqlite-src-3080704/tool/showwal.c
diff --git a/third_party/sqlite/sqlite-src-3070603/tool/showdb.c b/third_party/sqlite/sqlite-src-3080704/tool/showwal.c
similarity index 57%
copy from third_party/sqlite/sqlite-src-3070603/tool/showdb.c
copy to third_party/sqlite/sqlite-src-3080704/tool/showwal.c
index c954153cf2986bc68b18799b3b0d20b145ccee8b..35810c66a96ff875612068bf179995f43279ff77 100644
--- a/third_party/sqlite/sqlite-src-3070603/tool/showdb.c
+++ b/third_party/sqlite/sqlite-src-3080704/tool/showwal.c
@@ -1,23 +1,88 @@
/*
-** A utility for printing all or part of an SQLite database file.
+** A utility for printing content from a write-ahead log file.
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+
+#if !defined(_MSC_VER)
#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
#include <stdlib.h>
#include <string.h>
static int pagesize = 1024; /* Size of a database page */
-static int db = -1; /* File descriptor for reading the DB */
-static int mxPage = 0; /* Last page number */
+static int fd = -1; /* File descriptor for reading the WAL file */
+static int mxFrame = 0; /* Last frame */
static int perLine = 16; /* HEX elements to print per line */
typedef long long int i64; /* Datatype for 64-bit integers */
+/* Information for computing the checksum */
+typedef struct Cksum Cksum;
+struct Cksum {
+ int bSwap; /* True to do byte swapping on 32-bit words */
+ unsigned s0, s1; /* Current checksum value */
+};
+
+/*
+** extract a 32-bit big-endian integer
+*/
+static unsigned int getInt32(const unsigned char *a){
+ unsigned int x = (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
+ return x;
+}
+
+/*
+** Swap bytes on a 32-bit unsigned integer
+*/
+static unsigned int swab32(unsigned int x){
+ return (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8)
+ + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24);
+}
+
+/* Extend the checksum. Reinitialize the checksum if bInit is true.
+*/
+static void extendCksum(
+ Cksum *pCksum,
+ unsigned char *aData,
+ unsigned int nByte,
+ int bInit
+){
+ unsigned int *a32;
+ if( bInit ){
+ int a = 0;
+ *((char*)&a) = 1;
+ if( a==1 ){
+ /* Host is little-endian */
+ pCksum->bSwap = getInt32(aData)!=0x377f0682;
+ }else{
+ /* Host is big-endian */
+ pCksum->bSwap = getInt32(aData)!=0x377f0683;
+ }
+ pCksum->s0 = 0;
+ pCksum->s1 = 0;
+ }
+ a32 = (unsigned int*)aData;
+ while( nByte>0 ){
+ unsigned int x0 = a32[0];
+ unsigned int x1 = a32[1];
+ if( pCksum->bSwap ){
+ x0 = swab32(x0);
+ x1 = swab32(x1);
+ }
+ pCksum->s0 += x0 + pCksum->s1;
+ pCksum->s1 += x1 + pCksum->s0;
+ nByte -= 8;
+ a32 += 2;
+ }
+}
/*
** Convert the var-int format into i64. Return the number of bytes
@@ -35,13 +100,6 @@ static int decodeVarint(const unsigned char *z, i64 *pVal){
return 9;
}
-/*
-** Extract a big-endian 32-bit integer
-*/
-static unsigned int decodeInt32(const unsigned char *z){
- return (z[0]<<24) + (z[1]<<16) + (z[2]<<8) + z[3];
-}
-
/* Report an out-of-memory error and die.
*/
static void out_of_memory(void){
@@ -57,23 +115,22 @@ static void out_of_memory(void){
*/
static unsigned char *getContent(int ofst, int nByte){
unsigned char *aData;
- aData = malloc(nByte+32);
+ aData = malloc(nByte);
if( aData==0 ) out_of_memory();
- memset(aData, 0, nByte+32);
- lseek(db, ofst, SEEK_SET);
- read(db, aData, nByte);
+ lseek(fd, ofst, SEEK_SET);
+ read(fd, aData, nByte);
return aData;
}
/*
** Print a range of bytes as hex and as ascii.
*/
-static unsigned char *print_byte_range(
- int ofst, /* First byte in the range of bytes to print */
- int nByte, /* Number of bytes to print */
- int printOfst /* Add this amount to the index on the left column */
+static void print_byte_range(
+ int ofst, /* First byte in the range of bytes to print */
+ int nByte, /* Number of bytes to print */
+ unsigned char *aData, /* Content to print */
+ int printOfst /* Add this amount to the index on the left column */
){
- unsigned char *aData;
int i, j;
const char *zOfstFmt;
@@ -89,7 +146,6 @@ static unsigned char *print_byte_range(
zOfstFmt = " %08x: ";
}
- aData = getContent(ofst, nByte);
for(i=0; i<nByte; i += perLine){
fprintf(stdout, zOfstFmt, i+printOfst);
for(j=0; j<perLine; j++){
@@ -108,34 +164,21 @@ static unsigned char *print_byte_range(
}
fprintf(stdout,"\n");
}
- return aData;
-}
-
-/*
-** Print an entire page of content as hex
-*/
-static print_page(int iPg){
- int iStart;
- 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 print_decode_line(
+static void print_decode_line(
unsigned char *aData, /* Content being decoded */
int ofst, int nByte, /* Start and size of decode */
+ int asHex, /* If true, output value as hex */
const char *zMsg /* Message to append */
){
int i, j;
int val = aData[ofst];
char zBuf[100];
sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
- i = strlen(zBuf);
+ i = (int)strlen(zBuf);
for(j=1; j<4; j++){
if( j>=nByte ){
sprintf(&zBuf[i], " ");
@@ -143,55 +186,107 @@ 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]);
+ }
+ if( asHex ){
+ sprintf(&zBuf[i], " 0x%08x", val);
+ }else{
+ sprintf(&zBuf[i], " %9d", val);
}
- sprintf(&zBuf[i], " %9d", val);
printf("%s %s\n", zBuf, zMsg);
}
/*
-** Decode the database header.
+** Print an entire page of content as hex
*/
-static void print_db_header(void){
+static void print_frame(int iFrame){
+ int iStart;
unsigned char *aData;
- aData = print_byte_range(0, 100, 0);
- printf("Decoded:\n");
- print_decode_line(aData, 16, 2, "Database page size");
- print_decode_line(aData, 18, 1, "File format write version");
- print_decode_line(aData, 19, 1, "File format read version");
- print_decode_line(aData, 20, 1, "Reserved space at end of page");
- print_decode_line(aData, 24, 4, "File change counter");
- print_decode_line(aData, 28, 4, "Size of database in pages");
- print_decode_line(aData, 32, 4, "Page number of first freelist page");
- print_decode_line(aData, 36, 4, "Number of freelist pages");
- print_decode_line(aData, 40, 4, "Schema cookie");
- print_decode_line(aData, 44, 4, "Schema format version");
- print_decode_line(aData, 48, 4, "Default page cache size");
- print_decode_line(aData, 52, 4, "Largest auto-vac root page");
- print_decode_line(aData, 56, 4, "Text encoding");
- print_decode_line(aData, 60, 4, "User version");
- print_decode_line(aData, 64, 4, "Incremental-vacuum mode");
- print_decode_line(aData, 68, 4, "meta[7]");
- print_decode_line(aData, 72, 4, "meta[8]");
- print_decode_line(aData, 76, 4, "meta[9]");
- print_decode_line(aData, 80, 4, "meta[10]");
- print_decode_line(aData, 84, 4, "meta[11]");
- print_decode_line(aData, 88, 4, "meta[12]");
- print_decode_line(aData, 92, 4, "Change counter for version number");
- print_decode_line(aData, 96, 4, "SQLite version number");
+ iStart = 32 + (iFrame-1)*(pagesize+24);
+ fprintf(stdout, "Frame %d: (offsets 0x%x..0x%x)\n",
+ iFrame, iStart, iStart+pagesize+24);
+ aData = getContent(iStart, pagesize+24);
+ print_decode_line(aData, 0, 4, 0, "Page number");
+ print_decode_line(aData, 4, 4, 0, "DB size, or 0 for non-commit");
+ print_decode_line(aData, 8, 4, 1, "Salt-1");
+ print_decode_line(aData,12, 4, 1, "Salt-2");
+ print_decode_line(aData,16, 4, 1, "Checksum-1");
+ print_decode_line(aData,20, 4, 1, "Checksum-2");
+ print_byte_range(iStart+24, pagesize, aData+24, 0);
+ free(aData);
}
/*
+** Summarize a single frame on a single line.
+*/
+static void print_oneline_frame(int iFrame, Cksum *pCksum){
+ int iStart;
+ unsigned char *aData;
+ unsigned int s0, s1;
+ iStart = 32 + (iFrame-1)*(pagesize+24);
+ aData = getContent(iStart, 24);
+ extendCksum(pCksum, aData, 8, 0);
+ extendCksum(pCksum, getContent(iStart+24, pagesize), pagesize, 0);
+ s0 = getInt32(aData+16);
+ s1 = getInt32(aData+20);
+ fprintf(stdout, "Frame %4d: %6d %6d 0x%08x,%08x 0x%08x,%08x %s\n",
+ iFrame,
+ getInt32(aData),
+ getInt32(aData+4),
+ getInt32(aData+8),
+ getInt32(aData+12),
+ s0,
+ s1,
+ (s0==pCksum->s0 && s1==pCksum->s1) ? "" : "cksum-fail"
+ );
+
+ /* Reset the checksum so that a single frame checksum failure will not
+ ** cause all subsequent frames to also show a failure. */
+ pCksum->s0 = s0;
+ pCksum->s1 = s1;
+ free(aData);
+}
+
+/*
+** Decode the WAL header.
+*/
+static void print_wal_header(Cksum *pCksum){
+ unsigned char *aData;
+ aData = getContent(0, 32);
+ if( pCksum ){
+ extendCksum(pCksum, aData, 24, 1);
+ printf("Checksum byte order: %s\n", pCksum->bSwap ? "swapped" : "native");
+ }
+ printf("WAL Header:\n");
+ print_decode_line(aData, 0, 4,1,"Magic. 0x377f0682 (le) or 0x377f0683 (be)");
+ print_decode_line(aData, 4, 4, 0, "File format");
+ print_decode_line(aData, 8, 4, 0, "Database page size");
+ print_decode_line(aData, 12,4, 0, "Checkpoint sequence number");
+ print_decode_line(aData, 16,4, 1, "Salt-1");
+ print_decode_line(aData, 20,4, 1, "Salt-2");
+ print_decode_line(aData, 24,4, 1, "Checksum-1");
+ print_decode_line(aData, 28,4, 1, "Checksum-2");
+ if( pCksum ){
+ if( pCksum->s0!=getInt32(aData+24) ){
+ printf("**** cksum-1 mismatch: 0x%08x\n", pCksum->s0);
+ }
+ if( pCksum->s1!=getInt32(aData+28) ){
+ printf("**** cksum-2 mismatch: 0x%08x\n", pCksum->s1);
+ }
+ }
+ free(aData);
+}
+/*
** 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;
+ int n, j;
+ i64 i, x, v;
const unsigned char *pData;
const unsigned char *pLimit;
char sep = ' ';
@@ -231,15 +326,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;
}
@@ -250,11 +345,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;
@@ -275,26 +370,25 @@ static int localPayload(i64 nPayload, char cType){
}
return nLocal;
}
-
/*
** Create a description for a single cell.
**
** 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 ){
@@ -340,10 +434,10 @@ static int describeCell(
** Decode a btree page
*/
static void decode_btree_page(
- unsigned char *a, /* Page content */
+ unsigned char *a, /* Content of the btree page to be decoded */
int pgno, /* Page number */
- int hdrSize, /* Size of the page header. 0 or 100 */
- char *zArgs /* Flags to control formatting */
+ int hdrSize, /* Size of the page1-header in bytes */
+ const char *zArgs /* Flags to control formatting */
){
const char *zType = "unknown";
int nCell;
@@ -366,14 +460,14 @@ static void decode_btree_page(
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");
+ print_decode_line(a, 0, 1, 0, zType);
+ print_decode_line(a, 1, 2, 0, "Offset to first freeblock");
+ print_decode_line(a, 3, 2, 0, "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");
+ print_decode_line(a, 5, 2, 0, "Offset to cell content area");
+ print_decode_line(a, 7, 1, 0, "Fragmented byte count");
if( a[0]==2 || a[0]==5 ){
- print_decode_line(a, 8, 4, "Right child");
+ print_decode_line(a, 8, 4, 0, "Right child");
iCellPtr = 12;
}else{
iCellPtr = 8;
@@ -391,17 +485,17 @@ static void decode_btree_page(
for(i=0; i<nCell; i++){
int cofst = iCellPtr + i*2;
char *zDesc;
- int n;
+ i64 n;
cofst = a[cofst]*256 + a[cofst+1];
n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc);
if( showMap ){
char zBuf[30];
- memset(&zMap[cofst], '*', n);
+ memset(&zMap[cofst], '*', (size_t)n);
zMap[cofst] = '[';
zMap[cofst+n-1] = ']';
sprintf(zBuf, "%d", i);
- j = strlen(zBuf);
+ j = (int)strlen(zBuf);
if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j);
}
printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
@@ -414,93 +508,46 @@ static void decode_btree_page(
}
}
-/*
-** Decode a freelist trunk page.
-*/
-static void decode_trunk_page(
- int pgno, /* The page number */
- int pagesize, /* Size of each page */
- int detail, /* Show leaf pages if true */
- int recursive /* Follow the trunk change if true */
-){
- int n, i, k;
- unsigned char *a;
- while( pgno>0 ){
- a = getContent((pgno-1)*pagesize, pagesize);
- printf("Decode of freelist trunk page %d:\n", pgno);
- print_decode_line(a, 0, 4, "Next freelist trunk page");
- print_decode_line(a, 4, 4, "Number of entries on this page");
- if( detail ){
- n = (int)decodeInt32(&a[4]);
- for(i=0; i<n; i++){
- unsigned int x = decodeInt32(&a[8+4*i]);
- char zIdx[10];
- sprintf(zIdx, "[%d]", i);
- printf(" %5s %7u", zIdx, x);
- if( i%5==4 ) printf("\n");
- }
- if( i%5!=0 ) printf("\n");
- }
- if( !recursive ){
- pgno = 0;
- }else{
- pgno = (int)decodeInt32(&a[0]);
- }
- free(a);
- }
-}
-
-/*
-** Print a usage comment
-*/
-static void usage(const char *argv0){
- fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0);
- fprintf(stderr,
- "args:\n"
- " dbheader Show database header\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 leave freelist pages on the decode\n"
- " NNNtr Recurisvely decode freelist starting at NNN\n"
- );
-}
-
int main(int argc, char **argv){
struct stat sbuf;
- unsigned char zPgSz[2];
+ unsigned char zPgSz[4];
if( argc<2 ){
- usage(argv[0]);
+ fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]);
exit(1);
}
- db = open(argv[1], O_RDONLY);
- if( db<0 ){
+ fd = open(argv[1], O_RDONLY);
+ if( fd<0 ){
fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
exit(1);
}
zPgSz[0] = 0;
zPgSz[1] = 0;
- lseek(db, 16, SEEK_SET);
- read(db, zPgSz, 2);
- pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
+ lseek(fd, 8, SEEK_SET);
+ read(fd, zPgSz, 4);
+ pagesize = zPgSz[1]*65536 + zPgSz[2]*256 + zPgSz[3];
if( pagesize==0 ) pagesize = 1024;
printf("Pagesize: %d\n", pagesize);
- fstat(db, &sbuf);
- mxPage = sbuf.st_size/pagesize;
- printf("Available pages: 1..%d\n", mxPage);
+ fstat(fd, &sbuf);
+ if( sbuf.st_size<32 ){
+ printf("file too small to be a WAL\n");
+ return 0;
+ }
+ mxFrame = (sbuf.st_size - 32)/(pagesize + 24);
+ printf("Available pages: 1..%d\n", mxFrame);
if( argc==2 ){
int i;
- for(i=1; i<=mxPage; i++) print_page(i);
+ Cksum x;
+ print_wal_header(&x);
+ for(i=1; i<=mxFrame; i++){
+ print_oneline_frame(i, &x);
+ }
}else{
int i;
for(i=2; i<argc; i++){
int iStart, iEnd;
char *zLeft;
- if( strcmp(argv[i], "dbheader")==0 ){
- print_db_header();
+ if( strcmp(argv[i], "header")==0 ){
+ print_wal_header(0);
continue;
}
if( !isdigit(argv[i][0]) ){
@@ -509,13 +556,14 @@ int main(int argc, char **argv){
}
iStart = strtol(argv[i], &zLeft, 0);
if( zLeft && strcmp(zLeft,"..end")==0 ){
- iEnd = mxPage;
+ iEnd = mxFrame;
}else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){
iEnd = strtol(&zLeft[2], 0, 0);
}else if( zLeft && zLeft[0]=='b' ){
int ofst, nByte, hdrSize;
unsigned char *a;
if( iStart==1 ){
+ hdrSize = 100;
ofst = hdrSize = 100;
nByte = pagesize-100;
}else{
@@ -523,35 +571,26 @@ int main(int argc, char **argv){
ofst = (iStart-1)*pagesize;
nByte = pagesize;
}
+ ofst = 32 + hdrSize + (iStart-1)*(pagesize+24) + 24;
a = getContent(ofst, nByte);
- decode_btree_page(a, iStart, hdrSize, &zLeft[1]);
+ decode_btree_page(a, iStart, hdrSize, zLeft+1);
free(a);
continue;
- }else if( zLeft && zLeft[0]=='t' ){
- unsigned char *a;
- int detail = 0;
- int recursive = 0;
- int i;
- for(i=1; zLeft[i]; i++){
- if( zLeft[i]=='r' ) recursive = 1;
- if( zLeft[i]=='d' ) detail = 1;
- }
- decode_trunk_page(iStart, pagesize, detail, recursive);
- continue;
}else{
iEnd = iStart;
}
- if( iStart<1 || iEnd<iStart || iEnd>mxPage ){
+ if( iStart<1 || iEnd<iStart || iEnd>mxFrame ){
fprintf(stderr,
"Page argument should be LOWER?..UPPER?. Range 1 to %d\n",
- mxPage);
+ mxFrame);
exit(1);
}
while( iStart<=iEnd ){
- print_page(iStart);
+ print_frame(iStart);
iStart++;
}
}
}
- close(db);
+ close(fd);
+ return 0;
}
« no previous file with comments | « third_party/sqlite/sqlite-src-3080704/tool/showstat4.c ('k') | third_party/sqlite/sqlite-src-3080704/tool/soak1.tcl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698