Index: third_party/sqlite/src/ext/rbu/rbuprogress.test |
diff --git a/third_party/sqlite/src/ext/rbu/rbuprogress.test b/third_party/sqlite/src/ext/rbu/rbuprogress.test |
new file mode 100644 |
index 0000000000000000000000000000000000000000..af202829c13570d00061632400abcb213cf3bd01 |
--- /dev/null |
+++ b/third_party/sqlite/src/ext/rbu/rbuprogress.test |
@@ -0,0 +1,417 @@ |
+# 2016 March 18 |
+# |
+# 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 rbuprogress |
+ |
+ |
+proc create_db_file {filename sql} { |
+ forcedelete $filename |
+ sqlite3 tmpdb $filename |
+ tmpdb eval $sql |
+ tmpdb close |
+} |
+ |
+# Create a simple RBU database. That expects to write to a table: |
+# |
+# CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); |
+# |
+proc create_rbu1 {filename} { |
+ create_db_file $filename { |
+ CREATE TABLE data_t1(a, b, c, rbu_control); |
+ INSERT INTO data_t1 VALUES(1, 2, 3, 0); |
+ INSERT INTO data_t1 VALUES(2, 'two', 'three', 0); |
+ INSERT INTO data_t1 VALUES(3, NULL, 8.2, 0); |
+ |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data_t1', 3); |
+ } |
+ return $filename |
+} |
+ |
+ |
+do_execsql_test 1.0 { |
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); |
+} |
+ |
+do_test 1.1 { |
+ create_rbu1 rbu.db |
+ sqlite3rbu rbu test.db rbu.db |
+ rbu bp_progress |
+} {0 0} |
+do_test 1.2 { rbu step ; rbu bp_progress } {3333 0} |
+do_test 1.3 { rbu step ; rbu bp_progress } {6666 0} |
+do_test 1.4 { rbu step ; rbu bp_progress } {10000 0} |
+do_test 1.5 { rbu step ; rbu bp_progress } {10000 0} |
+do_test 1.6 { rbu step ; rbu bp_progress } {10000 0} |
+do_test 1.7 { rbu step ; rbu bp_progress } {10000 5000} |
+do_test 1.8 { rbu step ; rbu bp_progress } {10000 10000} |
+do_test 1.9 { rbu step ; rbu bp_progress } {10000 10000} |
+ |
+do_test 1.10 { |
+ rbu close |
+} {SQLITE_DONE} |
+ |
+#------------------------------------------------------------------------- |
+# |
+proc do_sp_test {tn bReopen target rbu reslist} { |
+ uplevel [list do_test $tn [subst -nocommands { |
+ if {$bReopen==0} { sqlite3rbu rbu $target $rbu } |
+ set res [list] |
+ while 1 { |
+ if {$bReopen} { sqlite3rbu rbu $target $rbu } |
+ set rc [rbu step] |
+ if {[set rc] != "SQLITE_OK"} { rbu close ; error "error 1" } |
+ lappend res [lindex [rbu bp_progress] 0] |
+ if {[lindex [set res] end]==10000} break |
+ if {$bReopen} { rbu close } |
+ } |
+ if {[set res] != [list $reslist]} { |
+ rbu close |
+ error "1. reslist incorrect (expect=$reslist got=[set res])" |
+ } |
+ |
+ # One step to clean up the temporary tables used to update the only |
+ # target table in the rbu database. And one more to move the *-oal |
+ # file to *-wal. After each of these steps, the progress remains |
+ # at "10000 0". |
+ # |
+ if {[lindex [list $reslist] 0]!=-1} { |
+ rbu step |
+ set res [rbu bp_progress] |
+ if {[set res] != [list 10000 0]} { |
+ rbu close |
+ error "2. reslist incorrect (expect=10000 0 got=[set res])" |
+ } |
+ } |
+ |
+ rbu step |
+ set res [rbu bp_progress] |
+ if {[set res] != [list 10000 0]} { |
+ rbu close |
+ error "3. reslist incorrect (expect=10000 0 got=[set res])" |
+ } |
+ |
+ # Do the checkpoint. |
+ while {[rbu step]=="SQLITE_OK"} { |
+ foreach {a b} [rbu bp_progress] {} |
+ if {[set a]!=10000 || [set b]<=0 || [set b]>10000} { |
+ rbu close |
+ error "4. reslist incorrect (expect=10000 1..10000 got=[set a] [set b])" |
+ } |
+ } |
+ |
+ set res [rbu bp_progress] |
+ if {[set res] != [list 10000 10000]} { |
+ rbu close |
+ error "5. reslist is incorrect (expect=10000 10000 got=[set res])" |
+ } |
+ |
+ rbu close |
+ }] {SQLITE_DONE}] |
+} |
+ |
+foreach {bReopen} { 0 1 } { |
+ reset_db |
+ do_test 2.$bReopen.1.0 { |
+ execsql { |
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); |
+ } |
+ create_db_file rbu.db { |
+ CREATE TABLE data_t1(a, b, c, rbu_control); |
+ INSERT INTO data_t1 VALUES(4, 4, 4, 0); |
+ INSERT INTO data_t1 VALUES(5, 5, 5, 0); |
+ |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data_t1', 2); |
+ } |
+ } {} |
+ do_sp_test 2.$bReopen.1.1 $bReopen test.db rbu.db {5000 10000} |
+ |
+ reset_db |
+ do_test 2.$bReopen.2.0 { |
+ execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) } |
+ create_rbu1 rbu.db |
+ } {rbu.db} |
+ do_sp_test 2.$bReopen.2.1 $bReopen test.db rbu.db {3333 6666 10000} |
+ |
+ reset_db |
+ do_test 2.$bReopen.3.0 { |
+ execsql { |
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); |
+ CREATE INDEX i1 ON t1(b); |
+ INSERT INTO t1 VALUES(1, 1, 1); |
+ INSERT INTO t1 VALUES(2, 2, 2); |
+ INSERT INTO t1 VALUES(3, 3, 3); |
+ } |
+ create_db_file rbu.db { |
+ CREATE TABLE data_t1(a, b, c, rbu_control); |
+ INSERT INTO data_t1 VALUES(4, 4, 4, 0); |
+ INSERT INTO data_t1 VALUES(2, NULL, NULL, 1); |
+ INSERT INTO data_t1 VALUES(5, NULL, NULL, 1); |
+ |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data_t1', 3); |
+ } |
+ } {} |
+ do_sp_test 2.$bReopen.3.1 $bReopen test.db rbu.db {1666 3333 6000 8000 10000} |
+ |
+ reset_db |
+ do_test 2.$bReopen.4.0 { |
+ execsql { |
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); |
+ CREATE INDEX i1 ON t1(b); |
+ INSERT INTO t1 VALUES(1, 1, 1); |
+ INSERT INTO t1 VALUES(2, 2, 2); |
+ INSERT INTO t1 VALUES(3, 3, 3); |
+ } |
+ create_db_file rbu.db { |
+ CREATE TABLE data_t1(a, b, c, rbu_control); |
+ INSERT INTO data_t1 VALUES(2, 4, 4, '.xx'); |
+ |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data_t1', 1); |
+ } |
+ } {} |
+ do_sp_test 2.$bReopen.4.1 $bReopen test.db rbu.db {3333 6666 10000} |
+ |
+ reset_db |
+ do_test 2.$bReopen.5.0 { |
+ execsql { |
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); |
+ CREATE INDEX i1 ON t1(b); |
+ INSERT INTO t1 VALUES(1, 1, 1); |
+ INSERT INTO t1 VALUES(2, 2, 2); |
+ INSERT INTO t1 VALUES(3, 3, 3); |
+ } |
+ create_db_file rbu.db { |
+ CREATE TABLE data_t1(a, b, c, rbu_control); |
+ INSERT INTO data_t1 VALUES(4, NULL, 4, '.xx'); |
+ |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data_t1', 1); |
+ } |
+ } {} |
+ do_sp_test 2.$bReopen.5.1 $bReopen test.db rbu.db {10000} |
+ |
+ reset_db |
+ do_test 2.$bReopen.6.0 { |
+ execsql { |
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); |
+ CREATE INDEX i1 ON t1(b); |
+ INSERT INTO t1 VALUES(1, 1, 1); |
+ INSERT INTO t1 VALUES(2, 2, 2); |
+ INSERT INTO t1 VALUES(3, 3, 3); |
+ } |
+ create_db_file rbu.db { |
+ CREATE TABLE data_t1(a, b, c, rbu_control); |
+ INSERT INTO data_t1 VALUES(4, 4, 4, 0); |
+ INSERT INTO data_t1 VALUES(2, NULL, NULL, 1); |
+ INSERT INTO data_t1 VALUES(5, NULL, NULL, 1); |
+ } |
+ } {} |
+ do_sp_test 2.$bReopen.6.1 $bReopen test.db rbu.db {-1 -1 -1 -1 -1 10000} |
+} |
+ |
+#------------------------------------------------------------------------- |
+# The following tests verify that the API works when resuming an update |
+# during the incremental checkpoint stage. |
+# |
+proc do_phase2_test {tn bReopen target rbu nStep} { |
+ uplevel [list do_test $tn [subst -nocommands { |
+ |
+ # Build the OAL/WAL file: |
+ sqlite3rbu rbu $target $rbu |
+ while {[lindex [rbu bp_progress] 0]<10000} { |
+ set rc [rbu step] |
+ if {"SQLITE_OK" != [set rc]} { rbu close } |
+ } |
+ |
+ # Clean up the temp tables and move the *-oal file to *-wal. |
+ rbu step |
+ rbu step |
+ |
+ for {set i 0} {[set i] < $nStep} {incr i} { |
+ if {$bReopen} { |
+ rbu close |
+ sqlite3rbu rbu $target $rbu |
+ } |
+ rbu step |
+ set res [rbu bp_progress] |
+ set expect [expr (1 + [set i]) * 10000 / $nStep] |
+ if {[lindex [set res] 1] != [set expect]} { |
+ error "Have [set res], expected 10000 [set expect]" |
+ } |
+ } |
+ |
+ set rc [rbu step] |
+ if {[set rc] != "SQLITE_DONE"} { |
+ error "Have [set rc], expected SQLITE_DONE" |
+ } |
+ |
+ rbu close |
+ }] {SQLITE_DONE}] |
+} |
+ |
+foreach bReopen {0 1} { |
+ do_test 3.$bReopen.1.0 { |
+ reset_db |
+ execsql { |
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b); |
+ CREATE TABLE t2(a INTEGER PRIMARY KEY, b); |
+ CREATE TABLE t3(a INTEGER PRIMARY KEY, b); |
+ CREATE TABLE t4(a INTEGER PRIMARY KEY, b); |
+ } |
+ create_db_file rbu.db { |
+ CREATE TABLE data_t1(a, b, rbu_control); |
+ CREATE TABLE data_t2(a, b, rbu_control); |
+ CREATE TABLE data_t3(a, b, rbu_control); |
+ CREATE TABLE data_t4(a, b, rbu_control); |
+ INSERT INTO data_t1 VALUES(1, 2, 0); |
+ INSERT INTO data_t2 VALUES(1, 2, 0); |
+ INSERT INTO data_t3 VALUES(1, 2, 0); |
+ INSERT INTO data_t4 VALUES(1, 2, 0); |
+ |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data_t1', 1); |
+ INSERT INTO rbu_count VALUES('data_t2', 1); |
+ INSERT INTO rbu_count VALUES('data_t3', 1); |
+ INSERT INTO rbu_count VALUES('data_t4', 1); |
+ } |
+ } {} |
+ do_phase2_test 3.$bReopen.1.1 $bReopen test.db rbu.db 5 |
+} |
+ |
+ |
+foreach {bReopen} { 0 1 } { |
+ foreach {tn tbl} { |
+ ipk { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) } |
+ wr { CREATE TABLE t1(a INT PRIMARY KEY, b, c) WITHOUT ROWID } |
+ pk { CREATE TABLE t1(a INT PRIMARY KEY, b, c) } |
+ } { |
+ |
+ foreach {tn2 rbusql r1 r3} { |
+ 1 { |
+ CREATE TABLE data0_t1(a, b, c, rbu_control); |
+ INSERT INTO data0_t1 VALUES(15, 15, 15, 0); |
+ INSERT INTO data0_t1 VALUES(20, 20, 20, 0); |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data0_t1', 2); |
+ } |
+ {2500 5000 7500 10000} |
+ {1666 3333 5000 6666 8333 10000} |
+ |
+ 2 { |
+ CREATE TABLE data0_t1(a, b, c, rbu_control); |
+ INSERT INTO data0_t1 VALUES(10, 10, 10, 2); |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data0_t1', 1); |
+ } |
+ {3333 6666 10000} |
+ {2000 4000 6000 8000 10000} |
+ |
+ 3 { |
+ CREATE TABLE data0_t1(a, b, c, rbu_control); |
+ INSERT INTO data0_t1 VALUES(7, 7, 7, 2); |
+ INSERT INTO data0_t1 VALUES(10, 10, 10, 2); |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data0_t1', 2); |
+ } |
+ {2500 4000 6000 8000 10000} |
+ {1666 2500 3750 5000 6250 7500 8750 10000} |
+ |
+ } { |
+ |
+ reset_db ; execsql $tbl |
+ do_test 4.$tn.$bReopen.$tn2.0 { |
+ execsql { |
+ CREATE INDEX t1c ON t1(c); |
+ INSERT INTO t1 VALUES(1, 1, 1); |
+ INSERT INTO t1 VALUES(5, 5, 5); |
+ INSERT INTO t1 VALUES(10, 10, 10); |
+ } |
+ create_db_file rbu.db $rbusql |
+ } {} |
+ |
+ set R(ipk) $r1 |
+ set R(wr) $r1 |
+ set R(pk) $r3 |
+ do_sp_test 4.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn) |
+ } |
+ } |
+} |
+ |
+foreach {bReopen} { 0 1 } { |
+ foreach {tn tbl} { |
+ nopk { |
+ CREATE TABLE t1(a, b, c); |
+ CREATE INDEX t1c ON t1(c); |
+ } |
+ vtab { |
+ CREATE VIRTUAL TABLE t1 USING fts5(a, b, c); |
+ } |
+ } { |
+ |
+ if {$tn=="vtab"} { ifcapable !fts5 break } |
+ |
+ foreach {tn2 rbusql r1 r2} { |
+ 1 { |
+ CREATE TABLE data0_t1(a, b, c, rbu_rowid, rbu_control); |
+ INSERT INTO data0_t1 VALUES(15, 15, 15, 4, 0); |
+ INSERT INTO data0_t1 VALUES(20, 20, 20, 5, 0); |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data0_t1', 2); |
+ } |
+ {2500 5000 7500 10000} |
+ {5000 10000} |
+ |
+ 2 { |
+ CREATE TABLE data0_t1(rbu_rowid, a, b, c, rbu_control); |
+ INSERT INTO data0_t1 VALUES(0, 7, 7, 7, 2); |
+ INSERT INTO data0_t1 VALUES(2, 10, 10, 10, 2); |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data0_t1', 2); |
+ } |
+ {2500 4000 6000 8000 10000} |
+ {5000 10000} |
+ |
+ 3 { |
+ CREATE TABLE data0_t1(rbu_rowid, a, b, c, rbu_control); |
+ INSERT INTO data0_t1 VALUES(1, NULL, NULL, NULL, 1); |
+ INSERT INTO data0_t1 VALUES(2, NULL, NULL, 7, '..x'); |
+ CREATE TABLE rbu_count(tbl, cnt); |
+ INSERT INTO rbu_count VALUES('data0_t1', 2); |
+ } |
+ {2500 4000 6000 8000 10000} |
+ {5000 10000} |
+ } { |
+ |
+ reset_db ; execsql $tbl |
+ do_test 5.$tn.$bReopen.$tn2.0 { |
+ execsql { |
+ INSERT INTO t1 VALUES(1, 1, 1); |
+ INSERT INTO t1 VALUES(5, 5, 5); |
+ INSERT INTO t1 VALUES(10, 10, 10); |
+ } |
+ create_db_file rbu.db $rbusql |
+ } {} |
+ |
+ set R(nopk) $r1 |
+ set R(vtab) $r2 |
+ do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn) |
+ } |
+ } |
+} |
+ |
+ |
+finish_test |
+ |