/ Check-in [c878d741]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix a problem with using "<db>-vacuum" (the default) as the state database when resuming an RBU vacuum.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:c878d741733a897d47a1a0b57b454bc9095ce302b48cc01089336d5d20e2a24c
User & Date: dan 2018-12-10 08:41:32
Context
2018-12-12
11:54
Fix a problem with using "<db>-vacuum" (the default) as the state database when resuming an RBU vacuum. check-in: 6b7567fc user: drh tags: branch-3.26
2018-12-10
18:15
Refactor the sqlite3_normalized_sql() implementation. check-in: 06e955e5 user: drh tags: trunk
08:41
Fix a problem with using "<db>-vacuum" (the default) as the state database when resuming an RBU vacuum. check-in: c878d741 user: dan tags: trunk
01:48
Add support for the VACUUM INTO command. check-in: 77f150b8 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/rbu/rbu_common.tcl.

    82     82       sqlite3 tmpdb $rbu
    83     83       tmpdb eval { DELETE FROM rbu_state WHERE k==10 }
    84     84       tmpdb close
    85     85     }
    86     86     set rc
    87     87   }
    88     88   
    89         -proc do_rbu_vacuum_test {tn step} {
    90         -  forcedelete state.db
    91         -  uplevel [list do_test $tn.1 {
    92         -    if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
           89  +proc do_rbu_vacuum_test {tn step {statedb state.db}} {
           90  +  forcedelete $statedb
           91  +  if {$statedb=="" && $step==1} breakpoint
           92  +  uplevel [list do_test $tn.1 [string map [list %state% $statedb] {
           93  +    if {$step==0} { sqlite3rbu_vacuum rbu test.db {%state%}}
    93     94       while 1 {
    94         -      if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db }
           95  +      if {$step==1} { sqlite3rbu_vacuum rbu test.db {%state%}}
    95     96         set state [rbu state]
    96     97         check_prestep_state test.db $state
    97     98         set rc [rbu step]
    98     99         check_poststep_state $rc test.db $state
    99    100         if {$rc!="SQLITE_OK"} break
   100    101         if {$step==1} { rbu close }
   101    102       }
   102    103       rbu close
   103         -  } {SQLITE_DONE}]
          104  +  }] {SQLITE_DONE}]
   104    105   
   105    106     uplevel [list do_execsql_test $tn.2 {
   106    107       PRAGMA integrity_check
   107    108     } ok]
   108    109   }
   109    110   

