File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / ext / rtree / rtreeA.test
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:17 2012 UTC (13 years, 1 month ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    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 "SQL logic error or missing database" {
  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: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>