Fix spurious errors that may occur if an empty database is opened and then initialized as a WAL database by a second connection.

FossilOrigin-Name: 16330a2f7262173a32ae48a72c0ee2522b6dc554
This commit is contained in:
dan 2012-02-28 17:57:34 +00:00
parent 4aced72a59
commit f602963dbc
5 changed files with 112 additions and 17 deletions

View File

@ -1,5 +1,5 @@
C Fix\sa\scase\swhere\san\serror\scode\swas\sbeing\soverwritten\sin\smultiplexDelete().
D 2012-02-28T11:52:12.825
C Fix\sspurious\serrors\sthat\smay\soccur\sif\san\sempty\sdatabase\sis\sopened\sand\sthen\sinitialized\sas\sa\sWAL\sdatabase\sby\sa\ssecond\sconnection.
D 2012-02-28T17:57:34.628
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 3f79a373e57c3b92dabf76f40b065e719d31ac34
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -239,7 +239,7 @@ F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684
F src/update.c d3076782c887c10e882996550345da9c4c9f9dea
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/util.c 906731099c4397bf8adf3fa90a833355e7472af0
F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa
F src/vacuum.c bfd53f9bd20a8fdb70b0fa8e77182b866875c0d8
F src/vdbe.c 32720e873ed0a23e6ee928b676cd995864b984d6
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
F src/vdbeInt.h 6ff4180a05683566a8835d12f7ec504b22932c82
@ -250,7 +250,7 @@ F src/vdbemem.c fb0ac964ccbcd94f595eb993c05bfd9c52468a4a
F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9
F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843
F src/vtab.c ab90fb600a3f5e4b7c48d22a4cdb2d6b23239847
F src/wal.c c164c39e8625b2b6e7d7b2aab5e7296ebd7e8190
F src/wal.c 7bb3ad807afc7973406c805d5157ec7a2f65e146
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c af623942514571895818b9b7ae11db95ae3b3d88
@ -913,6 +913,7 @@ F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437
F test/wal6.test 2e3bc767d9c2ce35c47106148d43fcbd072a93b3
F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd
F test/wal8.test 5ab217d21f7e5e86af2933a4ffd0d8357cc2c0bd
F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe
F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877
F test/walbig.test 0ab8a430ef420a3114f7092e0f30fc9585ffa155
@ -990,7 +991,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P e44e26771e5aa48f3bfa14d6db3e669b5b2a1e73
R a83bd20b956aa8e93cec00d5fc1e4306
P c267893a0813beb1764071409025e178318e1ca3
R 751c4f9505bcae82ab2d498f42151225
U dan
Z a4ff6a0dae74370332c0513312e14191
Z aacac9f6818b59f3fbe792ef77401913

View File

@ -1 +1 @@
c267893a0813beb1764071409025e178318e1ca3
16330a2f7262173a32ae48a72c0ee2522b6dc554

View File

@ -176,6 +176,18 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
}
#endif
rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Begin a transaction and take an exclusive lock on the main database
** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
** to ensure that we do not try to change the page-size on a WAL database.
*/
rc = execSql(db, pzErrMsg, "BEGIN;");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = sqlite3BtreeBeginTrans(pMain, 2);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Do not attempt to change the page size for a WAL database */
if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
==PAGER_JOURNALMODE_WAL ){
@ -189,20 +201,12 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
rc = SQLITE_NOMEM;
goto end_of_vacuum;
}
rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
if( rc!=SQLITE_OK ){
goto end_of_vacuum;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
sqlite3BtreeGetAutoVacuum(pMain));
#endif
/* Begin a transaction */
rc = execSql(db, pzErrMsg, "BEGIN EXCLUSIVE;");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Query the schema of the main database. Create a mirror schema
** in the temporary database.
*/

View File

@ -2397,7 +2397,7 @@ int sqlite3WalRead(
iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
*pInWal = 1;
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
}
*pInWal = 0;

90
test/wal8.test Normal file
View File

@ -0,0 +1,90 @@
# 2012 February 28
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is testing the operation of the library in
# "PRAGMA journal_mode=WAL" mode.
#
# Specifically, it tests the case where a connection opens an empty
# file. Then, another connection opens the same file and initializes
# the connection as a WAL database. Following this, the first connection
# executes a "PRAGMA page_size = XXX" command to set its expected page
# size, and then queries the database.
#
# This is an unusual case, as normally SQLite is able to glean the page
# size from the database file as soon as it is opened (even before the
# first read transaction is executed), and the "PRAGMA page_size = XXX"
# is a no-op.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix wal8
db close
forcedelete test.db test.db-wal
sqlite3 db test.db
sqlite3 db2 test.db
do_test 1.0 {
execsql {
PRAGMA journal_mode = wal;
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
} db2
} {wal}
do_catchsql_test 1.1 {
PRAGMA page_size = 4096;
VACUUM;
} {0 {}}
db close
db2 close
forcedelete test.db test.db-wal
sqlite3 db test.db
sqlite3 db2 test.db
do_test 2.0 {
execsql {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
PRAGMA journal_mode = wal;
} db2
} {wal}
do_catchsql_test 2.1 {
PRAGMA page_size = 4096;
VACUUM;
} {0 {}}
db close
db2 close
forcedelete test.db test.db-wal
sqlite3 db test.db
sqlite3 db2 test.db
do_test 3.0 {
execsql {
PRAGMA journal_mode = wal;
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 2);
} db2
} {wal}
do_execsql_test 3.1 {
PRAGMA page_size = 4096;
SELECT name FROM sqlite_master;
} {t1}
finish_test