xref: /sqlite-3.40.0/ext/rtree/rtree8.test (revision 6ab91a7a)
192e01aafSdan# 2010 February 16
292e01aafSdan#
392e01aafSdan# The author disclaims copyright to this source code.  In place of
492e01aafSdan# a legal notice, here is a blessing:
592e01aafSdan#
692e01aafSdan#    May you do good and not evil.
792e01aafSdan#    May you find forgiveness for yourself and forgive others.
892e01aafSdan#    May you share freely, never taking more than you give.
992e01aafSdan#
1092e01aafSdan#***********************************************************************
1192e01aafSdan#
1292e01aafSdan#
1392e01aafSdan
1492e01aafSdanif {![info exists testdir]} {
15897230ebSdan  set testdir [file join [file dirname [info script]] .. .. test]
1692e01aafSdan}
171917e92fSdansource [file join [file dirname [info script]] rtree_util.tcl]
1892e01aafSdansource $testdir/tester.tcl
1992e01aafSdanifcapable !rtree { finish_test ; return }
2092e01aafSdan
2192e01aafSdan#-------------------------------------------------------------------------
2292e01aafSdan# The following block of tests - rtree8-1.* - feature reading and writing
2392e01aafSdan# an r-tree table while there exist open cursors on it.
2492e01aafSdan#
2592e01aafSdanproc populate_t1 {n} {
2692e01aafSdan  execsql { DELETE FROM t1 }
2792e01aafSdan  for {set i 1} {$i <= $n} {incr i} {
2892e01aafSdan    execsql { INSERT INTO t1 VALUES($i, $i, $i+2) }
2992e01aafSdan  }
3092e01aafSdan}
3192e01aafSdan
3292e01aafSdan# A DELETE while a cursor is reading the table.
3392e01aafSdan#
3492e01aafSdando_test rtree8-1.1.1 {
3592e01aafSdan  execsql { PRAGMA page_size = 512 }
3692e01aafSdan  execsql { CREATE VIRTUAL TABLE t1 USING rtree_i32(id, x1, x2) }
3792e01aafSdan  populate_t1 5
3892e01aafSdan} {}
3992e01aafSdando_test rtree8-1.1.2 {
4092e01aafSdan  set res [list]
41c8c9cdd9Sdrh  set rc [catch {
4292e01aafSdan    db eval { SELECT * FROM t1 } {
4392e01aafSdan      lappend res $x1 $x2
4492e01aafSdan      if {$id==3} { db eval { DELETE FROM t1 WHERE id>3 } }
4592e01aafSdan    }
46c8c9cdd9Sdrh  } msg];
47c8c9cdd9Sdrh  lappend rc $msg
48c8c9cdd9Sdrh  set rc
49c8c9cdd9Sdrh} {1 {database table is locked}}
50c8c9cdd9Sdrhdo_test rtree8-1.1.2b {
51c8c9cdd9Sdrh  db eval { SELECT * FROM t1 ORDER BY +id } {
52c8c9cdd9Sdrh    if {$id==3} { db eval { DELETE FROM t1 WHERE id>3 } }
53c8c9cdd9Sdrh  }
54c8c9cdd9Sdrh  db eval {SELECT x1, x2 FROM t1}
5592e01aafSdan} {1 3 2 4 3 5}
5692e01aafSdando_test rtree8-1.1.3 {
5792e01aafSdan  execsql { SELECT * FROM t1 }
5892e01aafSdan} {1 1 3 2 2 4 3 3 5}
5992e01aafSdan
6092e01aafSdan# Many SELECTs on the same small table.
6192e01aafSdan#
6292e01aafSdanproc nested_select {n} {
6392e01aafSdan  set ::max $n
6492e01aafSdan  db eval { SELECT * FROM t1 } {
6592e01aafSdan    if {$id == $n} { nested_select [expr $n+1] }
6692e01aafSdan  }
6792e01aafSdan  return $::max
6892e01aafSdan}
6992e01aafSdando_test rtree8-1.2.1 { populate_t1 50  } {}
7092e01aafSdando_test rtree8-1.2.2 { nested_select 1 } {51}
7192e01aafSdan
7292e01aafSdan# This test runs many SELECT queries simultaneously against a large
7392e01aafSdan# table, causing a collision in the hash-table used to store r-tree
7492e01aafSdan# nodes internally.
7592e01aafSdan#
7692e01aafSdanpopulate_t1 1500
771917e92fSdando_rtree_integrity_test rtree8-1.3.0 t1
7892e01aafSdando_execsql_test rtree8-1.3.1 { SELECT max(nodeno) FROM t1_node } {164}
7992e01aafSdando_test rtree8-1.3.2 {
8092e01aafSdan  set rowids [execsql {SELECT min(rowid) FROM t1_rowid GROUP BY nodeno}]
8192e01aafSdan  set stmt_list [list]
8292e01aafSdan  foreach row $rowids {
8392e01aafSdan    set stmt [sqlite3_prepare db "SELECT * FROM t1 WHERE id = $row" -1 tail]
8492e01aafSdan    sqlite3_step $stmt
8592e01aafSdan    lappend res_list [sqlite3_column_int $stmt 0]
8692e01aafSdan    lappend stmt_list $stmt
8792e01aafSdan  }
8892e01aafSdan} {}
8992e01aafSdando_test rtree8-1.3.3 { set res_list } $rowids
9092e01aafSdando_execsql_test rtree8-1.3.4 { SELECT count(*) FROM t1 } {1500}
9192e01aafSdando_test rtree8-1.3.5 {
9292e01aafSdan  foreach stmt $stmt_list { sqlite3_finalize $stmt }
9392e01aafSdan} {}
9492e01aafSdan
9592e01aafSdan
9692e01aafSdan#-------------------------------------------------------------------------
9792e01aafSdan# The following block of tests - rtree8-2.* - test a couple of database
9892e01aafSdan# corruption cases. In this case things are not corrupted at the b-tree
9992e01aafSdan# level, but the contents of the various tables used internally by an
10092e01aafSdan# r-tree table are inconsistent.
10192e01aafSdan#
10292e01aafSdanpopulate_t1 50
10392e01aafSdando_execsql_test rtree8-2.1.1 { SELECT max(nodeno) FROM t1_node } {5}
104*0f0d3ddfSdrhsqlite3_db_config db DEFENSIVE 0
10592e01aafSdando_execsql_test rtree8-2.1.2 { DELETE FROM t1_node } {}
10692e01aafSdanfor {set i 1} {$i <= 50} {incr i} {
10792e01aafSdan  do_catchsql_test rtree8-2.1.3.$i {
10892e01aafSdan    SELECT * FROM t1 WHERE id = $i
10992e01aafSdan  } {1 {database disk image is malformed}}
11092e01aafSdan}
11192e01aafSdando_catchsql_test rtree8-2.1.4 {
11292e01aafSdan  SELECT * FROM t1
11392e01aafSdan} {1 {database disk image is malformed}}
11492e01aafSdando_catchsql_test rtree8-2.1.5 {
11592e01aafSdan  DELETE FROM t1
11692e01aafSdan} {1 {database disk image is malformed}}
11792e01aafSdan
11892e01aafSdando_execsql_test rtree8-2.1.6 {
11992e01aafSdan  DROP TABLE t1;
12092e01aafSdan  CREATE VIRTUAL TABLE t1 USING rtree_i32(id, x1, x2);
12192e01aafSdan} {}
12292e01aafSdan
123f836afd4Sdan
124f836afd4Sdanpopulate_t1 50
125*0f0d3ddfSdrhsqlite3_db_config db DEFENSIVE 0
126f836afd4Sdando_execsql_test rtree8-2.2.1 {
127f836afd4Sdan  DELETE FROM t1_parent
128f836afd4Sdan} {}
129f836afd4Sdando_catchsql_test rtree8-2.2.2 {
130f836afd4Sdan  DELETE FROM t1 WHERE id=25
131f836afd4Sdan} {1 {database disk image is malformed}}
132f836afd4Sdando_execsql_test rtree8-2.2.3 {
133f836afd4Sdan  DROP TABLE t1;
134f836afd4Sdan  CREATE VIRTUAL TABLE t1 USING rtree_i32(id, x1, x2);
135f836afd4Sdan} {}
136f836afd4Sdan
137f836afd4Sdan
13892e01aafSdan#-------------------------------------------------------------------------
13992e01aafSdan# Test that trying to use the MATCH operator with the r-tree module does
14092e01aafSdan# not confuse it.
14192e01aafSdan#
14292e01aafSdanpopulate_t1 10
14392e01aafSdando_catchsql_test rtree8-3.1 {
14492e01aafSdan  SELECT * FROM t1 WHERE x1 MATCH '1234'
145a690ff36Sdrh} {1 {SQL logic error}}
14692e01aafSdan
1472bf19178Sdan#-------------------------------------------------------------------------
1482bf19178Sdan# Test a couple of invalid arguments to rtreedepth().
1492bf19178Sdan#
1502bf19178Sdando_catchsql_test rtree8-4.1 {
1512bf19178Sdan  SELECT rtreedepth('hello world')
1522bf19178Sdan} {1 {Invalid argument to rtreedepth()}}
1532bf19178Sdando_catchsql_test rtree8-4.2 {
1542bf19178Sdan  SELECT rtreedepth(X'00')
1552bf19178Sdan} {1 {Invalid argument to rtreedepth()}}
1562bf19178Sdan
1572bf19178Sdan
1582bf19178Sdan#-------------------------------------------------------------------------
1592bf19178Sdan# Delete half of a lopsided tree.
1602bf19178Sdan#
1612bf19178Sdando_execsql_test rtree8-5.1 {
1622bf19178Sdan  CREATE VIRTUAL TABLE t2 USING rtree_i32(id, x1, x2)
1632bf19178Sdan} {}
1642bf19178Sdando_test rtree8-5.2 {
1652bf19178Sdan  execsql BEGIN
1662bf19178Sdan  for {set i 0} {$i < 100} {incr i} {
1672bf19178Sdan    execsql { INSERT INTO t2 VALUES($i, 100, 101) }
1682bf19178Sdan  }
1692bf19178Sdan  for {set i 100} {$i < 200} {incr i} {
1702bf19178Sdan    execsql { INSERT INTO t2 VALUES($i, 1000, 1001) }
1712bf19178Sdan  }
1722bf19178Sdan  execsql COMMIT
1732bf19178Sdan} {}
1741917e92fSdando_rtree_integrity_test rtree8-5.3 t2
1751917e92fSdando_test rtree8-5.4 {
1762bf19178Sdan  execsql BEGIN
1772bf19178Sdan  for {set i 0} {$i < 200} {incr i} {
1782bf19178Sdan    execsql { DELETE FROM t2 WHERE id = $i }
1792bf19178Sdan  }
1802bf19178Sdan  execsql COMMIT
1812bf19178Sdan} {}
1821917e92fSdando_rtree_integrity_test rtree8-5.5 t2
1832bf19178Sdan
18430fc7f80Sdrh# 2018-05-24
18530fc7f80Sdrh# The following script caused an assertion fault and/or segfault
18630fc7f80Sdrh# prior to the fix that prevents simultaneous reads and writes on
18730fc7f80Sdrh# the same rtree virtual table.
18830fc7f80Sdrh#
18930fc7f80Sdrhdo_test rtree8-6.1 {
19030fc7f80Sdrh  db close
19130fc7f80Sdrh  sqlite3 db :memory:
19230fc7f80Sdrh  db eval {
19330fc7f80Sdrh    PRAGMA page_size=512;
19430fc7f80Sdrh    CREATE VIRTUAL TABLE t1 USING rtree(id,x1,x2,y1,y2);
19530fc7f80Sdrh    WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<49)
19630fc7f80Sdrh    INSERT INTO t1 SELECT x, x, x+1, x, x+1 FROM c;
19730fc7f80Sdrh  }
19830fc7f80Sdrh  set rc [catch {
19930fc7f80Sdrh    db eval {SELECT id FROM t1} x {
20030fc7f80Sdrh      db eval {DELETE FROM t1 WHERE id=$x(id)}
20130fc7f80Sdrh    }
20230fc7f80Sdrh  } msg]
20330fc7f80Sdrh  lappend rc $msg
20430fc7f80Sdrh} {1 {database table is locked}}
20530fc7f80Sdrh
20630fc7f80Sdrh
20730fc7f80Sdrh
20892e01aafSdan
20992e01aafSdanfinish_test
210