mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Revert (6187). (CVS 6188)
FossilOrigin-Name: a353c1ab376b159c4d12532412365318cdbdcc60
This commit is contained in:
30
manifest
30
manifest
@@ -1,5 +1,5 @@
|
||||
C This\scommit\sis\san\serror.\sReverted\sby\s(6188).\s(CVS\s6187)
|
||||
D 2009-01-16T15:21:05
|
||||
C Revert\s(6187).\s(CVS\s6188)
|
||||
D 2009-01-16T16:23:38
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 8a00230c566c1a1cfc7ae53eedd458b32034da30
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@@ -101,11 +101,11 @@ F src/alter.c 7eee66a6de2605a4aa6a85be6b4688b89e0f48ff
|
||||
F src/analyze.c c86fd6a1425b22b3a46ce72ad403e4280026364f
|
||||
F src/attach.c 1c35f95da3c62d19de75b44cfefd12c81c1791b3
|
||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||
F src/bitvec.c 8042927940263bc593e68d33ab10e3b76bde8097
|
||||
F src/bitvec.c 1da48f915129b476cae0cfd7a6ed0eb0d03a9bdb
|
||||
F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
|
||||
F src/btree.c 3b446e24aa46fd7b3d2cdf0bc62baad52ebfda00
|
||||
F src/btree.c e183a4357e8f5081fd04c757e006ef6fdaaa79a1
|
||||
F src/btree.h 4f141cf748d2ee7c6d7fc175f64f87a45cd44113
|
||||
F src/btreeInt.h 638efe5806aeebbcbbe7e62ae461904124b89bd6
|
||||
F src/btreeInt.h 790482376263bbc5862ae7124354a26c70695369
|
||||
F src/build.c 6eb9d20e99db8da8c7c6e7316096a6ff3d9acab9
|
||||
F src/callback.c bee8949d619b1b7b1e4dfac8a19c5116ae1dd12a
|
||||
F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c
|
||||
@@ -142,11 +142,11 @@ F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
|
||||
F src/os_os2.c bed77dc26e3a95ce4a204936b9a1ca6fe612fcc5
|
||||
F src/os_unix.c c0ebce13fac2db7900367e83a3ebbd112ea4e90e
|
||||
F src/os_win.c 496e3ceb499aedc63622a89ef76f7af2dd902709
|
||||
F src/pager.c 629e3c8628045e192fba3c2d2bdf2b3e068806f7
|
||||
F src/pager.h 61a5259af27ab1b2da6bb3ca296df41b814477c4
|
||||
F src/pager.c b99d1e9f9c971cf42f4c7ede17117f238e9b9c2b
|
||||
F src/pager.h 3345547d4b5b4db323f50d855d91a01837c7f2de
|
||||
F src/parse.y b214295a91e985c42adb6bfd3ad1c56c47828e8d
|
||||
F src/pcache.c 922872b2150db19debb2fea1183937cf86fcf7bf
|
||||
F src/pcache.h a56b8998f5bf71c31c3d7bcfe0149880a21c442a
|
||||
F src/pcache.c a3c729f4bb3464fab27617ab7411916e0cded2bf
|
||||
F src/pcache.h 00adba50e5b90414a40f2c63e5272c152c523373
|
||||
F src/pcache1.c c0aa84ff69ea759fa944dbee9167a2463ab7c322
|
||||
F src/pragma.c 5b7ac60366b731b11cbc59352082aa5922439a98
|
||||
F src/prepare.c 2a11736383d0af2ea80aa62270f15ad80dd8b5cd
|
||||
@@ -158,13 +158,13 @@ F src/select.c ae72b604e47092521c4d9ae54e1b1cbeb872a747
|
||||
F src/shell.c 0d801ef653fd73d17161afebaab898a58ec3524b
|
||||
F src/sqlite.h.in 6cd2489e40fe97ba58c60044a4ced377e08b6d09
|
||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||
F src/sqliteInt.h b6266915bba217bcbacc89ab2402cf0822aedc70
|
||||
F src/sqliteInt.h 65b7b15aac8579b7c889416735637f10a8463002
|
||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||
F src/table.c 23db1e5f27c03160987c122a078b4bb51ef0b2f8
|
||||
F src/tclsqlite.c 7d77c3899d0244804d2773c9157e783788627762
|
||||
F src/test1.c 84221fbafc2f02e3a9285def0b3ed401f5cde258
|
||||
F src/test2.c 4fd2d995888fb580e768711e517a1c3209d04e72
|
||||
F src/test2.c 87d2ee3aa13321f1bba55dc9c675b56d97dbc6b4
|
||||
F src/test3.c 88a246b56b824275300e6c899634fbac1dc94b14
|
||||
F src/test4.c f79ab52d27ff49b784b631a42e2ccd52cfd5c84c
|
||||
F src/test5.c 162a1cea2105a2c460a3f39fa6919617b562a288
|
||||
@@ -202,7 +202,7 @@ F src/vdbe.c b917020da4c14c3ea6032cc288462f4ba525ade7
|
||||
F src/vdbe.h 03516f28bf5aca00a53c4dccd6c313f96adb94f6
|
||||
F src/vdbeInt.h 5530e45fc64c1572f123aca384096e1b84cf834b
|
||||
F src/vdbeapi.c 85c33cfbfa56249cbe627831610afafba754477d
|
||||
F src/vdbeaux.c 2f6c3fcedaebff15f2a161750e0f4dbf7b2df8b9
|
||||
F src/vdbeaux.c a593c4ceaecc2508c443c6447738f74419225f0e
|
||||
F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935
|
||||
F src/vdbemem.c 19f94b504d3da44b31aef200fa6c8e07862de2e8
|
||||
F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43
|
||||
@@ -697,7 +697,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
P 54ab8326a1ea574b183f84c8465315e989a23ca4
|
||||
R d956708750eec297164ae34e0e8a525f
|
||||
P aa67fd0cdb4f53a0c6e15c001d37554d15006718
|
||||
R c8509fb836bf1d76f87b59b07c81ef45
|
||||
U danielk1977
|
||||
Z 2079228925c670d6fce19286fd0ffd02
|
||||
Z 78ca002c1238dcdf491f58ff6219cf73
|
||||
|
@@ -1 +1 @@
|
||||
aa67fd0cdb4f53a0c6e15c001d37554d15006718
|
||||
a353c1ab376b159c4d12532412365318cdbdcc60
|
10
src/bitvec.c
10
src/bitvec.c
@@ -34,7 +34,7 @@
|
||||
** start of a transaction, and is thus usually less than a few thousand,
|
||||
** but can be as large as 2 billion for a really big database.
|
||||
**
|
||||
** @(#) $Id: bitvec.c,v 1.11 2009/01/16 15:21:05 danielk1977 Exp $
|
||||
** @(#) $Id: bitvec.c,v 1.12 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -275,14 +275,6 @@ void sqlite3BitvecDestroy(Bitvec *p){
|
||||
sqlite3_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the value of the iSize parameter specified when Bitvec *p
|
||||
** was created.
|
||||
*/
|
||||
u32 sqlite3BitvecSize(Bitvec *p){
|
||||
return p->iSize;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_BUILTIN_TEST
|
||||
/*
|
||||
** Let V[] be an array of unsigned characters sufficient to hold
|
||||
|
332
src/btree.c
332
src/btree.c
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.559 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** $Id: btree.c,v 1.560 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** See the header comment on "btreeInt.h" for additional information.
|
||||
@@ -282,80 +282,6 @@ static void invalidateAllOverflowCache(BtShared *pBt){
|
||||
#define invalidateAllOverflowCache(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Set bit pgno of the BtShared.pHasContent bitvec. This is called
|
||||
** when a page that previously contained data becomes a free-list leaf
|
||||
** page.
|
||||
**
|
||||
** The BtShared.pHasContent bitvec exists to work around an obscure
|
||||
** bug caused by the interaction of two useful IO optimizations surrounding
|
||||
** free-list leaf pages:
|
||||
**
|
||||
** 1) When all data is deleted from a page and the page becomes
|
||||
** a free-list leaf page, the page is not written to the database
|
||||
** (as free-list leaf pages contain no meaningful data). Sometimes
|
||||
** such a page is not even journalled (as it will not be modified,
|
||||
** why bother journalling it?).
|
||||
**
|
||||
** 2) When a free-list leaf page is reused, its content is not read
|
||||
** from the database or written to the journal file (why should it
|
||||
** be, if it is not at all meaningful?).
|
||||
**
|
||||
** By themselves, these optimizations work fine and provide a handy
|
||||
** performance boost to bulk delete or insert operations. However, if
|
||||
** a page is moved to the free-list and then reused within the same
|
||||
** transaction, a problem comes up. If the page is not journalled when
|
||||
** it is moved to the free-list and it is also not journalled when it
|
||||
** is extracted from the free-list and reused, then the original data
|
||||
** may be lost. In the event of a rollback, it may not be possible
|
||||
** to restore the database to its original configuration.
|
||||
**
|
||||
** The solution is the BtShared.pHasContent bitvec. Whenever a page is
|
||||
** moved to become a free-list leaf page, the corresponding bit is
|
||||
** set in the bitvec. Whenever a leaf page is extracted from the free-list,
|
||||
** optimization 2 above is ommitted if the corresponding bit is already
|
||||
** set in BtShared.pHasContent. The contents of the bitvec are cleared
|
||||
** at the end of every transaction.
|
||||
*/
|
||||
static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
|
||||
int rc = SQLITE_OK;
|
||||
if( !pBt->pHasContent ){
|
||||
int nPage;
|
||||
rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
|
||||
if( rc==SQLITE_OK ){
|
||||
pBt->pHasContent = sqlite3BitvecCreate((u32)nPage);
|
||||
if( !pBt->pHasContent ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
|
||||
rc = sqlite3BitvecSet(pBt->pHasContent, pgno);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Query the BtShared.pHasContent vector.
|
||||
**
|
||||
** This function is called when a free-list leaf page is removed from the
|
||||
** free-list for reuse. It returns false if it is safe to retrieve the
|
||||
** page from the pager layer with the 'no-content' flag set. True otherwise.
|
||||
*/
|
||||
static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
|
||||
Bitvec *p = pBt->pHasContent;
|
||||
return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
|
||||
}
|
||||
|
||||
/*
|
||||
** Clear (destroy) the BtShared.pHasContent bitvec. This should be
|
||||
** invoked at the conclusion of each write-transaction.
|
||||
*/
|
||||
static void btreeClearHasContent(BtShared *pBt){
|
||||
sqlite3BitvecDestroy(pBt->pHasContent);
|
||||
pBt->pHasContent = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Save the current cursor position in the variables BtCursor.nKey
|
||||
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
|
||||
@@ -1174,21 +1100,6 @@ int sqlite3BtreeGetPage(
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Retrieve a page from the pager cache. If the requested page is not
|
||||
** already in the pager cache return NULL. Initialize the MemPage.pBt and
|
||||
** MemPage.aData elements if needed.
|
||||
*/
|
||||
static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
|
||||
DbPage *pDbPage;
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
|
||||
if( pDbPage ){
|
||||
return btreePageFromDbPage(pDbPage, pgno, pBt);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the size of the database file in pages. If there is any kind of
|
||||
** error, return ((unsigned int)-1).
|
||||
@@ -1213,6 +1124,7 @@ static int getAndInitPage(
|
||||
MemPage **ppPage /* Write the page pointer here */
|
||||
){
|
||||
int rc;
|
||||
DbPage *pDbPage;
|
||||
MemPage *pPage;
|
||||
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
@@ -1225,9 +1137,10 @@ static int getAndInitPage(
|
||||
** pagerPagecount() to make sure pgno is within limits, which results
|
||||
** in a measureable performance improvements.
|
||||
*/
|
||||
*ppPage = pPage = btreePageLookup(pBt, pgno);
|
||||
if( pPage ){
|
||||
pDbPage = sqlite3PagerLookup(pBt->pPager, pgno);
|
||||
if( pDbPage ){
|
||||
/* Page is already in cache */
|
||||
*ppPage = pPage = btreePageFromDbPage(pDbPage, pgno, pBt);
|
||||
rc = SQLITE_OK;
|
||||
}else{
|
||||
/* Page not in cache. Acquire it. */
|
||||
@@ -2459,7 +2372,7 @@ int sqlite3BtreeIncrVacuum(Btree *p){
|
||||
rc = SQLITE_DONE;
|
||||
}else{
|
||||
invalidateAllOverflowCache(pBt);
|
||||
rc = incrVacuumStep(pBt, 0, pagerPagecount(pBt));
|
||||
rc = incrVacuumStep(pBt, 0, sqlite3PagerImageSize(pBt->pPager));
|
||||
}
|
||||
sqlite3BtreeLeave(p);
|
||||
return rc;
|
||||
@@ -2627,7 +2540,6 @@ int sqlite3BtreeCommitPhaseTwo(Btree *p){
|
||||
/* Set the handles current transaction state to TRANS_NONE and unlock
|
||||
** the pager if this call closed the only read or write transaction.
|
||||
*/
|
||||
btreeClearHasContent(pBt);
|
||||
p->inTrans = TRANS_NONE;
|
||||
unlockBtreeIfUnused(pBt);
|
||||
|
||||
@@ -2763,7 +2675,6 @@ int sqlite3BtreeRollback(Btree *p){
|
||||
}
|
||||
}
|
||||
|
||||
btreeClearHasContent(pBt);
|
||||
p->inTrans = TRANS_NONE;
|
||||
pBt->inStmt = 0;
|
||||
unlockBtreeIfUnused(pBt);
|
||||
@@ -3171,29 +3082,34 @@ int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
|
||||
**
|
||||
** If an error occurs an SQLite error code is returned. Otherwise:
|
||||
**
|
||||
** The page number of the next overflow page in the linked list is
|
||||
** written to *pPgnoNext. If page ovfl is the last page in its linked
|
||||
** list, *pPgnoNext is set to zero.
|
||||
** Unless pPgnoNext is NULL, the page number of the next overflow
|
||||
** page in the linked list is written to *pPgnoNext. If page ovfl
|
||||
** is the last page in its linked list, *pPgnoNext is set to zero.
|
||||
**
|
||||
** If ppPage is not NULL, and a reference to the MemPage object corresponding
|
||||
** to page number pOvfl was obtained, then *ppPage is set to point to that
|
||||
** reference. It is the responsibility of the caller to call releasePage()
|
||||
** on *ppPage to free the reference. In no reference was obtained (because
|
||||
** the pointer-map was used to obtain the value for *pPgnoNext), then
|
||||
** *ppPage is set to zero.
|
||||
** If ppPage is not NULL, *ppPage is set to the MemPage* handle
|
||||
** for page ovfl. The underlying pager page may have been requested
|
||||
** with the noContent flag set, so the page data accessable via
|
||||
** this handle may not be trusted.
|
||||
*/
|
||||
static int getOverflowPage(
|
||||
BtShared *pBt,
|
||||
Pgno ovfl, /* Overflow page */
|
||||
MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */
|
||||
MemPage **ppPage, /* OUT: MemPage handle */
|
||||
Pgno *pPgnoNext /* OUT: Next overflow page number */
|
||||
){
|
||||
Pgno next = 0;
|
||||
MemPage *pPage = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert(pPgnoNext);
|
||||
/* One of these must not be NULL. Otherwise, why call this function? */
|
||||
assert(ppPage || pPgnoNext);
|
||||
|
||||
/* If pPgnoNext is NULL, then this function is being called to obtain
|
||||
** a MemPage* reference only. No page-data is required in this case.
|
||||
*/
|
||||
if( !pPgnoNext ){
|
||||
return sqlite3BtreeGetPage(pBt, ovfl, ppPage, 1);
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
/* Try to find the next page in the overflow list using the
|
||||
@@ -3213,29 +3129,34 @@ static int getOverflowPage(
|
||||
|
||||
if( iGuess<=pagerPagecount(pBt) ){
|
||||
rc = ptrmapGet(pBt, iGuess, &eType, &pgno);
|
||||
if( rc==SQLITE_OK && eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
if( eType==PTRMAP_OVERFLOW2 && pgno==ovfl ){
|
||||
next = iGuess;
|
||||
rc = SQLITE_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, 0);
|
||||
if( next==0 || ppPage ){
|
||||
MemPage *pPage = 0;
|
||||
|
||||
rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, next!=0);
|
||||
assert(rc==SQLITE_OK || pPage==0);
|
||||
if( next==0 && rc==SQLITE_OK ){
|
||||
next = get4byte(pPage->aData);
|
||||
}
|
||||
}
|
||||
|
||||
*pPgnoNext = next;
|
||||
if( ppPage ){
|
||||
*ppPage = pPage;
|
||||
}else{
|
||||
releasePage(pPage);
|
||||
}
|
||||
return (rc==SQLITE_DONE ? SQLITE_OK : rc);
|
||||
}
|
||||
*pPgnoNext = next;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4344,7 +4265,6 @@ static int allocateBtreePage(
|
||||
|
||||
iPage = get4byte(&aData[8+closest*4]);
|
||||
if( !searchList || iPage==nearby ){
|
||||
int noContent;
|
||||
Pgno nPage;
|
||||
*pPgno = iPage;
|
||||
nPage = pagerPagecount(pBt);
|
||||
@@ -4361,9 +4281,9 @@ static int allocateBtreePage(
|
||||
}
|
||||
put4byte(&aData[4], k-1);
|
||||
assert( sqlite3PagerIswriteable(pTrunk->pDbPage) );
|
||||
noContent = !btreeGetHasContent(pBt, *pPgno);
|
||||
rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, noContent);
|
||||
rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 1);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3PagerDontRollback((*ppPage)->pDbPage);
|
||||
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(*ppPage);
|
||||
@@ -4381,10 +4301,6 @@ static int allocateBtreePage(
|
||||
int nPage = pagerPagecount(pBt);
|
||||
*pPgno = nPage + 1;
|
||||
|
||||
if( *pPgno==PENDING_BYTE_PAGE(pBt) ){
|
||||
(*pPgno)++;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
|
||||
/* If *pPgno refers to a pointer-map page, allocate two new pages
|
||||
@@ -4424,51 +4340,32 @@ end_allocate_page:
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used to add page iPage to the database file free-list.
|
||||
** It is assumed that the page is not already a part of the free-list.
|
||||
** Add a page of the database file to the freelist.
|
||||
**
|
||||
** The value passed as the second argument to this function is optional.
|
||||
** If the caller happens to have a pointer to the MemPage object
|
||||
** corresponding to page iPage handy, it may pass it as the second value.
|
||||
** Otherwise, it may pass NULL.
|
||||
**
|
||||
** If a pointer to a MemPage object is passed as the second argument,
|
||||
** its reference count is not altered by this function.
|
||||
** sqlite3PagerUnref() is NOT called for pPage.
|
||||
*/
|
||||
static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
MemPage *pTrunk = 0; /* Free-list trunk page */
|
||||
Pgno iTrunk = 0; /* Page number of free-list trunk page */
|
||||
MemPage *pPage1 = pBt->pPage1; /* Local reference to page 1 */
|
||||
MemPage *pPage; /* Page being freed. May be NULL. */
|
||||
int rc; /* Return Code */
|
||||
int nFree; /* Initial number of pages on free-list */
|
||||
static int freePage(MemPage *pPage){
|
||||
BtShared *pBt = pPage->pBt;
|
||||
MemPage *pPage1 = pBt->pPage1;
|
||||
int rc, n, k;
|
||||
|
||||
assert( sqlite3_mutex_held(pBt->mutex) );
|
||||
assert( iPage>1 );
|
||||
assert( !pMemPage || pMemPage->pgno==iPage );
|
||||
|
||||
if( pMemPage ){
|
||||
pPage = pMemPage;
|
||||
sqlite3PagerRef(pPage->pDbPage);
|
||||
}else{
|
||||
pPage = btreePageLookup(pBt, iPage);
|
||||
}
|
||||
/* Prepare the page for freeing */
|
||||
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
|
||||
assert( pPage->pgno>1 );
|
||||
pPage->isInit = 0;
|
||||
|
||||
/* Increment the free page count on pPage1 */
|
||||
rc = sqlite3PagerWrite(pPage1->pDbPage);
|
||||
if( rc ) goto freepage_out;
|
||||
nFree = get4byte(&pPage1->aData[36]);
|
||||
put4byte(&pPage1->aData[36], nFree+1);
|
||||
if( rc ) return rc;
|
||||
n = get4byte(&pPage1->aData[36]);
|
||||
put4byte(&pPage1->aData[36], n+1);
|
||||
|
||||
#ifdef SQLITE_SECURE_DELETE
|
||||
/* If the SQLITE_SECURE_DELETE compile-time option is enabled, then
|
||||
** always fully overwrite deleted information with zeros.
|
||||
*/
|
||||
if( (!pPage && (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0)))
|
||||
|| (rc = sqlite3PagerWrite(pPage->pDbPage))
|
||||
){
|
||||
goto freepage_out;
|
||||
}
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
if( rc ) return rc;
|
||||
memset(pPage->aData, 0, pPage->pBt->pageSize);
|
||||
#endif
|
||||
|
||||
@@ -4476,34 +4373,27 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
** to indicate that the page is free.
|
||||
*/
|
||||
if( ISAUTOVACUUM ){
|
||||
rc = ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0);
|
||||
if( rc ) goto freepage_out;
|
||||
rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0);
|
||||
if( rc ) return rc;
|
||||
}
|
||||
|
||||
/* Now manipulate the actual database free-list structure. There are two
|
||||
** possibilities. If the free-list is currently empty, or if the first
|
||||
** trunk page in the free-list is full, then this page will become a
|
||||
** new free-list trunk page. Otherwise, it will become a leaf of the
|
||||
** first trunk page in the current free-list. This block tests if it
|
||||
** is possible to add the page as a new free-list leaf.
|
||||
*/
|
||||
if( nFree!=0 ){
|
||||
int nLeaf; /* Initial number of leaf cells on trunk page */
|
||||
|
||||
iTrunk = get4byte(&pPage1->aData[32]);
|
||||
rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
goto freepage_out;
|
||||
}
|
||||
|
||||
nLeaf = get4byte(&pTrunk->aData[4]);
|
||||
if( nLeaf<0 ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto freepage_out;
|
||||
}
|
||||
if( nLeaf<pBt->usableSize/4 - 8 ){
|
||||
/* In this case there is room on the trunk page to insert the page
|
||||
** being freed as a new leaf.
|
||||
if( n==0 ){
|
||||
/* This is the first free page */
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
if( rc ) return rc;
|
||||
memset(pPage->aData, 0, 8);
|
||||
put4byte(&pPage1->aData[32], pPage->pgno);
|
||||
TRACE(("FREE-PAGE: %d first\n", pPage->pgno));
|
||||
}else{
|
||||
/* Other free pages already exist. Retrive the first trunk page
|
||||
** of the freelist and find out how many leaves it has. */
|
||||
MemPage *pTrunk;
|
||||
rc = sqlite3BtreeGetPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk, 0);
|
||||
if( rc ) return rc;
|
||||
k = get4byte(&pTrunk->aData[4]);
|
||||
if( k>=pBt->usableSize/4 - 8 ){
|
||||
/* The trunk is full. Turn the page being freed into a new
|
||||
** trunk page with no leaves.
|
||||
**
|
||||
** Note that the trunk page is not really full until it contains
|
||||
** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
|
||||
@@ -4516,49 +4406,32 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
|
||||
** to 3.6.0 or later) we should consider fixing the conditional above
|
||||
** to read "usableSize/4-2" instead of "usableSize/4-8".
|
||||
*/
|
||||
rc = sqlite3PagerWrite(pPage->pDbPage);
|
||||
if( rc==SQLITE_OK ){
|
||||
put4byte(pPage->aData, pTrunk->pgno);
|
||||
put4byte(&pPage->aData[4], 0);
|
||||
put4byte(&pPage1->aData[32], pPage->pgno);
|
||||
TRACE(("FREE-PAGE: %d new trunk page replacing %d\n",
|
||||
pPage->pgno, pTrunk->pgno));
|
||||
}
|
||||
}else if( k<0 ){
|
||||
rc = SQLITE_CORRUPT;
|
||||
}else{
|
||||
/* Add the newly freed page as a leaf on the current trunk */
|
||||
rc = sqlite3PagerWrite(pTrunk->pDbPage);
|
||||
if( rc==SQLITE_OK ){
|
||||
put4byte(&pTrunk->aData[4], nLeaf+1);
|
||||
put4byte(&pTrunk->aData[8+nLeaf*4], iPage);
|
||||
put4byte(&pTrunk->aData[4], k+1);
|
||||
put4byte(&pTrunk->aData[8+k*4], pPage->pgno);
|
||||
#ifndef SQLITE_SECURE_DELETE
|
||||
if( pPage ){
|
||||
sqlite3PagerDontWrite(pPage->pDbPage);
|
||||
}
|
||||
rc = sqlite3PagerDontWrite(pPage->pDbPage);
|
||||
#endif
|
||||
rc = btreeSetHasContent(pBt, iPage);
|
||||
}
|
||||
TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
|
||||
goto freepage_out;
|
||||
}
|
||||
}
|
||||
|
||||
/* If control flows to this point, then it was not possible to add the
|
||||
** the page being freed as a leaf page of the first trunk in the free-list.
|
||||
** Possibly because the free-list is empty, or possibly because the
|
||||
** first trunk in the free-list is full. Either way, the page being freed
|
||||
** will become the new first trunk page in the free-list.
|
||||
*/
|
||||
if( (!pPage && (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0)))
|
||||
|| (rc = sqlite3PagerWrite(pPage->pDbPage))
|
||||
){
|
||||
goto freepage_out;
|
||||
}
|
||||
put4byte(pPage->aData, iTrunk);
|
||||
put4byte(&pPage->aData[4], 0);
|
||||
put4byte(&pPage1->aData[32], iPage);
|
||||
TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk));
|
||||
|
||||
freepage_out:
|
||||
if( pPage ){
|
||||
pPage->isInit = 0;
|
||||
}
|
||||
releasePage(pPage);
|
||||
releasePage(pTrunk);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
static int freePage(MemPage *pPage){
|
||||
return freePage2(pPage->pBt, pPage, pPage->pgno);
|
||||
}
|
||||
|
||||
/*
|
||||
** Free any overflow pages associated with the given Cell.
|
||||
@@ -4581,21 +4454,16 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
|
||||
nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
|
||||
assert( ovflPgno==0 || nOvfl>0 );
|
||||
while( nOvfl-- ){
|
||||
Pgno iNext;
|
||||
MemPage *pOvfl = 0;
|
||||
MemPage *pOvfl;
|
||||
if( ovflPgno==0 || ovflPgno>pagerPagecount(pBt) ){
|
||||
return SQLITE_CORRUPT_BKPT;
|
||||
}
|
||||
if( nOvfl ){
|
||||
rc = getOverflowPage(pBt, ovflPgno, &pOvfl, &iNext);
|
||||
|
||||
rc = getOverflowPage(pBt, ovflPgno, &pOvfl, (nOvfl==0)?0:&ovflPgno);
|
||||
if( rc ) return rc;
|
||||
}
|
||||
rc = freePage2(pBt, pOvfl, ovflPgno);
|
||||
if( pOvfl ){
|
||||
rc = freePage(pOvfl);
|
||||
sqlite3PagerUnref(pOvfl->pDbPage);
|
||||
}
|
||||
if( rc ) return rc;
|
||||
ovflPgno = iNext;
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -6361,6 +6229,11 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){
|
||||
}
|
||||
assert( eType!=PTRMAP_ROOTPAGE );
|
||||
assert( eType!=PTRMAP_FREEPAGE );
|
||||
rc = sqlite3PagerWrite(pRoot->pDbPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
releasePage(pRoot);
|
||||
return rc;
|
||||
}
|
||||
rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove, 0);
|
||||
releasePage(pRoot);
|
||||
|
||||
@@ -7221,6 +7094,17 @@ const char *sqlite3BtreeGetFilename(Btree *p){
|
||||
return sqlite3PagerFilename(p->pBt->pPager);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the pathname of the directory that contains the database file.
|
||||
**
|
||||
** The pager directory name is invariant as long as the pager is
|
||||
** open so it is safe to access without the BtShared mutex.
|
||||
*/
|
||||
const char *sqlite3BtreeGetDirname(Btree *p){
|
||||
assert( p->pBt->pPager!=0 );
|
||||
return sqlite3PagerDirname(p->pBt->pPager);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the pathname of the journal file for this database. The return
|
||||
** value of this routine is the same regardless of whether the journal file
|
||||
@@ -7306,7 +7190,7 @@ static int btreeCopyFile(Btree *pTo, Btree *pFrom){
|
||||
** page is still on the rollback journal, though. And that is the
|
||||
** whole point of this block: to put pages on the rollback journal.
|
||||
*/
|
||||
sqlite3PagerDontWrite(pDbPage);
|
||||
rc = sqlite3PagerDontWrite(pDbPage);
|
||||
}
|
||||
sqlite3PagerUnref(pDbPage);
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btreeInt.h,v 1.39 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** $Id: btreeInt.h,v 1.40 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** For a detailed discussion of BTrees, refer to
|
||||
@@ -204,6 +204,10 @@
|
||||
** * zero or more pages numbers of leaves
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "pager.h"
|
||||
#include "btree.h"
|
||||
#include "os.h"
|
||||
#include <assert.h>
|
||||
|
||||
/* Round up a number to the next larger multiple of 8. This is used
|
||||
** to force 8-byte alignment on 64-bit architectures.
|
||||
@@ -379,7 +383,6 @@ struct BtShared {
|
||||
void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
|
||||
void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
|
||||
sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
|
||||
Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
int nRef; /* Number of references to this structure */
|
||||
BtShared *pNext; /* Next on a list of sharable BtShared structs */
|
||||
@@ -487,10 +490,18 @@ struct BtCursor {
|
||||
#define CURSOR_REQUIRESEEK 2
|
||||
#define CURSOR_FAULT 3
|
||||
|
||||
/*
|
||||
** The database page the PENDING_BYTE occupies. This page is never used.
|
||||
/* The database page the PENDING_BYTE occupies. This page is never used.
|
||||
** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
|
||||
** should possibly be consolidated (presumably in pager.h).
|
||||
**
|
||||
** If disk I/O is omitted (meaning that the database is stored purely
|
||||
** in memory) then there is no pending byte.
|
||||
*/
|
||||
# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
|
||||
#ifdef SQLITE_OMIT_DISKIO
|
||||
# define PENDING_BYTE_PAGE(pBt) 0x7fffffff
|
||||
#else
|
||||
# define PENDING_BYTE_PAGE(pBt) ((Pgno)((PENDING_BYTE/(pBt)->pageSize)+1))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** A linked list of the following structures is stored at BtShared.pLock.
|
||||
|
2087
src/pager.c
2087
src/pager.c
File diff suppressed because it is too large
Load Diff
80
src/pager.h
80
src/pager.h
@@ -13,16 +13,15 @@
|
||||
** subsystem. The page cache subsystem reads and writes a file a page
|
||||
** at a time and provides a journal for rollback.
|
||||
**
|
||||
** @(#) $Id: pager.h,v 1.94 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** @(#) $Id: pager.h,v 1.95 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PAGER_H_
|
||||
#define _PAGER_H_
|
||||
|
||||
/*
|
||||
** Default maximum size for persistent journal files. A negative
|
||||
** value means no limit. This value may be overridden using the
|
||||
** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit".
|
||||
** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
|
||||
** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
|
||||
*/
|
||||
#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
|
||||
#define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1
|
||||
@@ -44,20 +43,10 @@ typedef struct Pager Pager;
|
||||
*/
|
||||
typedef struct PgHdr DbPage;
|
||||
|
||||
/*
|
||||
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
|
||||
** reserved for working around a windows/posix incompatibility). It is
|
||||
** used in the journal to signify that the remainder of the journal file
|
||||
** is devoted to storing a master journal name - there are no more pages to
|
||||
** roll back. See comments for function writeMasterJournal() in pager.c
|
||||
** for details.
|
||||
*/
|
||||
#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
|
||||
|
||||
/*
|
||||
** Allowed values for the flags parameter to sqlite3PagerOpen().
|
||||
**
|
||||
** NOTE: These values must match the corresponding BTREE_ values in btree.h.
|
||||
** NOTE: This values must match the corresponding BTREE_ values in btree.h.
|
||||
*/
|
||||
#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */
|
||||
#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */
|
||||
@@ -80,84 +69,75 @@ typedef struct PgHdr DbPage;
|
||||
#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
|
||||
|
||||
/*
|
||||
** The remainder of this file contains the declarations of the functions
|
||||
** that make up the Pager sub-system API. See source code comments for
|
||||
** a detailed description of each routine.
|
||||
** See source code comments for a detailed description of the following
|
||||
** routines:
|
||||
*/
|
||||
|
||||
/* Open and close a Pager connection. */
|
||||
int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int);
|
||||
int sqlite3PagerClose(Pager *pPager);
|
||||
|
||||
/* Functions used to configure a Pager object. */
|
||||
void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
|
||||
void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*));
|
||||
int sqlite3PagerSetPagesize(Pager*, u16*);
|
||||
int sqlite3PagerMaxPageCount(Pager*, int);
|
||||
int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
|
||||
void sqlite3PagerSetCachesize(Pager*, int);
|
||||
void sqlite3PagerSetSafetyLevel(Pager*,int,int);
|
||||
int sqlite3PagerLockingMode(Pager *, int);
|
||||
int sqlite3PagerJournalMode(Pager *, int);
|
||||
i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
|
||||
|
||||
/* Functions used to obtain and release page references. */
|
||||
int sqlite3PagerClose(Pager *pPager);
|
||||
int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
|
||||
#define sqlite3PagerGet(A,B,C) sqlite3PagerAcquire(A,B,C,0)
|
||||
DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
|
||||
void sqlite3PagerRef(DbPage*);
|
||||
void sqlite3PagerUnref(DbPage*);
|
||||
|
||||
/* Operations on page references. */
|
||||
int sqlite3PagerWrite(DbPage*);
|
||||
void sqlite3PagerDontWrite(DbPage*);
|
||||
int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
|
||||
int sqlite3PagerPageRefcount(DbPage*);
|
||||
void *sqlite3PagerGetData(DbPage *);
|
||||
void *sqlite3PagerGetExtra(DbPage *);
|
||||
|
||||
/* Functions used to manage pager transactions and savepoints. */
|
||||
int sqlite3PagerRef(DbPage*);
|
||||
int sqlite3PagerUnref(DbPage*);
|
||||
int sqlite3PagerWrite(DbPage*);
|
||||
int sqlite3PagerPagecount(Pager*, int*);
|
||||
int sqlite3PagerBegin(DbPage*, int exFlag);
|
||||
int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
|
||||
int sqlite3PagerSync(Pager *pPager);
|
||||
int sqlite3PagerCommitPhaseTwo(Pager*);
|
||||
int sqlite3PagerRollback(Pager*);
|
||||
int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
|
||||
int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
|
||||
|
||||
/* Functions used to query pager state and configuration. */
|
||||
u8 sqlite3PagerIsreadonly(Pager*);
|
||||
void sqlite3PagerDontRollback(DbPage*);
|
||||
int sqlite3PagerDontWrite(DbPage*);
|
||||
int sqlite3PagerRefcount(Pager*);
|
||||
void sqlite3PagerSetSafetyLevel(Pager*,int,int);
|
||||
const char *sqlite3PagerFilename(Pager*);
|
||||
const sqlite3_vfs *sqlite3PagerVfs(Pager*);
|
||||
sqlite3_file *sqlite3PagerFile(Pager*);
|
||||
const char *sqlite3PagerDirname(Pager*);
|
||||
const char *sqlite3PagerJournalname(Pager*);
|
||||
int sqlite3PagerNosync(Pager*);
|
||||
int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int);
|
||||
void *sqlite3PagerGetData(DbPage *);
|
||||
void *sqlite3PagerGetExtra(DbPage *);
|
||||
int sqlite3PagerLockingMode(Pager *, int);
|
||||
int sqlite3PagerJournalMode(Pager *, int);
|
||||
i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
|
||||
void *sqlite3PagerTempSpace(Pager*);
|
||||
int sqlite3PagerSync(Pager *pPager);
|
||||
|
||||
int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
|
||||
int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
|
||||
|
||||
/* Functions used in auto-vacuum mode to truncate the database file. */
|
||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||
void sqlite3PagerTruncateImage(Pager*,Pgno);
|
||||
Pgno sqlite3PagerImageSize(Pager *);
|
||||
#endif
|
||||
|
||||
/* Used by encryption extensions. */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*);
|
||||
#endif
|
||||
|
||||
/* Functions to support testing and debugging. */
|
||||
#if !defined(NDEBUG) || defined(SQLITE_TEST)
|
||||
Pgno sqlite3PagerPagenumber(DbPage*);
|
||||
int sqlite3PagerIswriteable(DbPage*);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
int *sqlite3PagerStats(Pager*);
|
||||
void sqlite3PagerRefdump(Pager*);
|
||||
int sqlite3PagerIsMemdb(Pager*);
|
||||
void disable_simulated_io_errors(void);
|
||||
void enable_simulated_io_errors(void);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
void disable_simulated_io_errors(void);
|
||||
void enable_simulated_io_errors(void);
|
||||
#else
|
||||
# define disable_simulated_io_errors()
|
||||
# define enable_simulated_io_errors()
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file implements that page cache.
|
||||
**
|
||||
** @(#) $Id: pcache.c,v 1.40 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** @(#) $Id: pcache.c,v 1.41 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -431,8 +431,9 @@ void sqlite3PcacheClose(PCache *pCache){
|
||||
/*
|
||||
** Discard the contents of the cache.
|
||||
*/
|
||||
void sqlite3PcacheClear(PCache *pCache){
|
||||
int sqlite3PcacheClear(PCache *pCache){
|
||||
sqlite3PcacheTruncate(pCache, 0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the sqlite page cache
|
||||
** subsystem.
|
||||
**
|
||||
** @(#) $Id: pcache.h,v 1.17 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** @(#) $Id: pcache.h,v 1.18 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PCACHE_H_
|
||||
@@ -111,7 +111,7 @@ void sqlite3PcacheClose(PCache*);
|
||||
void sqlite3PcacheClearSyncFlags(PCache *);
|
||||
|
||||
/* Discard the contents of the cache */
|
||||
void sqlite3PcacheClear(PCache*);
|
||||
int sqlite3PcacheClear(PCache*);
|
||||
|
||||
/* Return the total number of outstanding page references */
|
||||
int sqlite3PcacheRefCount(PCache*);
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.826 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.827 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@@ -2255,7 +2255,6 @@ int sqlite3BitvecTest(Bitvec*, u32);
|
||||
int sqlite3BitvecSet(Bitvec*, u32);
|
||||
void sqlite3BitvecClear(Bitvec*, u32);
|
||||
void sqlite3BitvecDestroy(Bitvec*);
|
||||
u32 sqlite3BitvecSize(Bitvec*);
|
||||
int sqlite3BitvecBuiltinTest(int,int*);
|
||||
|
||||
RowSet *sqlite3RowSetInit(sqlite3*, void*, unsigned int);
|
||||
|
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test2.c,v 1.66 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** $Id: test2.c,v 1.67 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@@ -418,13 +418,18 @@ static int page_unref(
|
||||
const char **argv /* Text of each argument */
|
||||
){
|
||||
DbPage *pPage;
|
||||
int rc;
|
||||
if( argc!=2 ){
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" PAGE\"", 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
|
||||
sqlite3PagerUnref(pPage);
|
||||
rc = sqlite3PagerUnref(pPage);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, errorName(rc), 0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
@@ -14,7 +14,7 @@
|
||||
** to version 2.8.7, all this code was combined into the vdbe.c source file.
|
||||
** But that file was getting too big so this subroutines were split out.
|
||||
**
|
||||
** $Id: vdbeaux.c,v 1.431 2009/01/16 15:21:06 danielk1977 Exp $
|
||||
** $Id: vdbeaux.c,v 1.432 2009/01/16 16:23:38 danielk1977 Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -1388,10 +1388,10 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
|
||||
/* Sync the master journal file. If the IOCAP_SEQUENTIAL device
|
||||
** flag is set this is not required.
|
||||
*/
|
||||
if( needSync
|
||||
&& 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
|
||||
&& SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
|
||||
){
|
||||
zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt);
|
||||
if( (needSync
|
||||
&& (0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL))
|
||||
&& (rc=sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))!=SQLITE_OK) ){
|
||||
sqlite3OsCloseFree(pMaster);
|
||||
sqlite3OsDelete(pVfs, zMaster, 0);
|
||||
sqlite3DbFree(db, zMaster);
|
||||
|
Reference in New Issue
Block a user