mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Convert sqlite3PagerGet() into a pointer-dispatched virtual method. This
makes it about 25% faster. FossilOrigin-Name: 7f88bb44129a0cd36e27e00dc7c37e87cf3c90f7
This commit is contained in:
17
manifest
17
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\sa\sproblem\scausing\sSQLite\sto\sreturn\sfalse\s"foreign\skey\sviolation"\serrors\nwhen\sthere\sis\sa\spartial\s(i.e.\sWHERE\sconstrained)\sUNIQUE\sindex\son\sthe\sparent\nkey\scolumns.\sThis\sbug\sdid\snot\scause\sSQLite\sto\sallow\sillegal\sdata\sto\sbe\ninserted\sinto\sthe\sdatabase,\sonly\sto\sreject\slegal\soperations.
|
||||
D 2016-12-13T16:57:49.299
|
||||
C Convert\ssqlite3PagerGet()\sinto\sa\spointer-dispatched\svirtual\smethod.\s\sThis\nmakes\sit\sabout\s25%\sfaster.
|
||||
D 2016-12-13T18:47:54.625
|
||||
F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
|
||||
@@ -375,10 +375,10 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820
|
||||
F src/os_win.c cf90abd4e50d9f56d2c20ce8e005aff55d7bd8e9
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c eaf8590131ab651420e86e89c3fd12d729f55ad3
|
||||
F src/pager.c dbcac003871bf8a9bfb69d6cb66bbb85b528aaf6
|
||||
F src/pager.h d1e944291030351f362a0a7da9b5c3e34e603e39
|
||||
F src/parse.y 29153738a7322054359320eb00b5a4cd44389f20
|
||||
F src/pcache.c 219fc5238d5c80e2990ab01e1459db3a96866447
|
||||
F src/pcache.c 51070ec9b8251bbf9c6ea3d35fd96a458752929e
|
||||
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
|
||||
F src/pcache1.c e3967219b2a92b9edcb9324a4ba75009090d3953
|
||||
F src/pragma.c d932ba278654617cdd281f88a790a3185fca7c44
|
||||
@@ -1536,7 +1536,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 1a636d5e0eec0a4d968519d1dfd35a983e512c78
|
||||
R 5a6882353526d0c1387fb8d5e18f94f5
|
||||
U dan
|
||||
Z 8572282c856eadf1ae5a34d00073243b
|
||||
P 850877d1ea43104cc215353414b870c340acced2 dee20ba982125ea98c280ad1571789af0f393903
|
||||
R 1925a57b32b9d19fb42c95ae0d5863ee
|
||||
T +closed dee20ba982125ea98c280ad1571789af0f393903
|
||||
U drh
|
||||
Z ca81384c708270e6307c733a622217dc
|
||||
|
@@ -1 +1 @@
|
||||
850877d1ea43104cc215353414b870c340acced2
|
||||
7f88bb44129a0cd36e27e00dc7c37e87cf3c90f7
|
276
src/pager.c
276
src/pager.c
@@ -693,6 +693,7 @@ struct Pager {
|
||||
int nRead; /* Database pages read */
|
||||
#endif
|
||||
void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
|
||||
int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
|
||||
void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
|
||||
@@ -1019,6 +1020,33 @@ static char *print_pager_state(Pager *p){
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Forward references to the various page getters */
|
||||
static int getPageNormal(Pager*,Pgno,DbPage**,int);
|
||||
static int getPageError(Pager*,Pgno,DbPage**,int);
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
static int getPageMMap(Pager*,Pgno,DbPage**,int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Set the Pager.xGet method for the appropriate routine used to fetch
|
||||
** content from the pager.
|
||||
*/
|
||||
static void setGetterMethod(Pager *pPager){
|
||||
if( pPager->errCode ){
|
||||
pPager->xGet = getPageError;
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
}else if( USEFETCH(pPager)
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
&& pPager->xCodec==0
|
||||
#endif
|
||||
){
|
||||
pPager->xGet = getPageMMap;
|
||||
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
|
||||
}else{
|
||||
pPager->xGet = getPageNormal;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if it is necessary to write page *pPg into the sub-journal.
|
||||
** A page needs to be written into the sub-journal if there exists one
|
||||
@@ -1833,6 +1861,7 @@ static void pager_unlock(Pager *pPager){
|
||||
}
|
||||
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
|
||||
pPager->errCode = SQLITE_OK;
|
||||
setGetterMethod(pPager);
|
||||
}
|
||||
|
||||
pPager->journalOff = 0;
|
||||
@@ -1870,6 +1899,7 @@ static int pager_error(Pager *pPager, int rc){
|
||||
if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
|
||||
pPager->errCode = rc;
|
||||
pPager->eState = PAGER_ERROR;
|
||||
setGetterMethod(pPager);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -3437,6 +3467,7 @@ static void pagerFixMaplimit(Pager *pPager){
|
||||
sqlite3_int64 sz;
|
||||
sz = pPager->szMmap;
|
||||
pPager->bUseFetch = (sz>0);
|
||||
setGetterMethod(pPager);
|
||||
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
|
||||
}
|
||||
#endif
|
||||
@@ -4854,6 +4885,7 @@ act_like_temp_file:
|
||||
/* pPager->xBusyHandler = 0; */
|
||||
/* pPager->pBusyHandlerArg = 0; */
|
||||
pPager->xReiniter = xReinit;
|
||||
setGetterMethod(pPager);
|
||||
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
|
||||
/* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
|
||||
|
||||
@@ -5267,10 +5299,17 @@ static void pagerUnlockIfUnused(Pager *pPager){
|
||||
}
|
||||
|
||||
/*
|
||||
** Acquire a reference to page number pgno in pager pPager (a page
|
||||
** reference has type DbPage*). If the requested reference is
|
||||
** The page getter methods each try to acquire a reference to a
|
||||
** page with page number pgno. If the requested reference is
|
||||
** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
|
||||
**
|
||||
** There are different implementations of the getter method depending
|
||||
** on the current state of the pager.
|
||||
**
|
||||
** getPageNormal() -- The normal getter
|
||||
** getPageError() -- Used if the pager is in an error state
|
||||
** getPageMmap() -- Used if memory-mapped I/O is enabled
|
||||
**
|
||||
** If the requested page is already in the cache, it is returned.
|
||||
** Otherwise, a new page object is allocated and populated with data
|
||||
** read from the database file. In some cases, the pcache module may
|
||||
@@ -5282,14 +5321,14 @@ static void pagerUnlockIfUnused(Pager *pPager){
|
||||
** already in the cache when this function is called, then the extra
|
||||
** data is left as it was when the page object was last used.
|
||||
**
|
||||
** If the database image is smaller than the requested page or if a
|
||||
** non-zero value is passed as the noContent parameter and the
|
||||
** If the database image is smaller than the requested page or if
|
||||
** the flags parameter contains the PAGER_GET_NOCONTENT bit and the
|
||||
** requested page is not already stored in the cache, then no
|
||||
** actual disk read occurs. In this case the memory image of the
|
||||
** page is initialized to all zeros.
|
||||
**
|
||||
** If noContent is true, it means that we do not care about the contents
|
||||
** of the page. This occurs in two scenarios:
|
||||
** If PAGER_GET_NOCONTENT is true, it means that we do not care about
|
||||
** the contents of the page. This occurs in two scenarios:
|
||||
**
|
||||
** a) When reading a free-list leaf page from the database, and
|
||||
**
|
||||
@@ -5297,8 +5336,8 @@ static void pagerUnlockIfUnused(Pager *pPager){
|
||||
** a new page into the cache to be filled with the data read
|
||||
** from the savepoint journal.
|
||||
**
|
||||
** If noContent is true, then the data returned is zeroed instead of
|
||||
** being read from the database. Additionally, the bits corresponding
|
||||
** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead
|
||||
** of being read from the database. Additionally, the bits corresponding
|
||||
** to pgno in Pager.pInJournal (bitvec of pages already written to the
|
||||
** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
|
||||
** savepoints are set. This means if the page is made writable at any
|
||||
@@ -5316,107 +5355,38 @@ static void pagerUnlockIfUnused(Pager *pPager){
|
||||
** Since Lookup() never goes to disk, it never has to deal with locks
|
||||
** or journal files.
|
||||
*/
|
||||
int sqlite3PagerGet(
|
||||
static int getPageNormal(
|
||||
Pager *pPager, /* The pager open on the database file */
|
||||
Pgno pgno, /* Page number to fetch */
|
||||
DbPage **ppPage, /* Write a pointer to the page here */
|
||||
int flags /* PAGER_GET_XXX flags */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
PgHdr *pPg = 0;
|
||||
u32 iFrame = 0; /* Frame to read from WAL file */
|
||||
const int noContent = (flags & PAGER_GET_NOCONTENT);
|
||||
PgHdr *pPg;
|
||||
u8 noContent; /* True if PAGER_GET_NOCONTENT is set */
|
||||
sqlite3_pcache_page *pBase;
|
||||
|
||||
/* It is acceptable to use a read-only (mmap) page for any page except
|
||||
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
|
||||
** flag was specified by the caller. And so long as the db is not a
|
||||
** temporary or in-memory database. */
|
||||
const int bMmapOk = (pgno>1 && USEFETCH(pPager)
|
||||
&& (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
&& pPager->xCodec==0
|
||||
#endif
|
||||
);
|
||||
|
||||
/* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
|
||||
** allows the compiler optimizer to reuse the results of the "pgno>1"
|
||||
** test in the previous statement, and avoid testing pgno==0 in the
|
||||
** common case where pgno is large. */
|
||||
if( pgno<=1 && pgno==0 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
assert( pPager->errCode==SQLITE_OK );
|
||||
assert( pPager->eState>=PAGER_READER );
|
||||
assert( assert_pager_state(pPager) );
|
||||
assert( noContent==0 || bMmapOk==0 );
|
||||
|
||||
assert( pPager->hasHeldSharedLock==1 );
|
||||
|
||||
/* If the pager is in the error state, return an error immediately.
|
||||
** Otherwise, request the page from the PCache layer. */
|
||||
if( pPager->errCode!=SQLITE_OK ){
|
||||
rc = pPager->errCode;
|
||||
}else{
|
||||
if( bMmapOk && pagerUseWal(pPager) ){
|
||||
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
|
||||
if( rc!=SQLITE_OK ) goto pager_acquire_err;
|
||||
}
|
||||
|
||||
if( bMmapOk && iFrame==0 ){
|
||||
void *pData = 0;
|
||||
|
||||
rc = sqlite3OsFetch(pPager->fd,
|
||||
(i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
|
||||
);
|
||||
|
||||
if( rc==SQLITE_OK && pData ){
|
||||
if( pPager->eState>PAGER_READER || pPager->tempFile ){
|
||||
pPg = sqlite3PagerLookup(pPager, pgno);
|
||||
}
|
||||
if( pPg==0 ){
|
||||
rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
|
||||
}else{
|
||||
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
|
||||
}
|
||||
if( pPg ){
|
||||
assert( rc==SQLITE_OK );
|
||||
*ppPage = pPg;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto pager_acquire_err;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
sqlite3_pcache_page *pBase;
|
||||
pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
|
||||
if( pBase==0 ){
|
||||
rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
|
||||
if( rc!=SQLITE_OK ) goto pager_acquire_err;
|
||||
if( pBase==0 ){
|
||||
pPg = *ppPage = 0;
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto pager_acquire_err;
|
||||
}
|
||||
}
|
||||
pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
|
||||
assert( pPg!=0 );
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
/* Either the call to sqlite3PcacheFetch() returned an error or the
|
||||
** pager was already in the error-state when this function was called.
|
||||
** Set pPg to 0 and jump to the exception handler. */
|
||||
pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
|
||||
if( pBase==0 ){
|
||||
pPg = 0;
|
||||
goto pager_acquire_err;
|
||||
rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
|
||||
if( rc!=SQLITE_OK ) goto pager_acquire_err;
|
||||
if( pBase==0 ){
|
||||
rc = SQLITE_NOMEM_BKPT;
|
||||
goto pager_acquire_err;
|
||||
}
|
||||
}
|
||||
pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
|
||||
assert( pPg==(*ppPage) );
|
||||
assert( pPg->pgno==pgno );
|
||||
assert( pPg->pPager==pPager || pPg->pPager==0 );
|
||||
|
||||
if( pPg->pPager && !noContent ){
|
||||
if( pPg->pPager ){
|
||||
/* In this case the pcache already contains an initialized copy of
|
||||
** the page. Return without further ado. */
|
||||
assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
|
||||
@@ -5425,18 +5395,21 @@ int sqlite3PagerGet(
|
||||
|
||||
}else{
|
||||
/* The pager cache has created a new page. Its content needs to
|
||||
** be initialized. */
|
||||
|
||||
pPg->pPager = pPager;
|
||||
|
||||
/* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
|
||||
** number greater than this, or the unused locking-page, is requested. */
|
||||
if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
|
||||
** be initialized. But first some error checks:
|
||||
**
|
||||
** (1) Minimum page number is 1
|
||||
** (2) The maximum page number is 2^31
|
||||
** (3) Never try to fetch the locking page
|
||||
*/
|
||||
if( pgno==0 || pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto pager_acquire_err;
|
||||
}
|
||||
|
||||
pPg->pPager = pPager;
|
||||
|
||||
assert( !isOpen(pPager->fd) || !MEMDB );
|
||||
noContent = (flags & PAGER_GET_NOCONTENT)!=0;
|
||||
if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
|
||||
if( pgno>pPager->mxPgno ){
|
||||
rc = SQLITE_FULL;
|
||||
@@ -5461,7 +5434,8 @@ int sqlite3PagerGet(
|
||||
memset(pPg->pData, 0, pPager->pageSize);
|
||||
IOTRACE(("ZERO %p %d\n", pPager, pgno));
|
||||
}else{
|
||||
if( pagerUseWal(pPager) && bMmapOk==0 ){
|
||||
u32 iFrame = 0; /* Frame to read from WAL file */
|
||||
if( pagerUseWal(pPager) ){
|
||||
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
|
||||
if( rc!=SQLITE_OK ) goto pager_acquire_err;
|
||||
}
|
||||
@@ -5474,7 +5448,6 @@ int sqlite3PagerGet(
|
||||
}
|
||||
pager_set_pagehash(pPg);
|
||||
}
|
||||
|
||||
return SQLITE_OK;
|
||||
|
||||
pager_acquire_err:
|
||||
@@ -5483,11 +5456,107 @@ pager_acquire_err:
|
||||
sqlite3PcacheDrop(pPg);
|
||||
}
|
||||
pagerUnlockIfUnused(pPager);
|
||||
|
||||
*ppPage = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
/* The page getter for when memory-mapped I/O is enabled */
|
||||
static int getPageMMap(
|
||||
Pager *pPager, /* The pager open on the database file */
|
||||
Pgno pgno, /* Page number to fetch */
|
||||
DbPage **ppPage, /* Write a pointer to the page here */
|
||||
int flags /* PAGER_GET_XXX flags */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
PgHdr *pPg = 0;
|
||||
u32 iFrame = 0; /* Frame to read from WAL file */
|
||||
|
||||
assert( USEFETCH(pPager) );
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
assert( pPager->xCodec==0 );
|
||||
#endif
|
||||
|
||||
/* It is acceptable to use a read-only (mmap) page for any page except
|
||||
** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
|
||||
** flag was specified by the caller. And so long as the db is not a
|
||||
** temporary or in-memory database. */
|
||||
const int bMmapOk = (pgno>1
|
||||
&& (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
|
||||
);
|
||||
|
||||
/* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
|
||||
** allows the compiler optimizer to reuse the results of the "pgno>1"
|
||||
** test in the previous statement, and avoid testing pgno==0 in the
|
||||
** common case where pgno is large. */
|
||||
if( pgno<=1 && pgno==0 ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
assert( pPager->eState>=PAGER_READER );
|
||||
assert( assert_pager_state(pPager) );
|
||||
assert( pPager->hasHeldSharedLock==1 );
|
||||
assert( pPager->errCode==SQLITE_OK );
|
||||
|
||||
if( bMmapOk && pagerUseWal(pPager) ){
|
||||
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
|
||||
if( rc!=SQLITE_OK ){
|
||||
*ppPage = 0;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if( bMmapOk && iFrame==0 ){
|
||||
void *pData = 0;
|
||||
rc = sqlite3OsFetch(pPager->fd,
|
||||
(i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
|
||||
);
|
||||
if( rc==SQLITE_OK && pData ){
|
||||
if( pPager->eState>PAGER_READER || pPager->tempFile ){
|
||||
pPg = sqlite3PagerLookup(pPager, pgno);
|
||||
}
|
||||
if( pPg==0 ){
|
||||
rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
|
||||
}else{
|
||||
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
|
||||
}
|
||||
if( pPg ){
|
||||
assert( rc==SQLITE_OK );
|
||||
*ppPage = pPg;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
*ppPage = 0;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return getPageNormal(pPager, pgno, ppPage, flags);
|
||||
}
|
||||
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
|
||||
|
||||
/* The page getter method for when the pager is an error state */
|
||||
static int getPageError(
|
||||
Pager *pPager, /* The pager open on the database file */
|
||||
Pgno pgno, /* Page number to fetch */
|
||||
DbPage **ppPage, /* Write a pointer to the page here */
|
||||
int flags /* PAGER_GET_XXX flags */
|
||||
){
|
||||
assert( pPager->errCode!=SQLITE_OK );
|
||||
*ppPage = 0;
|
||||
return pPager->errCode;
|
||||
}
|
||||
|
||||
|
||||
/* Dispatch all page fetch requests to the appropriate getter method.
|
||||
*/
|
||||
int sqlite3PagerGet(
|
||||
Pager *pPager, /* The pager open on the database file */
|
||||
Pgno pgno, /* Page number to fetch */
|
||||
DbPage **ppPage, /* Write a pointer to the page here */
|
||||
int flags /* PAGER_GET_XXX flags */
|
||||
){
|
||||
return pPager->xGet(pPager, pgno, ppPage, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
** Acquire a page if it is already in the in-memory cache. Do
|
||||
** not read the page from disk. Return a pointer to the page,
|
||||
@@ -6460,6 +6529,7 @@ int sqlite3PagerRollback(Pager *pPager){
|
||||
*/
|
||||
pPager->errCode = SQLITE_ABORT;
|
||||
pPager->eState = PAGER_ERROR;
|
||||
setGetterMethod(pPager);
|
||||
return rc;
|
||||
}
|
||||
}else{
|
||||
@@ -6721,6 +6791,7 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
|
||||
){
|
||||
pPager->errCode = SQLITE_ABORT;
|
||||
pPager->eState = PAGER_ERROR;
|
||||
setGetterMethod(pPager);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -6793,6 +6864,7 @@ void sqlite3PagerSetCodec(
|
||||
pPager->xCodecSizeChng = xCodecSizeChng;
|
||||
pPager->xCodecFree = xCodecFree;
|
||||
pPager->pCodec = pCodec;
|
||||
setGetterMethod(pPager);
|
||||
pagerReportSize(pPager);
|
||||
}
|
||||
void *sqlite3PagerGetCodec(Pager *pPager){
|
||||
|
@@ -108,7 +108,7 @@ struct PCache {
|
||||
int sqlite3PcachePageSanity(PgHdr *pPg){
|
||||
PCache *pCache;
|
||||
assert( pPg!=0 );
|
||||
assert( pPg->pgno>0 ); /* Page number is 1 or more */
|
||||
assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */
|
||||
pCache = pPg->pCache;
|
||||
assert( pCache!=0 ); /* Every page has an associated PCache */
|
||||
if( pPg->flags & PGHDR_CLEAN ){
|
||||
@@ -372,7 +372,6 @@ sqlite3_pcache_page *sqlite3PcacheFetch(
|
||||
assert( pCache!=0 );
|
||||
assert( pCache->pCache!=0 );
|
||||
assert( createFlag==3 || createFlag==0 );
|
||||
assert( pgno>0 );
|
||||
assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) );
|
||||
|
||||
/* eCreate defines what to do if the page does not exist.
|
||||
|
Reference in New Issue
Block a user