Annotation of embedaddon/sqlite3/test/shared_err.test, revision 1.1

1.1     ! misho       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

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