]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add btree-page decoding logic to showwal.c. Commands of the form:
authordrh <drh@noemail.net>
Fri, 25 Jan 2013 15:59:55 +0000 (15:59 +0000)
committerdrh <drh@noemail.net>
Fri, 25 Jan 2013 15:59:55 +0000 (15:59 +0000)
"showwal $FILE 123bmc" show the content of the btree page in frame
123.  "b" means decode the btree.  "c" means show cell content.
"m" means give a map of the btree page.

FossilOrigin-Name: 93b159da5d2570946fdcd7da120bf7eb82b840f3

manifest
manifest.uuid
tool/showwal.c

index 1986fa9616f63fd04e944130c976e52b0e86c5ec..afedd7efda17f5148e9bf1e88bb951476df91e43 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Further\simprovements\sto\sshowwal.c:\s\sReset\sthe\schecksum\safter\seach\sframe\sso\sthat\nonly\sindividual\schecksum\sfailures\sare\sshown.\s\sAnd\sonly\sshow\sfailures,\snot\ncorrect\schecksums.
-D 2013-01-25T15:31:44.708
+C Add\sbtree-page\sdecoding\slogic\sto\sshowwal.c.\s\sCommands\sof\sthe\sform:\n"showwal\s$FILE\s123bmc"\sshow\sthe\scontent\sof\sthe\sbtree\spage\sin\sframe\n123.\s\s"b"\smeans\sdecode\sthe\sbtree.\s\s"c"\smeans\sshow\scell\scontent.\n"m"\smeans\sgive\sa\smap\sof\sthe\sbtree\spage.
+D 2013-01-25T15:59:55.661
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in a48faa9e7dd7d556d84f5456eabe5825dd8a6282
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -1016,7 +1016,7 @@ F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
 F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
 F tool/showdb.c aca2644aa4de7c0cad5821e50bbd55397e0974b8
 F tool/showjournal.c b62cecaab86a4053d944c276bb5232e4d17ece02
-F tool/showwal.c 0c98daec7f4152de1bc2712ba555d107638d43ac
+F tool/showwal.c 3f7f7da5ec0cba51b1449a75f700493377da57b5
 F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe
 F tool/space_used.tcl f714c41a59e326b8b9042f415b628b561bafa06b
 F tool/spaceanal.tcl 76f583a246a0b027f423252339e711f13198932e
@@ -1034,7 +1034,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P a7f6d19816cbfc50060a9d1c0c402cdd23bd16de
-R 993105ee6da40f7d0b83454a29ef235d
+P 4e2bf57549a8d50fc0993386c724eb4a2b35c9fe
+R 77bd3fc673a5a4823c7d3950cb50d684
 U drh
-Z 6c8cb359469cd78d4ad182442780b54d
+Z 3c8d1d2fa3c0372f4e65d42510e07e23
index 0e111fe8a63e40f15eb9ef77ba6e2c915d1ad8e4..80d89dd7f648fb85b61fa0eee9ea12a766d37fed 100644 (file)
@@ -1 +1 @@
-4e2bf57549a8d50fc0993386c724eb4a2b35c9fe
\ No newline at end of file
+93b159da5d2570946fdcd7da120bf7eb82b840f3
\ No newline at end of file
index 599d011647fcbda69896c22c4e42e5fe98e6cc07..2888c10aa590718b1ebf9a499745d0568e5fc6e3 100644 (file)
@@ -270,58 +270,189 @@ static void print_wal_header(Cksum *pCksum){
   }
   free(aData);
 }
+/*
+** Describe cell content.
+*/
+static int describeContent(
+  unsigned char *a,       /* Cell content */
+  int nLocal,             /* Bytes in a[] */
+  char *zDesc             /* Write description here */
+){
+  int nDesc = 0;
+  int n, i, j;
+  i64 x, v;
+  const unsigned char *pData;
+  const unsigned char *pLimit;
+  char sep = ' ';
+
+  pLimit = &a[nLocal];
+  n = decodeVarint(a, &x);
+  pData = &a[x];
+  a += n;
+  i = x - n;
+  while( i>0 && pData<=pLimit ){
+    n = decodeVarint(a, &x);
+    a += n;
+    i -= n;
+    nLocal -= n;
+    zDesc[0] = sep;
+    sep = ',';
+    nDesc++;
+    zDesc++;
+    if( x==0 ){
+      sprintf(zDesc, "*");     /* NULL is a "*" */
+    }else if( x>=1 && x<=6 ){
+      v = (signed char)pData[0];
+      pData++;
+      switch( x ){
+        case 6:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
+        case 5:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
+        case 4:  v = (v<<8) + pData[0];  pData++;
+        case 3:  v = (v<<8) + pData[0];  pData++;
+        case 2:  v = (v<<8) + pData[0];  pData++;
+      }
+      sprintf(zDesc, "%lld", v);
+    }else if( x==7 ){
+      sprintf(zDesc, "real");
+      pData += 8;
+    }else if( x==8 ){
+      sprintf(zDesc, "0");
+    }else if( x==9 ){
+      sprintf(zDesc, "1");
+    }else if( x>=12 ){
+      int size = (x-12)/2;
+      if( (x&1)==0 ){
+        sprintf(zDesc, "blob(%d)", size);
+      }else{
+        sprintf(zDesc, "txt(%d)", size);
+      }
+      pData += size;
+    }
+    j = strlen(zDesc);
+    zDesc += j;
+    nDesc += j;
+  }
+  return nDesc;
+}
+
+/*
+** 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;
+  if( cType==13 ){
+    /* Table leaf */
+    maxLocal = pagesize-35;
+    minLocal = (pagesize-12)*32/255-23;
+  }else{
+    maxLocal = (pagesize-12)*64/255-23;
+    minLocal = (pagesize-12)*32/255-23;
+  }
+  if( nPayload>maxLocal ){
+    surplus = minLocal + (nPayload-minLocal)%(pagesize-4);
+    if( surplus<=maxLocal ){
+      nLocal = surplus;
+    }else{
+      nLocal = minLocal;
+    }
+  }else{
+    nLocal = nPayload;
+  }
+  return nLocal;
+}
 
 /*
 ** Create a description for a single cell.
+**
+** The return value is the local cell size.
 */
