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

    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.1.1.1 2012/02/21 17:04:16 misho 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>