]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not allow VACUUM INTO into a file that already exists.
authordrh <drh@noemail.net>
Fri, 7 Dec 2018 23:48:41 +0000 (23:48 +0000)
committerdrh <drh@noemail.net>
Fri, 7 Dec 2018 23:48:41 +0000 (23:48 +0000)
FossilOrigin-Name: 92f70e0fa3c9de7fde046f11cc0a7c2800511bb5ace8e68c845133931607616e

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

index c59fcc04273396e6b60c2d4d6ea962c70fd4ff7b..635f30acfac1df09bfe7fbe40145bbed9689fab0 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\sthe\sVACUUM\ssimplification\sfrom\strunk.
-D 2018-12-07T20:40:12.098
+C Do\snot\sallow\sVACUUM\sINTO\sinto\sa\sfile\sthat\salready\sexists.
+D 2018-12-07T23:48:41.554
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 68d0ba0f0b533d5bc84c78c13a6ce84ee81183a67014caa47a969e67f028fa1c
@@ -577,7 +577,7 @@ F src/update.c 1816d56c1bca1ba4e0ef98cac2f49be62858e9df1dc08844c7067eb41cc44274
 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
-F src/vacuum.c 7b74a106ecac182900124e7708b3657377a5b2b18812efc31f100caca1c0eae3
+F src/vacuum.c 5d49497308883e608bb420c112e87c10417b576af2a6d1dd0dba62d4a494ffd7
 F src/vdbe.c 872bdd34338548242b36df18c49c90b34689e41c0b4e5c197e83bb82a38ce8dd
 F src/vdbe.h d82f323d581b36b8e147d650257ef34e0e93790039b6cbda45c321c275f7595e
 F src/vdbeInt.h 73f5051923f3f29779bfc374c0c68e23b8e5e3792def2e33e51b427edb890abd
@@ -1562,6 +1562,7 @@ F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568
 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7
 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9
 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae
+F test/vacuum-into.test dab9e498ea303f27370e71eb7e9a3369eb71ae90f4ea1afa741a1347ece39f5d
 F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
 F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
 F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
@@ -1782,7 +1783,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 036e3320a4af36c1311b25b2e504b0079c8b33df8ad7b7e5fddad07150e6f87d a92c398fc5df142ff1459c1be4a6832f2219bc7fabe5789535be3bbd41a4269b
-R 5e2deff1e10a62e804983a88b3d403b2
+P 93d92a0a5d21a1856316c0205ecaa253691b6e5349b552d43027005676d14820
+R 4b91cbcd00a28fb8ade4cd8b52c5b6e4
 U drh
-Z a260dfd202744b5f58f4cbc1728d27d6
+Z b3677de0205f375bf2be187f033f6ce8
index 94144aeb81707fa53f4107960877ee8cee87a5fa..4f71499d9692edb7b7ed1ce9185e51e79d67cfc2 100644 (file)
@@ -1 +1 @@
-93d92a0a5d21a1856316c0205ecaa253691b6e5349b552d43027005676d14820
\ No newline at end of file
+92f70e0fa3c9de7fde046f11cc0a7c2800511bb5ace8e68c845133931607616e
\ No newline at end of file
index 4f4fcf410c3b834fdc2a8c9abbcb2cdbbc52633f..a28541cc58c79bc4c0b2be57abc324bc72d6b671 100644 (file)
@@ -200,6 +200,15 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb, const char *zOut){
   pDb = &db->aDb[nDb];
   assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
   pTemp = pDb->pBt;
+  if( zOut!=0 ){
+    sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
+    i64 sz = 0;
+    if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
+      rc = SQLITE_ERROR;
+      sqlite3SetString(pzErrMsg, db, "output file already exists");
+      goto end_of_vacuum;
+    }
+  }
   nRes = sqlite3BtreeGetOptimalReserve(pMain);
 
   /* A VACUUM cannot change the pagesize of an encrypted database. */
@@ -374,11 +383,9 @@ end_of_vacuum:
     pDb->pSchema = 0;
   }
 
-  if( zOut==0 ){
-    /* This both clears the schemas and reduces the size of the db->aDb[]
-    ** array. */ 
-    sqlite3ResetAllSchemasOfConnection(db);
-  }
+  /* This both clears the schemas and reduces the size of the db->aDb[]
+  ** array. */ 
+  sqlite3ResetAllSchemasOfConnection(db);
 
   return rc;
 }
diff --git a/test/vacuum-into.test b/test/vacuum-into.test
new file mode 100644 (file)
index 0000000..f04c0be
--- /dev/null
@@ -0,0 +1,58 @@
+# 2018-12-07
+#
+# 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 VACUUM INTO statement.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# If the VACUUM statement is disabled in the current build, skip all
+# the tests in this file.
+#
+ifcapable {!vacuum} {
+  omit_test vacuum.test {Compiled with SQLITE_OMIT_VACUUM}
+  finish_test
+  return
+}
+
+forcedelete out.db
+do_execsql_test vacuum-into-100 {
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
+  INSERT INTO t1(a,b) SELECT x, randomblob(600) FROM c;
+  CREATE INDEX t1b ON t1(b);
+  DELETE FROM t1 WHERE a%2;
+  SELECT count(*), sum(a), sum(length(b)) FROM t1;
+} {50 2550 30000}
+do_execsql_test vacuum-into-110 {
+  VACUUM main INTO 'out.db';
+} {}
+sqlite3 db2 out.db
+do_test vacuum-into-120 {
+  db2 eval {SELECT count(*), sum(a), sum(length(b)) FROM t1}
+} {50 2550 30000}
+do_catchsql_test vacuum-into-130 {
+  VACUUM INTO 'out.db';
+} {1 {output file already exists}}
+forcedelete out2.db
+do_catchsql_test vacuum-into-140 {
+  VACUUM INTO 'out2.db';
+} {0 {}}
+do_catchsql_test vacuum-into-150 {
+  VACUUM INTO 'out2.db';
+} {1 {output file already exists}}
+
+do_catchsql_test vacuum-into-200 {
+  VACUUM main INTO ':memory:';
+} {0 {}}
+
+finish_test