-C Add\sthe\sSQLITE_MAX_WORKER_THREADS\scompile\stime\soption.\sAnd\sthe\sSQLITE_CONFIG_WORKER_THREADS\ssqlite3_config()\sswitch.
-D 2014-03-31T19:57:34.075
+C Fix\sa\sproblem\swith\sOOM\shandling\sin\sthe\ssorter\scode.
+D 2014-04-01T10:19:02.635
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ad0921c4b2780d01868cf69b419a4f102308d125
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
-F src/btree.c a59a199f21338ae1847d69f5db87c3e8ef1b1578
+F src/btree.c 0d1be67448c45eccc40114556186397eb9da7f7d
F src/btree.h 232836cb51753f2e96aa8ce0f052c6df850f76ba
F src/btreeInt.h 0be66063468a520e4d66b80c7a1dc26d04ee6ea4
F src/build.c 0d50ef95aad63f4c4fc47f3fa2670d4557c45db0
F src/sqlite.h.in 0249af5d9d3bbeab0dc1f58e1f9fee878807732a
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 7f42c2792b951db22fa189bbed828a5e3b38789c
+F src/sqliteInt.h 3ed0fedb5b64ece395a2114b7c73417678f3e420
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c e87c99e28a145943666b51b212dacae35fcea0bd
-F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299
+F src/test1.c 31596bf8a9c0629f88e514a4ec864847c8946c4e
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F src/vdbe.h 394464909ed682334aa3d5831aae0c2fe2abef94
F src/vdbeInt.h e6d83e5bfd62fc6685ba1ed6153f7099f82de9f7
F src/vdbeapi.c 0ed6053f947edd0b30f64ce5aeb811872a3450a4
-F src/vdbeaux.c 1153175fb57a8454e1c8cf79b59b7bf92b26779d
+F src/vdbeaux.c d8dc38965507a34b0e150c0d7fc82b02f8cf25ea
F src/vdbeblob.c 15377abfb59251bccedd5a9c7d014a895f0c04aa
F src/vdbemem.c 6fc77594c60f6155404f3f8d71bf36d1fdeb4447
-F src/vdbesort.c b4d6133bada297e118492420346f83cd76c6da31
+F src/vdbesort.c 35c270630fa5af14791fc6abc70024d1aeeaac0e
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 76e7fc6de229bea8b30bb2539110f03a494dc3a8
F test/lookaside.test 93f07bac140c5bb1d49f3892d2684decafdc7af2
F test/main.test 39c4bb8a157f57298ed1659d6df89d9f35aaf2c8
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
-F test/malloc.test fd368e31fe98d4779ed80442f311ed9f03bcd1f7
+F test/malloc.test 26ae08a09cc15a98d147ee63925e3a66048e71c9
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test fafce0aa9157060445cd1a56ad50fc79d82f28c3
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 18d1b402f2dbe78f1a1113bb356b710e348365ef
-R 8b3347b8372cc17a3226330524ab6da6
+P 2774710df8cd2bfaca49888c69f1b01c0ddadf9a
+R a6fe6d7d652069432584e1a691602cb5
U dan
-Z 11cb5db8cbfdddf6047ddaf9c26850df
+Z ac080311c2ad2c3d7bf733448ffc0f03
-2774710df8cd2bfaca49888c69f1b01c0ddadf9a
\ No newline at end of file
+59cd5229e2b5be5272cf57c7e7d09e97d16a5425
\ No newline at end of file
if( pIdxKey ){
xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
- pIdxKey->isCorrupt = 0;
+ pIdxKey->errCode = 0;
assert( pIdxKey->default_rc==1
|| pIdxKey->default_rc==0
|| pIdxKey->default_rc==-1
c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
sqlite3_free(pCellKey);
}
- assert( pIdxKey->isCorrupt==0 || c==0 );
+ assert(
+ (pIdxKey->errCode!=SQLITE_CORRUPT || c==0)
+ && (pIdxKey->errCode!=SQLITE_NOMEM || !pCur->pBtree->db->mallocFailed)
+ );
if( c<0 ){
lwr = idx+1;
}else if( c>0 ){
*pRes = 0;
rc = SQLITE_OK;
pCur->aiIdx[pCur->iPage] = (u16)idx;
- if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT;
+ if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
goto moveto_finish;
}
if( lwr>upr ) break;
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
- u8 isCorrupt; /* Corruption detected by xRecordCompare() */
+ u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
Mem *aMem; /* Values */
int r1; /* Value to return if (lhs > rhs) */
int r2; /* Value to return if (rhs < lhs) */
return TCL_ERROR;
}
+/*
+** Usage: add_test_utf16bin_collate <db ptr>
+**
+** Add a utf-16 collation sequence named "utf16bin" to the database
+** handle. This collation sequence compares arguments in the same way as the
+** built-in collation "binary".
+*/
+static int test_utf16bin_collate_func(
+ void *pCtx,
+ int nA, const void *zA,
+ int nB, const void *zB
+){
+ int nCmp = (nA>nB ? nB : nA);
+ int res = memcmp(zA, zB, nCmp);
+ if( res==0 ) res = nA - nB;
+ return res;
+}
+static int test_utf16bin_collate(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ sqlite3 *db;
+ int rc;
+
+ if( objc!=2 ) goto bad_args;
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+
+ rc = sqlite3_create_collation(db, "utf16bin", SQLITE_UTF16, 0,
+ test_utf16bin_collate_func
+ );
+ if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
+ return TCL_OK;
+
+bad_args:
+ Tcl_WrongNumArgs(interp, 1, objv, "DB");
+ return TCL_ERROR;
+}
+
/*
** When the collation needed callback is invoked, record the name of
** the requested collating function here. The recorded name is linked
{ "add_test_collate", test_collate, 0 },
{ "add_test_collate_needed", test_collate_needed, 0 },
{ "add_test_function", test_function, 0 },
+ { "add_test_utf16bin_collate", test_utf16bin_collate, 0 },
#endif
{ "sqlite3_test_errstr", test_errstr, 0 },
{ "tcl_variable_type", tcl_variable_type, 0 },
static int vdbeCompareMemString(
const Mem *pMem1,
const Mem *pMem2,
- const CollSeq *pColl
+ const CollSeq *pColl,
+ u8 *prcErr /* If an OOM occurs, set to SQLITE_NOMEM */
){
if( pMem1->enc==pColl->enc ){
/* The strings are already in the correct encoding. Call the
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
+ if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
return rc;
}
}
assert( !pColl || pColl->xCmp );
if( pColl ){
- return vdbeCompareMemString(pMem1, pMem2, pColl);
+ return vdbeCompareMemString(pMem1, pMem2, pColl, 0);
}
/* If a NULL pointer was passed as the collate function, fall through
** to the blob case and use memcmp(). */
** fields that appear in both keys are equal, then pPKey2->default_rc is
** returned.
**
-** If database corruption is discovered, set pPKey2->isCorrupt to non-zero
-** and return 0.
+** If database corruption is discovered, set pPKey2->errCode to
+** SQLITE_CORRUPT and return 0. If an OOM error is encountered,
+** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
+** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
*/
int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
if( d1>(unsigned)nKey1 ){
- pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}
i = 0;
testcase( (d1+mem1.n)==(unsigned)nKey1 );
testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
if( (d1+mem1.n) > (unsigned)nKey1 ){
- pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}else if( pKeyInfo->aColl[i] ){
mem1.enc = pKeyInfo->enc;
mem1.db = pKeyInfo->db;
mem1.flags = MEM_Str;
mem1.z = (char*)&aKey1[d1];
- rc = vdbeCompareMemString(&mem1, pRhs, pKeyInfo->aColl[i]);
+ rc = vdbeCompareMemString(
+ &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode
+ );
}else{
int nCmp = MIN(mem1.n, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
testcase( (d1+nStr)==(unsigned)nKey1 );
testcase( (d1+nStr+1)==(unsigned)nKey1 );
if( (d1+nStr) > (unsigned)nKey1 ){
- pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}else{
int nCmp = MIN(nStr, pRhs->n);
if( pKeyInfo->aSortOrder[i] ){
rc = -rc;
}
- assert( CORRUPT_DB
+ assert( CORRUPT_DB || pKeyInfo->db==0
|| (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
|| (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
|| pKeyInfo->db->mallocFailed
nStr = (serial_type-12) / 2;
if( (szHdr + nStr) > nKey1 ){
- pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
}
nCmp = MIN( pPKey2->aMem[0].n, nStr );
goto thread_out;
}
pThread->pUnpacked->nField = pThread->pKeyInfo->nField;
+ pThread->pUnpacked->errCode = 0;
}
if( pThread->eWork==SORTER_THREAD_CONS ){
thread_out:
pThread->bDone = 1;
+ if( rc==SQLITE_OK && pThread->pUnpacked->errCode ){
+ assert( pThread->pUnpacked->errCode==SQLITE_NOMEM );
+ rc = SQLITE_NOMEM;
+ }
return SQLITE_INT_TO_PTR(rc);
}
}
if( rc==SQLITE_OK ){
- int bUseFg = (bFg || i==(pSorter->nThread-1));
-
assert( pThread->pThread==0 && pThread->bDone==0 );
pThread->eWork = SORTER_THREAD_TO_PMA;
pThread->pList = pSorter->pRecord;
}
#if SQLITE_MAX_WORKER_THREADS>0
- if( bUseFg==0 ){
+ if( bFg || i==(pSorter->nThread-1) ){
/* Launch a background thread for this operation */
void *pCtx = (void*)pThread;
assert( pSorter->aMemory==0 || pThread->aListMemory!=0 );
db close
}
+reset_db
+add_test_utf16bin_collate db
+do_execsql_test 40.1 {
+ CREATE TABLE t1(a);
+ INSERT INTO t1 VALUES('fghij');
+ INSERT INTO t1 VALUES('pqrst');
+ INSERT INTO t1 VALUES('abcde');
+ INSERT INTO t1 VALUES('uvwxy');
+ INSERT INTO t1 VALUES('klmno');
+}
+do_execsql_test 40.2 {
+ SELECT * FROM t1 ORDER BY 1 COLLATE utf16bin;
+} {abcde fghij klmno pqrst uvwxy}
+do_faultsim_test 40.3 -faults oom-trans* -body {
+ execsql {
+ SELECT * FROM t1 ORDER BY 1 COLLATE utf16bin;
+ }
+} -test {
+ faultsim_test_result {0 {abcde fghij klmno pqrst uvwxy}}
+ faultsim_integrity_check
+}
+
# Ensure that no file descriptors were leaked.
do_test malloc-99.X {
catch {db close}