]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix spurious errors that may occur if an empty database is opened and then initialize...
authordan <dan@noemail.net>
Tue, 28 Feb 2012 17:57:34 +0000 (17:57 +0000)
committerdan <dan@noemail.net>
Tue, 28 Feb 2012 17:57:34 +0000 (17:57 +0000)
FossilOrigin-Name: 16330a2f7262173a32ae48a72c0ee2522b6dc554

manifest
manifest.uuid
src/vacuum.c
src/wal.c
test/wal8.test [new file with mode: 0644]

index 108aca806ac8c89191c316a5660a71e62607c769..ffe0e4775e16c4b7cf92e0fbea1c5fa684be5c01 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 8a835053fac4b07ebf7003c860e8cfcb125fde73..df6fdce3eee58e160c13938612d2997fa67eee0a 100644 (file)
@@ -1 +1 @@
-c267893a0813beb1764071409025e178318e1ca3
\ No newline at end of file
+16330a2f7262173a32ae48a72c0ee2522b6dc554
\ No newline at end of file
index 58a3c9d683b71086ba850ff6cfe52bed43dd81a4..c03b4500b3f15ec103b80eecf16b3a6dcc80378b 100644 (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.
   */
index 97d2185ea29d0f759698ef018cebae5c534704f4..b077d27d9e3b3f25890d84f078b1d58cd32b3539 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -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;
diff --git a/test/wal8.test b/test/wal8.test
new file mode 100644 (file)
index 0000000..4b97de7
--- /dev/null
@@ -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
+