1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-15 11:41:13 +03:00

Merge the nx-devkit changes into trunk.

FossilOrigin-Name: 03a70c3dae8d912fccd9d72c575dc372b198d238
This commit is contained in:
drh
2011-12-13 15:37:12 +00:00
7 changed files with 183 additions and 145 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sos_unix.c\sso\sthat,\sunless\s8.3\sfilenames\sare\sactually\sin\suse,\sjournal\sand\swal\sfile\spermissions\sare\sassigned\scorrectly\seven\sif\sSQLITE_ENABLE_8_3_NAMES\sis\sdefined. C Merge\sthe\snx-devkit\schanges\sinto\strunk.
D 2011-12-12T19:48:43.750 D 2011-12-13T15:37:12.235
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07 F Makefile.in 5b4a3e12a850b021547e43daf886b25133b44c07
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -146,8 +146,8 @@ F src/insert.c ea820fe9af748075b3b6827fb6f23f25079bf1f7
F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/loadext.c d0d2022a5a07274d408820b978b9e549189d314f F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
F src/main.c e10d5ad24ae1964d1dc53fbc283557c1c5cd29f3 F src/main.c b4c74ff20abd393b14b3cf7b2130758e2187a5b2
F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03 F src/mem1.c 7998e7003a3047e323c849a26dda004debc04d03
@@ -214,7 +214,7 @@ F src/test_intarray.h 489edb9068bb926583445cb02589344961054207
F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff F src/test_journal.c 03313c693cca72959dcaaf79f8d76f21c01e19ff
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5 F src/test_malloc.c 8d416f29ad8573f32601f6056c9d2b17472e9ad5
F src/test_multiplex.c 7dcf429b53f5f5ef22bba7987bea61234a0c7418 F src/test_multiplex.c 10aaf8b7ebeb74f82d5c96e06c398b776917e457
F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d F src/test_multiplex.h e99c571bc4968b7a9363b661481f3934bfead61d
F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec F src/test_onefile.c 40cf9e212a377a6511469384a64b01e6e34b2eec
@@ -605,8 +605,9 @@ F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5
F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91
F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52 F test/misc7.test eafaa41b9133d7a2ded4641bbe5f340731d35a52
F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
F test/multiplex.test 770f0295dd6673e60458cb93abd033ed2f253291 F test/multiplex.test 8bc3c71f73fe833bc8a659d454d320044a33b5da
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
F test/multiplex3.test cbc0d03da5fcd0c18a33a8973ef1df1b4bc2100a
F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41 F test/mutex1.test 78b2b9bb320e51d156c4efdb71b99b051e7a4b41
F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a F test/nan.test e9648b9d007c7045242af35e11a984d4b169443a
@@ -979,7 +980,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P ee1e012256ae8010b6b6c4895a74b6883f20e73c P 169e12295cca701443746b1209bd6a7714fd8988 2eb79efbff9cdab843b172e9fa9fb400c542fab1
R 6f54deb234c6e01cb7083112d4738ce0 R e5aa0bc552fbb5033b8311d030f5558d
U dan U drh
Z 1fe68808d0e2249c5544c1978ff3d49d Z afe5f3537b446035b4ee9315704cbe8b

View File

@@ -1 +1 @@
169e12295cca701443746b1209bd6a7714fd8988 03a70c3dae8d912fccd9d72c575dc372b198d238

View File

@@ -625,6 +625,7 @@ void sqlite3_reset_auto_extension(void){
void sqlite3AutoLoadExtensions(sqlite3 *db){ void sqlite3AutoLoadExtensions(sqlite3 *db){
int i; int i;
int go = 1; int go = 1;
int rc;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*); int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
wsdAutoextInit; wsdAutoextInit;
@@ -647,8 +648,8 @@ void sqlite3AutoLoadExtensions(sqlite3 *db){
} }
sqlite3_mutex_leave(mutex); sqlite3_mutex_leave(mutex);
zErrmsg = 0; zErrmsg = 0;
if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){ if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
sqlite3Error(db, SQLITE_ERROR, sqlite3Error(db, rc,
"automatic extension loading failed: %s", zErrmsg); "automatic extension loading failed: %s", zErrmsg);
go = 0; go = 0;
} }

View File

