wasCSharpSQLite – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | # 2005 December 30 |
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 | # |
||
12 | # The focus of the tests in this file are IO errors that occur in a shared |
||
13 | # cache context. What happens to connection B if one connection A encounters |
||
14 | # an IO-error whilst reading or writing the file-system? |
||
15 | # |
||
16 | # $Id: shared_err.test,v 1.24 2008/10/12 00:27:54 shane Exp $ |
||
17 | |||
18 | proc skip {args} {} |
||
19 | |||
20 | |||
21 | set testdir [file dirname $argv0] |
||
22 | source $testdir/tester.tcl |
||
23 | source $testdir/malloc_common.tcl |
||
24 | db close |
||
25 | |||
26 | ifcapable !shared_cache||!subquery { |
||
27 | finish_test |
||
28 | return |
||
29 | } |
||
30 | |||
31 | set ::enable_shared_cache [sqlite3_enable_shared_cache 1] |
||
32 | |||
33 | do_ioerr_test shared_ioerr-1 -tclprep { |
||
34 | sqlite3 db2 test.db |
||
35 | execsql { |
||
36 | PRAGMA read_uncommitted = 1; |
||
37 | CREATE TABLE t1(a,b,c); |
||
38 | BEGIN; |
||
39 | SELECT * FROM sqlite_master; |
||
40 | } db2 |
||
41 | } -sqlbody { |
||
42 | SELECT * FROM sqlite_master; |
||
43 | INSERT INTO t1 VALUES(1,2,3); |
||
44 | BEGIN TRANSACTION; |
||
45 | INSERT INTO t1 VALUES(1,2,3); |
||
46 | INSERT INTO t1 VALUES(4,5,6); |
||
47 | ROLLBACK; |
||
48 | SELECT * FROM t1; |
||
49 | BEGIN TRANSACTION; |
||
50 | INSERT INTO t1 VALUES(1,2,3); |
||
51 | INSERT INTO t1 VALUES(4,5,6); |
||
52 | COMMIT; |
||
53 | SELECT * FROM t1; |
||
54 | DELETE FROM t1 WHERE a<100; |
||
55 | } -cleanup { |
||
56 | do_test shared_ioerr-1.$n.cleanup.1 { |
||
57 | set res [catchsql { |
||
58 | SELECT * FROM t1; |
||
59 | } db2] |
||
60 | set possible_results [list \ |
||
61 | "1 {disk I/O error}" \ |
||
62 | "0 {1 2 3}" \ |
||
63 | "0 {1 2 3 1 2 3 4 5 6}" \ |
||
64 | "0 {1 2 3 1 2 3 4 5 6 1 2 3 4 5 6}" \ |
||
65 | "0 {}" \ |
||
66 | "1 {database disk image is malformed}" \ |
||
67 | ] |
||
68 | set rc [expr [lsearch -exact $possible_results $res] >= 0] |
||
69 | if {$rc != 1} { |
||
70 | puts "" |
||
71 | puts "Result: $res" |
||
72 | } |
||
73 | set rc |
||
74 | } {1} |
||
75 | |||
76 | # The "database disk image is malformed" is a special case that can |
||
77 | # occur if an IO error occurs during a rollback in the {SELECT * FROM t1} |
||
78 | # statement above. This test is to make sure there is no real database |
||
79 | # corruption. |
||
80 | db2 close |
||
81 | do_test shared_ioerr-1.$n.cleanup.2 { |
||
82 | execsql {pragma integrity_check} db |
||
83 | } {ok} |
||
84 | } |
||
85 | |||
86 | do_ioerr_test shared_ioerr-2 -tclprep { |
||
87 | sqlite3 db2 test.db |
||
88 | execsql { |
||
89 | PRAGMA read_uncommitted = 1; |
||
90 | BEGIN; |
||
91 | CREATE TABLE t1(a, b); |
||
92 | INSERT INTO t1(oid) VALUES(NULL); |
||
93 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
94 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
95 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
96 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
97 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
98 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
99 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
100 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
101 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
102 | INSERT INTO t1(oid) SELECT NULL FROM t1; |
||
103 | UPDATE t1 set a = oid, b = 'abcdefghijklmnopqrstuvwxyz0123456789'; |
||
104 | CREATE INDEX i1 ON t1(a); |
||
105 | COMMIT; |
||
106 | BEGIN; |
||
107 | SELECT * FROM sqlite_master; |
||
108 | } db2 |
||
109 | } -tclbody { |
||
110 | set ::residx 0 |
||
111 | execsql {DELETE FROM t1 WHERE 0 = (a % 2);} |
||
112 | incr ::residx |
||
113 | |||
114 | # When this transaction begins the table contains 512 entries. The |
||
115 | # two statements together add 512+146 more if it succeeds. |
||
116 | # (1024/7==146) |
||
117 | execsql {BEGIN;} |
||
118 | execsql {INSERT INTO t1 SELECT a+1, b FROM t1;} |
||
119 | execsql {INSERT INTO t1 SELECT 'string' || a, b FROM t1 WHERE 0 = (a%7);} |
||
120 | execsql {COMMIT;} |
||
121 | |||
122 | incr ::residx |
||
123 | } -cleanup { |
||
124 | catchsql ROLLBACK |
||
125 | do_test shared_ioerr-2.$n.cleanup.1 { |
||
126 | set res [catchsql { |
||
127 | SELECT max(a), min(a), count(*) FROM (SELECT a FROM t1 order by a); |
||
128 | } db2] |
||
129 | set possible_results [list \ |
||
130 | {0 {1024 1 1024}} \ |
||
131 | {0 {1023 1 512}} \ |
||
132 | {0 {string994 1 1170}} \ |
||
133 | ] |
||
134 | set idx [lsearch -exact $possible_results $res] |
||
135 | set success [expr {$idx==$::residx || $res=="1 {disk I/O error}"}] |
||
136 | if {!$success} { |
||
137 | puts "" |
||
138 | puts "Result: \"$res\" ($::residx)" |
||
139 | } |
||
140 | set success |
||
141 | } {1} |
||
142 | db2 close |
||
143 | } |
||
144 | |||
145 | # This test is designed to provoke an IO error when a cursor position is |
||
146 | # "saved" (because another cursor is going to modify the underlying table). |
||
147 | # |
||
148 | do_ioerr_test shared_ioerr-3 -tclprep { |
||
149 | sqlite3 db2 test.db |
||
150 | execsql { |
||
151 | PRAGMA read_uncommitted = 1; |
||
152 | PRAGMA cache_size = 10; |
||
153 | BEGIN; |
||
154 | CREATE TABLE t1(a, b, UNIQUE(a, b)); |
||
155 | } db2 |
||
156 | for {set i 0} {$i < 200} {incr i} { |
||
157 | set a [string range [string repeat "[format %03d $i]." 5] 0 end-1] |
||
158 | |||
159 | set b [string repeat $i 2000] |
||
160 | execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
||
161 | } |
||
162 | execsql {COMMIT} db2 |
||
163 | set ::DB2 [sqlite3_connection_pointer db2] |
||
164 | set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] |
||
165 | sqlite3_step $::STMT ;# Cursor points at 000.000.000.000 |
||
166 | sqlite3_step $::STMT ;# Cursor points at 001.001.001.001 |
||
167 | |||
168 | } -tclbody { |
||
169 | execsql { |
||
170 | BEGIN; |
||
171 | INSERT INTO t1 VALUES('201.201.201.201.201', NULL); |
||
172 | UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%'; |
||
173 | COMMIT; |
||
174 | } |
||
175 | } -cleanup { |
||
176 | set ::steprc [sqlite3_step $::STMT] |
||
177 | set ::column [sqlite3_column_text $::STMT 0] |
||
178 | set ::finalrc [sqlite3_finalize $::STMT] |
||
179 | |||
180 | # There are three possible outcomes here (assuming persistent IO errors): |
||
181 | # |
||
182 | # 1. If the [sqlite3_step] did not require any IO (required pages in |
||
183 | # the cache), then the next row ("002...") may be retrieved |
||
184 | # successfully. |
||
185 | # |
||
186 | # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns |
||
187 | # SQLITE_ERROR and [sqlite3_finalize] returns IOERR. |
||
188 | # |
||
189 | # 3. If, after the initial IO error, SQLite tried to rollback the |
||
190 | # active transaction and a second IO error was encountered, then |
||
191 | # statement $::STMT will have been aborted. This means [sqlite3_stmt] |
||
192 | # returns SQLITE_ABORT, and the statement cursor does not move. i.e. |
||
193 | # [sqlite3_column] still returns the current row ("001...") and |
||
194 | # [sqlite3_finalize] returns SQLITE_OK. |
||
195 | # |
||
196 | |||
197 | do_test shared_ioerr-3.$n.cleanup.1 { |
||
198 | expr { |
||
199 | $::steprc eq "SQLITE_ROW" || |
||
200 | $::steprc eq "SQLITE_ERROR" || |
||
201 | $::steprc eq "SQLITE_ABORT" |
||
202 | } |
||
203 | } {1} |
||
204 | do_test shared_ioerr-3.$n.cleanup.2 { |
||
205 | expr { |
||
206 | ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") || |
||
207 | ($::steprc eq "SQLITE_ERROR" && $::column eq "") || |
||
208 | ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001") |
||
209 | } |
||
210 | } {1} |
||
211 | do_test shared_ioerr-3.$n.cleanup.3 { |
||
212 | expr { |
||
213 | ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") || |
||
214 | ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") || |
||
215 | ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT") |
||
216 | } |
||
217 | } {1} |
||
218 | |||
219 | # db2 eval {select * from sqlite_master} |
||
220 | db2 close |
||
221 | } |
||
222 | |||
223 | # This is a repeat of the previous test except that this time we |
||
224 | # are doing a reverse-order scan of the table when the cursor is |
||
225 | # "saved". |
||
226 | # |
||
227 | do_ioerr_test shared_ioerr-3rev -tclprep { |
||
228 | sqlite3 db2 test.db |
||
229 | execsql { |
||
230 | PRAGMA read_uncommitted = 1; |
||
231 | PRAGMA cache_size = 10; |
||
232 | BEGIN; |
||
233 | CREATE TABLE t1(a, b, UNIQUE(a, b)); |
||
234 | } db2 |
||
235 | for {set i 0} {$i < 200} {incr i} { |
||
236 | set a [string range [string repeat "[format %03d $i]." 5] 0 end-1] |
||
237 | |||
238 | set b [string repeat $i 2000] |
||
239 | execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
||
240 | } |
||
241 | execsql {COMMIT} db2 |
||
242 | set ::DB2 [sqlite3_connection_pointer db2] |
||
243 | set ::STMT [sqlite3_prepare $::DB2 \ |
||
244 | "SELECT a FROM t1 ORDER BY a DESC" -1 DUMMY] |
||
245 | sqlite3_step $::STMT ;# Cursor points at 199.199.199.199.199 |
||
246 | sqlite3_step $::STMT ;# Cursor points at 198.198.198.198.198 |
||
247 | |||
248 | } -tclbody { |
||
249 | execsql { |
||
250 | BEGIN; |
||
251 | INSERT INTO t1 VALUES('201.201.201.201.201', NULL); |
||
252 | UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%'; |
||
253 | COMMIT; |
||
254 | } |
||
255 | } -cleanup { |
||
256 | set ::steprc [sqlite3_step $::STMT] |
||
257 | set ::column [sqlite3_column_text $::STMT 0] |
||
258 | set ::finalrc [sqlite3_finalize $::STMT] |
||
259 | |||
260 | # There are three possible outcomes here (assuming persistent IO errors): |
||
261 | # |
||
262 | # 1. If the [sqlite3_step] did not require any IO (required pages in |
||
263 | # the cache), then the next row ("002...") may be retrieved |
||
264 | # successfully. |
||
265 | # |
||
266 | # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns |
||
267 | # SQLITE_ERROR and [sqlite3_finalize] returns IOERR. |
||
268 | # |
||
269 | # 3. If, after the initial IO error, SQLite tried to rollback the |
||
270 | # active transaction and a second IO error was encountered, then |
||
271 | # statement $::STMT will have been aborted. This means [sqlite3_stmt] |
||
272 | # returns SQLITE_ABORT, and the statement cursor does not move. i.e. |
||
273 | # [sqlite3_column] still returns the current row ("001...") and |
||
274 | # [sqlite3_finalize] returns SQLITE_OK. |
||
275 | # |
||
276 | |||
277 | do_test shared_ioerr-3rev.$n.cleanup.1 { |
||
278 | expr { |
||
279 | $::steprc eq "SQLITE_ROW" || |
||
280 | $::steprc eq "SQLITE_ERROR" || |
||
281 | $::steprc eq "SQLITE_ABORT" |
||
282 | } |
||
283 | } {1} |
||
284 | do_test shared_ioerr-3rev.$n.cleanup.2 { |
||
285 | expr { |
||
286 | ($::steprc eq "SQLITE_ROW" && $::column eq "197.197.197.197.197") || |
||
287 | ($::steprc eq "SQLITE_ERROR" && $::column eq "") || |
||
288 | ($::steprc eq "SQLITE_ABORT" && $::column eq "198.198.198.198.198") |
||
289 | } |
||
290 | } {1} |
||
291 | do_test shared_ioerr-3rev.$n.cleanup.3 { |
||
292 | expr { |
||
293 | ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") || |
||
294 | ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") || |
||
295 | ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_ABORT") |
||
296 | } |
||
297 | } {1} |
||
298 | |||
299 | # db2 eval {select * from sqlite_master} |
||
300 | db2 close |
||
301 | } |
||
302 | |||
303 | # Provoke a malloc() failure when a cursor position is being saved. This |
||
304 | # only happens with index cursors (because they malloc() space to save the |
||
305 | # current key value). It does not happen with tables, because an integer |
||
306 | # key does not require a malloc() to store. |
||
307 | # |
||
308 | # The library should return an SQLITE_NOMEM to the caller. The query that |
||
309 | # owns the cursor (the one for which the position is not saved) should |
||
310 | # continue unaffected. |
||
311 | # |
||
312 | do_malloc_test shared_err-4 -tclprep { |
||
313 | sqlite3 db2 test.db |
||
314 | execsql { |
||
315 | PRAGMA read_uncommitted = 1; |
||
316 | BEGIN; |
||
317 | CREATE TABLE t1(a, b, UNIQUE(a, b)); |
||
318 | } db2 |
||
319 | for {set i 0} {$i < 5} {incr i} { |
||
320 | set a [string repeat $i 10] |
||
321 | set b [string repeat $i 2000] |
||
322 | execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
||
323 | } |
||
324 | execsql {COMMIT} db2 |
||
325 | set ::DB2 [sqlite3_connection_pointer db2] |
||
326 | set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] |
||
327 | sqlite3_step $::STMT ;# Cursor points at 0000000000 |
||
328 | sqlite3_step $::STMT ;# Cursor points at 1111111111 |
||
329 | } -tclbody { |
||
330 | execsql { |
||
331 | INSERT INTO t1 VALUES(6, NULL); |
||
332 | } |
||
333 | } -cleanup { |
||
334 | do_test shared_malloc-4.$::n.cleanup.1 { |
||
335 | set ::rc [sqlite3_step $::STMT] |
||
336 | expr {$::rc=="SQLITE_ROW" || $::rc=="SQLITE_ERROR"} |
||
337 | } {1} |
||
338 | if {$::rc=="SQLITE_ROW"} { |
||
339 | do_test shared_malloc-4.$::n.cleanup.2 { |
||
340 | sqlite3_column_text $::STMT 0 |
||
341 | } {2222222222} |
||
342 | } |
||
343 | do_test shared_malloc-4.$::n.cleanup.3 { |
||
344 | set rc [sqlite3_finalize $::STMT] |
||
345 | expr {$rc=="SQLITE_OK" || $rc=="SQLITE_ABORT" || |
||
346 | $rc=="SQLITE_NOMEM" || $rc=="SQLITE_IOERR"} |
||
347 | } {1} |
||
348 | # db2 eval {select * from sqlite_master} |
||
349 | db2 close |
||
350 | } |
||
351 | |||
352 | do_malloc_test shared_err-5 -tclbody { |
||
353 | db close |
||
354 | sqlite3 dbX test.db |
||
355 | sqlite3 dbY test.db |
||
356 | dbX close |
||
357 | dbY close |
||
358 | } -cleanup { |
||
359 | catch {dbX close} |
||
360 | catch {dbY close} |
||
361 | } |
||
362 | |||
363 | do_malloc_test shared_err-6 -tclbody { |
||
364 | catch {db close} |
||
365 | ifcapable deprecated { |
||
366 | sqlite3_thread_cleanup |
||
367 | } |
||
368 | sqlite3_enable_shared_cache 0 |
||
369 | } -cleanup { |
||
370 | sqlite3_enable_shared_cache 1 |
||
371 | } |
||
372 | |||
373 | # As of 3.5.0, sqlite3_enable_shared_cache can be called at |
||
374 | # any time and from any thread |
||
375 | #do_test shared_err-misuse-7.1 { |
||
376 | # sqlite3 db test.db |
||
377 | # catch { |
||
378 | # sqlite3_enable_shared_cache 0 |
||
379 | # } msg |
||
380 | # set msg |
||
381 | #} {library routine called out of sequence} |
||
382 | |||
383 | # Again provoke a malloc() failure when a cursor position is being saved, |
||
384 | # this time during a ROLLBACK operation by some other handle. |
||
385 | # |
||
386 | # The library should return an SQLITE_NOMEM to the caller. The query that |
||
387 | # owns the cursor (the one for which the position is not saved) should |
||
388 | # be aborted. |
||
389 | # |
||
390 | set ::aborted 0 |
||
391 | do_malloc_test shared_err-8 -tclprep { |
||
392 | sqlite3 db2 test.db |
||
393 | execsql { |
||
394 | PRAGMA read_uncommitted = 1; |
||
395 | BEGIN; |
||
396 | CREATE TABLE t1(a, b, UNIQUE(a, b)); |
||
397 | } db2 |
||
398 | for {set i 0} {$i < 2} {incr i} { |
||
399 | set a [string repeat $i 10] |
||
400 | set b [string repeat $i 2000] |
||
401 | execsql {INSERT INTO t1 VALUES($a, $b)} db2 |
||
402 | } |
||
403 | execsql {COMMIT} db2 |
||
404 | set ::DB2 [sqlite3_connection_pointer db2] |
||
405 | set ::STMT [sqlite3_prepare $::DB2 "SELECT a FROM t1 ORDER BY a" -1 DUMMY] |
||
406 | sqlite3_step $::STMT ;# Cursor points at 0000000000 |
||
407 | sqlite3_step $::STMT ;# Cursor points at 1111111111 |
||
408 | } -tclbody { |
||
409 | execsql { |
||
410 | BEGIN; |
||
411 | INSERT INTO t1 VALUES(6, NULL); |
||
412 | ROLLBACK; |
||
413 | } |
||
414 | } -cleanup { |
||
415 | # UPDATE: As of [5668], if the rollback fails SQLITE_CORRUPT is returned. |
||
416 | # So these tests have been updated to expect SQLITE_CORRUPT and its |
||
417 | # associated English language error message. |
||
418 | # |
||
419 | do_test shared_malloc-8.$::n.cleanup.1 { |
||
420 | set res [catchsql {SELECT a FROM t1} db2] |
||
421 | set ans [lindex $res 1] |
||
422 | if {[lindex $res 0]} { |
||
423 | set r [expr { |
||
424 | $ans=="disk I/O error" || |
||
425 | $ans=="out of memory" || |
||
426 | $ans=="database disk image is malformed" |
||
427 | }] |
||
428 | } else { |
||
429 | set r [expr {[lrange $ans 0 1]=="0000000000 1111111111"}] |
||
430 | } |
||
431 | } {1} |
||
432 | do_test shared_malloc-8.$::n.cleanup.2 { |
||
433 | set rc1 [sqlite3_step $::STMT] |
||
434 | set rc2 [sqlite3_finalize $::STMT] |
||
435 | if {$rc2=="SQLITE_ABORT"} { |
||
436 | incr ::aborted |
||
437 | } |
||
438 | expr { |
||
439 | ($rc1=="SQLITE_DONE" && $rc2=="SQLITE_OK") || |
||
440 | ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_ABORT") || |
||
441 | ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_NOMEM") || |
||
442 | ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_IOERR") || |
||
443 | ($rc1=="SQLITE_ERROR" && $rc2=="SQLITE_CORRUPT") |
||
444 | } |
||
445 | } {1} |
||
446 | db2 close |
||
447 | } |
||
448 | do_test shared_malloc-8.X { |
||
449 | # Test that one or more queries were aborted due to the malloc() failure. |
||
450 | expr $::aborted>=1 |
||
451 | } {1} |
||
452 | |||
453 | # This test is designed to catch a specific bug that was present during |
||
454 | # development of 3.5.0. If a malloc() failed while setting the page-size, |
||
455 | # a buffer (Pager.pTmpSpace) was being freed. This could cause a seg-fault |
||
456 | # later if another connection tried to use the pager. |
||
457 | # |
||
458 | # This test will crash 3.4.2. |
||
459 | # |
||
460 | do_malloc_test shared_err-9 -tclprep { |
||
461 | sqlite3 db2 test.db |
||
462 | } -sqlbody { |
||
463 | PRAGMA page_size = 4096; |
||
464 | PRAGMA page_size = 1024; |
||
465 | } -cleanup { |
||
466 | db2 eval { |
||
467 | CREATE TABLE abc(a, b, c); |
||
468 | BEGIN; |
||
469 | INSERT INTO abc VALUES(1, 2, 3); |
||
470 | ROLLBACK; |
||
471 | } |
||
472 | db2 close |
||
473 | } |
||
474 | |||
475 | catch {db close} |
||
476 | catch {db2 close} |
||
477 | do_malloc_test shared_err-10 -tclprep { |
||
478 | sqlite3 db test.db |
||
479 | sqlite3 db2 test.db |
||
480 | |||
481 | db eval { SELECT * FROM sqlite_master } |
||
482 | db2 eval { |
||
483 | BEGIN; |
||
484 | CREATE TABLE abc(a, b, c); |
||
485 | } |
||
486 | } -tclbody { |
||
487 | catch {db eval {SELECT * FROM sqlite_master}} |
||
488 | error 1 |
||
489 | } -cleanup { |
||
490 | execsql { SELECT * FROM sqlite_master } |
||
491 | } |
||
492 | |||
493 | do_malloc_test shared_err-11 -tclprep { |
||
494 | sqlite3 db test.db |
||
495 | sqlite3 db2 test.db |
||
496 | |||
497 | db eval { SELECT * FROM sqlite_master } |
||
498 | db2 eval { |
||
499 | BEGIN; |
||
500 | CREATE TABLE abc(a, b, c); |
||
501 | } |
||
502 | } -tclbody { |
||
503 | catch {db eval {SELECT * FROM sqlite_master}} |
||
504 | catch {sqlite3_errmsg16 db} |
||
505 | error 1 |
||
506 | } -cleanup { |
||
507 | execsql { SELECT * FROM sqlite_master } |
||
508 | } |
||
509 | |||
510 | catch {db close} |
||
511 | catch {db2 close} |
||
512 | |||
513 | do_malloc_test shared_err-12 -sqlbody { |
||
514 | CREATE TABLE abc(a, b, c); |
||
515 | INSERT INTO abc VALUES(1, 2, 3); |
||
516 | } |
||
517 | |||
518 | catch {db close} |
||
519 | catch {db2 close} |
||
520 | sqlite3_enable_shared_cache $::enable_shared_cache |
||
521 | finish_test |