Beispiel #1
0
/*
** 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);
  }
}
Beispiel #2
0
/*
** Describe the usages of a b-tree page
*/
static void page_usage_btree(
  int pgno,             /* Page to describe */
  int parent,           /* Parent of this page.  0 for root pages */
  int idx,              /* Which child of the parent */
  const char *zName     /* Name of the table */
){
  unsigned char *a;
  const char *zType = "corrupt node";
  int nCell;
  int i;
  int hdr = pgno==1 ? 100 : 0;

  if( pgno<=0 || pgno>mxPage ) return;
  a = getContent((pgno-1)*pagesize, pagesize);
  switch( a[hdr] ){
    case 2:  zType = "interior node of index";  break;
    case 5:  zType = "interior node of table";  break;
    case 10: zType = "leaf of index";           break;
    case 13: zType = "leaf of table";           break;
  }
  if( parent ){
    page_usage_msg(pgno, "%s [%s], child %d of page %d",
                   zType, zName, idx, parent);
  }else{
    page_usage_msg(pgno, "root %s [%s]", zType, zName);
  }
  nCell = a[hdr+3]*256 + a[hdr+4];
  if( a[hdr]==2 || a[hdr]==5 ){
    int cellstart = hdr+12;
    unsigned int child;
    for(i=0; i<nCell; i++){
      int ofst;

      ofst = cellstart + i*2;
      ofst = a[ofst]*256 + a[ofst+1];
      child = decodeInt32(a+ofst);
      page_usage_btree(child, pgno, i, zName);
    }
    child = decodeInt32(a+cellstart-4);
    page_usage_btree(child, pgno, i, zName);
  }
  if( a[hdr]==2 || a[hdr]==10 || a[hdr]==13 ){
    int cellstart = hdr + 8 + 4*(a[hdr]<=5);
    for(i=0; i<nCell; i++){
      int ofst;
      ofst = cellstart + i*2;
      ofst = a[ofst]*256 + a[ofst+1];
      page_usage_cell(a[hdr], a+ofst, pgno, i);
    }
  }
  free(a);
}
Beispiel #3
0
/*
** Try to figure out how every page in the database file is being used.
*/
static void page_usage_report(const char *zPrg, const char *zDbName){
  int i, j;
  int rc;
  sqlite3 *db;
  sqlite3_stmt *pStmt;
  unsigned char *a;
  char zQuery[200];

  /* Avoid the pathological case */
  if( g.mxPage<1 ){
    printf("empty database\n");
    return;
  }

  /* Open the database file */
  db = openDatabase(zPrg, zDbName);

  /* Set up global variables zPageUse[] and g.mxPage to record page
  ** usages */
  zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(g.mxPage+1) );
  if( zPageUse==0 ) out_of_memory();
  memset(zPageUse, 0, sizeof(zPageUse[0])*(g.mxPage+1));

  /* Discover the usage of each page */
  a = fileRead(0, 100);
  page_usage_freelist(decodeInt32(a+32));
  page_usage_ptrmap(a);
  sqlite3_free(a);
  page_usage_btree(1, 0, 0, "sqlite_master");
  sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0);
  for(j=0; j<2; j++){
    sqlite3_snprintf(sizeof(zQuery), zQuery,
             "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage"
             " ORDER BY rowid %s", j?"DESC":"");
    rc = sqlite3_prepare_v2(db, zQuery, -1, &pStmt, 0);
    if( rc==SQLITE_OK ){
      while( sqlite3_step(pStmt)==SQLITE_ROW ){
        int pgno = sqlite3_column_int(pStmt, 2);
        page_usage_btree(pgno, 0, 0, (const char*)sqlite3_column_text(pStmt,1));
      }
    }else{
      printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db));
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ) break;
  }
  sqlite3_close(db);

  /* Print the report and free memory used */
  for(i=1; i<=g.mxPage; i++){
    printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
    sqlite3_free(zPageUse[i]);
  }
  sqlite3_free(zPageUse);
  zPageUse = 0;
}
Beispiel #4
0
/*
** Find overflow pages of a cell and describe their usage.
*/
static void page_usage_cell(
  unsigned char cType,    /* Page type */
  unsigned char *a,       /* Cell content */
  int pgno,               /* page containing the cell */
  int cellno              /* Index of the cell on the page */
){
  int i;
  int nDesc = 0;
  int n = 0;
  i64 nPayload;
  i64 rowid;
  int nLocal;
  i = 0;
  if( cType<=5 ){
    a += 4;
    n += 4;
  }
  if( cType!=5 ){
    i = decodeVarint(a, &nPayload);
    a += i;
    n += i;
    nLocal = localPayload(nPayload, cType);
  }else{
    nPayload = nLocal = 0;
  }
  if( cType==5 || cType==13 ){
    i = decodeVarint(a, &rowid);
    a += i;
    n += i;
  }
  if( nLocal<nPayload ){
    int ovfl = decodeInt32(a+nLocal);
    int cnt = 0;
    while( ovfl && (cnt++)<mxPage ){
      page_usage_msg(ovfl, "overflow %d from cell %d of page %d",
                     cnt, cellno, pgno);
      a = getContent((ovfl-1)*pagesize, 4);
      ovfl = decodeInt32(a);
      free(a);
    }
  }
}
Beispiel #5
0
/*
** Try to figure out how every page in the database file is being used.
*/
static void page_usage_report(const char *zDbName){
  int i;
  int rc;
  sqlite3 *db;
  sqlite3_stmt *pStmt;
  unsigned char *a;

  /* Avoid the pathological case */
  if( mxPage<1 ){
    printf("empty database\n");
    return;
  }

  /* Open the database file */
  rc = sqlite3_open(zDbName, &db);
  if( rc ){
    printf("cannot open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    return;
  }

  /* Set up global variables zPageUse[] and mxPage to record page
  ** usages */
  zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(mxPage+1) );
  if( zPageUse==0 ) out_of_memory();
  memset(zPageUse, 0, sizeof(zPageUse[0])*(mxPage+1));

  /* Discover the usage of each page */
  a = getContent(0, 100);
  page_usage_freelist(decodeInt32(a+32));
  free(a);
  page_usage_btree(1, 0, 0, "sqlite_master");
  rc = sqlite3_prepare_v2(db,
           "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage",
           -1, &pStmt, 0);
  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));
    }
  }else{
    printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db));
  }
  sqlite3_finalize(pStmt);
  sqlite3_close(db);

  /* Print the report and free memory used */
  for(i=1; i<=mxPage; i++){
    printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
    sqlite3_free(zPageUse[i]);
  }
  sqlite3_free(zPageUse);
  zPageUse = 0;
}
Beispiel #6
0
/*
** Determine page usage by the freelist
*/
static void page_usage_freelist(int pgno){
  unsigned char *a;
  int cnt = 0;
  int i;
  int n;
  int iNext;
  int parent = 1;

  while( pgno>0 && pgno<=mxPage && (cnt++)<mxPage ){
    page_usage_msg(pgno, "freelist trunk #%d child of %d", cnt, parent);
    a = getContent((pgno-1)*pagesize, pagesize);
    iNext = decodeInt32(a);
    n = decodeInt32(a+4);
    for(i=0; i<n; i++){
      int child = decodeInt32(a + (i*4+8));
      page_usage_msg(child, "freelist leaf, child %d of trunk page %d",
                     i, pgno);
    }
    free(a);
    parent = pgno;
    pgno = iNext;
  }
}
Beispiel #7
0
/*
** 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;
  unsigned char *aHdr;
  unsigned char *a;
  int usable;
  int perPage;
  unsigned int i;

  /* Avoid the pathological case */
  if( mxPage<1 ){
    printf("empty database\n");
    return;
  }

  /* Make sure PTRMAPs are used in this database */
  aHdr = getContent(0, 100);
  if( aHdr[55]==0 ){
    printf("database does not use PTRMAP pages\n");
    return;
  }
  usable = pagesize - aHdr[20];
  perPage = usable/5;
  free(aHdr);
  printf("%5d: root of sqlite_master\n", 1);
  for(pgno=2; pgno<=mxPage; pgno += perPage+1){
    printf("%5d: PTRMAP page covering %d..%d\n", pgno,
           pgno+1, pgno+perPage);
    a = getContent((pgno-1)*pagesize, usable);
    for(i=0; i+5<=usable && pgno+1+i/5<=mxPage; i+=5){
      const char *zType = "???";
      unsigned int iFrom = decodeInt32(&a[i+1]);
      switch( a[i] ){
        case 1:  zType = "b-tree root page";        break;
        case 2:  zType = "freelist page";           break;
        case 3:  zType = "first page of overflow";  break;
        case 4:  zType = "later page of overflow";  break;
        case 5:  zType = "b-tree non-root page";    break;
      }
      printf("%5d: %s, parent=%u\n", pgno+1+i/5, zType, iFrom);
    }
    free(a);
  }
}
Beispiel #8
0
bool KeyedDecoder::decodeUInt32(const String& key, uint32_t& result)
{
    return decodeInt32(key, reinterpret_cast<int32_t&>(result));
}
Beispiel #9
0
/*
** 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 = 0;
  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<end && j<nHdr ){
       const char *zTypeName;
       int sz = 0;
       char zNm[30];
       i = decodeVarint(x+j, &iType);
       printBytes(a, x+j, i);
       printf("typecode[%d]: %d - ", nCol, (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);
       szCol[nCol] = sz;
       ofstCol[nCol] = (int)k;
       typeCol[nCol] = (int)iType;
       k += sz;
       nCol++;
       j += i;
    }
    for(i=0; i<nCol && ofstCol[i]+szCol[i]<=nLocal; i++){
       int s = ofstCol[i];
       i64 v;
       const unsigned char *pData;
       if( szCol[i]==0 ) continue;
       printBytes(a, x+s, szCol[i]);
       printf("data[%d]: ", i);
       pData = x+s;
       if( typeCol[i]<=7 ){
         v = (signed char)pData[0];
         for(k=1; k<szCol[i]; k++){
           v = (v<<8) + pData[k];
         }
         if( typeCol[i]==7 ){
           double r;
           memcpy(&r, &v, sizeof(r));
           printf("%#g\n", r);
         }else{
           printf("%lld\n", v);
         }
       }else{
         int ii, jj;
         char zConst[32];
         if( (typeCol[i]&1)==0 ){
           zConst[0] = 'x';
           zConst[1] = '\'';
           for(ii=2, jj=0; jj<szCol[i] && ii<24; jj++, ii+=2){
             sprintf(zConst+ii, "%02x", pData[jj]);
           }
         }else{
           zConst[0] = '\'';
           for(ii=1, jj=0; jj<szCol[i] && ii<24; jj++, ii++){
             zConst[ii] = ISPRINT(pData[jj]) ? pData[jj] : '.';
           }
           zConst[ii] = 0;
         }
         if( jj<szCol[i] ){
           memcpy(zConst+ii, "...'", 5);
         }else{
           memcpy(zConst+ii, "'", 2);
         }
         printf("%s\n", zConst);
       }
       j = ofstCol[i] + szCol[i];
    }
  }
  if( j<nLocal ){
    printBytes(a, x+j, 0);
    printf("... %lld bytes of content ...\n", nLocal-j);
  }
  if( nLocal<nPayload ){
    printBytes(a, x+nLocal, 4);
    printf("overflow-page: %d\n", decodeInt32(x+nLocal));
  }
}