Index: third_party/sqlite/sqlite-src-3080704/tool/offsets.c |
diff --git a/third_party/sqlite/sqlite-src-3080704/tool/offsets.c b/third_party/sqlite/sqlite-src-3080704/tool/offsets.c |
deleted file mode 100644 |
index 8e098e71cb98be9fa218331f7a8a1d9c31e5218a..0000000000000000000000000000000000000000 |
--- a/third_party/sqlite/sqlite-src-3080704/tool/offsets.c |
+++ /dev/null |
@@ -1,329 +0,0 @@ |
-/* |
-** This program searches an SQLite database file for the lengths and |
-** offsets for all TEXT or BLOB entries for a particular column of a |
-** particular table. The rowid, size and offset for the column are |
-** written to standard output. There are three arguments, which are the |
-** name of the database file, the table, and the column. |
-*/ |
-#include "sqlite3.h" |
-#include <stdio.h> |
-#include <stdlib.h> |
-#include <stdarg.h> |
-#include <string.h> |
- |
-typedef unsigned char u8; |
-typedef struct GState GState; |
- |
-#define ArraySize(X) (sizeof(X)/sizeof(X[0])) |
- |
-/* |
-** Global state information for this program. |
-*/ |
-struct GState { |
- char *zErr; /* Error message text */ |
- FILE *f; /* Open database file */ |
- int szPg; /* Page size for the database file */ |
- int iRoot; /* Root page of the table */ |
- int iCol; /* Column number for the column */ |
- int pgno; /* Current page number */ |
- u8 *aPage; /* Current page content */ |
- u8 *aStack[20]; /* Page stack */ |
- int aPgno[20]; /* Page number stack */ |
- int nStack; /* Depth of stack */ |
- int bTrace; /* True for tracing output */ |
-}; |
- |
-/* |
-** Write an error. |
-*/ |
-static void ofstError(GState *p, const char *zFormat, ...){ |
- va_list ap; |
- sqlite3_free(p->zErr); |
- va_start(ap, zFormat); |
- p->zErr = sqlite3_vmprintf(zFormat, ap); |
- va_end(ap); |
-} |
- |
-/* |
-** Write a trace message |
-*/ |
-static void ofstTrace(GState *p, const char *zFormat, ...){ |
- va_list ap; |
- if( p->bTrace ){ |
- va_start(ap, zFormat); |
- vprintf(zFormat, ap); |
- va_end(ap); |
- } |
-} |
- |
-/* |
-** Find the root page of the table and the column number of the column. |
-*/ |
-static void ofstRootAndColumn( |
- GState *p, /* Global state */ |
- const char *zFile, /* Name of the database file */ |
- const char *zTable, /* Name of the table */ |
- const char *zColumn /* Name of the column */ |
-){ |
- sqlite3 *db = 0; |
- sqlite3_stmt *pStmt = 0; |
- char *zSql = 0; |
- int rc; |
- if( p->zErr ) return; |
- rc = sqlite3_open(zFile, &db); |
- if( rc ){ |
- ofstError(p, "cannot open database file \"%s\"", zFile); |
- goto rootAndColumn_exit; |
- } |
- zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master WHERE name=%Q", |
- zTable); |
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
- if( rc ) ofstError(p, "%s: [%s]", sqlite3_errmsg(db), zSql); |
- sqlite3_free(zSql); |
- if( p->zErr ) goto rootAndColumn_exit; |
- if( sqlite3_step(pStmt)!=SQLITE_ROW ){ |
- ofstError(p, "cannot find table [%s]\n", zTable); |
- sqlite3_finalize(pStmt); |
- goto rootAndColumn_exit; |
- } |
- p->iRoot = sqlite3_column_int(pStmt , 0); |
- sqlite3_finalize(pStmt); |
- |
- p->iCol = -1; |
- zSql = sqlite3_mprintf("PRAGMA table_info(%Q)", zTable); |
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
- if( rc ) ofstError(p, "%s: [%s}", sqlite3_errmsg(db), zSql); |
- sqlite3_free(zSql); |
- if( p->zErr ) goto rootAndColumn_exit; |
- while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
- const char *zCol = sqlite3_column_text(pStmt, 1); |
- if( strlen(zCol)==strlen(zColumn) |
- && sqlite3_strnicmp(zCol, zColumn, strlen(zCol))==0 |
- ){ |
- p->iCol = sqlite3_column_int(pStmt, 0); |
- break; |
- } |
- } |
- sqlite3_finalize(pStmt); |
- if( p->iCol<0 ){ |
- ofstError(p, "no such column: %s.%s", zTable, zColumn); |
- goto rootAndColumn_exit; |
- } |
- |
- zSql = sqlite3_mprintf("PRAGMA page_size"); |
- rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); |
- if( rc ) ofstError(p, "%s: [%s]", sqlite3_errmsg(db), zSql); |
- sqlite3_free(zSql); |
- if( p->zErr ) goto rootAndColumn_exit; |
- if( sqlite3_step(pStmt)!=SQLITE_ROW ){ |
- ofstError(p, "cannot find page size"); |
- }else{ |
- p->szPg = sqlite3_column_int(pStmt, 0); |
- } |
- sqlite3_finalize(pStmt); |
- |
-rootAndColumn_exit: |
- sqlite3_close(db); |
- return; |
-} |
- |
-/* |
-** Pop a page from the stack |
-*/ |
-static void ofstPopPage(GState *p){ |
- if( p->nStack<=0 ) return; |
- p->nStack--; |
- sqlite3_free(p->aStack[p->nStack]); |
- p->pgno = p->aPgno[p->nStack-1]; |
- p->aPage = p->aStack[p->nStack-1]; |
-} |
- |
- |
-/* |
-** Push a new page onto the stack. |
-*/ |
-static void ofstPushPage(GState *p, int pgno){ |
- u8 *pPage; |
- size_t got; |
- if( p->zErr ) return; |
- if( p->nStack >= ArraySize(p->aStack) ){ |
- ofstError(p, "page stack overflow"); |
- return; |
- } |
- p->aPgno[p->nStack] = pgno; |
- p->aStack[p->nStack] = pPage = sqlite3_malloc( p->szPg ); |
- if( pPage==0 ){ |
- fprintf(stderr, "out of memory\n"); |
- exit(1); |
- } |
- p->nStack++; |
- p->aPage = pPage; |
- p->pgno = pgno; |
- fseek(p->f, (pgno-1)*p->szPg, SEEK_SET); |
- got = fread(pPage, 1, p->szPg, p->f); |
- if( got!=p->szPg ){ |
- ofstError(p, "unable to read page %d", pgno); |
- ofstPopPage(p); |
- } |
-} |
- |
-/* Read a two-byte integer at the given offset into the current page */ |
-static int ofst2byte(GState *p, int ofst){ |
- int x = p->aPage[ofst]; |
- return (x<<8) + p->aPage[ofst+1]; |
-} |
- |
-/* Read a four-byte integer at the given offset into the current page */ |
-static int ofst4byte(GState *p, int ofst){ |
- int x = p->aPage[ofst]; |
- x = (x<<8) + p->aPage[ofst+1]; |
- x = (x<<8) + p->aPage[ofst+2]; |
- x = (x<<8) + p->aPage[ofst+3]; |
- return x; |
-} |
- |
-/* Read a variable-length integer. Update the offset */ |
-static sqlite3_int64 ofstVarint(GState *p, int *pOfst){ |
- sqlite3_int64 x = 0; |
- u8 *a = &p->aPage[*pOfst]; |
- int n = 0; |
- while( n<8 && (a[0] & 0x80)!=0 ){ |
- x = (x<<7) + (a[0] & 0x7f); |
- n++; |
- a++; |
- } |
- if( n==8 ){ |
- x = (x<<8) + a[0]; |
- }else{ |
- x = (x<<7) + a[0]; |
- } |
- *pOfst += (n+1); |
- return x; |
-} |
- |
-/* Return the absolute offset into a file for the given offset |
-** into the current page */ |
-static int ofstInFile(GState *p, int ofst){ |
- return p->szPg*(p->pgno-1) + ofst; |
-} |
- |
-/* Return the size (in bytes) of the data corresponding to the |
-** given serial code */ |
-static int ofstSerialSize(int scode){ |
- if( scode<5 ) return scode; |
- if( scode==5 ) return 6; |
- if( scode<8 ) return 8; |
- if( scode<12 ) return 0; |
- return (scode-12)/2; |
-} |
- |
-/* Forward reference */ |
-static void ofstWalkPage(GState*, int); |
- |
-/* Walk an interior btree page */ |
-static void ofstWalkInteriorPage(GState *p){ |
- int nCell; |
- int i; |
- int ofst; |
- int iChild; |
- |
- nCell = ofst2byte(p, 3); |
- for(i=0; i<nCell; i++){ |
- ofst = ofst2byte(p, 12+i*2); |
- iChild = ofst4byte(p, ofst); |
- ofstWalkPage(p, iChild); |
- if( p->zErr ) return; |
- } |
- ofstWalkPage(p, ofst4byte(p, 8)); |
-} |
- |
-/* Walk a leaf btree page */ |
-static void ofstWalkLeafPage(GState *p){ |
- int nCell; |
- int i; |
- int ofst; |
- int nPayload; |
- sqlite3_int64 rowid; |
- int nHdr; |
- int j; |
- int scode; |
- int sz; |
- int dataOfst; |
- char zMsg[200]; |
- |
- nCell = ofst2byte(p, 3); |
- for(i=0; i<nCell; i++){ |
- ofst = ofst2byte(p, 8+i*2); |
- nPayload = ofstVarint(p, &ofst); |
- rowid = ofstVarint(p, &ofst); |
- if( nPayload > p->szPg-35 ){ |
- sqlite3_snprintf(sizeof(zMsg), zMsg, |
- "# overflow rowid %lld", rowid); |
- printf("%s\n", zMsg); |
- continue; |
- } |
- dataOfst = ofst; |
- nHdr = ofstVarint(p, &ofst); |
- dataOfst += nHdr; |
- for(j=0; j<p->iCol; j++){ |
- scode = ofstVarint(p, &ofst); |
- dataOfst += ofstSerialSize(scode); |
- } |
- scode = ofstVarint(p, &ofst); |
- sz = ofstSerialSize(scode); |
- sqlite3_snprintf(sizeof(zMsg), zMsg, |
- "rowid %12lld size %5d offset %8d", |
- rowid, sz, ofstInFile(p, dataOfst)); |
- printf("%s\n", zMsg); |
- } |
-} |
- |
-/* |
-** Output results from a single page. |
-*/ |
-static void ofstWalkPage(GState *p, int pgno){ |
- if( p->zErr ) return; |
- ofstPushPage(p, pgno); |
- if( p->zErr ) return; |
- if( p->aPage[0]==5 ){ |
- ofstWalkInteriorPage(p); |
- }else if( p->aPage[0]==13 ){ |
- ofstWalkLeafPage(p); |
- }else{ |
- ofstError(p, "page %d has a faulty type byte: %d", pgno, p->aPage[0]); |
- } |
- ofstPopPage(p); |
-} |
- |
-int main(int argc, char **argv){ |
- GState g; |
- memset(&g, 0, sizeof(g)); |
- if( argc>2 && strcmp(argv[1],"--trace")==0 ){ |
- g.bTrace = 1; |
- argc--; |
- argv++; |
- } |
- if( argc!=4 ){ |
- fprintf(stderr, "Usage: %s DATABASE TABLE COLUMN\n", *argv); |
- exit(1); |
- } |
- ofstRootAndColumn(&g, argv[1], argv[2], argv[3]); |
- if( g.zErr ){ |
- fprintf(stderr, "%s\n", g.zErr); |
- exit(1); |
- } |
- ofstTrace(&g, "# szPg = %d\n", g.szPg); |
- ofstTrace(&g, "# iRoot = %d\n", g.iRoot); |
- ofstTrace(&g, "# iCol = %d\n", g.iCol); |
- g.f = fopen(argv[1], "rb"); |
- if( g.f==0 ){ |
- fprintf(stderr, "cannot open \"%s\"\n", argv[1]); |
- exit(1); |
- } |
- ofstWalkPage(&g, g.iRoot); |
- if( g.zErr ){ |
- fprintf(stderr, "%s\n", g.zErr); |
- exit(1); |
- } |
- return 0; |
-} |