]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix an RBU problem causing spurious SQLITE_CONSTRAINT errors when restarting
authordan <dan@noemail.net>
Sat, 28 Apr 2018 18:20:01 +0000 (18:20 +0000)
committerdan <dan@noemail.net>
Sat, 28 Apr 2018 18:20:01 +0000 (18:20 +0000)
an RBU update in which more than one source table writes to a single target
database table.

FossilOrigin-Name: 564ae8297d417ba4b7978e430d41f125007177673163f6ed9adc3a3974f73d24

ext/rbu/rbu1.test
ext/rbu/rbu_common.tcl
ext/rbu/rbusplit.test [new file with mode: 0644]
ext/rbu/sqlite3rbu.c
manifest
manifest.uuid

index cd4172888602d07a4cd71d5f000b629b806c2a7d..1d16c1cd0a8f131675ed3465bd62aae6e0034634 100644 (file)
@@ -139,6 +139,7 @@ foreach {tn3 create_vfs destroy_vfs} {
   foreach {tn2 cmd} {
       1 run_rbu 
       2 step_rbu 3 step_rbu_uri 4 step_rbu_state
+      5 step_rbu_legacy
   } {
     foreach {tn schema} {
       1 {
index b216fe0858230fbfb1d174880aeb3ae1743844a7..2b263b7660d5a3a9f1e2392f63018f1cbf058700 100644 (file)
@@ -70,6 +70,22 @@ proc step_rbu {target rbu} {
   set rc
 }
 
+proc step_rbu_legacy {target rbu} {
+  while 1 {
+    sqlite3rbu rbu $target $rbu
+    set state [rbu state]
+    check_prestep_state $target $state
+    set rc [rbu step]
+    check_poststep_state $rc $target $state
+    rbu close
+    if {$rc != "SQLITE_OK"} break
+    sqlite3 tmpdb $rbu
+    tmpdb eval { DELETE FROM rbu_state WHERE k==10 }
+    tmpdb close
+  }
+  set rc
+}
+
 proc do_rbu_vacuum_test {tn step} {
   forcedelete state.db
   uplevel [list do_test $tn.1 {
diff --git a/ext/rbu/rbusplit.test b/ext/rbu/rbusplit.test
new file mode 100644 (file)
index 0000000..678f388
--- /dev/null
@@ -0,0 +1,95 @@
+# 2018 April 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.
+#
+#***********************************************************************
+#
+#
+
+source [file join [file dirname [info script]] rbu_common.tcl]
+set ::testprefix rbusplit
+
+db close
+sqlite3_shutdown
+sqlite3_config_uri 1
+
+autoinstall_test_functions
+
+proc build_db {db} {
+  $db eval {
+    CREATE TABLE t1(a PRIMARY KEY, b, c);
+    CREATE TABLE t2(a PRIMARY KEY, b, c);
+
+    CREATE INDEX t1c ON t1(c);
+  }
+}
+
+proc build_rbu {filename} {
+  forcedelete $filename
+  sqlite3 dbRbu $filename
+  dbRbu eval {
+    CREATE TABLE data0_t1(a, b, c, rbu_control);
+    CREATE TABLE data1_t1(a, b, c, rbu_control);
+    CREATE TABLE data2_t1(a, b, c, rbu_control);
+    CREATE TABLE data3_t1(a, b, c, rbu_control);
+
+    CREATE TABLE data_t2(a, b, c, rbu_control);
+
+    INSERT INTO data0_t1 VALUES(1, 1, 1, 0);
+    INSERT INTO data0_t1 VALUES(2, 2, 2, 0);
+    INSERT INTO data0_t1 VALUES(3, 3, 3, 0);
+    INSERT INTO data0_t1 VALUES(4, 4, 4, 0);
+    INSERT INTO data1_t1 VALUES(5, 5, 5, 0);
+    INSERT INTO data1_t1 VALUES(6, 6, 6, 0);
+    INSERT INTO data1_t1 VALUES(7, 7, 7, 0);
+    INSERT INTO data1_t1 VALUES(8, 8, 8, 0);
+    INSERT INTO data3_t1 VALUES(9, 9, 9, 0);
+
+    INSERT INTO data_t2 VALUES(1, 1, 1, 0);
+    INSERT INTO data_t2 VALUES(2, 2, 2, 0);
+    INSERT INTO data_t2 VALUES(3, 3, 3, 0);
+    INSERT INTO data_t2 VALUES(4, 4, 4, 0);
+    INSERT INTO data_t2 VALUES(5, 5, 5, 0);
+    INSERT INTO data_t2 VALUES(6, 6, 6, 0);
+    INSERT INTO data_t2 VALUES(7, 7, 7, 0);
+    INSERT INTO data_t2 VALUES(8, 8, 8, 0);
+    INSERT INTO data_t2 VALUES(9, 9, 9, 0);
+  }
+  
+  dbRbu close
+}
+
+foreach {tn cmd} {
+  1 run_rbu
+  2 step_rbu
+} {
+  reset_db
+  build_db db
+  build_rbu testrbu.db
+
+  do_test 1.$tn.1 {
+    $cmd test.db testrbu.db
+  } {SQLITE_DONE}
+  do_execsql_test 1.$tn.1 {
+    SELECT * FROM t1;
+  } {
+    1 1 1 2 2 2 3 3 3 4 4 4
+    5 5 5 6 6 6 7 7 7 8 8 8
+    9 9 9
+  }
+  do_execsql_test 1.$tn.2 {
+    SELECT * FROM t2;
+  } {
+    1 1 1 2 2 2 3 3 3 4 4 4
+    5 5 5 6 6 6 7 7 7 8 8 8
+    9 9 9
+  }
+}
+
+finish_test
+
index a3d54f91e522ce814d1c7c96f503a453939f5b33..065b13c7fa6175419a5b26056c7d1b67027039f5 100644 (file)
 **
 ** RBU_STATE_OALSZ:
 **   Valid if STAGE==1. The size in bytes of the *-oal file.
+**
+** RBU_STATE_DATATBL:
+**   Only valid if STAGE==1. The RBU database name of the table 
+**   currently being read.
 */
 #define RBU_STATE_STAGE        1
 #define RBU_STATE_TBL          2
 #define RBU_STATE_COOKIE       7
 #define RBU_STATE_OALSZ        8
 #define RBU_STATE_PHASEONESTEP 9
+#define RBU_STATE_DATATBL     10
 
 #define RBU_STAGE_OAL         1
 #define RBU_STAGE_MOVE        2
@@ -205,6 +210,7 @@ typedef sqlite3_int64 i64;
 struct RbuState {
   int eStage;
   char *zTbl;
+  char *zDataTbl;
   char *zIdx;
   i64 iWalCksum;
   int nRow;
@@ -2268,6 +2274,7 @@ static sqlite3 *rbuOpenDbhandle(
 static void rbuFreeState(RbuState *p){
   if( p ){
     sqlite3_free(p->zTbl);
+    sqlite3_free(p->zDataTbl);
     sqlite3_free(p->zIdx);
     sqlite3_free(p);
   }
@@ -2338,6 +2345,10 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
         pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1);
         break;
 
+      case RBU_STATE_DATATBL:
+        pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
+        break;
+
       default:
         rc = SQLITE_CORRUPT;
         break;
@@ -3112,7 +3123,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
           "(%d, %lld), "
           "(%d, %lld), "
           "(%d, %lld), "
-          "(%d, %lld) ",
+          "(%d, %lld), "
+          "(%d, %Q)  ",
           p->zStateDb,
           RBU_STATE_STAGE, eStage,
           RBU_STATE_TBL, p->objiter.zTbl, 
@@ -3122,7 +3134,8 @@ static void rbuSaveState(sqlite3rbu *p, int eStage){
           RBU_STATE_CKPT, p->iWalCksum,
           RBU_STATE_COOKIE, (i64)pFd->iCookie,
           RBU_STATE_OALSZ, p->iOalSz,
-          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep
+          RBU_STATE_PHASEONESTEP, p->nPhaseOneStep,
+          RBU_STATE_DATATBL, p->objiter.zDataTbl
       )
     );
     assert( pInsert==0 || rc==SQLITE_OK );
@@ -3378,7 +3391,8 @@ static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){
 
     while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup 
        || rbuStrCompare(pIter->zIdx, pState->zIdx)
-       || rbuStrCompare(pIter->zTbl, pState->zTbl) 
+       || (pState->zDataTbl==0 && rbuStrCompare(pIter->zTbl, pState->zTbl))
+       || (pState->zDataTbl && rbuStrCompare(pIter->zDataTbl, pState->zDataTbl))
     )){
       rc = rbuObjIterNext(p, pIter);
     }
index afe199c78d720710887d3f645df79bb7a86bc706..952b5b561d00ac7da0903dca02debbb176cec2ca 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\sSQLITE_DBCONFIG_RESET_DATABASE\scontrol\sfor\sresetting\sa\scorrupt\ndatabase\sfile\swithout\sclosing\sany\sdatabase\sconnections.\s\sAdded\sthe\n".dbconfig"\scommand\sto\sthe\sCLI.
-D 2018-04-28T13:21:00.131
+C Fix\san\sRBU\sproblem\scausing\sspurious\sSQLITE_CONSTRAINT\serrors\swhen\srestarting\nan\sRBU\supdate\sin\swhich\smore\sthan\sone\ssource\stable\swrites\sto\sa\ssingle\starget\ndatabase\stable.
+D 2018-04-28T18:20:01.187
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 5ce9343cba9c189046f1afe6d2bcc1f68079439febc05267b98aec6ecc752439
@@ -308,7 +308,7 @@ F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
 F ext/misc/zipfile.c c4de8f0ad446ce4a49aae11ff7b771cd7af60d7136c0bcfb53da1475b9075e79
 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
 F ext/rbu/rbu.c 4ae41f01d78dfae2204a63bcf39d5eb3548d039b094c29eec9a8d6683a66a5d3
-F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
+F ext/rbu/rbu1.test 41123c64e8c88bd14eb7d3f8562f37fa87aaeb154b1eade2881de21d3504be55
 F ext/rbu/rbu10.test 1846519a438697f45e9dcb246908af81b551c29e1078d0304fae83f1fed7e9ee
 F ext/rbu/rbu11.test 9bc68c2d3dbeb1720153626e3bd0466dcc017702
 F ext/rbu/rbu12.test bde22ed0004dd5d1888c72a84ae407e574aeae16
@@ -323,7 +323,7 @@ F ext/rbu/rbu9.test 0806d1772c9f4981774ff028de6656e4183082af
 F ext/rbu/rbuA.test 4e58e46e60d4064248614c43303d71f1b18cc804dd834ce6a913b3861828b28d
 F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
 F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
-F ext/rbu/rbu_common.tcl ebb8d81f44dc20e360cff1f34eb2ad0def33128805c5b36afcc44ab338509589
+F ext/rbu/rbu_common.tcl acfb7fbbaf8d46a9f6f6a5ec795616c84d705e1565d918afe43f0ff53ea0efa5
 F ext/rbu/rbucollate.test 86d6fc9b8f59a27b7b5a6e20b5e29816d338a0dbdea8c54bfcc549a0d437f3ea
 F ext/rbu/rbucrash.test 61470d977a06a0abc2ec35b05d82a1d7d87d10f4ffabad14c1c231edc942ad66
 F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d
@@ -338,10 +338,11 @@ F ext/rbu/rbumulti.test 2cf153ab3d5861ff26517dc6cbaec430787a59f1d50e8771fe7a7529
 F ext/rbu/rbuprogress.test 1849d4e0e50616edf5ce75ce7db86622e656b5cf
 F ext/rbu/rburesume.test 8acb77f4a422ff55acfcfc9cc15a5cb210b1de83
 F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
+F ext/rbu/rbusplit.test 69271c790732b28bd465551d80b0a9a3f074e189896ee8490ce56d22078c124d
 F ext/rbu/rbutemplimit.test cd553a9288d515d0b5f87d277e76fd18c4aa740b761e7880fab11ce986ea18d1
 F ext/rbu/rbuvacuum.test ff357e9b556ca7ad4673da0ff7f244def919ff858e0f9f350d3e30fdd83a62a8
 F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
-F ext/rbu/sqlite3rbu.c f6e9ca388b5d4680fbf266a4d10a21aec11d6baf48f6d06fd53f6b205fad959f
+F ext/rbu/sqlite3rbu.c f438fea899d15d13ff3e3133242b9e378c37b5a3d76add8c342c68bdd65c6819
 F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2
 F ext/rbu/test_rbu.c baa23eb28457580673d2175e5f0c29ced0cd320ee819b13ad362398c53b96e90
 F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
@@ -1725,7 +1726,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 6e098ee415f1a530e17a942c9ba51d67c25a3ebff6b97377b7858d0b10bcec92 ff836cb8b0377c5970ecb2b797702e2b5d208eda443ecbd55f4c238a3094b28a
-R edbc587ec4dfbdf46b4ab916ffe47e60
-U drh
-Z 995979318a529c573ca1f05b93ed22e0
+P a200a49edeaca5a787a3036070f7ced3cb6e9495f8afe7b74d5cde02c79b20dc
+R a57111df9a8d9421276a0abc4d9ce2ed
+U dan
+Z ad185b98451d11b0164183c41426fb3b
index d123b5ff6ba31a73e38ce620ee16394736b6ff2c..996f9ff76927edbce9f6aa6fa25459569960dbf2 100644 (file)
@@ -1 +1 @@
-a200a49edeaca5a787a3036070f7ced3cb6e9495f8afe7b74d5cde02c79b20dc
\ No newline at end of file
+564ae8297d417ba4b7978e430d41f125007177673163f6ed9adc3a3974f73d24
\ No newline at end of file