3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
12 # Randomized test cases for the rtree extension.
15 if {![info exists testdir]} {
16 set testdir [file join [file dirname [info script]] .. .. test]
18 source [file join [file dirname [info script]] rtree_util.tcl]
19 source $testdir/tester.tcl
27 if {[info exists G(isquick)] && $G(isquick)} {
31 ifcapable !rtree_int_only {
32 # Return a floating point number between -X and X.
35 return [expr {int((rand()-0.5)*1024.0*$X)/512.0}]
38 # Return a positive floating point number less than or equal to X
42 set r [expr {int(rand()*$X*32.0)/32.0}]
43 if {$r>0.0} {return $r}
47 # For rtree_int_only, return an number between -X and X.
50 return [expr {int((rand()-0.5)*2*$X)}]
53 # Return a positive integer less than or equal to X
57 set r [expr {int(rand()*$X)+1}]
63 # Scramble the $inlist into a random order.
65 proc scramble {inlist} {
68 lappend y [list [expr {rand()}] $x]
73 lappend outlist [lindex $x 1]
78 # Always use the same random seed so that the sequence of tests
83 # Run these tests for all number of dimensions between 1 and 5.
85 for {set nDim 1} {$nDim<=5} {incr nDim} {
87 # Construct an rtree virtual table and an ordinary btree table
88 # to mirror it. The ordinary table should be much slower (since
89 # it has to do a full table scan) but should give the exact same
92 do_test rtree4-$nDim.1 {
95 for {set i 0} {$i<$nDim} {incr i} {
96 lappend clist mn$i mx$i
97 lappend cklist "mn$i<mx$i"
99 db eval "DROP TABLE IF EXISTS rx"
100 db eval "DROP TABLE IF EXISTS bx"
101 db eval "CREATE VIRTUAL TABLE rx USING rtree(id, [join $clist ,])"
102 db eval "CREATE TABLE bx(id INTEGER PRIMARY KEY,\
103 [join $clist ,], CHECK( [join $cklist { AND }] ))"
106 # Do many insertions of small objects. Do both overlapping and
107 # contained-within queries after each insert to verify that all
110 unset -nocomplain where
111 for {set i 1} {$i<$::NROW} {incr i} {
114 do_test rtree4-$nDim.2.$i.1 {
116 for {set j 0} {$j<$nDim} {incr j} {
118 set mx [expr {$mn+[randincr 50]}]
119 lappend vlist $mn $mx
121 db eval "INSERT INTO rx VALUES(NULL, [join $vlist ,])"
122 db eval "INSERT INTO bx VALUES(NULL, [join $vlist ,])"
125 # Do a contained-in query on all dimensions
128 for {set j 0} {$j<$nDim} {incr j} {
130 set mx [expr {$mn+[randincr 500]}]
131 lappend where mn$j>=$mn mx$j<=$mx
133 set where "WHERE [join $where { AND }]"
134 do_test rtree4-$nDim.2.$i.2 {
135 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
136 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
138 # Do an overlaps query on all dimensions
141 for {set j 0} {$j<$nDim} {incr j} {
143 set mx [expr {$mn+[randincr 500]}]
144 lappend where mx$j>=$mn mn$j<=$mx
146 set where "WHERE [join $where { AND }]"
147 do_test rtree4-$nDim.2.$i.3 {
148 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
149 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
151 # Do a contained-in query with surplus contraints at the beginning.
152 # This should force a full-table scan on the rtree.
155 for {set j 0} {$j<$nDim} {incr j} {
156 lappend where mn$j>-10000 mx$j<10000
158 for {set j 0} {$j<$nDim} {incr j} {
160 set mx [expr {$mn+[randincr 500]}]
161 lappend where mn$j>=$mn mx$j<=$mx
163 set where "WHERE [join $where { AND }]"
164 do_test rtree4-$nDim.2.$i.3 {
165 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
166 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
168 # Do an overlaps query with surplus contraints at the beginning.
169 # This should force a full-table scan on the rtree.
172 for {set j 0} {$j<$nDim} {incr j} {
173 lappend where mn$j>=-10000 mx$j<=10000
175 for {set j 0} {$j<$nDim} {incr j} {
177 set mx [expr {$mn+[randincr 500]}]
178 lappend where mx$j>$mn mn$j<$mx
180 set where "WHERE [join $where { AND }]"
181 do_test rtree4-$nDim.2.$i.4 {
182 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
183 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
185 # Do a contained-in query with surplus contraints at the end
188 for {set j 0} {$j<$nDim} {incr j} {
190 set mx [expr {$mn+[randincr 500]}]
191 lappend where mn$j>=$mn mx$j<$mx
193 for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} {
194 lappend where mn$j>=-10000 mx$j<10000
196 set where "WHERE [join $where { AND }]"
197 do_test rtree4-$nDim.2.$i.5 {
198 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
199 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
201 # Do an overlaps query with surplus contraints at the end
204 for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} {
206 set mx [expr {$mn+[randincr 500]}]
207 lappend where mx$j>$mn mn$j<=$mx
209 for {set j 0} {$j<$nDim} {incr j} {
210 lappend where mx$j>-10000 mn$j<=10000
212 set where "WHERE [join $where { AND }]"
213 do_test rtree4-$nDim.2.$i.6 {
214 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
215 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
217 # Do a contained-in query with surplus contraints where the
218 # constraints appear in a random order.
221 for {set j 0} {$j<$nDim} {incr j} {
223 set mn2 [expr {$mn1+[randincr 100]}]
224 set mx1 [expr {$mn2+[randincr 400]}]
225 set mx2 [expr {$mx1+[randincr 100]}]
226 lappend where mn$j>=$mn1 mn$j>$mn2 mx$j<$mx1 mx$j<=$mx2
228 set where "WHERE [join [scramble $where] { AND }]"
229 do_test rtree4-$nDim.2.$i.7 {
230 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
231 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
233 # Do an overlaps query with surplus contraints where the
234 # constraints appear in a random order.
237 for {set j 0} {$j<$nDim} {incr j} {
239 set mn2 [expr {$mn1+[randincr 100]}]
240 set mx1 [expr {$mn2+[randincr 400]}]
241 set mx2 [expr {$mx1+[randincr 100]}]
242 lappend where mx$j>=$mn1 mx$j>$mn2 mn$j<$mx1 mn$j<=$mx2
244 set where "WHERE [join [scramble $where] { AND }]"
245 do_test rtree4-$nDim.2.$i.8 {
246 list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
247 } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
250 do_rtree_integrity_test rtree4-$nDim.3 rx