1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-05-28 12:41:31 +03:00

Pull the experimental file-size-in-header changes into the trunk.

FossilOrigin-Name: 0092b36c7bbd04bf3826de7805e8a14739390f31
This commit is contained in:
drh 2010-03-29 21:22:00 +00:00
commit 4b11b0897a
8 changed files with 92 additions and 72 deletions

View File

@ -1,5 +1,8 @@
C Increase\sthe\sestimated\scost\sof\susing\sa\svirtual\stable\sas\sthe\souter\sloop\sof\sa\sjoin\swhen\sthere\sexists\san\sORDER\sBY\sclause\sthat\sis\snot\ssatisfied\sby\sthe\svirtual\stable.\sFix\sfor\s[775b39dd3c].
D 2010-03-27T09:44:42
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C Pull\sthe\sexperimental\sfile-size-in-header\schanges\sinto\sthe\strunk.
D 2010-03-29T21:22:01
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 4f2f967b7e58a35bb74fb7ec8ae90e0f4ca7868b
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -109,9 +112,9 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c b293534bc2df23c57668a585b17ee7faaaef0939
F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
F src/btree.c 0d6e44d664b1775b269ea7e6f66fdffcfc32ceb3
F src/btree.c ca75bce3383240f9fb14590ddfcd72883cc09609
F src/btree.h 0e193b7e90f1d78b79c79474040e3d66a553a4fa
F src/btreeInt.h 71ed5e7f009caf17b7dc304350b3cb64b5970135
F src/btreeInt.h 22447d259639271774a931cbf66aa55112846681
F src/build.c 11100b66fb97638d2d874c1d34d8db90650bb1d7
F src/callback.c 908f3e0172c3d4058f4ca0acd42c637c52e9669f
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
@ -152,7 +155,7 @@ F src/os_common.h 240c88b163b02c21a9f21f87d49678a0aa21ff30
F src/os_os2.c 75a8c7b9a00a2cf1a65f9fa4afbc27d46634bb2f
F src/os_unix.c 148d2f625db3727250c0b880481ae7630b6d0eb0
F src/os_win.c 1c7453c2df4dab26d90ff6f91272aea18bcf7053
F src/pager.c 2a374f72e6c87150d043173b8041dc537f926b02
F src/pager.c af1c58b7b884839853cc553681f771297de56049
F src/pager.h ef8a2cf10084f60ab45ee2dfded8bf8b0c655ddf
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
@ -293,7 +296,7 @@ F test/colmeta.test 087c42997754b8c648819832241daf724f813322
F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
F test/conflict.test 0ed68b11f22721052d880ee80bd528a0e0828236
F test/corrupt.test 0d346c9fe064ca71281685a8a732fcc83461bb99
F test/corrupt2.test a571e30ea4e82318f319a24b6cc55935ce862079
F test/corrupt2.test 576122d756feda40e63ef1c1ff6c4720a927d126
F test/corrupt3.test 263e8bb04e2728df832fddf6973cf54c91db0c32
F test/corrupt4.test acdb01afaedf529004b70e55de1a6f5a05ae7fff
F test/corrupt5.test c23da7bfb20917cc7fdbb13ee25c7cc4e9fffeff
@ -444,7 +447,7 @@ F test/insert5.test 1f93cbe9742110119133d7e8e3ccfe6d7c249766
F test/intarray.test 066b7d7ac38d25bf96f87f1b017bfc687551cdd4
F test/interrupt.test 42e7cf98646fd9cb4a3b131a93ed3c50b9e149f1
F test/intpkey.test 537669fd535f62632ca64828e435b9e54e8d677f
F test/io.test e7bd58edb4e2131a8ecd81b4b00af3ee5c79d464
F test/io.test 1b895d6774491895cbc75659969f07ca01860c88
F test/ioerr.test 390785ec65f10aa58a82b048ee12e9052d783fa8
F test/ioerr2.test 1b56cb80d5b0726ee3ba325ca175734541e32955
F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
@ -528,7 +531,7 @@ F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
F test/pcache.test eebc4420b37cb07733ae9b6e99c9da7c40dd6d58
F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
F test/permutations.test 91928573ca2db2c88dbc50ab34e4a585d912b580
F test/pragma.test 5aeb48a442dba3c3e8e38773b121371814ab3b17
F test/pragma.test 6960f9efbce476f70ba9ee2171daf5042f9e3d8a
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301
@ -794,7 +797,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P c33b38b59f733494ca0bce3f59a669fe7ed76b9f
R 1048b4f005b8cf985bff319e6cd284fa
U dan
Z 25a9f1889e9ba9dd674533c69390c60b
P 9e075e70f0e2a1ad302d17150cd58f91669a97a6 01ef6c1944507c188a83a434ff00e98ad767f744
R 374d4e1ebc45357833ef412064f83b3a
U drh
Z 57cc17a4ebdb6db8a7496650df2ea784
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFLsRn8oxKgR168RlERAg2zAKCErrX+/Kxo1OQ3scmJtMXF6sW7igCfRiyC
IbDKiWnRdJiQJBnIvthiNrk=
=Js1q
-----END PGP SIGNATURE-----

