Index: third_party/sqlite/src/src/test_stat.c |
diff --git a/third_party/sqlite/src/src/test_stat.c b/third_party/sqlite/src/src/test_stat.c |
index c85463e52657d712d07684c72b64406972a9b250..615df3d80fe155847516cf00b5a5c0f0e129ea25 100644 |
--- a/third_party/sqlite/src/src/test_stat.c |
+++ b/third_party/sqlite/src/src/test_stat.c |
@@ -18,7 +18,9 @@ |
** for an example implementation. |
*/ |
-#include "sqliteInt.h" |
+#ifndef SQLITE_AMALGAMATION |
+# include "sqliteInt.h" |
+#endif |
#ifndef SQLITE_OMIT_VIRTUALTABLE |
@@ -62,20 +64,11 @@ |
" ncell INTEGER, /* Cells on page (0 for overflow) */" \ |
" payload INTEGER, /* Bytes of payload on this page */" \ |
" unused INTEGER, /* Bytes of unused space on this page */" \ |
- " mx_payload INTEGER /* Largest payload size of all cells */" \ |
+ " mx_payload INTEGER, /* Largest payload size of all cells */" \ |
+ " pgoffset INTEGER, /* Offset of page in file */" \ |
+ " pgsize INTEGER /* Size of the page */" \ |
");" |
-#if 0 |
-#define VTAB_SCHEMA2 \ |
- "CREATE TABLE yy( " \ |
- " pageno INTEGER, /* B-tree page number */" \ |
- " cellno INTEGER, /* Cell number within page */" \ |
- " local INTEGER, /* Bytes of content stored locally */" \ |
- " payload INTEGER, /* Total cell payload size */" \ |
- " novfl INTEGER /* Number of overflow pages */" \ |
- ");" |
-#endif |
- |
typedef struct StatTable StatTable; |
typedef struct StatCursor StatCursor; |
@@ -124,6 +117,8 @@ struct StatCursor { |
int nPayload; /* Value of 'payload' column */ |
int nUnused; /* Value of 'unused' column */ |
int nMxPayload; /* Value of 'mx_payload' column */ |
+ i64 iOffset; /* Value of 'pgOffset' column */ |
+ int szPage; /* Value of 'pgSize' column */ |
}; |
struct StatTable { |
@@ -281,6 +276,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ |
int iOff; |
int nHdr; |
int isLeaf; |
+ int szPage; |
u8 *aData = sqlite3PagerGetData(p->pPg); |
u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; |
@@ -301,10 +297,11 @@ static int statDecodePage(Btree *pBt, StatPage *p){ |
} |
p->nUnused = nUnused; |
p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); |
+ szPage = sqlite3BtreeGetPageSize(pBt); |
if( p->nCell ){ |
int i; /* Used to iterate through cells */ |
- int nUsable = sqlite3BtreeGetPageSize(pBt) - sqlite3BtreeGetReserve(pBt); |
+ int nUsable = szPage - sqlite3BtreeGetReserve(pBt); |
p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell)); |
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell)); |
@@ -327,12 +324,13 @@ static int statDecodePage(Btree *pBt, StatPage *p){ |
u64 dummy; |
iOff += sqlite3GetVarint(&aData[iOff], &dummy); |
} |
- if( nPayload>p->nMxPayload ) p->nMxPayload = nPayload; |
+ if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload; |
getLocalPayload(nUsable, p->flags, nPayload, &nLocal); |
pCell->nLocal = nLocal; |
- assert( nPayload>=nLocal ); |
+ assert( nLocal>=0 ); |
+ assert( nPayload>=(u32)nLocal ); |
assert( nLocal<=(nUsable-35) ); |
- if( nPayload>nLocal ){ |
+ if( nPayload>(u32)nLocal ){ |
int j; |
int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); |
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); |
@@ -360,6 +358,32 @@ static int statDecodePage(Btree *pBt, StatPage *p){ |
} |
/* |
+** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on |
+** the current value of pCsr->iPageno. |
+*/ |
+static void statSizeAndOffset(StatCursor *pCsr){ |
+ StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab; |
+ Btree *pBt = pTab->db->aDb[0].pBt; |
+ Pager *pPager = sqlite3BtreePager(pBt); |
+ sqlite3_file *fd; |
+ sqlite3_int64 x[2]; |
+ |
+ /* The default page size and offset */ |
+ pCsr->szPage = sqlite3BtreeGetPageSize(pBt); |
+ pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); |
+ |
+ /* If connected to a ZIPVFS backend, override the page size and |
+ ** offset with actual values obtained from ZIPVFS. |
+ */ |
+ fd = sqlite3PagerFile(pPager); |
+ x[0] = pCsr->iPageno; |
+ if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ |
+ pCsr->iOffset = x[0]; |
+ pCsr->szPage = (int)x[1]; |
+ } |
+} |
+ |
+/* |
** Move a statvfs cursor to the next entry in the file. |
*/ |
static int statNext(sqlite3_vtab_cursor *pCursor){ |
@@ -373,11 +397,12 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ |
sqlite3_free(pCsr->zPath); |
pCsr->zPath = 0; |
+statNextRestart: |
if( pCsr->aPage[0].pPg==0 ){ |
rc = sqlite3_step(pCsr->pStmt); |
if( rc==SQLITE_ROW ){ |
int nPage; |
- u32 iRoot = sqlite3_column_int64(pCsr->pStmt, 1); |
+ u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1); |
sqlite3PagerPagecount(pPager, &nPage); |
if( nPage==0 ){ |
pCsr->isEof = 1; |
@@ -417,17 +442,18 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ |
pCsr->nUnused = nUsable - 4 - pCsr->nPayload; |
} |
pCell->iOvfl++; |
+ statSizeAndOffset(pCsr); |
return SQLITE_OK; |
} |
if( p->iRightChildPg ) break; |
p->iCell++; |
} |
- while( !p->iRightChildPg || p->iCell>p->nCell ){ |
+ if( !p->iRightChildPg || p->iCell>p->nCell ){ |
statClearPage(p); |
if( pCsr->iPage==0 ) return statNext(pCursor); |
pCsr->iPage--; |
- p = &pCsr->aPage[pCsr->iPage]; |
+ goto statNextRestart; /* Tail recursion */ |
} |
pCsr->iPage++; |
assert( p==&pCsr->aPage[pCsr->iPage-1] ); |
@@ -454,6 +480,7 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ |
pCsr->iPageno = p->iPgno; |
statDecodePage(pBt, p); |
+ statSizeAndOffset(pCsr); |
switch( p->flags ){ |
case 0x05: /* table internal */ |
@@ -529,6 +556,12 @@ static int statColumn( |
case 7: /* mx_payload */ |
sqlite3_result_int(ctx, pCsr->nMxPayload); |
break; |
+ case 8: /* pgoffset */ |
+ sqlite3_result_int64(ctx, pCsr->iOffset); |
+ break; |
+ case 9: /* pgsize */ |
+ sqlite3_result_int(ctx, pCsr->szPage); |
+ break; |
} |
return SQLITE_OK; |
} |
@@ -568,7 +601,7 @@ int sqlite3_dbstat_register(sqlite3 *db){ |
#endif |
-#ifdef SQLITE_TEST |
+#if defined(SQLITE_TEST) || TCLSH==2 |
#include <tcl.h> |
static int test_dbstat( |
@@ -604,4 +637,4 @@ int SqlitetestStat_Init(Tcl_Interp *interp){ |
Tcl_CreateObjCommand(interp, "register_dbstat_vtab", test_dbstat, 0, 0); |
return TCL_OK; |
} |
-#endif |
+#endif /* if defined(SQLITE_TEST) || TCLSH==2 */ |