modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/rtree/rtreeA.test (about)

     1  # 2010 September 22
     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  # This file contains tests for the r-tree module. Specifically, it tests
    12  # that corrupt or inconsistent databases do not cause crashes in the r-tree
    13  # module.
    14  # 
    15  
    16  if {![info exists testdir]} {
    17    set testdir [file join [file dirname [info script]] .. .. test]
    18  } 
    19  source $testdir/tester.tcl
    20  ifcapable !rtree { finish_test ; return }
    21  
    22  proc create_t1 {} {
    23    db close
    24    forcedelete test.db
    25    sqlite3 db test.db
    26    execsql {
    27      PRAGMA page_size = 1024;
    28      CREATE VIRTUAL TABLE t1 USING rtree(id, x1, x2, y1, y2);
    29    }
    30  }
    31  proc populate_t1 {} {
    32    execsql BEGIN
    33    for {set i 0} {$i < 500} {incr i} {
    34      set x2 [expr $i+5]
    35      set y2 [expr $i+5]
    36      execsql { INSERT INTO t1 VALUES($i, $i, $x2, $i, $y2) }
    37    }
    38    execsql COMMIT
    39  }
    40  
    41  proc truncate_node {nodeno nTrunc} {
    42    set blob [db one {SELECT data FROM t1_node WHERE nodeno=$nodeno}]
    43    if {$nTrunc<0} {set nTrunc "end-$nTrunc"}
    44    set blob [string range $blob 0 $nTrunc]
    45    db eval { UPDATE t1_node SET data = $blob WHERE nodeno=$nodeno }
    46  }
    47  
    48  proc set_tree_depth {tbl {newvalue ""}} {
    49    set blob [db one "SELECT data FROM ${tbl}_node WHERE nodeno=1"]
    50  
    51    if {$newvalue == ""} {
    52      binary scan $blob Su oldvalue
    53      return $oldvalue
    54    }
    55  
    56    set blob [binary format Sua* $newvalue [string range $blob 2 end]]
    57    db eval "UPDATE ${tbl}_node SET data = \$blob WHERE nodeno=1"
    58    return [set_tree_depth $tbl]
    59  }
    60  
    61  proc set_entry_count {tbl nodeno {newvalue ""}} {
    62    set blob [db one "SELECT data FROM ${tbl}_node WHERE nodeno=$nodeno"]
    63  
    64    if {$newvalue == ""} {
    65      binary scan [string range $blob 2 end] Su oldvalue
    66      return $oldvalue
    67    }
    68  
    69    set blob [binary format a*Sua* \
    70      [string range $blob 0 1] $newvalue [string range $blob 4 end]
    71    ]
    72    db eval "UPDATE ${tbl}_node SET data = \$blob WHERE nodeno=$nodeno"
    73    return [set_entry_count $tbl $nodeno]
    74  }
    75  
    76  
    77  proc do_corruption_tests {prefix args} {
    78    set testarray [lindex $args end]
    79    set errormsg {database disk image is malformed}
    80  
    81    foreach {z value} [lrange $args 0 end-1] {
    82      set n [string length $z]
    83      if {$n>=2 && [string equal -length $n $z "-error"]} {
    84        set errormsg $value
    85      }
    86    }
    87  
    88    foreach {tn sql} $testarray {
    89      do_catchsql_test $prefix.$tn $sql [list 1 $errormsg]
    90    }
    91  }
    92  
    93  #-------------------------------------------------------------------------
    94  # Test the libraries response if the %_node table is completely empty
    95  # (i.e. the root node is missing), or has been removed from the database
    96  # entirely.
    97  #
    98  create_t1
    99  populate_t1
   100  do_execsql_test rtreeA-1.0 {
   101    DELETE FROM t1_node;
   102  } {}
   103  
   104  do_corruption_tests rtreeA-1.1 {
   105    1   "SELECT * FROM t1"
   106    2   "SELECT * FROM t1 WHERE rowid=5"
   107    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   108    4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
   109  }
   110  
   111  do_execsql_test  rtreeA-1.2.0 { DROP TABLE t1_node } {}
   112  do_corruption_tests rtreeA-1.2 -error "database disk image is malformed" {
   113    1   "SELECT * FROM t1"
   114    2   "SELECT * FROM t1 WHERE rowid=5"
   115    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   116    4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
   117  }
   118  
   119  #-------------------------------------------------------------------------
   120  # Test the libraries response if some of the entries in the %_node table 
   121  # are the wrong size.
   122  #
   123  create_t1
   124  populate_t1
   125  do_test rtreeA-2.1.0 {
   126    set nodes [db eval {select nodeno FROM t1_node}]
   127    foreach {a b c} $nodes { truncate_node $c 200 }
   128  } {}
   129  do_corruption_tests rtreeA-2.1 {
   130    1   "SELECT * FROM t1"
   131    2   "SELECT * FROM t1 WHERE rowid=5"
   132    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   133    4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
   134  }
   135  
   136  create_t1
   137  populate_t1
   138  do_test rtreeA-2.2.0 { truncate_node 1 200 } {}
   139  do_corruption_tests rtreeA-2.2 {
   140    1   "SELECT * FROM t1"
   141    2   "SELECT * FROM t1 WHERE rowid=5"
   142    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   143    4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
   144  }
   145  
   146  #-------------------------------------------------------------------------
   147  # Set the "depth" of the tree stored on the root node incorrectly. Test
   148  # that this does not cause any problems.
   149  #
   150  create_t1
   151  populate_t1
   152  do_test rtreeA-3.1.0.1 { set_tree_depth t1 } {1}
   153  do_test rtreeA-3.1.0.2 { set_tree_depth t1 3 } {3}
   154  do_corruption_tests rtreeA-3.1 {
   155    1   "SELECT * FROM t1"
   156    2   "SELECT * FROM t1 WHERE rowid=5"
   157    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   158  }
   159  
   160  do_test rtreeA-3.2.0 { set_tree_depth t1 1000 } {1000}
   161  do_corruption_tests rtreeA-3.2 {
   162    1   "SELECT * FROM t1"
   163    2   "SELECT * FROM t1 WHERE rowid=5"
   164    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   165  }
   166  
   167  create_t1
   168  populate_t1
   169  do_test rtreeA-3.3.0 { 
   170    execsql { DELETE FROM t1 WHERE rowid = 0 }
   171    set_tree_depth t1 65535
   172  } {65535}
   173  do_corruption_tests rtreeA-3.3 {
   174    1   "SELECT * FROM t1"
   175    2   "SELECT * FROM t1 WHERE rowid=5"
   176    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   177  }
   178  
   179  #-------------------------------------------------------------------------
   180  # Set the "number of entries" field on some nodes incorrectly.
   181  #
   182  create_t1
   183  populate_t1
   184  do_test rtreeA-4.1.0 { 
   185    set_entry_count t1 1 4000
   186  } {4000}
   187  do_corruption_tests rtreeA-4.1 {
   188    1   "SELECT * FROM t1"
   189    2   "SELECT * FROM t1 WHERE rowid=5"
   190    3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
   191    4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
   192  }
   193  
   194  #-------------------------------------------------------------------------
   195  # Remove entries from the %_parent table and check that this does not
   196  # cause a crash.
   197  #
   198  create_t1
   199  populate_t1
   200  do_execsql_test rtreeA-5.1.0 { DELETE FROM t1_parent } {}
   201  do_corruption_tests rtreeA-5.1 {
   202    1   "DELETE FROM t1 WHERE rowid = 5"
   203    2   "DELETE FROM t1"
   204  }
   205  
   206  #-------------------------------------------------------------------------
   207  # Add some bad entries to the %_parent table.
   208  #
   209  create_t1
   210  populate_t1
   211  do_execsql_test rtreeA-6.1.0 { 
   212    UPDATE t1_parent set parentnode = parentnode+1
   213  } {}
   214  do_corruption_tests rtreeA-6.1 {
   215    1   "DELETE FROM t1 WHERE rowid = 5"
   216    2   "UPDATE t1 SET x1=x1+1, x2=x2+1"
   217  }
   218  
   219  #-------------------------------------------------------------------------
   220  # Truncated blobs in the _node table.
   221  #
   222  create_t1
   223  populate_t1
   224  sqlite3 db test.db
   225  do_execsql_test rtreeA-7.100 { 
   226    UPDATE t1_node SET data=x'' WHERE rowid=1;
   227  } {}
   228  do_catchsql_test rtreeA-7.110 {
   229    SELECT * FROM t1 WHERE x1>0 AND x1<100 AND x2>0 AND x2<100;
   230  } {1 {undersize RTree blobs in "t1_node"}}
   231  do_test rtreeA-7.120 {
   232    sqlite3_extended_errcode db
   233  } {SQLITE_CORRUPT_VTAB}
   234  
   235  
   236  
   237  finish_test