xref: /sqlite-3.40.0/ext/rtree/rtree4.test (revision b13dee99)
1# 2008 May 23
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#
12# Randomized test cases for the rtree extension.
13#
14# $Id: rtree4.test,v 1.3 2008/06/23 15:55:52 danielk1977 Exp $
15#
16
17if {![info exists testdir]} {
18  set testdir [file join [file dirname $argv0] .. .. test]
19}
20source $testdir/tester.tcl
21
22ifcapable !rtree {
23  finish_test
24  return
25}
26
27set ::NROW 2500
28if {[info exists ISQUICK] && $ISQUICK} {
29  set ::NROW 250
30}
31
32# Return a floating point number between -X and X.
33#
34proc rand {X} {
35  return [expr {int((rand()-0.5)*1024.0*$X)/512.0}]
36}
37
38# Return a positive floating point number less than or equal to X
39#
40proc randincr {X} {
41  while 1 {
42    set r [expr {int(rand()*$X*32.0)/32.0}]
43    if {$r>0.0} {return $r}
44  }
45}
46
47# Scramble the $inlist into a random order.
48#
49proc scramble {inlist} {
50  set y {}
51  foreach x $inlist {
52    lappend y [list [expr {rand()}] $x]
53  }
54  set y [lsort $y]
55  set outlist {}
56  foreach x $y {
57    lappend outlist [lindex $x 1]
58  }
59  return $outlist
60}
61
62# Always use the same random seed so that the sequence of tests
63# is repeatable.
64#
65expr {srand(1234)}
66
67# Run these tests for all number of dimensions between 1 and 5.
68#
69for {set nDim 1} {$nDim<=5} {incr nDim} {
70
71  # Construct an rtree virtual table and an ordinary btree table
72  # to mirror it.  The ordinary table should be much slower (since
73  # it has to do a full table scan) but should give the exact same
74  # answers.
75  #
76  do_test rtree4-$nDim.1 {
77    set clist {}
78    set cklist {}
79    for {set i 0} {$i<$nDim} {incr i} {
80      lappend clist mn$i mx$i
81      lappend cklist "mn$i<mx$i"
82    }
83    db eval "DROP TABLE IF EXISTS rx"
84    db eval "DROP TABLE IF EXISTS bx"
85    db eval "CREATE VIRTUAL TABLE rx USING rtree(id, [join $clist ,])"
86    db eval "CREATE TABLE bx(id INTEGER PRIMARY KEY,\
87                [join $clist ,], CHECK( [join $cklist { AND }] ))"
88  } {}
89
90  # Do many insertions of small objects.  Do both overlapping and
91  # contained-within queries after each insert to verify that all
92  # is well.
93  #
94  unset -nocomplain where
95  for {set i 1} {$i<$::NROW} {incr i} {
96    # Do a random insert
97    #
98    do_test rtree-$nDim.2.$i.1 {
99      set vlist {}
100      for {set j 0} {$j<$nDim} {incr j} {
101        set mn [rand 10000]
102        set mx [expr {$mn+[randincr 50]}]
103        lappend vlist $mn $mx
104      }
105      db eval "INSERT INTO rx VALUES(NULL, [join $vlist ,])"
106      db eval "INSERT INTO bx VALUES(NULL, [join $vlist ,])"
107    } {}
108
109    # Do a contained-in query on all dimensions
110    #
111    set where {}
112    for {set j 0} {$j<$nDim} {incr j} {
113      set mn [rand 10000]
114      set mx [expr {$mn+[randincr 500]}]
115      lappend where mn$j>=$mn mx$j<=$mx
116    }
117    set where "WHERE [join $where { AND }]"
118    do_test rtree-$nDim.2.$i.2 {
119      list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
120    } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
121
122    # Do an overlaps query on all dimensions
123    #
124    set where {}
125    for {set j 0} {$j<$nDim} {incr j} {
126      set mn [rand 10000]
127      set mx [expr {$mn+[randincr 500]}]
128      lappend where mx$j>=$mn mn$j<=$mx
129    }
130    set where "WHERE [join $where { AND }]"
131    do_test rtree-$nDim.2.$i.3 {
132      list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
133    } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
134
135    # Do a contained-in query with surplus contraints at the beginning.
136    # This should force a full-table scan on the rtree.
137    #
138    set where {}
139    for {set j 0} {$j<$nDim} {incr j} {
140      lappend where mn$j>-10000 mx$j<10000
141    }
142    for {set j 0} {$j<$nDim} {incr j} {
143      set mn [rand 10000]
144      set mx [expr {$mn+[randincr 500]}]
145      lappend where mn$j>=$mn mx$j<=$mx
146    }
147    set where "WHERE [join $where { AND }]"
148    do_test rtree-$nDim.2.$i.3 {
149      list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
150    } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
151
152    # Do an overlaps query with surplus contraints at the beginning.
153    # This should force a full-table scan on the rtree.
154    #
155    set where {}
156    for {set j 0} {$j<$nDim} {incr j} {
157      lappend where mn$j>=-10000 mx$j<=10000
158    }
159    for {set j 0} {$j<$nDim} {incr j} {
160      set mn [rand 10000]
161      set mx [expr {$mn+[randincr 500]}]
162      lappend where mx$j>$mn mn$j<$mx
163    }
164    set where "WHERE [join $where { AND }]"
165    do_test rtree-$nDim.2.$i.4 {
166      list $where [db eval "SELECT id FROM rx $where ORDER BY id"]
167    } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]]
168
169    # Do a contained-in query with surplus contraints at the end
170    #
171    set where {}
172    for {set j 0} {$j<$nDim} {incr j} {
173      set mn [rand 10000]
174      set mx [expr {$mn+[randincr 500]}]
175      lappend where mn$j>=$mn mx$j<$mx
176    }
177    for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} {
178      lappend where mn$j>=-10000 mx$j<10000
179    }
180    set where "WHERE [join $where { AND }]"
181    do_test rtree-$nDim.2.$i.5 {
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"]]
184
185    # Do an overlaps query with surplus contraints at the end
186    #
187    set where {}
188    for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} {
189      set mn [rand 10000]
190      set mx [expr {$mn+[randincr 500]}]
191      lappend where mx$j>$mn mn$j<=$mx
192    }
193    for {set j 0} {$j<$nDim} {incr j} {
194      lappend where mx$j>-10000 mn$j<=10000
195    }
196    set where "WHERE [join $where { AND }]"
197    do_test rtree-$nDim.2.$i.6 {
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"]]
200
201    # Do a contained-in query with surplus contraints where the
202    # constraints appear in a random order.
203    #
204    set where {}
205    for {set j 0} {$j<$nDim} {incr j} {
206      set mn1 [rand 10000]
207      set mn2 [expr {$mn1+[randincr 100]}]
208      set mx1 [expr {$mn2+[randincr 400]}]
209      set mx2 [expr {$mx1+[randincr 100]}]
210      lappend where mn$j>=$mn1 mn$j>$mn2 mx$j<$mx1 mx$j<=$mx2
211    }
212    set where "WHERE [join [scramble $where] { AND }]"
213    do_test rtree-$nDim.2.$i.7 {
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"]]
216
217    # Do an overlaps query with surplus contraints where the
218    # constraints appear in a random order.
219    #
220    set where {}
221    for {set j 0} {$j<$nDim} {incr j} {
222      set mn1 [rand 10000]
223      set mn2 [expr {$mn1+[randincr 100]}]
224      set mx1 [expr {$mn2+[randincr 400]}]
225      set mx2 [expr {$mx1+[randincr 100]}]
226      lappend where mx$j>=$mn1 mx$j>$mn2 mn$j<$mx1 mn$j<=$mx2
227    }
228    set where "WHERE [join [scramble $where] { AND }]"
229    do_test rtree-$nDim.2.$i.8 {
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"]]
232  }
233
234}
235
236finish_test
237