(28282, -80.846382, -80.844193, 35.223972, 35.225655);
}
-finish_test
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+# Section 3.3 of documentation.
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+set testprefix rtreedoc-5
+reset_db
+
+
+
+
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+# Section 3.4 of documentation.
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+set testprefix rtreedoc-6
+
+# EVIDENCE-OF: R-08327-00674 By default, coordinates are stored in an
+# R*Tree using 32-bit floating point values.
+#
+# Show this by showing that rounding is consistent with 32-bit float
+# rounding.
+do_execsql_test 1.0 {
+ CREATE VIRTUAL TABLE rt USING rtree(id, a,b);
+}
+do_execsql_test 1.1 {
+ INSERT INTO rt VALUES(14, -1000000000000, 1000000000000);
+ SELECT * FROM rt;
+} {14 -1000000126976.0 1000000126976.0}
+
+# EVIDENCE-OF: R-39127-51288 When a coordinate cannot be exactly
+# represented by a 32-bit floating point number, the lower-bound
+# coordinates are rounded down and the upper-bound coordinates are
+# rounded up.
+foreach {tn val} {
+ 1 100000000000
+ 2 200000000000
+ 3 300000000000
+ 4 400000000000
+
+ 5 -100000000000
+ 6 -200000000000
+ 7 -300000000000
+ 8 -400000000000
+} {
+ set val [expr $val]
+ do_execsql_test 2.$tn.0 {DELETE FROM rt}
+ do_execsql_test 2.$tn.1 {INSERT INTO rt VALUES(23, $val, $val)}
+ do_execsql_test 2.$tn.2 {
+ SELECT $val>=a, $val<=b, a!=b FROM rt
+ } {1 1 1}
+}
+
+do_execsql_test 3.0 {
+ DROP TABLE rt;
+ CREATE VIRTUAL TABLE rt USING rtree(id, x1,x2, y1,y2);
+}
+
+# EVIDENCE-OF: R-45870-62834 Thus, bounding boxes might be slightly
+# larger than specified, but will never be any smaller.
+foreach {tn x1 x2 y1 y2} {
+ 1 100000000000 200000000000 300000000000 400000000000
+} {
+ set val [expr $val]
+ do_execsql_test 3.$tn.0 {DELETE FROM rt}
+ do_execsql_test 3.$tn.1 {INSERT INTO rt VALUES(23, $x1, $x2, $y1, $y2)}
+ do_execsql_test 3.$tn.2 {
+ SELECT (x2-x1)*(y2-y1) >= ($x2-$x1)*($y2-$y1) FROM rt
+ } {1}
+}
+
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+# Section 3.5 of documentation.
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+set testprefix rtreedoc-7
+reset_db
+
+# EVIDENCE-OF: R-55979-39402 It is the nature of the Guttman R-Tree
+# algorithm that any write might radically restructure the tree, and in
+# the process change the scan order of the nodes.
+#
+# In the test below, the INSERT marked "THIS INSERT!!" does not affect
+# the results of queries with an ORDER BY, but does affect the results
+# of one without an ORDER BY. Therefore the INSERT changed the scan
+# order.
+do_execsql_test 1.0 {
+ CREATE VIRTUAL TABLE rt USING rtree(id, minX, maxX);
+ WITH s(i) AS (
+ SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<51
+ )
+ INSERT INTO rt SELECT NULL, i%10, (i%10)+5 FROM s
+}
+do_execsql_test 1.1 { SELECT count(*) FROM rt_node } 1
+do_test 1.2 {
+ set res1 [db eval {SELECT * FROM rt WHERE maxX < 30}]
+ set res1o [db eval {SELECT * FROM rt WHERE maxX < 30 ORDER BY +id}]
+
+ db eval { INSERT INTO rt VALUES(NULL, 50, 50) } ;# THIS INSERT!!
+ set res2 [db eval {SELECT * FROM rt WHERE maxX < 30}]
+ set res2o [db eval {SELECT * FROM rt WHERE maxX < 30 ORDER BY +id}]
+ list [expr {$res1==$res2}] [expr {$res1o==$res2o}]
+} {0 1}
+
+do_execsql_test 1.3 { SELECT count(*) FROM rt_node } 3
+
+# EVIDENCE-OF: R-00683-48865 For this reason, it is not generally
+# possible to modify the R-Tree in the middle of a query of the R-Tree.
+# Attempts to do so will fail with a SQLITE_LOCKED "database table is
+# locked" error.
+#
+# SQLITE_LOCKED==6
+#
+do_test 1.4 {
+ set nCnt 3
+ db eval { SELECT * FROM rt WHERE minX>0 AND maxX<12 } {
+ incr nCnt -1
+ if {$nCnt==0} {
+ set rc [catch {db eval {
+ INSERT INTO rt VALUES(NULL, 51, 51);
+ }} msg]
+ set errorcode [db errorcode]
+ break
+ }
+ }
+
+ list $errorcode $rc $msg
+} {6 1 {database table is locked}}
+
+# EVIDENCE-OF: R-19740-29710 So, for example, suppose an application
+# runs one query against an R-Tree like this: SELECT id FROM demo_index
+# WHERE maxY>=35.0 AND minY<=35.0; Then for each "id" value
+# returned, suppose the application creates an UPDATE statement like the
+# following and binds the "id" value returned against the "?1"
+# parameter: UPDATE demo_index SET maxY=maxY+0.5 WHERE id=?1;
+#
+# EVIDENCE-OF: R-52919-32711 Then the UPDATE might fail with an
+# SQLITE_LOCKED error.
+do_execsql_test 2.0 {
+ CREATE VIRTUAL TABLE demo_index USING rtree(
+ id, -- Integer primary key
+ minX, maxX, -- Minimum and maximum X coordinate
+ minY, maxY -- Minimum and maximum Y coordinate
+ );
+ INSERT INTO demo_index VALUES
+ (28215, -80.781227, -80.604706, 35.208813, 35.297367),
+ (28216, -80.957283, -80.840599, 35.235920, 35.367825),
+ (28217, -80.960869, -80.869431, 35.133682, 35.208233),
+ (28226, -80.878983, -80.778275, 35.060287, 35.154446);
+}
+do_test 2.1 {
+ db eval { SELECT id FROM demo_index WHERE maxY>=35.0 AND minY<=35.0 } {
+ set rc [catch {
+ db eval { UPDATE demo_index SET maxY=maxY+0.5 WHERE id=$id }
+ } msg]
+ set errorcode [db errorcode]
+ break
+ }
+ list $errorcode $rc $msg
+} {6 1 {database table is locked}}
+
+# EVIDENCE-OF: R-32604-49843 Ordinary tables in SQLite are able to read
+# and write at the same time.
+#
+do_execsql_test 3.0 {
+ CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c);
+ INSERT INTO x1 VALUES(1, 1, 1);
+ INSERT INTO x1 VALUES(2, 2, 2);
+ INSERT INTO x1 VALUES(3, 3, 3);
+ INSERT INTO x1 VALUES(4, 4, 4);
+}
+do_test 3.1 {
+ set res [list]
+ db eval { SELECT * FROM x1 } {
+ lappend res $a $b $c
+ switch -- $a {
+ 1 {
+ db eval { INSERT INTO x1 VALUES(5, 5, 5) }
+ }
+ 2 {
+ db eval { UPDATE x1 SET c=20 WHERE a=2 }
+ }
+ 3 {
+ db eval { DELETE FROM x1 WHERE c IN (3,4) }
+ }
+ }
+ }
+ set res
+} {1 1 1 2 2 2 3 3 3 5 5 5}
+do_execsql_test 3.2 {
+ SELECT * FROM x1
+} {1 1 1 2 2 20 5 5 5}
+
+# EVIDENCE-OF: R-06177-00576 And R-Tree can appear to read and write at
+# the same time in some circumstances, if it can figure out how to
+# reliably run the query to completion before starting the update.
+#
+# In 8.2, it can, it 8.1, it cannot.
+do_test 8.1 {
+ db eval { SELECT * FROM rt } {
+ set rc [catch { db eval { INSERT INTO rt VALUES(53,53,53) } } msg]
+ break;
+ }
+ list $rc $msg
+} {1 {database table is locked}}
+do_test 8.2 {
+ db eval { SELECT * FROM rt ORDER BY +id } {
+ set rc [catch { db eval { INSERT INTO rt VALUES(53,53,53) } } msg]
+ break
+ }
+ list $rc $msg
+} {0 {}}
+
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+# Section 4 of documentation.
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+set testprefix rtreedoc-8
+
+
+finish_test