From c5f20a00616ca2d0d18cbacff234715b7682b0fb Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 7 Oct 2011 16:57:59 +0000 Subject: [PATCH] Add the SQLITE_FCNTL_OVERWRITE file-control. Used by SQLite to indicate to the OS layer that the current transaction will overwrite the entire file. FossilOrigin-Name: 1da87fcdacfa7d277c3ee98e410a9ea8b529c368 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/backup.c | 9 +++++++++ src/sqlite.h.in | 7 ++++++- src/vacuum.c | 12 +++++------- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 791d69d826..e2c9eff23d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite3_data_count()\sroutine\sso\sthat\sit\scan\sbe\sused\sto\sdetermine\nif\sSQLITE_DONE\shas\sbeen\sseen\son\sthe\sprepared\sstatement. -D 2011-10-07T12:59:23.182 +C Add\sthe\sSQLITE_FCNTL_OVERWRITE\sfile-control.\sUsed\sby\sSQLite\sto\sindicate\sto\sthe\sOS\slayer\sthat\sthe\scurrent\stransaction\swill\soverwrite\sthe\sentire\sfile. +D 2011-10-07T16:57:59.355 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in a162fe39e249b8ed4a65ee947c30152786cfe897 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -121,7 +121,7 @@ F src/alter.c ac80a0f31189f8b4a524ebf661e47e84536ee7f5 F src/analyze.c 775421ced0bd78181cc206fbc63063658066c1da F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 -F src/backup.c 28a4fe55327ff708bfaf9d4326d02686f7a553c3 +F src/backup.c 4fd4440c8f81339d8eb8e5d2df54b68d79e94f2f F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 77b09c69d4849a90361e6fe5db36d167f20600c0 @@ -181,7 +181,7 @@ F src/resolve.c 36368f44569208fa074e61f4dd0b6c4fb60ca2b4 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c d9b7d20b0365f80761846f00ef3638d4b33eeaf2 F src/shell.c e8fe1251aee84baa2fb232ce83d938de25aa650f -F src/sqlite.h.in 1865923bdb9deb8dde42da5862aca0071adb6061 +F src/sqlite.h.in b22e3187e048661d98a748ad54099c69dccfe497 F src/sqlite3ext.h 1a1a4f784aa9c3b00edd287940197de52487cd93 F src/sqliteInt.h 28cca77ebdaf6025ae5df52717dff429c7c6d4ef F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d @@ -237,7 +237,7 @@ F src/trigger.c 1cfb80e2290ef66ea89cb4e821caae65a02c0d56 F src/update.c 74a6cfb34e9732c1e2a86278b229913b4b51eeec F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/util.c 06302ffd2b80408d4f6c7af71f7090e0cf8d8ff7 -F src/vacuum.c 297f39745e05d7a6ed7def7929451474d570a31e +F src/vacuum.c 0c0ba2242355c6048d65e2b333abe0f7c06348fa F src/vdbe.c 60340bfb23f456ea0791cb28262a887363773371 F src/vdbe.h f0725ee997db869ecae5bb70a71612aabeca7755 F src/vdbeInt.h 693d6ac6810298fc6b4c503cfbe3f99a240f40af @@ -967,7 +967,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P baa80c7bc31900decae0d8e6090b30fcde377492 -R 1223a474d1e5cea6170a2af45d3f0303 -U drh -Z 7e8fd93d23ec7d2fecbdff0e025997fa +P 9913996e7b0f94ba1c51200b61433193002f3638 +R 95c2b529419f78d1f0a0f16ca9ea56e3 +U dan +Z 751eeeee5e1f94cafba63c56e2ffa2f0 diff --git a/manifest.uuid b/manifest.uuid index 9fe70085bf..abd31e2d97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9913996e7b0f94ba1c51200b61433193002f3638 \ No newline at end of file +1da87fcdacfa7d277c3ee98e410a9ea8b529c368 \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 70a782665b..411a9b8d6a 100644 --- a/src/backup.c +++ b/src/backup.c @@ -669,10 +669,18 @@ void sqlite3BackupRestart(sqlite3_backup *pBackup){ */ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ int rc; + sqlite3_file *pFd; /* File descriptor for database pTo */ sqlite3_backup b; sqlite3BtreeEnter(pTo); sqlite3BtreeEnter(pFrom); + assert( sqlite3BtreeIsInTrans(pTo) ); + pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); + if( pFd->pMethods ){ + i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + } + /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set ** to 0. This is used by the implementations of sqlite3_backup_step() ** and sqlite3_backup_finish() to detect that they are being called @@ -698,6 +706,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ pTo->pBt->pageSizeFixed = 0; } + assert( sqlite3BtreeIsInTrans(pTo)==0 ); sqlite3BtreeLeave(pFrom); sqlite3BtreeLeave(pTo); return rc; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d13f17639d..040c365d80 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -766,7 +766,11 @@ struct sqlite3_io_methods { ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. -** +** +** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening +** a write transaction to indicate that, unless it is rolled back for some +** reason, the entire database file will be overwritten by the current +** transaction. This is used by VACUUM operations. */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_GET_LOCKPROXYFILE 2 @@ -778,6 +782,7 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_SYNC_OMITTED 8 #define SQLITE_FCNTL_WIN32_AV_RETRY 9 #define SQLITE_FCNTL_PERSIST_WAL 10 +#define SQLITE_FCNTL_OVERWRITE 11 /* ** CAPI3REF: Mutex Handle diff --git a/src/vacuum.c b/src/vacuum.c index 0e92f4fb0e..58a3c9d683 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -263,13 +263,11 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ ); if( rc ) goto end_of_vacuum; - /* At this point, unless the main db was completely empty, there is now a - ** transaction open on the vacuum database, but not on the main database. - ** Open a btree level transaction on the main database. This allows a - ** call to sqlite3BtreeCopyFile(). The main database btree level - ** transaction is then committed, so the SQL level never knows it was - ** opened for writing. This way, the SQL transaction used to create the - ** temporary database never needs to be committed. + /* At this point, there is a write transaction open on both the + ** vacuum database and the main database. Assuming no error occurs, + ** both transactions are closed by this block - the main database + ** transaction by sqlite3BtreeCopyFile() and the other by an explicit + ** call to sqlite3BtreeCommit(). */ { u32 meta; -- 2.47.2