Annotation of embedaddon/sqlite3/ext/rtree/rtreeA.test, revision 1.1

1.1     ! misho       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>