Annotation of embedaddon/sqlite3/test/interrupt.test, revision 1.1.1.1

1.1       misho       1: # 2004 Feb 8
                      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 implements regression tests for SQLite library.  The
                     12: # focus of this script is the sqlite_interrupt() API.
                     13: #
                     14: # $Id: interrupt.test,v 1.16 2008/01/16 17:46:38 drh Exp $
                     15: 
                     16: 
                     17: set testdir [file dirname $argv0]
                     18: source $testdir/tester.tcl
                     19: set DB [sqlite3_connection_pointer db]
                     20: 
                     21: # This routine attempts to execute the sql in $sql.  It triggers an
                     22: # interrupt at progressively later and later points during the processing
                     23: # and checks to make sure SQLITE_INTERRUPT is returned.  Eventually,
                     24: # the routine completes successfully.
                     25: #
                     26: proc interrupt_test {testid sql result {initcnt 0}} {
                     27:   set orig_sum [cksum]
                     28:   set i $initcnt
                     29:   while 1 {
                     30:     incr i
                     31:     set ::sqlite_interrupt_count $i
                     32:     do_test $testid.$i.1 [format {
                     33:       set ::r [catchsql %s]
                     34:       set ::code [db errorcode]
                     35:       expr {$::code==0 || $::code==9}
                     36:     } [list $sql]] 1
                     37:     if {$::code==9} {
                     38:       do_test $testid.$i.2 {
                     39:         cksum
                     40:       } $orig_sum
                     41:     } else {
                     42:       do_test $testid.$i.99 {
                     43:         set ::r
                     44:       } [list 0 $result]
                     45:       break
                     46:     }
                     47:   }
                     48:   set ::sqlite_interrupt_count 0
                     49: }
                     50: 
                     51: do_test interrupt-1.1 {
                     52:   execsql {
                     53:     CREATE TABLE t1(a,b);
                     54:     SELECT name FROM sqlite_master;
                     55:   }
                     56: } {t1}
                     57: interrupt_test interrupt-1.2 {DROP TABLE t1} {}
                     58: do_test interrupt-1.3 {
                     59:   execsql {
                     60:     SELECT name FROM sqlite_master;
                     61:   }
                     62: } {}
                     63: integrity_check interrupt-1.4
                     64: 
                     65: do_test interrrupt-2.1 {
                     66:   execsql {
                     67:     BEGIN;
                     68:     CREATE TABLE t1(a,b);
                     69:     INSERT INTO t1 VALUES(1,randstr(300,400));
                     70:     INSERT INTO t1 SELECT a+1, randstr(300,400) FROM t1;
                     71:     INSERT INTO t1 SELECT a+2, a || '-' || b FROM t1;
                     72:     INSERT INTO t1 SELECT a+4, a || '-' || b FROM t1;
                     73:     INSERT INTO t1 SELECT a+8, a || '-' || b FROM t1;
                     74:     INSERT INTO t1 SELECT a+16, a || '-' || b FROM t1;
                     75:     INSERT INTO t1 SELECT a+32, a || '-' || b FROM t1;
                     76:     COMMIT;
                     77:     UPDATE t1 SET b=substr(b,-5,5);
                     78:     SELECT count(*) from t1;
                     79:   }
                     80: } 64
                     81: set origsize [file size test.db]
                     82: set cksum [db eval {SELECT md5sum(a || b) FROM t1}]
                     83: ifcapable {vacuum} {
                     84:   interrupt_test interrupt-2.2 {VACUUM} {} 100
                     85: }
                     86: do_test interrupt-2.3 {
                     87:   execsql {
                     88:     SELECT md5sum(a || b) FROM t1;
                     89:   }
                     90: } $cksum
                     91: ifcapable {vacuum && !default_autovacuum} {
                     92:   do_test interrupt-2.4 {
                     93:     expr {$::origsize>[file size test.db]}
                     94:   } 1
                     95: }
                     96: ifcapable {explain} {
                     97:   do_test interrupt-2.5 {
                     98:     set sql {EXPLAIN SELECT max(a,b), a, b FROM t1}
                     99:     execsql $sql
                    100:     set rc [catch {db eval $sql {sqlite3_interrupt $DB}} msg]
                    101:     lappend rc $msg
                    102:   } {1 interrupted}
                    103: }
                    104: integrity_check interrupt-2.6
                    105: 
                    106: # Ticket #594.  If an interrupt occurs in the middle of a transaction
                    107: # and that transaction is later rolled back, the internal schema tables do
                    108: # not reset.
                    109: #
                    110: # UPDATE: Interrupting a DML statement in the middle of a transaction now
                    111: # causes the transaction to roll back. Leaving the transaction open after
                    112: # an SQL statement was interrupted halfway through risks database corruption.
                    113: #
                    114: ifcapable tempdb {
                    115:   for {set i 1} {$i<50} {incr i 5} {
                    116:     do_test interrupt-3.$i.1 {
                    117:       execsql {
                    118:         BEGIN;
                    119:         CREATE TEMP TABLE t2(x,y);
                    120:         SELECT name FROM sqlite_temp_master;
                    121:       }
                    122:     } {t2}
                    123:     do_test interrupt-3.$i.2 {
                    124:       set ::sqlite_interrupt_count $::i
                    125:       catchsql {
                    126:         INSERT INTO t2 SELECT * FROM t1;
                    127:       }
                    128:     } {1 interrupted}
                    129:     do_test interrupt-3.$i.3 {
                    130:       execsql {
                    131:         SELECT name FROM sqlite_temp_master;
                    132:       }
                    133:     } {}
                    134:     do_test interrupt-3.$i.4 {
                    135:       catchsql {
                    136:         ROLLBACK
                    137:       }
                    138:     } {1 {cannot rollback - no transaction is active}}
                    139:     do_test interrupt-3.$i.5 {
                    140:       catchsql {SELECT name FROM sqlite_temp_master};
                    141:       execsql {
                    142:         SELECT name FROM sqlite_temp_master;
                    143:       }
                    144:     } {}
                    145:   }
                    146: }
                    147: 
                    148: # There are reports of a memory leak if an interrupt occurs during
                    149: # the beginning of a complex query - before the first callback.  We
                    150: # will try to reproduce it here:
                    151: #
                    152: execsql {
                    153:   CREATE TABLE t2(a,b,c);
                    154:   INSERT INTO t2 SELECT round(a/10), randstr(50,80), randstr(50,60) FROM t1;
                    155: }
                    156: set sql {
                    157:   SELECT max(min(b,c)), min(max(b,c)), a FROM t2 GROUP BY a ORDER BY a;
                    158: }
                    159: set sqlite_interrupt_count 1000000
                    160: execsql $sql
                    161: set max_count [expr {1000000-$sqlite_interrupt_count}]
                    162: for {set i 1} {$i<$max_count-5} {incr i 1} {
                    163:   do_test interrupt-4.$i.1 {
                    164:     set ::sqlite_interrupt_count $::i
                    165:     catchsql $sql
                    166:   } {1 interrupted}
                    167: }
                    168: 
                    169: # Interrupt during parsing
                    170: #
                    171: do_test interrupt-5.1 {
                    172:   proc fake_interrupt {args} {
                    173:     db collate fake_collation no-op
                    174:     sqlite3_interrupt db
                    175:     return SQLITE_OK
                    176:   }
                    177:   db collation_needed fake_interrupt
                    178:   catchsql {
                    179:     CREATE INDEX fake ON fake1(a COLLATE fake_collation, b, c DESC);
                    180:   }
                    181: } {1 interrupt}
                    182: 
                    183: finish_test

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