@@ -257,6 +257,10 @@ int sqlite3_initialize(void){
*/ */
int sqlite3_shutdown(void){ int sqlite3_shutdown(void){
if( sqlite3GlobalConfig.isInit ){ if( sqlite3GlobalConfig.isInit ){
#ifdef SQLITE_EXTRA_SHUTDOWN
void SQLITE_EXTRA_SHUTDOWN(void);
SQLITE_EXTRA_SHUTDOWN();
#endif
sqlite3_os_end(); sqlite3_os_end();
sqlite3_reset_auto_extension(); sqlite3_reset_auto_extension();
sqlite3GlobalConfig.isInit = 0; sqlite3GlobalConfig.isInit = 0;
@@ -2239,11 +2243,14 @@ static int openDatabase(
/* Load automatic extensions - extensions that have been registered /* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API. ** using the sqlite3_automatic_extension() API.
*/ */
rc = sqlite3_errcode(db);
if( rc==SQLITE_OK ){
sqlite3AutoLoadExtensions(db); sqlite3AutoLoadExtensions(db);
rc = sqlite3_errcode(db); rc = sqlite3_errcode(db);
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
goto opendb_out; goto opendb_out;
} }
}
#ifdef SQLITE_ENABLE_FTS1 #ifdef SQLITE_ENABLE_FTS1
if( !db->mallocFailed ){ if( !db->mallocFailed ){

View File

@@ -213,71 +213,6 @@ static int multiplexStrlen30(const char *z){
return 0x3fffffff & (int)(z2 - z); return 0x3fffffff & (int)(z2 - z);
} }
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at pOrigVfs->mxPathname characters. This function departs
** from the traditional temporary name generation in the os_win
** and os_unix VFS in several ways, but is necessary so that
** the file name is known for temporary files (like those used
** during vacuum.)
**
** N.B. This routine assumes your underlying VFS is ok with using
** "/" as a directory seperator. This is the default for UNIXs
** and is allowed (even mixed) for most versions of Windows.
*/
static int multiplexGetTempname(sqlite3_vfs *pOrigVfs, int nBuf, char *zBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
int i,j;
int attempts = 0;
int exists = 0;
int rc = SQLITE_ERROR;
/* Check that the output buffer is large enough for
** pVfs->mxPathname characters.
*/
if( pOrigVfs->mxPathname <= nBuf ){
char *zTmp = sqlite3_malloc(pOrigVfs->mxPathname);
if( zTmp==0 ) return SQLITE_NOMEM;
/* sqlite3_temp_directory should always be less than
** pVfs->mxPathname characters.
*/
sqlite3_snprintf(pOrigVfs->mxPathname,
zTmp,
"%s/",
sqlite3_temp_directory ? sqlite3_temp_directory : ".");
rc = pOrigVfs->xFullPathname(pOrigVfs, zTmp, nBuf, zBuf);
sqlite3_free(zTmp);
if( rc ) return rc;
/* Check that the output buffer is large enough for the temporary file
** name.
*/
j = multiplexStrlen30(zBuf);
if( (j + 8 + 1 + 3 + 1) <= nBuf ){
/* Make 3 attempts to generate a unique name. */
do {
attempts++;
sqlite3_randomness(8, &zBuf[j]);
for(i=0; i<8; i++){
unsigned char uc = (unsigned char)zBuf[j+i];
zBuf[j+i] = (char)zChars[uc%(sizeof(zChars)-1)];
}
memcpy(&zBuf[j+i], ".tmp", 5);
rc = pOrigVfs->xAccess(pOrigVfs, zBuf, SQLITE_ACCESS_EXISTS, &exists);
} while ( (rc==SQLITE_OK) && exists && (attempts<3) );
if( rc==SQLITE_OK && exists ){
rc = SQLITE_ERROR;
}
}
}
return rc;
}
/* Compute the filename for the iChunk-th chunk /* Compute the filename for the iChunk-th chunk
*/ */
static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
@@ -291,7 +226,7 @@ static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
pGroup->aReal = p; pGroup->aReal = p;
pGroup->nReal = iChunk+1; pGroup->nReal = iChunk+1;
} }
if( pGroup->aReal[iChunk].z==0 ){ if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
char *z; char *z;
int n = pGroup->nName; int n = pGroup->nName;
pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+4 ); pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+4 );
@@ -461,6 +396,7 @@ static int multiplexOpen(
UNUSED_PARAMETER(pVfs); UNUSED_PARAMETER(pVfs);
memset(pConn, 0, pVfs->szOsFile); memset(pConn, 0, pVfs->szOsFile);
assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) );
/* We need to create a group structure and manage /* We need to create a group structure and manage
** access to this group of files. ** access to this group of files.
@@ -468,23 +404,9 @@ static int multiplexOpen(
multiplexEnter(); multiplexEnter();
pMultiplexOpen = (multiplexConn*)pConn; pMultiplexOpen = (multiplexConn*)pConn;
/* If the second argument to this function is NULL, generate a
** temporary file name to use. This will be handled by the
** original xOpen method. We just need to allocate space for
** it.
*/
if( !zName ){
zName = zToFree = sqlite3_malloc( pOrigVfs->mxPathname + 10 );
if( zName==0 ){
rc = SQLITE_NOMEM;
}else{
rc = multiplexGetTempname(pOrigVfs, pOrigVfs->mxPathname, zToFree);
}
}
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
/* allocate space for group */ /* allocate space for group */
nName = multiplexStrlen30(zName); nName = zName ? multiplexStrlen30(zName) : 0;
sz = sizeof(multiplexGroup) /* multiplexGroup */ sz = sizeof(multiplexGroup) /* multiplexGroup */
+ nName + 1; /* zName */ + nName + 1; /* zName */
pGroup = sqlite3_malloc( sz ); pGroup = sqlite3_malloc( sz );
@@ -495,11 +417,13 @@ static int multiplexOpen(
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
/* assign pointers to extra space allocated */ /* assign pointers to extra space allocated */
char *p = (char *)&pGroup[1];
pMultiplexOpen->pGroup = pGroup;
memset(pGroup, 0, sz); memset(pGroup, 0, sz);
pMultiplexOpen->pGroup = pGroup;
pGroup->bEnabled = -1; pGroup->bEnabled = -1;
pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE; pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE;
if( zName ){
char *p = (char *)&pGroup[1];
if( flags & SQLITE_OPEN_URI ){ if( flags & SQLITE_OPEN_URI ){
const char *zChunkSize; const char *zChunkSize;
zChunkSize = sqlite3_uri_parameter(zName, "chunksize"); zChunkSize = sqlite3_uri_parameter(zName, "chunksize");
@@ -518,9 +442,9 @@ static int multiplexOpen(
} }
} }
pGroup->zName = p; pGroup->zName = p;
/* save off base filename, name length, and original open flags */
memcpy(pGroup->zName, zName, nName+1); memcpy(pGroup->zName, zName, nName+1);
pGroup->nName = nName; pGroup->nName = nName;
}
pGroup->flags = flags; pGroup->flags = flags;
rc = multiplexSubFilename(pGroup, 1); rc = multiplexSubFilename(pGroup, 1);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
@@ -796,7 +720,6 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
multiplexConn *p = (multiplexConn*)pConn; multiplexConn *p = (multiplexConn*)pConn;
multiplexGroup *pGroup = p->pGroup; multiplexGroup *pGroup = p->pGroup;
int rc = SQLITE_OK; int rc = SQLITE_OK;
int rc2;
int i; int i;
multiplexEnter(); multiplexEnter();
if( !pGroup->bEnabled ){ if( !pGroup->bEnabled ){
@@ -809,39 +732,33 @@ static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
}else{ }else{
sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;
*pSize = 0; *pSize = 0;
for(i=0; 1; i++){ for(i=0; rc==SQLITE_OK; i++){
sqlite3_file *pSubOpen = 0; sqlite3_file *pSubOpen = 0;
int exists = 0; int exists = 0;
rc = multiplexSubFilename(pGroup, i); rc = multiplexSubFilename(pGroup, i);
if( rc ) break; if( rc!=SQLITE_OK ) break;
if( pGroup->flags & SQLITE_OPEN_DELETEONCLOSE ){ if( pGroup->nReal>i && pGroup->aReal[i].p!=0 ){
exists = pGroup->nReal>=i && pGroup->aReal[i].p!=0; exists = 1;
rc2 = SQLITE_OK; }else if( (pGroup->flags & SQLITE_OPEN_DELETEONCLOSE)==0 ){
}else{ const char *zReal = pGroup->aReal[i].z;
rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z, rc = pOrigVfs->xAccess(pOrigVfs, zReal, SQLITE_ACCESS_EXISTS, &exists);
SQLITE_ACCESS_EXISTS, &exists);
} }
if( rc2==SQLITE_OK && exists){ if( exists==0 ){
/* if it exists, open it */ /* stop at first "gap" or IO error. */
pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
}else{
/* stop at first "gap" */
break; break;
} }
if( pSubOpen ){ if( rc==SQLITE_OK ){
sqlite3_int64 sz; pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); }
if( rc2!=SQLITE_OK ){ assert( pSubOpen || rc!=SQLITE_OK );
rc = rc2; if( rc==SQLITE_OK ){
}else{ sqlite3_int64 sz = 0;
if( sz>pGroup->szChunk ){ rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
if( rc==SQLITE_OK && sz>pGroup->szChunk ){
rc = SQLITE_IOERR_FSTAT; rc = SQLITE_IOERR_FSTAT;
} }
*pSize += sz; *pSize += sz;
} }
}else{
break;
}
} }
} }
multiplexLeave(); multiplexLeave();
@@ -1191,9 +1108,13 @@ static int test_multiplex_dump(
for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){ for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){
pGroupTerm = Tcl_NewObj(); pGroupTerm = Tcl_NewObj();
if( pGroup->zName ){
pGroup->zName[pGroup->nName] = '\0'; pGroup->zName[pGroup->nName] = '\0';
Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_ListObjAppendElement(interp, pGroupTerm,
Tcl_NewStringObj(pGroup->zName, -1)); Tcl_NewStringObj(pGroup->zName, -1));
}else{
Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewObj());
}
Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_ListObjAppendElement(interp, pGroupTerm,
Tcl_NewIntObj(pGroup->nName)); Tcl_NewIntObj(pGroup->nName));
Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_ListObjAppendElement(interp, pGroupTerm,

View File

@@ -14,6 +14,16 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
source $testdir/malloc_common.tcl source $testdir/malloc_common.tcl
# The tests in this file assume that SQLite is compiled without
# ENABLE_8_3_NAMES.
#
ifcapable 8_3_names {
puts -nonewline "SQLite compiled with SQLITE_ENABLE_8_3_NAMES. "
puts "Skipping tests multiplex-*."
finish_test
return
}
set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ] set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ]
set g_max_chunks 32 set g_max_chunks 32