View File

@ -1 +1 @@
9e075e70f0e2a1ad302d17150cd58f91669a97a6
0092b36c7bbd04bf3826de7805e8a14739390f31

View File

@ -516,11 +516,8 @@ static void invalidateIncrblobCursors(
static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
int rc = SQLITE_OK;
if( !pBt->pHasContent ){
int nPage = 100;
sqlite3PagerPagecount(pBt->pPager, &nPage);
/* If sqlite3PagerPagecount() fails there is no harm because the
** nPage variable is unchanged from its default value of 100 */
pBt->pHasContent = sqlite3BitvecCreate((u32)nPage);
assert( pgno<=pBt->nPage );
pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
if( !pBt->pHasContent ){
rc = SQLITE_NOMEM;
}
@ -1564,12 +1561,8 @@ static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
** error, return ((unsigned int)-1).
*/
static Pgno pagerPagecount(BtShared *pBt){
int nPage = -1;
int rc;
assert( pBt->pPage1 );
rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
assert( rc==SQLITE_OK || nPage==-1 );
return (Pgno)nPage;
int nPage = (int)pBt->nPage;
return nPage;
}
/*
@ -2254,8 +2247,8 @@ static int lockBtree(BtShared *pBt){
/* Do some checking to help insure the file we opened really is
** a valid database file.
*/
rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
if( rc!=SQLITE_OK ){
nPage = get4byte(28+(u8*)pPage1->aData);
if( nPage==0 && (rc = sqlite3PagerPagecount(pBt->pPager, &nPage))!=0 ){
goto page1_init_failed;
}else if( nPage>0 ){
int pageSize;
@ -2333,6 +2326,7 @@ static int lockBtree(BtShared *pBt){
pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23;
assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
pBt->pPage1 = pPage1;
pBt->nPage = nPage;
return SQLITE_OK;
page1_init_failed:
@ -2370,12 +2364,10 @@ static int newDatabase(BtShared *pBt){
MemPage *pP1;
unsigned char *data;
int rc;
int nPage;
assert( sqlite3_mutex_held(pBt->mutex) );
rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
if( rc!=SQLITE_OK || nPage>0 ){
return rc;
if( pBt->nPage>0 ){
return SQLITE_OK;
}
pP1 = pBt->pPage1;
assert( pP1!=0 );
@ -2401,6 +2393,8 @@ static int newDatabase(BtShared *pBt){
put4byte(&data[36 + 4*4], pBt->autoVacuum);
put4byte(&data[36 + 7*4], pBt->incrVacuum);
#endif
pBt->nPage = 1;
data[31] = 1;
return SQLITE_OK;
}
@ -2490,6 +2484,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
if( SQLITE_OK!=rc ) goto trans_begun;
pBt->initiallyEmpty = pBt->nPage==0;
do {
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
@ -2769,12 +2764,12 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
*/
static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
Pgno nFreeList; /* Number of pages still on the free-list */
int rc;
assert( sqlite3_mutex_held(pBt->mutex) );
assert( iLastPg>nFin );
if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){
int rc;
u8 eType;
Pgno iPtrPage;
@ -2850,7 +2845,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){
if( PTRMAP_ISPAGE(pBt, iLastPg) ){
MemPage *pPg;
int rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
rc = btreeGetPage(pBt, iLastPg, &pPg, 0);
if( rc!=SQLITE_OK ){
return rc;
}
@ -2863,6 +2858,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){
iLastPg--;
}
sqlite3PagerTruncateImage(pBt->pPager, iLastPg);
pBt->nPage = iLastPg;
}
return SQLITE_OK;
}
@ -2886,6 +2882,10 @@ int sqlite3BtreeIncrVacuum(Btree *p){
}else{
invalidateAllOverflowCache(pBt);
rc = incrVacuumStep(pBt, 0, pagerPagecount(pBt));
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
put4byte(&pBt->pPage1->aData[28], pBt->nPage);
}
}
sqlite3BtreeLeave(p);
return rc;
@ -2941,11 +2941,12 @@ static int autoVacuumCommit(BtShared *pBt){
rc = incrVacuumStep(pBt, nFin, iFree);
}
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
rc = SQLITE_OK;
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
put4byte(&pBt->pPage1->aData[32], 0);
put4byte(&pBt->pPage1->aData[36], 0);
put4byte(&pBt->pPage1->aData[28], nFin);
sqlite3PagerTruncateImage(pBt->pPager, nFin);
pBt->nPage = nFin;
}
if( rc!=SQLITE_OK ){
sqlite3PagerRollback(pPager);
@ -3232,17 +3233,13 @@ int sqlite3BtreeBeginStmt(Btree *p, int iStatement){
assert( pBt->readOnly==0 );
assert( iStatement>0 );
assert( iStatement>p->db->nSavepoint );
if( NEVER(p->inTrans!=TRANS_WRITE || pBt->readOnly) ){
rc = SQLITE_INTERNAL;
}else{
assert( pBt->inTransaction==TRANS_WRITE );
/* At the pager level, a statement transaction is a savepoint with
** an index greater than all savepoints created explicitly using
** SQL statements. It is illegal to open, release or rollback any
** such savepoints while the statement transaction savepoint is active.
*/
rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement);
}
assert( pBt->inTransaction==TRANS_WRITE );
/* At the pager level, a statement transaction is a savepoint with
** an index greater than all savepoints created explicitly using
** SQL statements. It is illegal to open, release or rollback any
** such savepoints while the statement transaction savepoint is active.
*/
rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement);
sqlite3BtreeLeave(p);
return rc;
}
@ -3268,7 +3265,9 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
sqlite3BtreeEnter(p);
rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
if( rc==SQLITE_OK ){
if( iSavepoint<0 && pBt->initiallyEmpty ) pBt->nPage = 0;
rc = newDatabase(pBt);
pBt->nPage = get4byte(28 + pBt->pPage1->aData);
}
sqlite3BtreeLeave(p);
}
@ -4833,35 +4832,35 @@ static int allocateBtreePage(
}else{
/* There are no pages on the freelist, so create a new page at the
** end of the file */
int nPage = pagerPagecount(pBt);
*pPgno = nPage + 1;
if( *pPgno==PENDING_BYTE_PAGE(pBt) ){
(*pPgno)++;
}
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
if( rc ) return rc;
pBt->nPage++;
if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++;
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, *pPgno) ){
if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt, pBt->nPage) ){
/* If *pPgno refers to a pointer-map page, allocate two new pages
** at the end of the file instead of one. The first allocated page
** becomes a new pointer-map page, the second is used by the caller.
*/
MemPage *pPg = 0;
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno));
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
rc = btreeGetPage(pBt, *pPgno, &pPg, 0);
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1);
if( rc==SQLITE_OK ){
rc = sqlite3PagerWrite(pPg->pDbPage);
releasePage(pPg);
}
if( rc ) return rc;
(*pPgno)++;
if( *pPgno==PENDING_BYTE_PAGE(pBt) ){ (*pPgno)++; }
pBt->nPage++;
if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; }
}
#endif
put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
*pPgno = pBt->nPage;
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
rc = btreeGetPage(pBt, *pPgno, ppPage, 0);
rc = btreeGetPage(pBt, *pPgno, ppPage, 1);
if( rc ) return rc;
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
if( rc!=SQLITE_OK ){

View File

@ -408,6 +408,7 @@ struct BtShared {
u8 readOnly; /* True if the underlying file is readonly */
u8 pageSizeFixed; /* True if the page size can no longer be changed */
u8 secureDelete; /* True if secure_delete is enabled */
u8 initiallyEmpty; /* Database is empty at start of transaction */
#ifndef SQLITE_OMIT_AUTOVACUUM
u8 autoVacuum; /* True if auto-vacuum is enabled */
u8 incrVacuum; /* True if incr-vacuum is enabled */
@ -420,6 +421,7 @@ struct BtShared {
u16 minLeaf; /* Minimum local payload in a LEAFDATA table */
u8 inTransaction; /* Transaction state */
int nTransaction; /* Number of open transactions (read + write) */
u32 nPage; /* Number of pages in the database */
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 */

View File

@ -4156,10 +4156,10 @@ static int pager_write(PgHdr *pPg){
*/
assert( pPager->state>=PAGER_RESERVED );
/* If an error has been previously detected, we should not be
** calling this routine. Repeat the error for robustness.
/* If an error has been previously detected, report the same error
** again.
*/
if( NEVER(pPager->errCode) ) return pPager->errCode;
if( pPager->errCode ) return pPager->errCode;
/* Higher-level routines never call this function if database is not
** writable. But check anyway, just for robustness. */
@ -4489,10 +4489,6 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
change_counter++;
put32bits(((char*)pPgHdr->pData)+24, change_counter);
/* Also store the current database size in bytes 28..31 */
assert( pPager->dbSizeValid );
put32bits(((char*)pPgHdr->pData)+28, pPager->dbSize);
/* Also store the SQLite version number in bytes 96..99 */
assert( pPager->dbSizeValid );
put32bits(((char*)pPgHdr->pData)+96, SQLITE_VERSION_NUMBER);
@ -4570,10 +4566,8 @@ int sqlite3PagerCommitPhaseOne(
/* The dbOrigSize is never set if journal_mode=OFF */
assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 );
/* If a prior error occurred, this routine should not be called. ROLLBACK
** is the appropriate response to an error, not COMMIT. Guard against
** coding errors by repeating the prior error. */
if( NEVER(pPager->errCode) ) return pPager->errCode;
/* If a prior error occurred, report that error again. */
if( pPager->errCode ) return pPager->errCode;
PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n",
pPager->zFilename, zMaster, pPager->dbSize));
@ -4925,6 +4919,9 @@ int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
int ii; /* Iterator variable */
PagerSavepoint *aNew; /* New Pager.aSavepoint array */
rc = sqlite3PagerPagecount(pPager, 0);
if( rc ) return rc;
/* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
** if the allocation fails. Otherwise, zero the new portion in case a
** malloc failure occurs while populating it in the for(...) loop below.

View File

@ -334,6 +334,7 @@ ifcapable autovacuum {
seek $fd 0 end
puts -nonewline $fd [string repeat x $nAppend]
close $fd
hexio_write corrupt.db 28 00000000
} -test {
do_test corrupt2-6.4 {
catchsql {
@ -522,6 +523,7 @@ ifcapable autovacuum {
file size corrupt.db
} $::sqlite_pending_byte
hexio_write corrupt.db [expr $::sqlite_pending_byte+1023] 00
hexio_write corrupt.db 28 00000000
} -test {
do_test corrupt2-13.2 {
file size corrupt.db

View File

@ -200,10 +200,16 @@ do_test io-2.5.3 {
# journal file is not actually created until the 'COMMIT' statement
# is executed.
#
# Changed 2010-03-27: The size of the database is now stored in
# bytes 28..31 and so when a page is added to the database, page 1
# is immediately modified and the journal file immediately comes into
# existance. To fix this test, the BEGIN is changed into a a
# BEGIN IMMEDIATE and the INSERT is omitted.
#
do_test io-2.6.1 {
execsql {
BEGIN;
INSERT INTO abc VALUES(9, randstr(1000,1000));
BEGIN IMMEDIATE;
-- INSERT INTO abc VALUES(9, randstr(1000,1000));
}
file exists test.db-journal
} {0}
@ -213,12 +219,15 @@ do_test io-2.6.2 {
# should fail with SQLITE_CANTOPEN and the transaction rolled back.
#
file mkdir test.db-journal
catchsql { COMMIT }
catchsql {
INSERT INTO abc VALUES(9, randstr(1000,1000));
COMMIT
}
} {1 {unable to open database file}}
do_test io-2.6.3 {
file delete -force test.db-journal
catchsql { COMMIT }
} {1 {cannot commit - no transaction is active}}
} {0 {}}
do_test io-2.6.4 {
execsql { SELECT * FROM abc }
} {1 2 3 4 5 6 7 8}

View File

@ -317,6 +317,7 @@ ifcapable attach {
puts -nonewline $out [read $in]
close $in
close $out
hexio_write testerr.db 28 00000000
execsql {REINDEX t2}
execsql {PRAGMA integrity_check}
} {ok}