From: drh Date: Fri, 5 Feb 2016 01:55:27 +0000 (+0000) Subject: Improvements to the way that OOM errors are processed. X-Git-Tag: version-3.11.0~49^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a642b60607e55a2c25f663b472af3609c76b214;p=thirdparty%2Fsqlite.git Improvements to the way that OOM errors are processed. FossilOrigin-Name: c3ef03478a5788c855b3aef385d43ae7f494f440 --- diff --git a/ext/misc/json1.c b/ext/misc/json1.c index e4ea4fb9f0..3c63b6e946 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -343,7 +343,7 @@ static void jsonAppendValue( default: { if( p->bErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); - p->bErr = 1; + p->bErr = 2; jsonReset(p); } break; @@ -1571,7 +1571,7 @@ static void jsonArrayFinal(sqlite3_context *ctx){ pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); if( pStr->bErr ){ - sqlite3_result_error_nomem(ctx); + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else{ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, @@ -1619,7 +1619,7 @@ static void jsonObjectFinal(sqlite3_context *ctx){ if( pStr ){ jsonAppendChar(pStr, '}'); if( pStr->bErr ){ - sqlite3_result_error_nomem(ctx); + if( pStr->bErr==0 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else{ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, diff --git a/manifest b/manifest index 7d7eb20c87..d515b0a7f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Temporarily\sback\sout\sthe\s0.5%\sperformance\simprovement\sfrom\ncheck-in\s[632071bac5ff32].\s\sNeed\sa\smore\selaborate\ssolution\sthat\sworks\nwith\sreentrant\svirtual\stables\sand\sSQL\sfunctions. -D 2016-02-04T19:50:33.284 +C Improvements\sto\sthe\sway\sthat\sOOM\serrors\sare\sprocessed. +D 2016-02-05T01:55:27.277 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -206,7 +206,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 8698ea0ce24bda23bd8ad4a124620d758f92760b +F ext/misc/json1.c a27cf1eca6583f9b6e18abab5c2a9a82c4540ca9 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc @@ -284,9 +284,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c b6e0befc17d69b59c66f4b8a126c05b1ee7ef10a -F src/analyze.c 0043d3e501f04297fed2bb50b488bc08d5c39f36 -F src/attach.c 27743a694df17ca468eee3956126a5d28d2a29ea +F src/alter.c e4a5132e6264e002ab87c268108f416df3f1fb10 +F src/analyze.c 5338dbbc9f12087b38d74234de00907bdf023a92 +F src/attach.c b943546856ac657c702e1a92fb7adcf67c1dc397 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf @@ -294,27 +294,27 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 0b359bcc2316a57acf12f583253974ad22b4654f F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 88ee370118ff7f081f2060ad3fb6c170f9aed7d3 -F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 +F src/build.c dcb55142c4c4293cbec181ef1ae1485ce0bc94d6 +F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c F src/delete.c 33ed87dc0746b1f8ce186f62b608bf40801af9c0 -F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a +F src/expr.c fddb1b19d77730d423ef2c219ae17e10087554ba F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6 -F src/func.c 42b24923328f65849f52f1659efb2a0907ad78fd +F src/fkey.c dc893ee37a21868fcf07e3d941c7663957807ad2 +F src/func.c 86e55fee35b9577e485f47d9dd5c1d34cd513288 F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 3e2462294fc8bc6e46f377ec824ff315e79fc36d +F src/insert.c e3e2811c69318ff62d8a764b01f5a5677d846b1e F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d -F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e +F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b -F src/main.c b686dabe9a7ece9121da87120d5c7bf402d77eb3 -F src/malloc.c b67c26c359c13836d370350b3f43d228dff5b360 +F src/main.c 62b7fe3ed245757d1ff2e6268a7ec0bc30100308 +F src/malloc.c 65168ef91884206bf3fa14a3070e79255561324b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -337,23 +337,23 @@ F src/os_win.c ccf29ddded3e41e506b6bd98c1171aa0963b23f2 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 67cd2fbab58d0e35fed5f81432856f4f0af9fc6d F src/pager.h f3eb324a3ff2408b28bab7e81c1c55c13720f865 -F src/parse.y 426a91fbbbf7cdde3fd4b8798de7317a8782bec5 +F src/parse.y d7bff41d460f2df96fb890f36700e85cb0fc5634 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c 3c4f3fadf05893e289f2adf3a20c671a842cadec +F src/pragma.c 80ee77226d0008d9188356a6cbbe6010866e1bee F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead -F src/printf.c 98a5cef7fc84577ab8a3098cfa48ecfa5a70b9f8 +F src/prepare.c db4ce553dd1f03909a01858a760fa293e0f32ca0 +F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c ea6f3b0c279aa37eb3701792d094673a7ad1bf88 +F src/select.c 07178f2ae1239404874492ba7e3b9a46361ebbbc F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h bf8c17fb55d7cd09b477111212b19d661b134989 +F src/sqliteInt.h e251b755c71c343434bce1e82c6593603c7af364 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -406,31 +406,31 @@ F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 -F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 +F src/tokenize.c 214b783d6138e9f9fbb6b225ce9a376db3b03d42 F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b -F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816 +F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 16ca0c1e2975fac04c3ea5c62b34dc24b13fea13 +F src/vdbe.c 2e49c5d1b8f2f24f91ddd6c6b003d8e7fbbc4e56 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 -F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 -F src/vdbeaux.c 23b38b447ebf5991de1d3d456003c58cf523a5da +F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459 +F src/vdbeaux.c 0e66330ac8ad473bdefde88278725202d0174ae5 F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db -F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 +F src/vdbemem.c 9a6736339ca581f3b9503d5a1a40b7d718ca4635 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde +F src/vtab.c 2cc0b7bb253851c8718b8850dfaed8592b6dc7f8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 +F src/where.c 8bdb43e09d4e7f20bb371154799da39c25b51dfd F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a F src/wherecode.c 791a784bbf8749d560fdb0b990b607bc4f44a38d -F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 +F src/whereexpr.c 85ee2de9ff0fe40a4afaf2a477bd6c9a808548b3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1426,8 +1426,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P c9c6457d8ea911f6cc63967127e58da3146fd3ef -Q -632071bac5ff324a74cec9bdbba2deb60c0945e9 -R c2fbdbab2e50abda4a6e36464c2e90a7 +P 42736fb0adc82a0fb692850ff3dd3f9b501cbf1f +R 1d34f5ef33e19e0d2d7f06ad149ac201 +T *branch * oom-handling +T *sym-oom-handling * +T -sym-trunk * U drh -Z d787da74a7d8bd75c2afcf5547eaa172 +Z a95dbad943095aee523b449d4529a303 diff --git a/manifest.uuid b/manifest.uuid index 902f64f567..a42eab21cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42736fb0adc82a0fb692850ff3dd3f9b501cbf1f \ No newline at end of file +c3ef03478a5788c855b3aef385d43ae7f494f440 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 16b7a9e192..3419059fa2 100644 --- a/src/alter.c +++ b/src/alter.c @@ -695,7 +695,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc!=SQLITE_OK ){ - db->mallocFailed = 1; + assert( db->mallocFailed = 1 ); return; } if( !pVal ){ diff --git a/src/analyze.c b/src/analyze.c index 4d777fa9f5..7a7d68f59a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1523,7 +1523,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ ** the old data with the new instead of allocating a new array. */ if( pIndex->aiRowEst==0 ){ pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); - if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1; + if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); } aiRowEst = pIndex->aiRowEst; #endif @@ -1670,7 +1670,7 @@ static int loadStatTbl( Index *pPrevIdx = 0; /* Previous index in the loop */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ - assert( db->lookaside.bEnabled==0 ); + assert( db->lookaside.bDisable ); zSql = sqlite3MPrintf(db, zSql1, zDb); if( !zSql ){ return SQLITE_NOMEM; @@ -1784,7 +1784,7 @@ static int loadStatTbl( static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ - assert( db->lookaside.bEnabled==0 ); + assert( db->lookaside.bDisable ); if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ rc = loadStatTbl(db, 0, "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", @@ -1866,10 +1866,9 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ - int lookasideEnabled = db->lookaside.bEnabled; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; rc = loadStat4(db, sInfo.zDatabase); - db->lookaside.bEnabled = lookasideEnabled; + db->lookaside.bDisable--; } for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); @@ -1879,7 +1878,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ #endif if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } return rc; } diff --git a/src/attach.c b/src/attach.c index 12d3ac3ff6..e167951f68 100644 --- a/src/attach.c +++ b/src/attach.c @@ -127,7 +127,7 @@ static void attachFunc( flags = db->openFlags; rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); return; @@ -230,7 +230,7 @@ static void attachFunc( sqlite3ResetAllSchemasOfConnection(db); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, zErrDyn); zErrDyn = sqlite3MPrintf(db, "out of memory"); }else if( zErrDyn==0 ){ diff --git a/src/build.c b/src/build.c index cea05d51c7..097149fd4f 100644 --- a/src/build.c +++ b/src/build.c @@ -78,7 +78,7 @@ void sqlite3TableLock( p->zName = zName; }else{ pToplevel->nTableLock = 0; - pToplevel->db->mallocFailed = 1; + sqlite3OomFault(pToplevel->db); } } @@ -1555,7 +1555,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ n += 35 + 6*p->nCol; zStmt = sqlite3DbMallocRaw(0, n); if( zStmt==0 ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return 0; } sqlite3_snprintf(n, zStmt, "CREATE TABLE "); @@ -2038,7 +2038,7 @@ void sqlite3EndTable( pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ - db->mallocFailed = 1; + sqlite3OomFault(db); return; } pParse->pNewTable = 0; @@ -2142,7 +2142,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ sqlite3_xauth xAuth; /* Saved xAuth pointer */ - u8 bEnabledLA; /* Saved db->lookaside.bEnabled state */ assert( pTable ); @@ -2188,18 +2187,18 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** statement that defines the view. */ assert( pTable->pSelect ); - bEnabledLA = db->lookaside.bEnabled; if( pTable->pCheck ){ - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); + db->lookaside.bDisable--; }else{ pSel = sqlite3SelectDup(db, pTable->pSelect, 0); if( pSel ){ n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; @@ -2208,6 +2207,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); #endif + db->lookaside.bDisable--; pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); @@ -2226,7 +2226,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ nErr++; } } - db->lookaside.bEnabled = bEnabledLA; pTable->pSchema->schemaFlags |= DB_UnresetViews; #endif /* SQLITE_OMIT_VIEW */ return nErr; @@ -2692,7 +2691,7 @@ void sqlite3CreateForeignKey( pFKey->zTo, (void *)pFKey ); if( pNextTo==pFKey ){ - db->mallocFailed = 1; + sqlite3OomFault(db); goto fk_end; } if( pNextTo ){ @@ -3274,7 +3273,7 @@ Index *sqlite3CreateIndex( pIndex->zName, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ - db->mallocFailed = 1; + sqlite3OomFault(db); goto exit_create_index; } db->flags |= SQLITE_InternChanges; @@ -3992,7 +3991,7 @@ int sqlite3OpenTempDatabase(Parse *pParse){ db->aDb[1].pBt = pBt; assert( db->aDb[1].pSchema ); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return 1; } } diff --git a/src/callback.c b/src/callback.c index 2a9f5b802a..2b955fdcdb 100644 --- a/src/callback.c +++ b/src/callback.c @@ -177,7 +177,7 @@ static CollSeq *findCollSeqEntry( */ assert( pDel==0 || pDel==pColl ); if( pDel!=0 ){ - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, pDel); pColl = 0; } @@ -465,7 +465,7 @@ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); } if( !p ){ - db->mallocFailed = 1; + sqlite3OomFault(db); }else if ( 0==p->file_format ){ sqlite3HashInit(&p->tblHash); sqlite3HashInit(&p->idxHash); diff --git a/src/expr.c b/src/expr.c index c91db2834f..5b134d6661 100644 --- a/src/expr.c +++ b/src/expr.c @@ -699,7 +699,10 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ if( x>pParse->nzVar ){ char **a; a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); - if( a==0 ) return; /* Error reported through db->mallocFailed */ + if( a==0 ){ + assert( db->mallocFailed ); /* Error reported through mallocFailed */ + return; + } pParse->azVar = a; memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); pParse->nzVar = x; diff --git a/src/fkey.c b/src/fkey.c index 7eb188924d..fae25c4828 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1165,7 +1165,6 @@ static Trigger *fkActionTrigger( pTrigger = pFKey->apTrigger[iAction]; if( action!=OE_None && !pTrigger ){ - u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ char const *zFrom; /* Name of child table */ int nFrom; /* Length in bytes of zFrom */ Index *pIdx = 0; /* Parent key index for this FK */ @@ -1274,8 +1273,7 @@ static Trigger *fkActionTrigger( } /* Disable lookaside memory allocation */ - enableLookaside = db->lookaside.bEnabled; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ @@ -1297,7 +1295,7 @@ static Trigger *fkActionTrigger( } /* Re-enable the lookaside buffer, if it was disabled earlier. */ - db->lookaside.bEnabled = enableLookaside; + db->lookaside.bDisable--; sqlite3ExprDelete(db, pWhere); sqlite3ExprDelete(db, pWhen); diff --git a/src/func.c b/src/func.c index 982a8c2caa..d615cf90b1 100644 --- a/src/func.c +++ b/src/func.c @@ -1615,7 +1615,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ int rc = sqlite3_overload_function(db, "MATCH", 2); assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } } diff --git a/src/insert.c b/src/insert.c index 5f36c089f6..a8cde72954 100644 --- a/src/insert.c +++ b/src/insert.c @@ -83,7 +83,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ Table *pTab = pIdx->pTable; pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return 0; } for(n=0; nnColumn; n++){ @@ -134,7 +134,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ sqlite3 *db = sqlite3VdbeDb(v); zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return; } diff --git a/src/legacy.c b/src/legacy.c index a10006e558..1b5e518d43 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -90,7 +90,7 @@ int sqlite3_exec( for(i=0; imallocFailed = 1; + sqlite3OomFault(db); goto exec_out; } } diff --git a/src/main.c b/src/main.c index 63a105c3f0..588461b48a 100644 --- a/src/main.c +++ b/src/main.c @@ -698,12 +698,12 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; - db->lookaside.bEnabled = 1; + db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ db->lookaside.pStart = db; db->lookaside.pEnd = db; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable = 1; db->lookaside.bMalloced = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ @@ -2208,7 +2208,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){ ** be cleared before returning. Do this directly, instead of via ** sqlite3ApiExit(), to avoid setting the database handle error message. */ - db->mallocFailed = 0; + sqlite3OomClear(db); } sqlite3_mutex_leave(db->mutex); return z; @@ -2846,7 +2846,7 @@ static int openDatabase( db->openFlags = flags; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); sqlite3_free(zErrMsg); goto opendb_out; diff --git a/src/malloc.c b/src/malloc.c index c8a04128cf..057d36a4be 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -608,10 +608,8 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ #ifndef SQLITE_OMIT_LOOKASIDE if( db ){ LookasideSlot *pBuf; - if( db->mallocFailed ){ - return 0; - } - if( db->lookaside.bEnabled ){ + if( db->lookaside.bDisable==0 ){ + assert( db->mallocFailed==0 ); if( n>db->lookaside.sz ){ db->lookaside.anStat[1]++; }else if( (pBuf = db->lookaside.pFree)==0 ){ @@ -625,7 +623,10 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ } return (void*)pBuf; } + }else if( db->mallocFailed ){ + return 0; } + } #else if( db && db->mallocFailed ){ @@ -637,10 +638,10 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ void *p = sqlite3Malloc(n); if( !p && db ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } sqlite3MemdebugSetType(p, - (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); + (db && db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); return p; } @@ -671,10 +672,10 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ sqlite3MemdebugSetType(p, MEMTYPE_HEAP); pNew = sqlite3_realloc64(p, n); if( !pNew ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } sqlite3MemdebugSetType(pNew, - (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); + (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); } } return pNew; @@ -736,11 +737,43 @@ void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ *pz = sqlite3DbStrDup(db, zNew); } +/* +** Call this routine to record the fact that an OOM (out-of-memory) error +** has happened. This routine will set db->mallocFailed, and also +** temporarily disable the lookaside memory allocator and interrupt +** any running VDBEs. +*/ +void sqlite3OomFault(sqlite3 *db){ + if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ + db->mallocFailed = 1; + if( db->nVdbeExec>0 ){ + db->u1.isInterrupted = 1; + } + db->lookaside.bDisable++; + } +} + +/* +** This routine reactivates the memory allocator and clears the +** db->mallocFailed flag as necessary. +** +** The memory allocator is not restarted if there are running +** VDBEs. +*/ +void sqlite3OomClear(sqlite3 *db){ + if( db->mallocFailed && db->nVdbeExec==0 ){ + db->mallocFailed = 0; + db->u1.isInterrupted = 0; + assert( db->lookaside.bDisable>0 ); + db->lookaside.bDisable--; + } +} + /* ** Take actions at the end of an API call to indicate an OOM error */ static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ - db->mallocFailed = 0; + sqlite3OomClear(db); sqlite3Error(db, SQLITE_NOMEM); return SQLITE_NOMEM; } diff --git a/src/parse.y b/src/parse.y index 846c2504b7..0bfe4e473a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -106,6 +106,15 @@ struct TrigEvent { int a; IdList * b; }; */ struct AttachKey { int type; Token key; }; +/* +** Disable lookaside memory allocation for objects that might be +** shared across database connections. +*/ +static void disableLookaside(Parse *pParse){ + pParse->disableLookaside++; + pParse->db->lookaside.bDisable++; +} + } // end %include // Input is a single SQL command @@ -156,7 +165,7 @@ create_table ::= createkw temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). { sqlite3StartTable(pParse,&Y,&Z,T,0,0,E); } createkw(A) ::= CREATE(X). { - pParse->db->lookaside.bEnabled = 0; + disableLookaside(pParse); A = X; } %type ifnotexists {int} @@ -1507,7 +1516,7 @@ cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column(Y). { sqlite3AlterFinishAddColumn(pParse, &Y); } add_column_fullname ::= fullname(X). { - pParse->db->lookaside.bEnabled = 0; + disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, X); } kwcolumn_opt ::= . diff --git a/src/pragma.c b/src/pragma.c index bde17d1e86..c34d5421c2 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -478,7 +478,7 @@ void sqlite3Pragma( */ db->nextPagesize = sqlite3Atoi(zRight); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } } break; diff --git a/src/prepare.c b/src/prepare.c index f8ad54665a..3fb71a770e 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -32,7 +32,7 @@ static void corruptSchema( if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra); sqlite3DbFree(db, *pData->pzErrMsg); *pData->pzErrMsg = z; - if( z==0 ) db->mallocFailed = 1; + if( z==0 ) sqlite3OomFault(db); } pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; } @@ -91,7 +91,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } @@ -336,7 +336,7 @@ initone_error_out: error_out: if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } return rc; } @@ -434,7 +434,7 @@ static void schemaIsValid(Parse *pParse){ if( !sqlite3BtreeIsInReadTrans(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } if( rc!=SQLITE_OK ) return; openedTransaction = 1; @@ -497,6 +497,11 @@ void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; sqlite3DbFree(db, pParse->aLabel); sqlite3ExprListDelete(db, pParse->pConstExpr); + if( db ){ + assert( db->lookaside.bDisable >= pParse->disableLookaside ); + db->lookaside.bDisable -= pParse->disableLookaside; + } + pParse->disableLookaside = 0; } } @@ -592,9 +597,6 @@ static int sqlite3Prepare( } assert( 0==pParse->nQueryLoop ); - if( db->mallocFailed ){ - pParse->rc = SQLITE_NOMEM; - } if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; if( pParse->checkSchema ){ schemaIsValid(pParse); @@ -716,7 +718,7 @@ int sqlite3Reprepare(Vdbe *p){ rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); if( rc ){ if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } assert( pNew==0 ); return rc; diff --git a/src/printf.c b/src/printf.c index 946161f64c..238997f37d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -929,7 +929,7 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ sqlite3VXPrintf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); if( acc.accError==STRACCUM_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } return z; } diff --git a/src/select.c b/src/select.c index 891b123543..84d5423de6 100644 --- a/src/select.c +++ b/src/select.c @@ -1016,7 +1016,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ p->nRef = 1; memset(&p[1], 0, nExtra); }else{ - db->mallocFailed = 1; + sqlite3OomFault(db); } return p; } @@ -1677,7 +1677,7 @@ int sqlite3ColumnsFromExprList( pCol->zName = zName; sqlite3ColumnPropertiesFromName(0, pCol); if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } } sqlite3HashClear(&ht); @@ -1764,7 +1764,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ } /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside ** is disabled */ - assert( db->lookaside.bEnabled==0 ); + assert( db->lookaside.bDisable ); pTab->nRef = 1; pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); @@ -5562,7 +5562,8 @@ int sqlite3Select( if( flag ){ pMinMax = sqlite3ExprListDup(db, pMinMax, 0); pDel = pMinMax; - if( pMinMax && !db->mallocFailed ){ + assert( db->mallocFailed || pMinMax!=0 ); + if( !db->mallocFailed ){ pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; pMinMax->a[0].pExpr->op = TK_COLUMN; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 16d3ea9921..70f210c0a2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1094,8 +1094,8 @@ struct Schema { ** lookaside allocations are not used to construct the schema objects. */ struct Lookaside { + u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ - u8 bEnabled; /* False to disable new lookaside allocations */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ int nOut; /* Number of buffers currently checked out */ int mxOut; /* Highwater mark for nOut */ @@ -1178,6 +1178,7 @@ struct sqlite3 { u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ + u8 bBenignMalloc; /* Do not require OOMs if true */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ @@ -2733,6 +2734,7 @@ struct Parse { u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ + u8 disableLookaside; /* Number of times lookaside has been disabled */ int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ @@ -3777,6 +3779,8 @@ int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), FuncDestructor *pDestructor ); +void sqlite3OomFault(sqlite3*); +void sqlite3OomClear(sqlite3*); int sqlite3ApiExit(sqlite3 *db, int); int sqlite3OpenTempDatabase(Parse *); diff --git a/src/tokenize.c b/src/tokenize.c index b85e35dc10..5bee3d5a84 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -390,7 +390,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ void *pEngine; /* The LEMON-generated LALR(1) parser */ int tokenType; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ - u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ @@ -406,7 +405,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ /* sqlite3ParserTrace(stdout, "parser: "); */ pEngine = sqlite3ParserAlloc(sqlite3Malloc); if( pEngine==0 ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return SQLITE_NOMEM; } assert( pParse->pNewTable==0 ); @@ -414,8 +413,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->nVar==0 ); assert( pParse->nzVar==0 ); assert( pParse->azVar==0 ); - enableLookaside = db->lookaside.bEnabled; - if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; while( zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; @@ -428,7 +425,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); if( db->u1.isInterrupted ){ - sqlite3ErrorMsg(pParse, "interrupt"); pParse->rc = SQLITE_INTERRUPT; break; } @@ -463,7 +459,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ sqlite3ParserFree(pEngine, sqlite3_free); - db->lookaside.bEnabled = enableLookaside; if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } diff --git a/src/trigger.c b/src/trigger.c index 4bfb55af69..72c31eb2a3 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -323,7 +323,7 @@ void sqlite3FinishTrigger( assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTrig = sqlite3HashInsert(pHash, zName, pTrig); if( pTrig ){ - db->mallocFailed = 1; + sqlite3OomFault(db); }else if( pLink->pSchema==pLink->pTabSchema ){ Table *pTab; pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); diff --git a/src/vdbe.c b/src/vdbe.c index 62ad86d4f3..c0eff6a09f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -629,7 +629,6 @@ int sqlite3VdbeExec( #endif for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ assert( pOp>=aOp && pOp<&aOp[p->nOp]); - if( db->mallocFailed ) goto no_mem; #ifdef VDBE_PROFILE start = sqlite3Hwtime(); #endif @@ -6785,7 +6784,7 @@ vdbe_error_halt: sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); - if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); rc = SQLITE_ERROR; if( resetSchemaOnFault>0 ){ sqlite3ResetOneSchema(db, resetSchemaOnFault-1); @@ -6815,7 +6814,7 @@ too_big: /* Jump to here if a malloc() fails. */ no_mem: - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3VdbeError(p, "out of memory"); rc = SQLITE_NOMEM; goto vdbe_error_halt; @@ -6836,7 +6835,7 @@ abort_due_to_error: */ abort_due_to_interrupt: assert( db->u1.isInterrupted ); - rc = SQLITE_INTERRUPT; + rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_INTERRUPT; p->rc = rc; sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); goto vdbe_error_halt; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 0a15633ddf..fce43630e7 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -473,7 +473,7 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM; pCtx->fErrorOrAux = 1; - pCtx->pOut->db->mallocFailed = 1; + sqlite3OomFault(pCtx->pOut->db); } /* @@ -1101,7 +1101,7 @@ static const void *columnName( ** is the case, clear the mallocFailed flag and return NULL. */ if( db->mallocFailed ){ - db->mallocFailed = 0; + sqlite3OomClear(db); ret = 0; } sqlite3_mutex_leave(db->mutex); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 632c1231aa..7d3a8c4293 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1423,7 +1423,6 @@ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; - u8 malloc_failed = db->mallocFailed; if( db->pnBytesFreed ){ do{ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); @@ -1459,7 +1458,6 @@ static void releaseMemArray(Mem *p, int N){ p->flags = MEM_Undefined; }while( (++p)mallocFailed = malloc_failed; } } @@ -1520,7 +1518,7 @@ int sqlite3VdbeList( if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ - db->mallocFailed = 1; + sqlite3OomFault(db); return SQLITE_ERROR; } @@ -2711,12 +2709,12 @@ int sqlite3VdbeTransferError(Vdbe *p){ sqlite3 *db = p->db; int rc = p->rc; if( p->zErrMsg ){ - u8 mallocFailed = db->mallocFailed; + db->bBenignMalloc++; sqlite3BeginBenignMalloc(); if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3EndBenignMalloc(); - db->mallocFailed = mallocFailed; + db->bBenignMalloc--; db->errCode = rc; }else{ sqlite3Error(db, rc); diff --git a/src/vdbemem.c b/src/vdbemem.c index 0eeb59ef85..974b990747 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1381,7 +1381,7 @@ static int valueFromExpr( return rc; no_mem: - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, zVal); assert( *ppVal==0 ); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 diff --git a/src/vtab.c b/src/vtab.c index ea79cd8cef..ca444944f4 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -62,7 +62,7 @@ static int createModule( pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); assert( pDel==0 || pDel==pMod ); if( pDel ){ - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, pDel); } } @@ -439,7 +439,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); if( pOld ){ - db->mallocFailed = 1; + sqlite3OomFault(db); assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } @@ -530,7 +530,7 @@ static int vtabCallConstructor( db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = sCtx.pPrior; - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); assert( sCtx.pTab==pTab ); if( SQLITE_OK!=rc ){ @@ -1088,7 +1088,7 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ pToplevel->apVtabLock = apVtabLock; pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; }else{ - pToplevel->db->mallocFailed = 1; + sqlite3OomFault(pToplevel->db); } } diff --git a/src/where.c b/src/where.c index 8c8dfbb7b6..d3a4ab87e4 100644 --- a/src/where.c +++ b/src/where.c @@ -943,7 +943,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ - pParse->db->mallocFailed = 1; + sqlite3OomFault(pParse->db); }else if( !pVtab->zErrMsg ){ sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); }else{ diff --git a/src/whereexpr.c b/src/whereexpr.c index e0b8bac1b7..ec244bcb46 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -563,7 +563,6 @@ static void exprAnalyzeOrTerm( sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); sqlite3WhereExprAnalyze(pSrc, pAndWC); pAndWC->pOuter = pWC; - testcase( db->mallocFailed ); if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ assert( pAndTerm->pExpr );