98
test/multiplex3.test Normal file
View File

@@ -0,0 +1,98 @@
# 2011 December 13
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file contains tests for error (IO, OOM etc.) handling when using
# the multiplexor extension with 8.3 filenames.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
set ::testprefix multiplex3
ifcapable !8_3_names {
puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. "
puts "Skipping tests multiplex3-*."
finish_test
return
}
db close
sqlite3_shutdown
sqlite3_config_uri 1
autoinstall_test_functions
sqlite3_multiplex_initialize "" 1
proc destroy_vfs_stack {} {
generic_unregister stack
sqlite3_multiplex_shutdown
}
proc multiplex_delete_db {} {
forcedelete test.db
for {set i 1} {$i <= 1000} {incr i} {
forcedelete test.[format %03d $i]
}
}
# Procs to save and restore the current muliplexed database.
#
proc multiplex_save_db {} {
foreach f [glob -nocomplain sv_test.*] { forcedelete $f }
foreach f [glob -nocomplain test.*] { forcecopy $f "sv_$f" }
}
proc multiplex_restore_db {} {
foreach f [glob -nocomplain test.*] {forcedelete $f}
foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} }
do_test 1.0 {
multiplex_delete_db
sqlite3 db file:test.db?8_3_names=1
sqlite3_multiplex_control db main chunk_size [expr 256*1024]
execsql {
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(randomblob(15), randomblob(2000));
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 2
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 4
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 8
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 16
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 32
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 64
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 128
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 256
INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1; -- 512
}
set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
db close
multiplex_save_db
} {}
do_faultsim_test 1 -prep {
multiplex_restore_db
sqlite3 db file:test.db?8_3_names=1
sqlite3_multiplex_control db main chunk_size [expr 256*1024]
} -body {
execsql "UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0"
} -test {
faultsim_test_result {0 {}}
if {$testrc!=0} {
set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
if {$cksum2 != $::cksum1} { error "data mismatch" }
}
}
catch { db close }
sqlite3_multiplex_shutdown
finish_test