-static int describeCell(unsigned char cType, unsigned char *a, char **pzDesc){
+static int 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;
   int n = 0;
   int leftChild;
   i64 nPayload;
   i64 rowid;
-  static char zDesc[100];
+  int nLocal;
+  static char zDesc[1000];
   i = 0;
   if( cType<=5 ){
     leftChild = ((a[0]*256 + a[1])*256 + a[2])*256 + a[3];
     a += 4;
     n += 4;
-    sprintf(zDesc, "left-child: %d ", leftChild);
+    sprintf(zDesc, "lx: %d ", leftChild);
     nDesc = strlen(zDesc);
   }
   if( cType!=5 ){
     i = decodeVarint(a, &nPayload);
     a += i;
     n += i;
-    sprintf(&zDesc[nDesc], "sz: %lld ", nPayload);
+    sprintf(&zDesc[nDesc], "n: %lld ", nPayload);
     nDesc += strlen(&zDesc[nDesc]);
+    nLocal = localPayload(nPayload, cType);
+  }else{
+    nPayload = nLocal = 0;
   }
   if( cType==5 || cType==13 ){
     i = decodeVarint(a, &rowid);
     a += i;
     n += i;
-    sprintf(&zDesc[nDesc], "rowid: %lld ", rowid);
+    sprintf(&zDesc[nDesc], "r: %lld ", rowid);
     nDesc += strlen(&zDesc[nDesc]);
   }
+  if( nLocal<nPayload ){
+    int ovfl;
+    unsigned char *b = &a[nLocal];
+    ovfl = ((b[0]*256 + b[1])*256 + b[2])*256 + b[3];
+    sprintf(&zDesc[nDesc], "ov: %d ", ovfl);
+    nDesc += strlen(&zDesc[nDesc]);
+    n += 4;
+  }
+  if( showCellContent && cType!=5 ){
+    nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]);
+  }
   *pzDesc = zDesc;
-  return n;
+  return nLocal+n;
 }
 
 /*
 ** Decode a btree page
 */
-static void decode_btree_page(unsigned char *a, int pgno, int hdrSize){
+static void decode_btree_page(
+  unsigned char *a,   /* Content of the btree page to be decoded */
+  int pgno,           /* Page number */
+  int hdrSize,        /* Size of the page1-header in bytes */
+  const char *zArgs   /* Flags to control formatting */
+){
   const char *zType = "unknown";
   int nCell;
-  int i;
+  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++;
+  }
   printf("Decode of btree page %d:\n", pgno);
   print_decode_line(a, 0, 1, 0, zType);
   print_decode_line(a, 1, 2, 0, "Offset to first freeblock");
@@ -335,13 +466,40 @@ static void decode_btree_page(unsigned char *a, int pgno, int hdrSize){
   }else{
     iCellPtr = 8;
   }
+  if( nCell>0 ){
+    printf(" key: lx=left-child n=payload-size r=rowid\n");
+  }
+  if( showMap ){
+    zMap = malloc(pagesize);
+    memset(zMap, '.', pagesize);
+    memset(zMap, '1', hdrSize);
+    memset(&zMap[hdrSize], 'H', iCellPtr);
+    memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell);
+  }
   for(i=0; i<nCell; i++){
     int cofst = iCellPtr + i*2;
     char *zDesc;
+    int n;
+
     cofst = a[cofst]*256 + a[cofst+1];
-    describeCell(a[0], &a[cofst-hdrSize], &zDesc);
+    n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc);
+    if( showMap ){
+      char zBuf[30];
+      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);
+    }
     printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
   }
+  if( showMap ){
+    for(i=0; i<pagesize; i+=64){
+      printf(" %03x: %.64s\n", i, &zMap[i]);
+    }
+    free(zMap);
+  }  
 }
 
 int main(int argc, char **argv){
@@ -395,11 +553,11 @@ int main(int argc, char **argv){
         iEnd = mxFrame;
       }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){
         iEnd = strtol(&zLeft[2], 0, 0);
-#if 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{
@@ -407,11 +565,11 @@ 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);
+        decode_btree_page(a, iStart, hdrSize, zLeft+1);
         free(a);
         continue;
-#endif
       }else{
         iEnd = iStart;
       }