Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
interrupt.test200 linesDownload Raw Back to test
1# 2004 Feb 82#3# The author disclaims copyright to this source code.  In place of4# 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.  The12# 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 17set testdir [file dirname $argv0]18source $testdir/tester.tcl19set DB [sqlite3_connection_pointer db]20 21# This routine attempts to execute the sql in $sql.  It triggers an22# interrupt at progressively later and later points during the processing23# and checks to make sure SQLITE_INTERRUPT is returned.  Eventually,24# the routine completes successfully.25#26proc interrupt_test {testid sql result {initcnt 0}} {27  set orig_sum [cksum]28  set i $initcnt29  while 1 {30    incr i31    set ::sqlite_interrupt_count $i32    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]] 137    if {$::code==9} {38      do_test $testid.$i.2 {39        cksum40      } $orig_sum41    } else {42      do_test $testid.$i.99 {43        set ::r44      } [list 0 $result]45      break46    }47  }48  set ::sqlite_interrupt_count 049}50 51do_test interrupt-1.1 {52  execsql {53    CREATE TABLE t1(a,b);54    SELECT name FROM sqlite_master;55  }56} {t1}57interrupt_test interrupt-1.2 {DROP TABLE t1} {}58do_test interrupt-1.3 {59  execsql {60    SELECT name FROM sqlite_master;61  }62} {}63integrity_check interrupt-1.464 65do_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} 6481set origsize [file size test.db]82set cksum [db eval {SELECT md5sum(a || b) FROM t1}]83ifcapable {vacuum} {84  interrupt_test interrupt-2.2 {VACUUM} {} 10085}86do_test interrupt-2.3 {87  execsql {88    SELECT md5sum(a || b) FROM t1;89  }90} $cksum91ifcapable {vacuum && !default_autovacuum} {92  do_test interrupt-2.4 {93    expr {$::origsize>[file size test.db]}94  } 195}96ifcapable {explain} {97  do_test interrupt-2.5.1 {98    sqlite3_is_interrupted $DB99  } {0}100  do_test interrupt-2.5.2 {101    unset -nocomplain ::interrupt_count102    set ::interrupt_count 0103    set sql {EXPLAIN SELECT max(a,b), a, b FROM t1}104    execsql $sql105    set rc [catch {db eval $sql {106      sqlite3_interrupt $DB;107      incr ::interrupt_count [sqlite3_is_interrupted $DB];108    }} msg]109    lappend rc $msg110  } {1 interrupted}111  do_test interrupt-2.5.3 {112    set ::interrupt_count113  } {1}114}115integrity_check interrupt-2.6116do_test interrupt-2.7 {117  sqlite3_is_interrupted $DB118} {0}119 120# Ticket #594.  If an interrupt occurs in the middle of a transaction121# and that transaction is later rolled back, the internal schema tables do122# not reset.123#124# UPDATE: Interrupting a DML statement in the middle of a transaction now125# causes the transaction to roll back. Leaving the transaction open after126# an SQL statement was interrupted halfway through risks database corruption.127#128ifcapable tempdb {129  for {set i 1} {$i<50} {incr i 5} {130    do_test interrupt-3.$i.1 {131      execsql {132        BEGIN;133        CREATE TEMP TABLE t2(x,y);134        SELECT name FROM sqlite_temp_master;135      }136    } {t2}137    do_test interrupt-3.$i.2 {138      set ::sqlite_interrupt_count $::i139      catchsql {140        INSERT INTO t2 SELECT * FROM t1;141      }142    } {1 interrupted}143    do_test interrupt-3.$i.3 {144      execsql {145        SELECT name FROM temp.sqlite_master;146      }147    } {}148    do_test interrupt-3.$i.4 {149      catchsql {150        ROLLBACK151      }152    } {1 {cannot rollback - no transaction is active}}153    do_test interrupt-3.$i.5 {154      catchsql {SELECT name FROM sqlite_temp_master};155      execsql {156        SELECT name FROM temp.sqlite_master;157      }158    } {}159  }160}161 162# There are reports of a memory leak if an interrupt occurs during163# the beginning of a complex query - before the first callback.  We164# will try to reproduce it here:165#166execsql {167  CREATE TABLE t2(a,b,c);168  INSERT INTO t2 SELECT round(a/10), randstr(50,80), randstr(50,60) FROM t1;169}170set sql {171  SELECT max(min(b,c)), min(max(b,c)), a FROM t2 GROUP BY a ORDER BY a;172}173set sqlite_interrupt_count 1000000174execsql $sql175set max_count [expr {1000000-$sqlite_interrupt_count}]176for {set i 1} {$i<$max_count-5} {incr i 1} {177  do_test interrupt-4.$i.1 {178    set ::sqlite_interrupt_count $::i179    catchsql $sql180  } {1 interrupted}181}182 183if {0} {  # This doesn't work anymore since the collation factor is184          # no longer called during schema parsing.185# Interrupt during parsing186#187do_test interrupt-5.1 {188  proc fake_interrupt {args} {189    db collate fake_collation no-op190    sqlite3_interrupt db191    return SQLITE_OK192  }193  db collation_needed fake_interrupt194  catchsql {195    CREATE INDEX fake ON fake1(a COLLATE fake_collation, b, c DESC);196  }197} {1 interrupt}198}199finish_test200