aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2011-10-07 16:57:59 +0000
committerdan <dan@noemail.net>2011-10-07 16:57:59 +0000
commitc5f20a00616ca2d0d18cbacff234715b7682b0fb (patch)
tree854117c384ac3773ad2c52b88298a5405079e269 /src
parentf3259997c017d9660587ffd61a5ca3d3a7db973e (diff)
downloadsqlite-c5f20a00616ca2d0d18cbacff234715b7682b0fb.tar.gz
sqlite-c5f20a00616ca2d0d18cbacff234715b7682b0fb.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/backup.c9
-rw-r--r--src/sqlite.h.in7
-rw-r--r--src/vacuum.c12
3 files changed, 20 insertions, 8 deletions
diff --git a/src/backup.c b/src/backup.c
index 70a782665..411a9b8d6 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 d13f17639..040c365d8 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 0e92f4fb0..58a3c9d68 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;