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