-C Fix\sa\sproblem\sin\sALTER\sTABLE\scausing\stable\sor\scolumn\sreferences\sin\ssub-selects\ston\sthe\sRHS\sof\sa\svector\sSET\sclause\sin\san\sUPDATE\swithin\sa\strigger\s(i.e.\s"SET\s(a,b)\s=\s(\s(SELECT...),\s<expr>\s)").
-D 2021-09-27T15:44:03.909
+C Have\sthe\sdbstat\svirtual\stable\stake\sa\scopy\sof\seach\spage\sbuffer\sthat\sit\straverses\sinstead\sof\sjust\sa\sreference\sto\sthe\spage-cache\sobject.\sThis\savoids\sproblems\sif\san\serror\scauses\stransaction\srollback\swhile\sa\sdbstat\scursor\sis\sopen.\sdbsqlfuzz\scrash-417224040fee04f0f0e62b70265c518893b08769.
+D 2021-09-27T17:11:20.381
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/ctime.c 8159d5f706551861c18ec6c8f6bdf105e15ea00367f05d9ab65d31a1077facc1
F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
-F src/dbstat.c 14d9098266fa712472bed757986eee70eb3613e9ba6e55bddac6708acf8d2857
+F src/dbstat.c bea044cfe99eab6c527837e196a5335c128989bdb354cf1b4973b85ea561d66b
F src/delete.c 3ce6af6b64c8b476de51ccc32da0cb3142d42e65754e1d8118addf65b8bcba15
F src/expr.c f2e0f5dd07d1b202f700f26b0851f2ea485e36ec8f335b05aec2cd91cd08853f
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 7a8fcf6d2c8e3c8f10ff515c8c00c761d15a28eef8e0e31e09e22feb06c9443b
-R 2a9beef8a41074983f454ce08ecf7909
+P 255b0eeed113d83b474efc5bc8fc790a270bc43ee598df4b2c378e1ad2d729b7
+R 547ad4e37246025cb31145d1566b52e1
U dan
-Z 371a9c0c029e52ab1de450a489c6939c
+Z e0b0decb4370dc0c0faf674ef290b1f7
/* Size information for a single btree page */
struct StatPage {
u32 iPgno; /* Page number */
- DbPage *pPg; /* Page content */
+ u8 *aPg; /* Page buffer from sqlite3_malloc() */
int iCell; /* Current cell */
-
char *zPath; /* Path to this page */
/* Variables populated by statDecodePage(): */
}
static void statClearPage(StatPage *p){
+ u8 *aPg = p->aPg;
statClearCells(p);
- sqlite3PagerUnref(p->pPg);
sqlite3_free(p->zPath);
memset(p, 0, sizeof(StatPage));
+ p->aPg = aPg;
}
static void statResetCsr(StatCursor *pCsr){
** this happens. dbsqlfuzz 9ed3e4e3816219d3509d711636c38542bf3f40b1. */
for(i=0; i<ArraySize(pCsr->aPage); i++){
statClearPage(&pCsr->aPage[i]);
+ sqlite3_free(pCsr->aPage[i].aPg);
+ pCsr->aPage[i].aPg = 0;
}
sqlite3_reset(pCsr->pStmt);
pCsr->iPage = 0;
int isLeaf;
int szPage;
- u8 *aData = sqlite3PagerGetData(p->pPg);
+ u8 *aData = p->aPg;
u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
p->flags = aHdr[0];
}
}
+/*
+** Load a copy of the page data for page iPg into the buffer belonging
+** to page object pPg. Allocate the buffer if necessary. Return SQLITE_OK
+** if successful, or an SQLite error code otherwise.
+*/
+static int statGetPage(
+ Btree *pBt, /* Load page from this b-tree */
+ u32 iPg, /* Page number to load */
+ StatPage *pPg /* Load page into this object */
+){
+ int pgsz = sqlite3BtreeGetPageSize(pBt);
+ DbPage *pDbPage = 0;
+ int rc;
+
+ if( pPg->aPg==0 ){
+ pPg->aPg = (u8*)sqlite3_malloc(pgsz);
+ if( pPg->aPg==0 ){
+ return SQLITE_NOMEM_BKPT;
+ }
+ }
+
+ rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPg, &pDbPage, 0);
+ if( rc==SQLITE_OK ){
+ const u8 *a = sqlite3PagerGetData(pDbPage);
+ memcpy(pPg->aPg, a, pgsz);
+ sqlite3PagerUnref(pDbPage);
+ }
+
+ return rc;
+}
+
/*
** Move a DBSTAT cursor to the next entry. Normally, the next
** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0),
pCsr->zPath = 0;
statNextRestart:
- if( pCsr->aPage[0].pPg==0 ){
+ if( pCsr->iPage<0 ){
/* Start measuring space on the next btree */
statResetCounts(pCsr);
rc = sqlite3_step(pCsr->pStmt);
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
}
- rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
+ rc = statGetPage(pBt, iRoot, &pCsr->aPage[0]);
pCsr->aPage[0].iPgno = iRoot;
pCsr->aPage[0].iCell = 0;
if( !pCsr->isAgg ){
if( !p->iRightChildPg || p->iCell>p->nCell ){
statClearPage(p);
- if( pCsr->iPage>0 ){
- pCsr->iPage--;
- }else if( pCsr->isAgg ){
+ pCsr->iPage--;
+ if( pCsr->isAgg && pCsr->iPage<0 ){
/* label-statNext-done: When computing aggregate space usage over
** an entire btree, this is the exit point from this function */
return SQLITE_OK;
}else{
p[1].iPgno = p->aCell[p->iCell].iChildPg;
}
- rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
+ rc = statGetPage(pBt, p[1].iPgno, &p[1]);
pCsr->nPage++;
p[1].iCell = 0;
if( !pCsr->isAgg ){
}
if( rc==SQLITE_OK ){
+ pCsr->iPage = -1;
rc = statNext(pCursor);
}
return rc;