OLD | NEW |
(Empty) | |
| 1 # 2012 January 11 {} |
| 2 # |
| 3 # The author disclaims copyright to this source code. In place of |
| 4 # a legal notice, here is a blessing: |
| 5 # |
| 6 # May you do good and not evil. |
| 7 # May you find forgiveness for yourself and forgive others. |
| 8 # May you share freely, never taking more than you give. |
| 9 # |
| 10 #*********************************************************************** |
| 11 # This file implements regression tests for SQLite library. |
| 12 # |
| 13 # This file implements tests for the recover module, which can read |
| 14 # through corrupt rows and pages. |
| 15 # |
| 16 # $Id$ |
| 17 |
| 18 # TODO(shess): These all test that the module correctly reads good |
| 19 # data. It would be good to implement tests of corrupt data. |
| 20 |
| 21 set testdir [file dirname $argv0] |
| 22 source $testdir/tester.tcl |
| 23 |
| 24 db eval { |
| 25 DROP TABLE IF EXISTS altered; |
| 26 CREATE TABLE altered ( |
| 27 c TEXT |
| 28 ); |
| 29 INSERT INTO altered VALUES ('a'); |
| 30 INSERT INTO altered VALUES ('b'); |
| 31 INSERT INTO altered VALUES ('c'); |
| 32 ALTER TABLE altered ADD COLUMN i INTEGER NOT NULL DEFAULT 10; |
| 33 INSERT INTO altered VALUES ('d', 5); |
| 34 } |
| 35 |
| 36 # SQLite will fill the earlier rows with the default. |
| 37 do_test recover-alter-1.0 { |
| 38 execsql {SELECT c, i FROM altered ORDER BY rowid} |
| 39 } {a 10 b 10 c 10 d 5} |
| 40 |
| 41 # recover sees NULL for those rows. |
| 42 do_test recover-alter-1.1 { |
| 43 db eval { |
| 44 DROP TABLE IF EXISTS temp.altered_recover; |
| 45 CREATE VIRTUAL TABLE temp.altered_recover USING recover( |
| 46 altered, |
| 47 c TEXT, |
| 48 i INTEGER |
| 49 ); |
| 50 } |
| 51 execsql {SELECT c, i FROM altered_recover ORDER BY rowid} |
| 52 } {a {} b {} c {} d 5} |
| 53 |
| 54 # Can skip those NULL columns like if they contained a real NULL. |
| 55 do_test recover-alter-1.2 { |
| 56 db eval { |
| 57 DROP TABLE IF EXISTS temp.altered_recover; |
| 58 CREATE VIRTUAL TABLE temp.altered_recover USING recover( |
| 59 altered, |
| 60 c TEXT, |
| 61 i INTEGER NOT NULL |
| 62 ); |
| 63 } |
| 64 execsql {SELECT c, i FROM altered_recover ORDER BY rowid} |
| 65 } {d 5} |
| 66 |
| 67 if {0} { |
| 68 # It would be neat if this could work. I tried putting "DEFAULT ..." |
| 69 # in the schema exposed by the recover table, but it doesn't do the |
| 70 # trick. |
| 71 do_test recover-alter-1.2 { |
| 72 db eval { |
| 73 DROP TABLE IF EXISTS temp.altered_recover; |
| 74 CREATE VIRTUAL TABLE temp.altered_recover USING recover( |
| 75 altered, |
| 76 c TEXT, |
| 77 i INTEGER NOT NULL DEFAULT 10 |
| 78 ); |
| 79 } |
| 80 execsql {SELECT c, i FROM altered_recover ORDER BY rowid} |
| 81 } {a 10 b 10 c 10 d 5} |
| 82 } |
| 83 |
| 84 # Helper function to generate an arbitrarily-sized table. |
| 85 proc generate {table base count} { |
| 86 db eval "DROP TABLE IF EXISTS $table" |
| 87 db transaction immediate { |
| 88 db eval "CREATE TABLE $table (t TEXT,n INT)" |
| 89 for {set i 0} {$i<$count} {incr i} { |
| 90 set t [concat $base $i] |
| 91 db eval [concat {INSERT INTO} $table {VALUES ($t, $i)}] |
| 92 } |
| 93 } |
| 94 } |
| 95 |
| 96 # Leaf-only database parses. |
| 97 do_test recover-leaf-1.0 { |
| 98 db close |
| 99 sqlite3 db test.db |
| 100 generate "leaf" "Leaf-node-generating line " 10 |
| 101 |
| 102 db eval { |
| 103 DROP TABLE IF EXISTS temp.leaf_recover; |
| 104 CREATE VIRTUAL TABLE temp.leaf_recover USING recover( |
| 105 leaf, |
| 106 t TEXT, |
| 107 n INTEGER |
| 108 ); |
| 109 } |
| 110 execsql {SELECT t, n FROM leaf_recover ORDER BY rowid} |
| 111 } {{Leaf-node-generating line 0} 0 {Leaf-node-generating line 1} 1 {Leaf-node-ge
nerating line 2} 2 {Leaf-node-generating line 3} 3 {Leaf-node-generating line 4}
4 {Leaf-node-generating line 5} 5 {Leaf-node-generating line 6} 6 {Leaf-node-ge
nerating line 7} 7 {Leaf-node-generating line 8} 8 {Leaf-node-generating line 9}
9} |
| 112 |
| 113 # Single level of interior node. |
| 114 do_test recover-interior-1.0 { |
| 115 db close |
| 116 sqlite3 db test.db |
| 117 generate "interior" "Interior-node-generating line " 100 |
| 118 |
| 119 db eval { |
| 120 DROP TABLE IF EXISTS temp.interior_recover; |
| 121 CREATE VIRTUAL TABLE temp.interior_recover USING recover( |
| 122 interior, |
| 123 t TEXT, |
| 124 n INTEGER |
| 125 ); |
| 126 } |
| 127 execsql {SELECT t, n FROM interior_recover WHERE (rowid%10)=0 ORDER BY rowid} |
| 128 } {{Interior-node-generating line 9} 9 {Interior-node-generating line 19} 19 {In
terior-node-generating line 29} 29 {Interior-node-generating line 39} 39 {Interi
or-node-generating line 49} 49 {Interior-node-generating line 59} 59 {Interior-n
ode-generating line 69} 69 {Interior-node-generating line 79} 79 {Interior-node-
generating line 89} 89 {Interior-node-generating line 99} 99} |
| 129 |
| 130 # Multiple levels of interior node. |
| 131 do_test recover-interior-2.0 { |
| 132 db close |
| 133 sqlite3 db test.db |
| 134 generate "interior2" "Interior-node-generating line " 5000 |
| 135 |
| 136 db eval { |
| 137 DROP TABLE IF EXISTS temp.interior2_recover; |
| 138 CREATE VIRTUAL TABLE temp.interior2_recover USING recover( |
| 139 interior2, |
| 140 t TEXT, |
| 141 n INTEGER |
| 142 ); |
| 143 } |
| 144 execsql {SELECT t, n FROM interior2_recover WHERE (rowid%500)=0 ORDER BY rowid
} |
| 145 } {{Interior-node-generating line 499} 499 {Interior-node-generating line 999} 9
99 {Interior-node-generating line 1499} 1499 {Interior-node-generating line 1999
} 1999 {Interior-node-generating line 2499} 2499 {Interior-node-generating line
2999} 2999 {Interior-node-generating line 3499} 3499 {Interior-node-generating l
ine 3999} 3999 {Interior-node-generating line 4499} 4499 {Interior-node-generati
ng line 4999} 4999} |
| 146 |
| 147 finish_test |
OLD | NEW |