14b4f7801Sdrh# 2008 May 23 24b4f7801Sdrh# 34b4f7801Sdrh# The author disclaims copyright to this source code. In place of 44b4f7801Sdrh# a legal notice, here is a blessing: 54b4f7801Sdrh# 64b4f7801Sdrh# May you do good and not evil. 74b4f7801Sdrh# May you find forgiveness for yourself and forgive others. 84b4f7801Sdrh# May you share freely, never taking more than you give. 94b4f7801Sdrh# 104b4f7801Sdrh#*********************************************************************** 114b4f7801Sdrh# 124b4f7801Sdrh# Randomized test cases for the rtree extension. 134b4f7801Sdrh# 144b4f7801Sdrh 15b13dee99Sdanielk1977if {![info exists testdir]} { 16897230ebSdan set testdir [file join [file dirname [info script]] .. .. test] 17b13dee99Sdanielk1977} 181917e92fSdansource [file join [file dirname [info script]] rtree_util.tcl] 194b4f7801Sdrhsource $testdir/tester.tcl 204b4f7801Sdrh 214b4f7801Sdrhifcapable !rtree { 224b4f7801Sdrh finish_test 234b4f7801Sdrh return 244b4f7801Sdrh} 254b4f7801Sdrh 26b13dee99Sdanielk1977set ::NROW 2500 2792e01aafSdanif {[info exists G(isquick)] && $G(isquick)} { 28b13dee99Sdanielk1977 set ::NROW 250 29b13dee99Sdanielk1977} 30b13dee99Sdanielk1977 31f439fbdaSdrhifcapable !rtree_int_only { 324b4f7801Sdrh # Return a floating point number between -X and X. 334b4f7801Sdrh # 344b4f7801Sdrh proc rand {X} { 354b4f7801Sdrh return [expr {int((rand()-0.5)*1024.0*$X)/512.0}] 364b4f7801Sdrh } 374b4f7801Sdrh 384b4f7801Sdrh # Return a positive floating point number less than or equal to X 394b4f7801Sdrh # 404b4f7801Sdrh proc randincr {X} { 414b4f7801Sdrh while 1 { 424b4f7801Sdrh set r [expr {int(rand()*$X*32.0)/32.0}] 434b4f7801Sdrh if {$r>0.0} {return $r} 444b4f7801Sdrh } 454b4f7801Sdrh } 46f439fbdaSdrh} else { 47f439fbdaSdrh # For rtree_int_only, return an number between -X and X. 48f439fbdaSdrh # 49f439fbdaSdrh proc rand {X} { 50f439fbdaSdrh return [expr {int((rand()-0.5)*2*$X)}] 51f439fbdaSdrh } 52f439fbdaSdrh 53f439fbdaSdrh # Return a positive integer less than or equal to X 54f439fbdaSdrh # 55f439fbdaSdrh proc randincr {X} { 56f439fbdaSdrh while 1 { 57f439fbdaSdrh set r [expr {int(rand()*$X)+1}] 58f439fbdaSdrh if {$r>0} {return $r} 59f439fbdaSdrh } 60f439fbdaSdrh } 61f439fbdaSdrh} 624b4f7801Sdrh 634b4f7801Sdrh# Scramble the $inlist into a random order. 644b4f7801Sdrh# 654b4f7801Sdrhproc scramble {inlist} { 664b4f7801Sdrh set y {} 674b4f7801Sdrh foreach x $inlist { 684b4f7801Sdrh lappend y [list [expr {rand()}] $x] 694b4f7801Sdrh } 704b4f7801Sdrh set y [lsort $y] 714b4f7801Sdrh set outlist {} 724b4f7801Sdrh foreach x $y { 734b4f7801Sdrh lappend outlist [lindex $x 1] 744b4f7801Sdrh } 754b4f7801Sdrh return $outlist 764b4f7801Sdrh} 774b4f7801Sdrh 784b4f7801Sdrh# Always use the same random seed so that the sequence of tests 794b4f7801Sdrh# is repeatable. 804b4f7801Sdrh# 814b4f7801Sdrhexpr {srand(1234)} 824b4f7801Sdrh 834b4f7801Sdrh# Run these tests for all number of dimensions between 1 and 5. 844b4f7801Sdrh# 854b4f7801Sdrhfor {set nDim 1} {$nDim<=5} {incr nDim} { 864b4f7801Sdrh 874b4f7801Sdrh # Construct an rtree virtual table and an ordinary btree table 884b4f7801Sdrh # to mirror it. The ordinary table should be much slower (since 894b4f7801Sdrh # it has to do a full table scan) but should give the exact same 904b4f7801Sdrh # answers. 914b4f7801Sdrh # 924b4f7801Sdrh do_test rtree4-$nDim.1 { 934b4f7801Sdrh set clist {} 944b4f7801Sdrh set cklist {} 954b4f7801Sdrh for {set i 0} {$i<$nDim} {incr i} { 964b4f7801Sdrh lappend clist mn$i mx$i 974b4f7801Sdrh lappend cklist "mn$i<mx$i" 984b4f7801Sdrh } 994b4f7801Sdrh db eval "DROP TABLE IF EXISTS rx" 1004b4f7801Sdrh db eval "DROP TABLE IF EXISTS bx" 1014b4f7801Sdrh db eval "CREATE VIRTUAL TABLE rx USING rtree(id, [join $clist ,])" 1024b4f7801Sdrh db eval "CREATE TABLE bx(id INTEGER PRIMARY KEY,\ 1034b4f7801Sdrh [join $clist ,], CHECK( [join $cklist { AND }] ))" 1044b4f7801Sdrh } {} 1054b4f7801Sdrh 1064b4f7801Sdrh # Do many insertions of small objects. Do both overlapping and 1074b4f7801Sdrh # contained-within queries after each insert to verify that all 1084b4f7801Sdrh # is well. 1094b4f7801Sdrh # 1104b4f7801Sdrh unset -nocomplain where 111b13dee99Sdanielk1977 for {set i 1} {$i<$::NROW} {incr i} { 1124b4f7801Sdrh # Do a random insert 1134b4f7801Sdrh # 114897230ebSdan do_test rtree4-$nDim.2.$i.1 { 1154b4f7801Sdrh set vlist {} 1164b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1174b4f7801Sdrh set mn [rand 10000] 1184b4f7801Sdrh set mx [expr {$mn+[randincr 50]}] 1194b4f7801Sdrh lappend vlist $mn $mx 1204b4f7801Sdrh } 1214b4f7801Sdrh db eval "INSERT INTO rx VALUES(NULL, [join $vlist ,])" 1224b4f7801Sdrh db eval "INSERT INTO bx VALUES(NULL, [join $vlist ,])" 1234b4f7801Sdrh } {} 1244b4f7801Sdrh 1254b4f7801Sdrh # Do a contained-in query on all dimensions 1264b4f7801Sdrh # 1274b4f7801Sdrh set where {} 1284b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1294b4f7801Sdrh set mn [rand 10000] 1304b4f7801Sdrh set mx [expr {$mn+[randincr 500]}] 1314b4f7801Sdrh lappend where mn$j>=$mn mx$j<=$mx 1324b4f7801Sdrh } 1334b4f7801Sdrh set where "WHERE [join $where { AND }]" 134897230ebSdan do_test rtree4-$nDim.2.$i.2 { 1354b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 1364b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 1374b4f7801Sdrh 1384b4f7801Sdrh # Do an overlaps query on all dimensions 1394b4f7801Sdrh # 1404b4f7801Sdrh set where {} 1414b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1424b4f7801Sdrh set mn [rand 10000] 1434b4f7801Sdrh set mx [expr {$mn+[randincr 500]}] 1444b4f7801Sdrh lappend where mx$j>=$mn mn$j<=$mx 1454b4f7801Sdrh } 1464b4f7801Sdrh set where "WHERE [join $where { AND }]" 147897230ebSdan do_test rtree4-$nDim.2.$i.3 { 1484b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 1494b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 1504b4f7801Sdrh 1514b4f7801Sdrh # Do a contained-in query with surplus contraints at the beginning. 1524b4f7801Sdrh # This should force a full-table scan on the rtree. 1534b4f7801Sdrh # 1544b4f7801Sdrh set where {} 1554b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1564b4f7801Sdrh lappend where mn$j>-10000 mx$j<10000 1574b4f7801Sdrh } 1584b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1594b4f7801Sdrh set mn [rand 10000] 1604b4f7801Sdrh set mx [expr {$mn+[randincr 500]}] 1614b4f7801Sdrh lappend where mn$j>=$mn mx$j<=$mx 1624b4f7801Sdrh } 1634b4f7801Sdrh set where "WHERE [join $where { AND }]" 164897230ebSdan do_test rtree4-$nDim.2.$i.3 { 1654b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 1664b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 1674b4f7801Sdrh 1684b4f7801Sdrh # Do an overlaps query with surplus contraints at the beginning. 1694b4f7801Sdrh # This should force a full-table scan on the rtree. 1704b4f7801Sdrh # 1714b4f7801Sdrh set where {} 1724b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1734b4f7801Sdrh lappend where mn$j>=-10000 mx$j<=10000 1744b4f7801Sdrh } 1754b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1764b4f7801Sdrh set mn [rand 10000] 1774b4f7801Sdrh set mx [expr {$mn+[randincr 500]}] 1784b4f7801Sdrh lappend where mx$j>$mn mn$j<$mx 1794b4f7801Sdrh } 1804b4f7801Sdrh set where "WHERE [join $where { AND }]" 181897230ebSdan do_test rtree4-$nDim.2.$i.4 { 1824b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 1834b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 1844b4f7801Sdrh 1854b4f7801Sdrh # Do a contained-in query with surplus contraints at the end 1864b4f7801Sdrh # 1874b4f7801Sdrh set where {} 1884b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 1894b4f7801Sdrh set mn [rand 10000] 1904b4f7801Sdrh set mx [expr {$mn+[randincr 500]}] 1914b4f7801Sdrh lappend where mn$j>=$mn mx$j<$mx 1924b4f7801Sdrh } 1934b4f7801Sdrh for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} { 1944b4f7801Sdrh lappend where mn$j>=-10000 mx$j<10000 1954b4f7801Sdrh } 1964b4f7801Sdrh set where "WHERE [join $where { AND }]" 197897230ebSdan do_test rtree4-$nDim.2.$i.5 { 1984b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 1994b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 2004b4f7801Sdrh 2014b4f7801Sdrh # Do an overlaps query with surplus contraints at the end 2024b4f7801Sdrh # 2034b4f7801Sdrh set where {} 2044b4f7801Sdrh for {set j [expr {$nDim-1}]} {$j>=0} {incr j -1} { 2054b4f7801Sdrh set mn [rand 10000] 2064b4f7801Sdrh set mx [expr {$mn+[randincr 500]}] 2074b4f7801Sdrh lappend where mx$j>$mn mn$j<=$mx 2084b4f7801Sdrh } 2094b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 2104b4f7801Sdrh lappend where mx$j>-10000 mn$j<=10000 2114b4f7801Sdrh } 2124b4f7801Sdrh set where "WHERE [join $where { AND }]" 213897230ebSdan do_test rtree4-$nDim.2.$i.6 { 2144b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 2154b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 2164b4f7801Sdrh 2174b4f7801Sdrh # Do a contained-in query with surplus contraints where the 2184b4f7801Sdrh # constraints appear in a random order. 2194b4f7801Sdrh # 2204b4f7801Sdrh set where {} 2214b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 2224b4f7801Sdrh set mn1 [rand 10000] 2234b4f7801Sdrh set mn2 [expr {$mn1+[randincr 100]}] 2244b4f7801Sdrh set mx1 [expr {$mn2+[randincr 400]}] 2254b4f7801Sdrh set mx2 [expr {$mx1+[randincr 100]}] 2264b4f7801Sdrh lappend where mn$j>=$mn1 mn$j>$mn2 mx$j<$mx1 mx$j<=$mx2 2274b4f7801Sdrh } 2284b4f7801Sdrh set where "WHERE [join [scramble $where] { AND }]" 229897230ebSdan do_test rtree4-$nDim.2.$i.7 { 2304b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 2314b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 2324b4f7801Sdrh 2334b4f7801Sdrh # Do an overlaps query with surplus contraints where the 2344b4f7801Sdrh # constraints appear in a random order. 2354b4f7801Sdrh # 2364b4f7801Sdrh set where {} 2374b4f7801Sdrh for {set j 0} {$j<$nDim} {incr j} { 2384b4f7801Sdrh set mn1 [rand 10000] 2394b4f7801Sdrh set mn2 [expr {$mn1+[randincr 100]}] 2404b4f7801Sdrh set mx1 [expr {$mn2+[randincr 400]}] 2414b4f7801Sdrh set mx2 [expr {$mx1+[randincr 100]}] 2424b4f7801Sdrh lappend where mx$j>=$mn1 mx$j>$mn2 mn$j<$mx1 mn$j<=$mx2 2434b4f7801Sdrh } 2444b4f7801Sdrh set where "WHERE [join [scramble $where] { AND }]" 245897230ebSdan do_test rtree4-$nDim.2.$i.8 { 2464b4f7801Sdrh list $where [db eval "SELECT id FROM rx $where ORDER BY id"] 2474b4f7801Sdrh } [list $where [db eval "SELECT id FROM bx $where ORDER BY id"]] 2484b4f7801Sdrh } 2494b4f7801Sdrh 2501917e92fSdan do_rtree_integrity_test rtree4-$nDim.3 rx 2514b4f7801Sdrh} 2524b4f7801Sdrh 253*eab0e103Sdanexpand_all_sql db 2544b4f7801Sdrhfinish_test 255