Changes to ext/rbu/rbuvacuum2.test.

    12     12   # This file contains tests for the RBU module. More specifically, it
    13     13   # contains tests to ensure that the sqlite3rbu_vacuum() API works as
    14     14   # expected.
    15     15   #
    16     16   
    17     17   source [file join [file dirname [info script]] rbu_common.tcl]
    18     18   
    19         -foreach step {0 1} {
    20         -  set ::testprefix rbuvacuum2-$step
           19  +foreach {step} {0 1} {
           20  +foreach {ttt state} {
           21  +  s state.db t test.db-vacuum n {}
           22  +} {
           23  +  set ::testprefix rbuvacuum2-$step$ttt
    21     24     
    22     25     #-------------------------------------------------------------------------
    23     26     # Test that a database that contains fts3 tables can be vacuumed.
    24     27     #
    25     28     ifcapable fts3 {
    26     29       reset_db
    27     30       do_execsql_test 1.1 {
    28     31         CREATE VIRTUAL TABLE t1 USING fts3(z, y);
    29     32         INSERT INTO t1 VALUES('fix this issue', 'at some point');
    30     33       }
    31     34     
    32         -    do_rbu_vacuum_test 1.2 $step
           35  +    do_rbu_vacuum_test 1.2 $step $state
    33     36     
    34     37       do_execsql_test 1.3 {
    35     38         SELECT * FROM t1;
    36     39       } {{fix this issue} {at some point}}
    37     40     
    38     41       do_execsql_test 1.4 {
    39     42         SELECT rowid FROM t1 WHERE t1 MATCH 'fix';
................................................................................
    42     45       do_execsql_test 1.5 {
    43     46         INSERT INTO t1 VALUES('a b c', 'd e f');
    44     47         INSERT INTO t1 VALUES('l h i', 'd e f');
    45     48         DELETE FROM t1 WHERE docid = 2;
    46     49         INSERT INTO t1 VALUES('a b c', 'x y z');
    47     50       }
    48     51   
    49         -    do_rbu_vacuum_test 1.6 $step
           52  +    do_rbu_vacuum_test 1.6 $step $state
    50     53       do_execsql_test 1.7 {
    51     54         INSERT INTO t1(t1) VALUES('integrity-check');
    52     55         SELECT * FROM t1;
    53     56       } {
    54     57         {fix this issue} {at some point}
    55     58         {l h i} {d e f}
    56     59         {a b c} {x y z}
................................................................................
    63     66     ifcapable fts5 {
    64     67       reset_db
    65     68       do_execsql_test 2.1 {
    66     69         CREATE VIRTUAL TABLE t1 USING fts5(z, y);
    67     70         INSERT INTO t1 VALUES('fix this issue', 'at some point');
    68     71       }
    69     72     
    70         -    do_rbu_vacuum_test 2.2 $step
           73  +    do_rbu_vacuum_test 2.2 $step $state
    71     74     
    72     75       do_execsql_test 2.3 {
    73     76         SELECT * FROM t1;
    74     77       } {{fix this issue} {at some point}}
    75     78     
    76     79       do_execsql_test 2.4 {
    77     80         SELECT rowid FROM t1 ('fix');
................................................................................
    80     83       do_execsql_test 2.5 {
    81     84         INSERT INTO t1 VALUES('a b c', 'd e f');
    82     85         INSERT INTO t1 VALUES('l h i', 'd e f');
    83     86         DELETE FROM t1 WHERE rowid = 2;
    84     87         INSERT INTO t1 VALUES('a b c', 'x y z');
    85     88       }
    86     89   
    87         -    do_rbu_vacuum_test 2.6 $step
           90  +    do_rbu_vacuum_test 2.6 $step $state
    88     91       do_execsql_test 2.7 {
    89     92         INSERT INTO t1(t1) VALUES('integrity-check');
    90     93         SELECT * FROM t1;
    91     94       } {
    92     95         {fix this issue} {at some point}
    93     96         {l h i} {d e f}
    94     97         {a b c} {x y z}
................................................................................
   103    106       do_execsql_test 3.1 {
   104    107         CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
   105    108         INSERT INTO rt VALUES(1, 45, 55);
   106    109         INSERT INTO rt VALUES(2, 50, 60);
   107    110         INSERT INTO rt VALUES(3, 55, 65);
   108    111       }
   109    112     
   110         -    do_rbu_vacuum_test 3.2 $step
          113  +    do_rbu_vacuum_test 3.2 $step $state
   111    114     
   112    115       do_execsql_test 3.3 {
   113    116         SELECT * FROM rt;
   114    117       } {1 45.0 55.0 2 50.0 60.0 3 55.0 65.0}
   115    118     
   116    119       do_execsql_test 3.4.1 {
   117    120         SELECT rowid FROM rt WHERE x2>51 AND x1 < 51
   118    121       } {1 2}
   119    122       do_execsql_test 3.4.2 {
   120    123         SELECT rowid FROM rt WHERE x2>59 AND x1 < 59
   121    124       } {2 3}
   122    125   
   123         -    do_rbu_vacuum_test 3.5 $step
          126  +    do_rbu_vacuum_test 3.5 $step $state
   124    127   
   125    128       do_execsql_test 3.6.1 {
   126    129         SELECT rowid FROM rt WHERE x2>51 AND x1 < 51
   127    130       } {1 2}
   128    131       do_execsql_test 3.6.2 {
   129    132         SELECT rowid FROM rt WHERE x2>59 AND x1 < 59
   130    133       } {2 3}
................................................................................
   143    146         SELECT * FROM sqlite_master;
   144    147       } {
   145    148       table t1 t1 2 {CREATE TABLE t1(a, b, c)}
   146    149       view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t1}
   147    150       trigger tr1 t1 0 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END}
   148    151       }
   149    152   
   150         -    do_rbu_vacuum_test 4.3 $step
          153  +    do_rbu_vacuum_test 4.3 $step $state
   151    154       do_execsql_test 4.4 {
   152    155         SELECT * FROM sqlite_master;
   153    156       } {
   154    157       table t1 t1 2 {CREATE TABLE t1(a, b, c)}
   155    158       view v1 v1 0 {CREATE VIEW v1 AS SELECT * FROM t1}
   156    159       trigger tr1 t1 0 {CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END}
   157    160       }
   158    161     }
          162  +}
   159    163   }
   160    164     
   161    165   #-------------------------------------------------------------------------
   162    166   # Test that passing a NULL value as the second argument to 
   163    167   # sqlite3rbu_vacuum() causes it to:
   164    168   #
   165    169   #   * Use <database>-vacuum as the state db, and
................................................................................
   227    231   do_test 6.3 {
   228    232     sqlite3rbu_vacuum rbu test.db test.db2
   229    233     while {[rbu step]!="SQLITE_DONE"} { rbu step }
   230    234     rbu close
   231    235     execsql { PRAGMA integrity_check }
   232    236   } {ok}
   233    237   
          238  +do_test 6.4 {
          239  +  sqlite3rbu_vacuum rbu test.db test.db-vactmp
          240  +  list [catch { rbu close } msg] $msg
          241  +} {1 SQLITE_MISUSE}
          242  +
   234    243   finish_test

Changes to ext/rbu/sqlite3rbu.c.

  2473   2473           zExtra = &p->zRbu[5];
  2474   2474           while( *zExtra ){
  2475   2475             if( *zExtra++=='?' ) break;
  2476   2476           }
  2477   2477           if( *zExtra=='\0' ) zExtra = 0;
  2478   2478         }
  2479   2479   
  2480         -      zTarget = sqlite3_mprintf("file:%s-vacuum?rbu_memory=1%s%s", 
         2480  +      zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s", 
  2481   2481             sqlite3_db_filename(p->dbRbu, "main"),
  2482   2482             (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra)
  2483   2483         );
  2484   2484   
  2485   2485         if( zTarget==0 ){
  2486   2486           p->rc = SQLITE_NOMEM;
  2487   2487           return;
................................................................................
  3739   3739   ** Open a handle to begin or resume an RBU VACUUM operation.
  3740   3740   */
  3741   3741   sqlite3rbu *sqlite3rbu_vacuum(
  3742   3742     const char *zTarget, 
  3743   3743     const char *zState
  3744   3744   ){
  3745   3745     if( zTarget==0 ){ return rbuMisuseError(); }
         3746  +  if( zState ){
         3747  +    int n = strlen(zState);
         3748  +    if( n>=7 && 0==memcmp("-vactmp", &zState[n-7], 7) ){
         3749  +      return rbuMisuseError();
         3750  +    }
         3751  +  }
  3746   3752     /* TODO: Check that both arguments are non-NULL */
  3747   3753     return openRbuHandle(0, zTarget, zState);
  3748   3754   }
  3749   3755   
  3750   3756   /*
  3751   3757   ** Return the database handle used by pRbu.
  3752   3758   */

Changes to ext/rbu/sqlite3rbu.h.

   329    329   ** The vacuum can be resumed by calling this function to open a new RBU
   330    330   ** handle specifying the same target and state databases.
   331    331   **
   332    332   ** If the second argument passed to this function is NULL, then the
   333    333   ** name of the state database is "<database>-vacuum", where <database>
   334    334   ** is the name of the target database file. In this case, on UNIX, if the
   335    335   ** state database is not already present in the file-system, it is created
   336         -** with the same permissions as the target db is made.
          336  +** with the same permissions as the target db is made. 
          337  +**
          338  +** With an RBU vacuum, it is an SQLITE_MISUSE error if the name of the 
          339  +** state database ends with "-vactmp". This name is reserved for internal 
          340  +** use.
   337    341   **
   338    342   ** This function does not delete the state database after an RBU vacuum
   339    343   ** is completed, even if it created it. However, if the call to
   340    344   ** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
   341    345   ** of the state tables within the state database are zeroed. This way,
   342    346   ** the next call to sqlite3rbu_vacuum() opens a handle that starts a 
   343    347   ** new RBU vacuum operation.

Changes to ext/rbu/test_rbu.c.

   269    269     if( objc!=3 && objc!=4 ){
   270    270       Tcl_WrongNumArgs(interp, 1, objv, "NAME TARGET-DB ?STATE-DB?");
   271    271       return TCL_ERROR;
   272    272     }
   273    273     zCmd = Tcl_GetString(objv[1]);
   274    274     zTarget = Tcl_GetString(objv[2]);
   275    275     if( objc==4 ) zStateDb = Tcl_GetString(objv[3]);
          276  +  if( zStateDb && zStateDb[0]=='\0' ) zStateDb = 0;
   276    277   
   277    278     pRbu = sqlite3rbu_vacuum(zTarget, zStateDb);
   278    279     Tcl_CreateObjCommand(interp, zCmd, test_sqlite3rbu_cmd, (ClientData)pRbu, 0);
   279    280     Tcl_SetObjResult(interp, objv[1]);
   280    281     return TCL_OK;
   281    282   }
   282    283