Annotation of embedaddon/sqlite3/ext/rtree/rtreeA.test, revision 1.1.1.1
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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>