Return to rtreeA.test CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / ext / rtree |
1.1 ! misho 1: # 2010 September 22 ! 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 contains tests for the r-tree module. Specifically, it tests ! 12: # that corrupt or inconsistent databases do not cause crashes in the r-tree ! 13: # module. ! 14: # ! 15: ! 16: if {![info exists testdir]} { ! 17: set testdir [file join [file dirname [info script]] .. .. test] ! 18: } ! 19: source $testdir/tester.tcl ! 20: ifcapable !rtree { finish_test ; return } ! 21: ! 22: proc create_t1 {} { ! 23: db close ! 24: forcedelete test.db ! 25: sqlite3 db test.db ! 26: execsql { ! 27: PRAGMA page_size = 1024; ! 28: CREATE VIRTUAL TABLE t1 USING rtree(id, x1, x2, y1, y2); ! 29: } ! 30: } ! 31: proc populate_t1 {} { ! 32: execsql BEGIN ! 33: for {set i 0} {$i < 500} {incr i} { ! 34: set x2 [expr $i+5] ! 35: set y2 [expr $i+5] ! 36: execsql { INSERT INTO t1 VALUES($i, $i, $x2, $i, $y2) } ! 37: } ! 38: execsql COMMIT ! 39: } ! 40: ! 41: proc truncate_node {nodeno nTrunc} { ! 42: set blob [db one {SELECT data FROM t1_node WHERE nodeno=$nodeno}] ! 43: if {$nTrunc<0} {set nTrunc "end-$nTrunc"} ! 44: set blob [string range $blob 0 $nTrunc] ! 45: db eval { UPDATE t1_node SET data = $blob WHERE nodeno=$nodeno } ! 46: } ! 47: ! 48: proc set_tree_depth {tbl {newvalue ""}} { ! 49: set blob [db one "SELECT data FROM ${tbl}_node WHERE nodeno=1"] ! 50: ! 51: if {$newvalue == ""} { ! 52: binary scan $blob Su oldvalue ! 53: return $oldvalue ! 54: } ! 55: ! 56: set blob [binary format Sua* $newvalue [string range $blob 2 end]] ! 57: db eval "UPDATE ${tbl}_node SET data = \$blob WHERE nodeno=1" ! 58: return [set_tree_depth $tbl] ! 59: } ! 60: ! 61: proc set_entry_count {tbl nodeno {newvalue ""}} { ! 62: set blob [db one "SELECT data FROM ${tbl}_node WHERE nodeno=$nodeno"] ! 63: ! 64: if {$newvalue == ""} { ! 65: binary scan [string range $blob 2 end] Su oldvalue ! 66: return $oldvalue ! 67: } ! 68: ! 69: set blob [binary format a*Sua* \ ! 70: [string range $blob 0 1] $newvalue [string range $blob 4 end] ! 71: ] ! 72: db eval "UPDATE ${tbl}_node SET data = \$blob WHERE nodeno=$nodeno" ! 73: return [set_entry_count $tbl $nodeno] ! 74: } ! 75: ! 76: ! 77: proc do_corruption_tests {prefix args} { ! 78: set testarray [lindex $args end] ! 79: set errormsg {database disk image is malformed} ! 80: ! 81: foreach {z value} [lrange $args 0 end-1] { ! 82: set n [string length $z] ! 83: if {$n>=2 && [string equal -length $n $z "-error"]} { ! 84: set errormsg $value ! 85: } ! 86: } ! 87: ! 88: foreach {tn sql} $testarray { ! 89: do_catchsql_test $prefix.$tn $sql [list 1 $errormsg] ! 90: } ! 91: } ! 92: ! 93: #------------------------------------------------------------------------- ! 94: # Test the libraries response if the %_node table is completely empty ! 95: # (i.e. the root node is missing), or has been removed from the database ! 96: # entirely. ! 97: # ! 98: create_t1 ! 99: populate_t1 ! 100: do_execsql_test rtreeA-1.0 { ! 101: DELETE FROM t1_node; ! 102: } {} ! 103: ! 104: do_corruption_tests rtreeA-1.1 { ! 105: 1 "SELECT * FROM t1" ! 106: 2 "SELECT * FROM t1 WHERE rowid=5" ! 107: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 108: 4 "SELECT * FROM t1 WHERE x1<10 AND x2>12" ! 109: } ! 110: ! 111: do_execsql_test rtreeA-1.2.0 { DROP TABLE t1_node } {} ! 112: do_corruption_tests rtreeA-1.2 -error "SQL logic error or missing database" { ! 113: 1 "SELECT * FROM t1" ! 114: 2 "SELECT * FROM t1 WHERE rowid=5" ! 115: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 116: 4 "SELECT * FROM t1 WHERE x1<10 AND x2>12" ! 117: } ! 118: ! 119: #------------------------------------------------------------------------- ! 120: # Test the libraries response if some of the entries in the %_node table ! 121: # are the wrong size. ! 122: # ! 123: create_t1 ! 124: populate_t1 ! 125: do_test rtreeA-2.1.0 { ! 126: set nodes [db eval {select nodeno FROM t1_node}] ! 127: foreach {a b c} $nodes { truncate_node $c 200 } ! 128: } {} ! 129: do_corruption_tests rtreeA-2.1 { ! 130: 1 "SELECT * FROM t1" ! 131: 2 "SELECT * FROM t1 WHERE rowid=5" ! 132: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 133: 4 "SELECT * FROM t1 WHERE x1<10 AND x2>12" ! 134: } ! 135: ! 136: create_t1 ! 137: populate_t1 ! 138: do_test rtreeA-2.2.0 { truncate_node 1 200 } {} ! 139: do_corruption_tests rtreeA-2.2 { ! 140: 1 "SELECT * FROM t1" ! 141: 2 "SELECT * FROM t1 WHERE rowid=5" ! 142: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 143: 4 "SELECT * FROM t1 WHERE x1<10 AND x2>12" ! 144: } ! 145: ! 146: #------------------------------------------------------------------------- ! 147: # Set the "depth" of the tree stored on the root node incorrectly. Test ! 148: # that this does not cause any problems. ! 149: # ! 150: create_t1 ! 151: populate_t1 ! 152: do_test rtreeA-3.1.0.1 { set_tree_depth t1 } {1} ! 153: do_test rtreeA-3.1.0.2 { set_tree_depth t1 3 } {3} ! 154: do_corruption_tests rtreeA-3.1 { ! 155: 1 "SELECT * FROM t1" ! 156: 2 "SELECT * FROM t1 WHERE rowid=5" ! 157: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 158: } ! 159: ! 160: do_test rtreeA-3.2.0 { set_tree_depth t1 1000 } {1000} ! 161: do_corruption_tests rtreeA-3.2 { ! 162: 1 "SELECT * FROM t1" ! 163: 2 "SELECT * FROM t1 WHERE rowid=5" ! 164: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 165: } ! 166: ! 167: create_t1 ! 168: populate_t1 ! 169: do_test rtreeA-3.3.0 { ! 170: execsql { DELETE FROM t1 WHERE rowid = 0 } ! 171: set_tree_depth t1 65535 ! 172: } {65535} ! 173: do_corruption_tests rtreeA-3.3 { ! 174: 1 "SELECT * FROM t1" ! 175: 2 "SELECT * FROM t1 WHERE rowid=5" ! 176: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 177: } ! 178: ! 179: #------------------------------------------------------------------------- ! 180: # Set the "number of entries" field on some nodes incorrectly. ! 181: # ! 182: create_t1 ! 183: populate_t1 ! 184: do_test rtreeA-4.1.0 { ! 185: set_entry_count t1 1 4000 ! 186: } {4000} ! 187: do_corruption_tests rtreeA-4.1 { ! 188: 1 "SELECT * FROM t1" ! 189: 2 "SELECT * FROM t1 WHERE rowid=5" ! 190: 3 "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)" ! 191: 4 "SELECT * FROM t1 WHERE x1<10 AND x2>12" ! 192: } ! 193: ! 194: #------------------------------------------------------------------------- ! 195: # Remove entries from the %_parent table and check that this does not ! 196: # cause a crash. ! 197: # ! 198: create_t1 ! 199: populate_t1 ! 200: do_execsql_test rtreeA-5.1.0 { DELETE FROM t1_parent } {} ! 201: do_corruption_tests rtreeA-5.1 { ! 202: 1 "DELETE FROM t1 WHERE rowid = 5" ! 203: 2 "DELETE FROM t1" ! 204: } ! 205: ! 206: #------------------------------------------------------------------------- ! 207: # Add some bad entries to the %_parent table. ! 208: # ! 209: create_t1 ! 210: populate_t1 ! 211: do_execsql_test rtreeA-6.1.0 { ! 212: UPDATE t1_parent set parentnode = parentnode+1 ! 213: } {} ! 214: do_corruption_tests rtreeA-6.1 { ! 215: 1 "DELETE FROM t1 WHERE rowid = 5" ! 216: 2 "UPDATE t1 SET x1=x1+1, x2=x2+1" ! 217: } ! 218: ! 219: ! 220: finish_test