Some elements of the new malloc() failure handling. Not all cases work properly yet. Also, library is not threadsafe if malloc() fails right now. (CVS 2800)

FossilOrigin-Name: e1606658f1b4530e3001db4779b5669c8d13c853
This commit is contained in:
danielk1977 2005-12-06 12:52:59 +00:00
parent 67e0b84f7d
commit 261919cc16
30 changed files with 446 additions and 267 deletions

View File

@ -1,5 +1,5 @@
C Update\smailing\slist\shyperlink\son\sthe\ssupport\spage.\s(CVS\s2799)
D 2005-12-05T22:22:40
C Some\selements\sof\sthe\snew\smalloc()\sfailure\shandling.\sNot\sall\scases\swork\sproperly\syet.\sAlso,\slibrary\sis\snot\sthreadsafe\sif\smalloc()\sfails\sright\snow.\s(CVS\s2800)
D 2005-12-06T12:52:59
F Makefile.in e3c6b3a38d734d41574c04f2fc90d18de2b87102
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -30,68 +30,68 @@ F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.def c413e514217736884254739a105c8c942fdf0c2f
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
F src/alter.c 149e871e1ad6648da9b72e69feb1bd1407bf5226
F src/alter.c 7ed4b794c2e3a8ad8c1effe50202eaef42cedc23
F src/analyze.c ea42005eed52c382fcc7ef66969e7f1858597633
F src/attach.c 4b21689700a72ae281fa85dbaff06b2a62bd49ee
F src/attach.c 8c3e09452be967e005a016299a110ed8ee33606a
F src/auth.c 31e2304bef67f44d635655f44234387ea7d21454
F src/btree.c aa88194f460becf8fff6196996d6e38f1b37286e
F src/btree.h 1ed561263ca0e335bc3e81d761c9d5ff8c22f61e
F src/build.c 8c93ae10563e8b92d3d7ea532a606424be3cb4f7
F src/callback.c 90ab4f235a2603c4cb8e6a2497091a71fb732bfa
F src/build.c 41350367dc5837b0dafa83cbd5bf08f0108031b0
F src/callback.c 4bc404e9912eecb28be1235581833f6269920c27
F src/complete.c 4de937dfdd4c79a501772ab2035b26082f337a79
F src/date.c 8bc8d084a17d19c44d9cbf357b5f656db6706ce1
F src/delete.c 29dac493f4d83b05f91233b116827c133bcdab72
F src/delete.c 6010a081edda9871895260def092e852f0bb60a0
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
F src/expr.c 80ceb8c7d15dd53985831f0b4c660b3c3df796a3
F src/expr.c 540ed7eb44b79e5603c3656466bf1d7381abcfc7
F src/func.c 7d81dccd9c440c6c4e761056333e629192814af0
F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c da031c3ed8e1675fac891990095d277c2ba6e205
F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
F src/main.c 7d719efe04b760c5e0faa9e910c6d4f00f85f2f3
F src/insert.c 5393479164f317ea0aeec954c6500cafa097ef33
F src/legacy.c 7b88d20efc8e6c208f262d97aee9c8e2cf02bc91
F src/main.c 2babbdbc5f0ad8a4dc9152b27ba3436b55572a2d
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.c bdd3a2fd089777e7ad18b57c896f1141d5a0c1fd
F src/os.h d5ae3f4c1c7731437b6cddec279b7c06f761c44e
F src/os_common.h d74a11728ad2444b6b695b94c28c06881f049e49
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
F src/os_unix.c 1a7278bf7ad95f8c62a946d6b1726a539ab5e790
F src/os_unix.c 76189e4cb5e1ad451293ce1aeb348c3b829e7e13
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
F src/os_win.c d962ac2dd0e482847e42b846d46cd044f97d1c32
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
F src/pager.c bcb54653c3020d7cde88b4e8bad81ff6f93402b4
F src/pager.c 893cb2106261a4f77d84c1fa0d10a083e889b23b
F src/pager.h e7b41ce8e7b5f629d456708b7ad9a8c8ede37140
F src/parse.y e4d57c2fd5cc02f19822ec41f6dc2bfc9bc85609
F src/pragma.c 2793699ab0d73fa730fa8c1c7521e9436604f024
F src/prepare.c fc098db25d2a121affb08686cf04833fd50452d4
F src/prepare.c e93967011379051316728d316755f533a9bb438c
F src/printf.c 3ea3a17d25d7ac498efc18007c70371a42c968f8
F src/random.c ff5e9a8cad790e2a51cd4d2e7737dc8540e09d1d
F src/select.c 4a9e5366f4a16bd2e6e93c05f585633887be6372
F src/select.c 0e4d3627fec4a445b45f6cb471f68aab9c97a8b3
F src/shell.c 3596c1e559b82663057940d19ba533ad421c7dd3
F src/sqlite.h.in 8e648e1f386e4509f2f96c09ded7c07b0df0c9a2
F src/sqliteInt.h 4148c9778e350014c2e27b332d7a2ef7278fe62e
F src/sqliteInt.h 71dc0f753e9a646d9c9b3b6b5bb9d2fcc2dad9e5
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
F src/tclsqlite.c a497c3adfd2c85da6a934331ec0041e47884fbcb
F src/test1.c 3d1803af3232fbe29c1902735a7eadd5b4598ffe
F src/test1.c 0b4bf8ab9afb37f34a83c46f81de54adf519b23d
F src/test2.c 36390cdfc70c08e5ee0b466d0654a117f398bbff
F src/test3.c f4e6a16a602091696619a1171bda25c0e3df49f7
F src/test4.c a8fd681e139e1c61f22a77d07fc3a99cb28fff3f
F src/test5.c 64f08b2a50ef371a1bd68ff206829e7b1b9997f5
F src/test6.c cb811391ec0b7c75f29e545d4820a9cf19f3637e
F src/tokenize.c bdb79702217af49eba44c2a3b4f5fc7bd9ed2917
F src/trigger.c aea0283a3ef729a3e9c8dc5dc1a11c9fcc0a12a7
F src/update.c fec7665138ccf2a2133f11dcd24c1134c6b33526
F src/tokenize.c a189d7466524076220f41a21baed05e1639a82f4
F src/trigger.c 388c13a2f07584decdb88413a63017391f9a7f7a
F src/update.c ec8e540617b116725b5a55c8d6b4db8bc67fdd7d
F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
F src/util.c 48fecbbef4391d102a23096d32f0d74173428406
F src/vacuum.c c9fe2660919bd1595a7fbdeddadc16c7d9723400
F src/vdbe.c 91b91272446d0a62b2d27d330d6a1a622acfb0fb
F src/util.c 88ebafb5708f04002e58a373386e3c8c31bfd858
F src/vacuum.c b99062005217f72568c4023390e0331e1b4568b3
F src/vdbe.c 7f4a2affee140b7b57952ab2c081a9c22b950638
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
F src/vdbeInt.h 0055c37eccbf3a189fd893a90f8eb6a5fa60c871
F src/vdbeapi.c 73d56a8899d46cf0353e32a85aa1ff7f36cb24ea
F src/vdbeaux.c 0c4af4af29d42a7f008c7562afee58b470dd6d4a
F src/vdbeapi.c 4fd33e87aa6cbd77e59da142e1df67ec0430225f
F src/vdbeaux.c 90143aaffbe232a700fd05e4b2e7428d512b605b
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
F src/vdbemem.c cd9609c1e7f71ec76d9840c84c3a57ebfa6539cf
F src/where.c a9fed5a5b549f5dae1aa95dc9463cd1f35efa0f1
F src/where.c c0882f2d42e636f78fb45b9279e2739d4291e6ab
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
@ -177,8 +177,8 @@ F test/lock.test 9b7afcb24f53d24da502abb33daaad2cd6d44107
F test/lock2.test d83ba79d3c4fffdb5b926c7d8ca7a36c34288a55
F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
F test/main.test b12f01d49a5c805a33fa6c0ef168691f63056e79
F test/malloc.test 666c77a878ce50f5c22b9211ed43e889cabb63a6
F test/malloc2.test 655b972372d2754a3f6c6ed54d7cfd18fde9bd32
F test/malloc.test a5ed721cf7d1b12602ede4f98c11b65ab1582cc0
F test/malloc2.test e6e321db96d6c94cb18bf82ad7215070c41e624e
F test/manydb.test d81debbf5871242e3b5df1d3bb5e14c50431b6f8
F test/memdb.test 1860e060be810bf0775bc57408a5b7c4954bcaea
F test/memleak.test df2b2b96e77f8ba159a332299535b1e5f18e49ac
@ -204,7 +204,7 @@ F test/reindex.test 38b138abe36bf9a08c791ed44d9f76cd6b97b78b
F test/rollback.test 94cd981ee3a627d9f6466f69dcf1f7dbfe695d7a
F test/rowid.test 040a3bef06f970c45f5fcd14b2355f7f4d62f0cf
F test/safety.test 907b64fee719554a3622853812af3886fddbbb4f
F test/schema.test 21cbe7dac652f6d7eb058f3dec369bdbf46bbde6
F test/schema.test 8a2ae440fb15f5798a68059e8746402f3137be46
F test/select1.test 480233d4f5a81d7d59a55e40d05084d97e57ecdf
F test/select2.test f3c2678c3a9f3cf08ec4988a3845bda64be6d9e3
F test/select3.test 8fece41cd8f2955131b3f973a7123bec60b6e65e
@ -260,7 +260,7 @@ F tool/lemon.c 26d271a753ef87fe1e6194f53c594ab5e6783d85
F tool/lempar.c 424df14a48736bb961ed47acf30c26d66ed85a62
F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
F tool/memleak3.tcl 009da0ea82dc5893edca76cf1a21fb7260e9412e
F tool/memleak3.tcl 7707006ee908cffff210c98158788d85bb3fcdbf
F tool/mkkeywordhash.c 5263a654e5c9fd8d6e3238fb39c2d5c3126be32f
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
@ -324,7 +324,7 @@ F www/tclsqlite.tcl ddcf912ea48695603c8ed7efb29f0812ef8d1b49
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P 9d6057cd141e7cdaf32ce68dea39e67c2c67a08d
R dd2af97c916f976a63f6fe8ff108d90a
U drh
Z d032ae7a997d740a148585b12b585af9
P 41a7aeeeb427d59e3d7cc71c94a8c5be832bd0fa
R ce02aa0c65608cead49ff0e73829ca6c
U danielk1977
Z 3b6d26a30c726439418b3a6a9650fe3d

View File

@ -1 +1 @@
41a7aeeeb427d59e3d7cc71c94a8c5be832bd0fa
e1606658f1b4530e3001db4779b5669c8d13c853

View File

@ -12,7 +12,7 @@
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
** $Id: alter.c,v 1.9 2005/10/20 07:28:18 drh Exp $
** $Id: alter.c,v 1.10 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -258,7 +258,7 @@ void sqlite3AlterRenameTable(
char *zWhere = 0; /* Where clause to locate temp triggers */
#endif
if( sqlite3_malloc_failed ) goto exit_rename_table;
if( sqlite3Tsd()->mallocFailed ) goto exit_rename_table;
assert( pSrc->nSrc==1 );
pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
@ -504,7 +504,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
/* Look up the table being altered. */
assert( pParse->pNewTable==0 );
if( sqlite3_malloc_failed ) goto exit_begin_add_column;
if( sqlite3Tsd()->mallocFailed ) goto exit_begin_add_column;
pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
if( !pTab ) goto exit_begin_add_column;

View File

@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.34 2005/08/20 03:03:04 drh Exp $
** $Id: attach.c,v 1.35 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -150,6 +150,7 @@ void sqlite3Attach(
if( pParse->rc==SQLITE_OK ){
pParse->rc = SQLITE_ERROR;
}
db->nDb = i;
}
attach_end:

View File

@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
** $Id: build.c,v 1.355 2005/11/14 22:29:05 drh Exp $
** $Id: build.c,v 1.356 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -50,7 +50,7 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3 *db;
Vdbe *v;
if( sqlite3_malloc_failed ) return;
if( sqlite3Tsd()->mallocFailed ) return;
if( pParse->nested ) return;
if( !pParse->pVdbe ){
if( pParse->rc==SQLITE_OK && pParse->nErr ){
@ -1296,7 +1296,9 @@ void sqlite3EndTable(
Table *p;
sqlite3 *db = pParse->db;
if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3_malloc_failed ) return;
if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite3Tsd()->mallocFailed ) {
return;
}
p = pParse->pNewTable;
if( p==0 ) return;
@ -1522,6 +1524,9 @@ void sqlite3CreateView(
*/
p->pSelect = sqlite3SelectDup(pSelect);
sqlite3SelectDelete(pSelect);
if( sqlite3Tsd()->mallocFailed ){
return;
}
if( !pParse->db->init.busy ){
sqlite3ViewGetColumnNames(pParse, p);
}
@ -1592,24 +1597,28 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
*/
assert( pTable->pSelect );
pSel = sqlite3SelectDup(pTable->pSelect);
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
pParse->nTab = n;
if( pSelTab ){
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite3DeleteTable(0, pSelTab);
DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
}else{
pTable->nCol = 0;
if( pSel ){
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel);
pParse->nTab = n;
if( pSelTab ){
assert( pTable->aCol==0 );
pTable->nCol = pSelTab->nCol;
pTable->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite3DeleteTable(0, pSelTab);
DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
}else{
pTable->nCol = 0;
nErr++;
}
sqlite3SelectDelete(pSel);
} else {
nErr++;
}
sqlite3SelectDelete(pSel);
return nErr;
}
#endif /* SQLITE_OMIT_VIEW */
@ -1749,7 +1758,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){
sqlite3 *db = pParse->db;
int iDb;
if( pParse->nErr || sqlite3_malloc_failed ) goto exit_drop_table;
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto exit_drop_table;
assert( pName->nSrc==1 );
pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);
@ -2098,7 +2107,7 @@ void sqlite3CreateIndex(
int iDb; /* Index of the database that is being written */
Token *pName = 0; /* Unqualified name of the index to create */
if( pParse->nErr || sqlite3_malloc_failed ) goto exit_create_index;
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto exit_create_index;
/*
** Find the table that is to be indexed. Return early if not found.
@ -2226,7 +2235,7 @@ void sqlite3CreateIndex(
*/
pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + sizeof(int) +
(sizeof(int)*2 + sizeof(CollSeq*))*pList->nExpr );
if( sqlite3_malloc_failed ) goto exit_create_index;
if( sqlite3Tsd()->mallocFailed ) goto exit_create_index;
pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr];
pIndex->aiRowEst = (unsigned*)&pIndex->aiColumn[pList->nExpr];
pIndex->zName = (char*)&pIndex->aiRowEst[pList->nExpr+1];
@ -2472,7 +2481,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){
Vdbe *v;
sqlite3 *db = pParse->db;
if( pParse->nErr || sqlite3_malloc_failed ){
if( pParse->nErr || sqlite3Tsd()->mallocFailed ){
goto exit_drop_index;
}
assert( pName->nSrc==1 );
@ -2679,11 +2688,14 @@ SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
int i;
struct SrcList_item *pItem;
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->iCursor>=0 ) break;
pItem->iCursor = pParse->nTab++;
if( pItem->pSelect ){
sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
assert(pList || sqlite3Tsd()->mallocFailed);
if( pList ){
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
if( pItem->iCursor>=0 ) break;
pItem->iCursor = pParse->nTab++;
if( pItem->pSelect ){
sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc);
}
}
}
}
@ -2725,7 +2737,7 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
int i;
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
if( pParse->nErr || sqlite3_malloc_failed ) return;
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) return;
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
v = sqlite3GetVdbe(pParse);
@ -2746,7 +2758,7 @@ void sqlite3CommitTransaction(Parse *pParse){
Vdbe *v;
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
if( pParse->nErr || sqlite3_malloc_failed ) return;
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) return;
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
v = sqlite3GetVdbe(pParse);
@ -2763,7 +2775,7 @@ void sqlite3RollbackTransaction(Parse *pParse){
Vdbe *v;
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
if( pParse->nErr || sqlite3_malloc_failed ) return;
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) return;
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
v = sqlite3GetVdbe(pParse);

View File

@ -13,7 +13,7 @@
** This file contains functions used to access the internal hash tables
** of user defined functions and collation sequences.
**
** $Id: callback.c,v 1.4 2005/10/20 07:28:18 drh Exp $
** $Id: callback.c,v 1.5 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -175,7 +175,7 @@ static CollSeq *findCollSeqEntry(
** return the pColl pointer to be deleted (because it wasn't added
** to the hash table).
*/
assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) );
assert( !pDel || (sqlite3Tsd()->mallocFailed && pDel==pColl) );
sqliteFree(pDel);
}
}

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.111 2005/09/20 17:42:23 drh Exp $
** $Id: delete.c,v 1.112 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -102,7 +102,7 @@ void sqlite3DeleteFrom(
#endif
sContext.pParse = 0;
if( pParse->nErr || sqlite3_malloc_failed ){
if( pParse->nErr || sqlite3Tsd()->mallocFailed ){
goto delete_from_cleanup;
}
db = pParse->db;

View File

@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.240 2005/11/29 03:13:22 drh Exp $
** $Id: expr.c,v 1.241 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -263,7 +263,7 @@ Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
assert( pRight!=0 );
assert( pLeft!=0 );
if( !sqlite3_malloc_failed && pRight->z && pLeft->z ){
if( !sqlite3Tsd()->mallocFailed && pRight->z && pLeft->z ){
assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
if( pLeft->dyn==0 && pRight->dyn==0 ){
pExpr->span.z = pLeft->z;
@ -358,7 +358,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
sqlite3ReallocOrFree((void**)&pParse->apVarExpr,
pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
}
if( !sqlite3_malloc_failed ){
if( !sqlite3Tsd()->mallocFailed ){
assert( pParse->apVarExpr!=0 );
pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
}
@ -462,7 +462,7 @@ ExprList *sqlite3ExprListDup(ExprList *p){
sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
}
assert( pNewExpr==0 || pNewExpr->span.z!=0
|| pOldExpr->span.z==0 || sqlite3_malloc_failed );
|| pOldExpr->span.z==0 || sqlite3Tsd()->mallocFailed );
pItem->zName = sqliteStrDup(pOldItem->zName);
pItem->sortOrder = pOldItem->sortOrder;
pItem->isAgg = pOldItem->isAgg;
@ -831,7 +831,7 @@ static int lookupName(
zDb = sqlite3NameFromToken(pDbToken);
zTab = sqlite3NameFromToken(pTableToken);
zCol = sqlite3NameFromToken(pColumnToken);
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
goto lookupname_end;
}
@ -1305,7 +1305,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
int mem = pParse->nMem++;
sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
assert( testAddr>0 || sqlite3_malloc_failed );
assert( testAddr>0 || sqlite3Tsd()->mallocFailed );
sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
}

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.149 2005/11/24 13:15:33 drh Exp $
** $Id: insert.c,v 1.150 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -224,7 +224,7 @@ void sqlite3Insert(
int counterRowid; /* Memory cell holding rowid of autoinc counter */
#endif
if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto insert_cleanup;
db = pParse->db;
/* Locate the table into which we will be inserting new information.
@ -338,7 +338,7 @@ void sqlite3Insert(
/* Resolve the expressions in the SELECT statement and execute it. */
rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup;
if( rc || pParse->nErr || sqlite3Tsd()->mallocFailed ) goto insert_cleanup;
iCleanup = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);

View File

@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: legacy.c,v 1.7 2004/09/06 17:34:13 drh Exp $
** $Id: legacy.c,v 1.8 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -122,7 +122,7 @@ exec_out:
if( pStmt ) sqlite3_finalize(pStmt);
if( azCols ) sqliteFree(azCols);
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
rc = SQLITE_NOMEM;
}
if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){

View File

@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.304 2005/11/30 03:20:31 drh Exp $
** $Id: main.c,v 1.305 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -635,7 +635,7 @@ int sqlite3BtreeFactory(
*/
const char *sqlite3_errmsg(sqlite3 *db){
const char *z;
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
return sqlite3ErrStr(SQLITE_NOMEM);
}
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
@ -674,7 +674,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
};
const void *z;
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
}
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
@ -694,7 +694,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
** Return the most recent error code generated by an SQLite routine.
*/
int sqlite3_errcode(sqlite3 *db){
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
return SQLITE_NOMEM;
}
if( sqlite3SafetyCheck(db) ){
@ -742,8 +742,7 @@ static int openDatabase(
if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) ||
sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) ||
(db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0))==0 ){
rc = db->errCode;
assert( rc!=SQLITE_OK );
assert(rc!=SQLITE_OK || sqlite3Tsd()->mallocFailed);
db->magic = SQLITE_MAGIC_CLOSED;
goto opendb_out;
}
@ -786,7 +785,7 @@ static int openDatabase(
db->magic = SQLITE_MAGIC_OPEN;
opendb_out:
if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){
if( sqlite3_errcode(db)==SQLITE_OK && sqlite3Tsd()->mallocFailed ){
sqlite3Error(db, SQLITE_NOMEM, 0);
}
*ppDb = db;
@ -1010,12 +1009,13 @@ int sqlite3_collation_needed16(
** dangerous and will almost certainly result in malfunctions.
*/
int sqlite3_global_recover(){
#if 0
int rc = SQLITE_OK;
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
sqlite3 *db;
int i;
sqlite3_malloc_failed = 0;
sqlite3Tsd()->mallocFailed = 0;
for(db=pDbList; db; db=db->pNext ){
sqlite3ExpirePreparedStatements(db);
for(i=0; i<db->nDb; i++){
@ -1030,9 +1030,11 @@ int sqlite3_global_recover(){
recover_out:
if( rc!=SQLITE_OK ){
sqlite3_malloc_failed = 1;
sqlite3Tsd()->mallocFailed = 1;
}
return rc;
#endif
return SQLITE_OK;
}
#endif

View File

@ -689,6 +689,7 @@ static int unixOpenReadOnly(const char *zFilename, OsFile **pId){
}
f.locktype = 0;
TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename);
return allocateUnixFile(&f, pId);
}

View File

@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.222 2005/11/30 03:20:31 drh Exp $
** @(#) $Id: pager.c,v 1.223 2005/12/06 12:52:59 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@ -1598,7 +1598,7 @@ int sqlite3pager_open(
*ppPager = 0;
memset(&fd, 0, sizeof(fd));
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
return SQLITE_NOMEM;
}
if( zFilename && zFilename[0] ){
@ -2413,7 +2413,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){
+ sizeof(u32) + pPager->nExtra
+ MEMDB*sizeof(PgHistory) );
if( pPg==0 ){
pPager->errMask |= PAGER_ERR_MEM;
// pPager->errMask |= PAGER_ERR_MEM;
return SQLITE_NOMEM;
}
memset(pPg, 0, sizeof(*pPg));
@ -2692,7 +2692,7 @@ static int pager_open_journal(Pager *pPager){
if( pPager->stmtAutoopen && rc==SQLITE_OK ){
rc = sqlite3pager_stmt_begin(pPager);
}
if( rc!=SQLITE_OK ){
if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
rc = pager_unwritelock(pPager);
if( rc==SQLITE_OK ){
rc = SQLITE_FULL;
@ -2703,8 +2703,17 @@ static int pager_open_journal(Pager *pPager){
failed_to_open_journal:
sqliteFree(pPager->aInJournal);
pPager->aInJournal = 0;
sqlite3OsUnlock(pPager->fd, NO_LOCK);
pPager->state = PAGER_UNLOCK;
if( rc==SQLITE_NOMEM ){
/* If this was a malloc() failure, then we will not be closing the pager
** file. So delete any journal file we may have just created. Otherwise,
** the system will get confused, we have a read-lock on the file and a
** mysterious journal has appeared in the filesystem.
*/
sqlite3Os.xDelete(pPager->zJournal);
}else{
sqlite3OsUnlock(pPager->fd, NO_LOCK);
pPager->state = PAGER_UNLOCK;
}
return rc;
}
@ -3270,7 +3279,7 @@ int sqlite3pager_stmt_begin(Pager *pPager){
assert( pPager->journalOpen );
pPager->aInStmt = sqliteMalloc( pPager->dbSize/8 + 1 );
if( pPager->aInStmt==0 ){
sqlite3OsLock(pPager->fd, SHARED_LOCK);
/* sqlite3OsLock(pPager->fd, SHARED_LOCK); */
return SQLITE_NOMEM;
}
#ifndef NDEBUG

View File

@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
** $Id: prepare.c,v 1.4 2005/09/10 16:46:13 drh Exp $
** $Id: prepare.c,v 1.5 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -24,7 +24,7 @@
** that the database is corrupt.
*/
static void corruptSchema(InitData *pData, const char *zExtra){
if( !sqlite3_malloc_failed ){
if( !sqlite3Tsd()->mallocFailed ){
sqlite3SetString(pData->pzErrMsg, "malformed database schema",
zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
}
@ -71,7 +71,11 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
db->init.iDb = 0;
if( SQLITE_OK!=rc ){
corruptSchema(pData, zErr);
if( rc==SQLITE_NOMEM ){
sqlite3Tsd()->mallocFailed = 1;
}else{
corruptSchema(pData, zErr);
}
sqlite3_free(zErr);
return rc;
}
@ -301,7 +305,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
#endif
sqlite3BtreeCloseCursor(curMain);
}
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
rc = SQLITE_NOMEM;
sqlite3ResetInternalSchema(db, 0);
@ -425,9 +429,7 @@ int sqlite3_prepare(
char *zErrMsg = 0;
int rc = SQLITE_OK;
if( sqlite3_malloc_failed ){
return SQLITE_NOMEM;
}
assert(!sqlite3Tsd()->mallocFailed);
assert( ppStmt );
*ppStmt = 0;
@ -439,12 +441,14 @@ int sqlite3_prepare(
sParse.db = db;
sqlite3RunParser(&sParse, zSql, &zErrMsg);
if( sqlite3_malloc_failed ){
rc = SQLITE_NOMEM;
if( sqlite3Tsd()->mallocFailed ){
sParse.rc = SQLITE_NOMEM;
#if 0
sqlite3RollbackInternalChanges(db);
sqlite3RollbackAll(db);
sqlite3ResetInternalSchema(db, 0);
db->flags &= ~SQLITE_InTrans;
goto prepare_out;
db->autoCommit = 1;
#endif
}
if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
if( sParse.rc!=SQLITE_OK && sParse.checkSchema && !schemaIsValid(db) ){
@ -490,6 +494,16 @@ prepare_out:
}else{
sqlite3Error(db, rc, 0);
}
/* We must check for malloc failure last of all, in case malloc() failed
** inside of the sqlite3Error() call above or something.
*/
if( sqlite3Tsd()->mallocFailed ){
rc = SQLITE_NOMEM;
sqlite3Error(db, rc, 0);
}
sqlite3ClearMallocFailed();
return rc;
}

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.280 2005/11/16 13:47:51 drh Exp $
** $Id: select.c,v 1.281 2005/12/06 12:52:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -155,7 +155,7 @@ static int columnIndex(Table *pTab, const char *zCol){
*/
static void setToken(Token *p, const char *z){
p->z = z;
p->n = strlen(z);
p->n = z ? strlen(z) : 0;
p->dyn = 0;
}
@ -856,7 +856,7 @@ static void generateColumnNames(
#endif
assert( v!=0 );
if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return;
if( pParse->colNamesSet || v==0 || sqlite3Tsd()->mallocFailed ) return;
pParse->colNamesSet = 1;
fullNames = (db->flags & SQLITE_FullColNames)!=0;
shortNames = (db->flags & SQLITE_ShortColNames)!=0;
@ -984,7 +984,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
zName = sqlite3MPrintf("column%d", i+1);
}
sqlite3Dequote(zName);
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
sqliteFree(zName);
sqlite3DeleteTable(0, pTab);
return 0;
@ -1056,7 +1056,7 @@ static int prepSelectStmt(Parse *pParse, Select *p){
Table *pTab;
struct SrcList_item *pFrom;
if( p==0 || p->pSrc==0 || sqlite3_malloc_failed ) return 1;
if( p==0 || p->pSrc==0 || sqlite3Tsd()->mallocFailed ) return 1;
pTabList = p->pSrc;
pEList = p->pEList;
@ -1164,7 +1164,11 @@ static int prepSelectStmt(Parse *pParse, Select *p){
/* This particular expression does not need to be expanded.
*/
pNew = sqlite3ExprListAppend(pNew, a[k].pExpr, 0);
pNew->a[pNew->nExpr-1].zName = a[k].zName;
if( pNew ){
pNew->a[pNew->nExpr-1].zName = a[k].zName;
}else{
rc = 1;
}
a[k].pExpr = 0;
a[k].zName = 0;
}else{
@ -2639,7 +2643,7 @@ int sqlite3Select(
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1;
if( sqlite3Tsd()->mallocFailed || pParse->nErr || p==0 ) return 1;
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
memset(&sAggInfo, 0, sizeof(sAggInfo));
@ -2893,7 +2897,7 @@ int sqlite3Select(
goto select_end;
}
}
if( sqlite3_malloc_failed ) goto select_end;
if( sqlite3Tsd()->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
** much more complex tha aggregates without a GROUP BY.

View File

@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.428 2005/11/14 22:29:05 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.429 2005/12/06 12:52:59 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@ -263,12 +263,6 @@ struct BusyHandler {
# define sqliteStrNDup sqlite3StrNDup
#endif
/*
** This variable gets set if malloc() ever fails. After it gets set,
** the SQLite library shuts down permanently.
*/
extern int sqlite3_malloc_failed;
/*
** The following global variables are used for testing and debugging
** only. They only work if SQLITE_DEBUG is defined.
@ -1385,6 +1379,14 @@ typedef struct {
char **pzErrMsg; /* Error message stored here */
} InitData;
/*
** An instance of this structure is allocated for each thread that uses SQLite.
*/
typedef struct SqliteTsd SqliteTsd;
struct SqliteTsd {
int mallocFailed; /* True after a malloc() has failed */
};
/*
* This global flag is set for performance testing of triggers. When it is set
* SQLite will perform the overhead of building new and old trigger references
@ -1674,6 +1676,8 @@ void sqlite3AnalysisLoad(sqlite3*,int iDB);
void sqlite3DefaultRowEst(Index*);
void sqlite3RegisterLikeFunctions(sqlite3*, int);
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
SqliteTsd *sqlite3Tsd();
void sqlite3ClearMallocFailed();
#ifdef SQLITE_SSE
#include "sseInt.h"

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.170 2005/12/05 13:20:02 drh Exp $
** $Id: test1.c,v 1.171 2005/12/06 12:53:00 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@ -787,7 +787,7 @@ static int sqlite3_mprintf_hexdouble(
** first failure will continue to fail on every call. If REPEAT-INTERVAL is
** 2 then every other malloc will fail. And so forth.
**
** Turn off this mechanism and reset the sqlite3_malloc_failed variable is N==0.
** Turn off this mechanism and reset the sqlite3Tsd()->mallocFailed variable is N==0.
*/
#ifdef SQLITE_MEMDEBUG
static int sqlite_malloc_fail(
@ -810,7 +810,7 @@ static int sqlite_malloc_fail(
}
sqlite3_iMallocFail = n;
sqlite3_iMallocReset = rep;
sqlite3_malloc_failed = 0;
sqlite3Tsd()->mallocFailed = 0;
return TCL_OK;
}
#endif
@ -952,7 +952,7 @@ static int test_finalize(
/*
** Usage: sqlite3_reset STMT
**
** Finalize a statement handle.
** Reset a statement handle.
*/
static int test_reset(
void * clientData,
@ -972,12 +972,15 @@ static int test_reset(
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
rc = sqlite3_reset(pStmt);
if( pStmt &&
sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( pStmt && sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ){
return TCL_ERROR;
}
Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
/*
if( rc ){
return TCL_ERROR;
}
*/
return TCL_OK;
}

View File

@ -15,7 +15,7 @@
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.108 2005/10/23 11:29:40 drh Exp $
** $Id: tokenize.c,v 1.109 2005/12/06 12:53:00 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -348,7 +348,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
i = 0;
pEngine = sqlite3ParserAlloc((void*(*)(int))sqlite3MallocX);
if( pEngine==0 ){
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
return SQLITE_NOMEM;
}
assert( pParse->sLastToken.dyn==0 );
@ -359,7 +358,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
assert( pParse->nVarExprAlloc==0 );
assert( pParse->apVarExpr==0 );
pParse->zTail = pParse->zSql = zSql;
while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
while( sqlite3Tsd()->mallocFailed==0 && zSql[i]!=0 ){
assert( i>=0 );
pParse->sLastToken.z = &zSql[i];
assert( pParse->sLastToken.dyn==0 );
@ -407,12 +406,11 @@ abort_parse:
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
}
sqlite3ParserFree(pEngine, sqlite3FreeX);
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
pParse->rc = SQLITE_NOMEM;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc),
(char*)0);
sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
}
if( pParse->zErrMsg ){
if( pzErrMsg && *pzErrMsg==0 ){

View File

@ -80,14 +80,14 @@ void sqlite3BeginTrigger(
** If sqlite3SrcListLookup() returns 0, indicating the table does not
** exist, the error is caught by the block below.
*/
if( !pTableName || sqlite3_malloc_failed ) goto trigger_cleanup;
if( !pTableName || sqlite3Tsd()->mallocFailed ) goto trigger_cleanup;
pTab = sqlite3SrcListLookup(pParse, pTableName);
if( pName2->n==0 && pTab && pTab->iDb==1 ){
iDb = 1;
}
/* Ensure the table name matches database name and that the table exists */
if( sqlite3_malloc_failed ) goto trigger_cleanup;
if( sqlite3Tsd()->mallocFailed ) goto trigger_cleanup;
assert( pTableName->nSrc==1 );
if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) &&
sqlite3FixSrcList(&sFix, pTableName) ){
@ -250,7 +250,7 @@ void sqlite3FinishTrigger(
pDel = sqlite3HashInsert(&db->aDb[pTrig->iDb].trigHash,
pTrig->name, strlen(pTrig->name)+1, pTrig);
if( pDel ){
assert( sqlite3_malloc_failed && pDel==pTrig );
assert( sqlite3Tsd()->mallocFailed && pDel==pTrig );
goto triggerfinish_cleanup;
}
pTab = sqlite3LocateTable(pParse,pTrig->table,db->aDb[pTrig->iTabDb].zName);
@ -430,7 +430,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
int nName;
sqlite3 *db = pParse->db;
if( sqlite3_malloc_failed ) goto drop_trigger_cleanup;
if( sqlite3Tsd()->mallocFailed ) goto drop_trigger_cleanup;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto drop_trigger_cleanup;
}

View File

@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.113 2005/11/14 22:29:05 drh Exp $
** $Id: update.c,v 1.114 2005/12/06 12:53:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -99,7 +99,7 @@ void sqlite3Update(
int oldIdx = -1; /* index of trigger "old" temp table */
sContext.pParse = 0;
if( pParse->nErr || sqlite3_malloc_failed ) goto update_cleanup;
if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto update_cleanup;
db = pParse->db;
assert( pTabList->nSrc==1 );

View File

@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.148 2005/10/20 07:28:19 drh Exp $
** $Id: util.c,v 1.149 2005/12/06 12:53:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@ -37,11 +37,13 @@ void print_stack_trace(){
#define print_stack_trace()
#endif
#if 0
/*
** If malloc() ever fails, this global variable gets set to 1.
** This causes the library to abort and never again function.
*/
int sqlite3_malloc_failed = 0;
int sqlite3Tsd()->mallocFailed = 0;
#endif
/*
** If SQLITE_MEMDEBUG is defined, then use versions of malloc() and
@ -81,7 +83,7 @@ static int simulatedMallocFailure(int n, char *zFile, int line){
if( sqlite3_iMallocFail>=0 ){
sqlite3_iMallocFail--;
if( sqlite3_iMallocFail==0 ){
sqlite3_malloc_failed++;
sqlite3Tsd()->mallocFailed++;
#if SQLITE_MEMDEBUG>1
fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
n, zFile,line);
@ -101,6 +103,19 @@ void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){
void *p;
int *pi;
int i, k;
/* Any malloc() calls between a malloc() failure and clearing the
** mallocFailed flag (done before returning control to the user)
** automatically fail. Although this restriction may have to be relaxed in
** the future, for now it makes the system easier to test.
**
** TODO: This will eventually be done as part of the same wrapper that may
** call sqlite3_release_memory(). Above the sqlite3OsMalloc() level.
*/
if( sqlite3Tsd()->mallocFailed ){
return 0;
}
if( n==0 ){
return 0;
}
@ -112,7 +127,7 @@ void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){
k = (n+sizeof(int)-1)/sizeof(int);
pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
if( pi==0 ){
if( n>0 ) sqlite3_malloc_failed++;
if( n>0 ) sqlite3Tsd()->mallocFailed++;
return 0;
}
sqlite3_nMalloc++;
@ -228,7 +243,7 @@ void *sqlite3Realloc_(void *oldP, int n, char *zFile, int line){
k = (n + sizeof(int) - 1)/sizeof(int);
pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
if( pi==0 ){
if( n>0 ) sqlite3_malloc_failed++;
if( n>0 ) sqlite3Tsd()->mallocFailed++;
return 0;
}
for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
@ -294,7 +309,7 @@ void *sqlite3Malloc(int n){
void *p;
if( n==0 ) return 0;
if( (p = malloc(n))==0 ){
if( n>0 ) sqlite3_malloc_failed++;
if( n>0 ) sqlite3Tsd()->mallocFailed++;
}else{
memset(p, 0, n);
}
@ -309,7 +324,7 @@ void *sqlite3MallocRaw(int n){
void *p;
if( n==0 ) return 0;
if( (p = malloc(n))==0 ){
if( n>0 ) sqlite3_malloc_failed++;
if( n>0 ) sqlite3Tsd()->mallocFailed++;
}
return p;
}
@ -339,7 +354,7 @@ void *sqlite3Realloc(void *p, int n){
}
p2 = realloc(p, n);
if( p2==0 ){
if( n>0 ) sqlite3_malloc_failed++;
if( n>0 ) sqlite3Tsd()->mallocFailed++;
}
return p2;
}
@ -1007,3 +1022,18 @@ void *sqlite3TextToPtr(const char *z){
return p;
}
#endif
/*
** Return a pointer to the SqliteTsd associated with the calling thread.
*/
static SqliteTsd tsd = { 0 };
SqliteTsd *sqlite3Tsd(){
return &tsd;
}
void sqlite3ClearMallocFailed(){
sqlite3Tsd()->mallocFailed = 0;
}

View File

@ -14,7 +14,7 @@
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.49 2005/11/30 03:20:32 drh Exp $
** $Id: vacuum.c,v 1.50 2005/12/06 12:53:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -170,7 +170,10 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain),
sqlite3BtreeGetReserve(pMain));
assert( sqlite3BtreeGetPageSize(pTemp)==sqlite3BtreeGetPageSize(pMain) );
execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
rc = execSql(db, "PRAGMA vacuum_db.synchronous=OFF");
if( rc!=SQLITE_OK ){
goto end_of_vacuum;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
sqlite3BtreeSetAutoVacuum(pTemp, sqlite3BtreeGetAutoVacuum(pMain));
@ -284,6 +287,14 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
}
end_of_vacuum:
/* If one of the execSql() calls above returned SQLITE_NOMEM, then the
** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()).
** Fix this so the flag and return code match.
*/
if( rc==SQLITE_NOMEM ){
sqlite3Tsd()->mallocFailed = 1;
}
/* Restore the original value of db->flags */
db->flags = saved_flags;
@ -295,9 +306,18 @@ end_of_vacuum:
** is closed by the DETACH.
*/
db->autoCommit = 1;
rc2 = execSql(db, "DETACH vacuum_db;");
if( rc==SQLITE_OK ){
rc = rc2;
/* TODO: We need to detach vacuum_db (if it is attached) even if malloc()
** failed. Right now trying to do so will cause an assert() to fail in **
**_prepare() (because it should be impossible to call _prepare() with the **
** mallocFailed flag set). So really, we need to be able to detach a database
** without calling malloc(). Which seems plausible.
*/
if( !sqlite3Tsd()->mallocFailed ){
rc2 = execSql(db, "DETACH vacuum_db;");
if( rc==SQLITE_OK ){
rc = rc2;
}
}
if( zTemp ){
sqlite3Os.xDelete(zTemp);

View File

@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.501 2005/11/30 03:20:32 drh Exp $
** $Id: vdbe.c,v 1.502 2005/12/06 12:53:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -394,7 +394,7 @@ int sqlite3VdbeExec(
p->rc = SQLITE_OK;
assert( p->explain==0 );
pTos = p->pTos;
if( sqlite3_malloc_failed ) goto no_mem;
if( sqlite3Tsd()->mallocFailed ) goto no_mem;
if( p->popStack ){
popStack(&pTos, p->popStack);
p->popStack = 0;
@ -405,7 +405,7 @@ int sqlite3VdbeExec(
for(pc=p->pc; rc==SQLITE_OK; pc++){
assert( pc>=0 && pc<p->nOp );
assert( pTos<=&p->aStack[pc] );
if( sqlite3_malloc_failed ) goto no_mem;
if( sqlite3Tsd()->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
origPc = pc;
start = hwtime();
@ -1135,7 +1135,7 @@ case OP_Function: {
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
(*ctx.pFunc->xFunc)(&ctx, n, apVal);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( sqlite3_malloc_failed ) goto no_mem;
if( sqlite3Tsd()->mallocFailed ) goto no_mem;
popStack(&pTos, n);
/* If any auxilary data functions have been called by this user function,
@ -3113,7 +3113,10 @@ case OP_NewRowid: {
if( pC->nextRowidValid ){
v = pC->nextRowid;
}else{
rx = sqlite3BtreeLast(pC->pCursor, &res);
rc = sqlite3BtreeLast(pC->pCursor, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
if( res ){
v = 1;
}else{
@ -3893,9 +3896,14 @@ case OP_ParseSchema: { /* no-push */
sqlite3SafetyOff(db);
assert( db->init.busy==0 );
db->init.busy = 1;
assert(0==sqlite3Tsd()->mallocFailed);
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
db->init.busy = 0;
sqlite3SafetyOn(db);
if( rc==SQLITE_NOMEM ){
sqlite3Tsd()->mallocFailed = 1;
goto no_mem;
}
sqliteFree(zSql);
break;
}
@ -4433,7 +4441,7 @@ abort_due_to_misuse:
*/
abort_due_to_error:
if( p->zErrMsg==0 ){
if( sqlite3_malloc_failed ) rc = SQLITE_NOMEM;
if( sqlite3Tsd()->mallocFailed ) rc = SQLITE_NOMEM;
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
}
goto vdbe_halt;

View File

@ -156,6 +156,8 @@ int sqlite3_step(sqlite3_stmt *pStmt){
sqlite3 *db;
int rc;
assert(!sqlite3Tsd()->mallocFailed);
if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_MISUSE;
}
@ -239,6 +241,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
#endif
sqlite3Error(p->db, rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
sqlite3ClearMallocFailed();
return rc;
}

View File

@ -102,7 +102,7 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
p->nOp++;
assert( p->magic==VDBE_MAGIC_INIT );
resizeOpArray(p, i+1);
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
return 0;
}
pOp = &p->aOp[i];
@ -301,7 +301,7 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
int addr;
assert( p->magic==VDBE_MAGIC_INIT );
resizeOpArray(p, p->nOp + nOp);
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
return 0;
}
addr = p->nOp;
@ -416,7 +416,9 @@ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
Op *pOp;
assert( p->magic==VDBE_MAGIC_INIT );
if( p==0 || p->aOp==0 ){
freeP3(n, (void*)*(char**)&zP3);
if (n != P3_KEYINFO) {
freeP3(n, (void*)*(char**)&zP3);
}
return;
}
if( addr<0 || addr>=p->nOp ){
@ -734,7 +736,7 @@ void sqlite3VdbeMakeReady(
+ nMem*sizeof(Mem) /* aMem */
+ nCursor*sizeof(Cursor*) /* apCsr */
);
if( !sqlite3_malloc_failed ){
if( !sqlite3Tsd()->mallocFailed ){
p->aMem = &p->aStack[nStack];
p->nMem = nMem;
p->aVar = &p->aMem[nMem];
@ -884,7 +886,7 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
int rc;
Mem *pColName;
assert( idx<(2*p->nResColumn) );
if( sqlite3_malloc_failed ) return SQLITE_NOMEM;
if( sqlite3Tsd()->mallocFailed ) return SQLITE_NOMEM;
assert( p->aColName!=0 );
pColName = &(p->aColName[idx]);
if( N==P3_DYNAMIC || N==P3_STATIC ){
@ -1148,6 +1150,10 @@ int sqlite3VdbeHalt(Vdbe *p){
int i;
int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */
if( sqlite3Tsd()->mallocFailed ){
p->rc = SQLITE_NOMEM;
}
if( p->magic!=VDBE_MAGIC_RUN ){
/* Already halted. Nothing to do. */
assert( p->magic==VDBE_MAGIC_HALT );
@ -1158,7 +1164,8 @@ int sqlite3VdbeHalt(Vdbe *p){
if( p->pc<0 ){
/* No commit or rollback needed if the program never started */
}else if( db->autoCommit && db->activeVdbeCnt==1 ){
if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && p->rc!=SQLITE_NOMEM)){
/* The auto-commit flag is true, there are no other active queries
** using this handle and the vdbe program was successful or hit an
** 'OR FAIL' constraint. This means a commit is required.
@ -1169,11 +1176,50 @@ int sqlite3VdbeHalt(Vdbe *p){
}else if( rc!=SQLITE_OK ){
p->rc = rc;
xFunc = sqlite3BtreeRollback;
}else{
sqlite3CommitInternalChanges(db);
}
}else{
xFunc = sqlite3BtreeRollback;
}
}else{
if( p->rc==SQLITE_NOMEM ){
/* This loop does static analysis of the query to see which of the
** following three categories it falls into:
**
** Read-only
** Query with statement journal -> rollback statement
** Query without statement journal -> rollback transaction
**
** We could do something more elegant than this static analysis (i.e.
** store the type of query as part of the compliation phase), but
** handling malloc() failure is a fairly obscure edge case so this is
** probably easier.
**
** Todo: This means we always override the p->errorAction value for a
** malloc() failure. Is there any other choice here though?
*/
int isReadOnly = 1;
int isStatement = 0;
assert(p->aOp || p->nOp==0);
for(i=0; i<p->nOp; i++){
switch( p->aOp[i].opcode ){
case OP_Transaction:
isReadOnly = 0;
break;
case OP_Statement:
isStatement = 1;
break;
}
}
if( (isReadOnly||isStatement) && p->errorAction!=OE_Rollback ){
p->errorAction = OE_Abort;
}else{
p->errorAction = OE_Rollback;
}
}
if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
xFunc = sqlite3BtreeCommitStmt;
}else if( p->errorAction==OE_Abort ){
@ -1210,10 +1256,11 @@ int sqlite3VdbeHalt(Vdbe *p){
}
/* Rollback or commit any schema changes that occurred. */
if( p->rc!=SQLITE_OK ){
sqlite3RollbackInternalChanges(db);
}else if( db->flags & SQLITE_InternChanges ){
sqlite3CommitInternalChanges(db);
if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
sqlite3ResetInternalSchema(db, 0);
if( xFunc!=sqlite3BtreeRollback ){
db->flags = (db->flags | SQLITE_InternChanges);
}
}
/* We have successfully halted and closed the VM. Record this fact. */
@ -1278,7 +1325,7 @@ int sqlite3VdbeReset(Vdbe *p){
/* Save profiling information from this VDBE run.
*/
assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 );
assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || !p->aStack );
#ifdef VDBE_PROFILE
{
FILE *out = fopen("vdbe_profile.out", "a");

View File

@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.185 2005/11/26 14:24:41 drh Exp $
** $Id: where.c,v 1.186 2005/12/06 12:53:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
@ -567,7 +567,7 @@ static void exprAnalyze(
int nPattern;
int isComplete;
if( sqlite3_malloc_failed ) return;
if( sqlite3Tsd()->mallocFailed ) return;
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
if( pExpr->op==TK_IN ){
assert( pExpr->pRight==0 );
@ -1432,7 +1432,7 @@ WhereInfo *sqlite3WhereBegin(
** return value.
*/
pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
goto whereBeginNoMem;
}
pWInfo->pParse = pParse;
@ -1456,7 +1456,7 @@ WhereInfo *sqlite3WhereBegin(
createMask(&maskSet, pTabList->a[i].iCursor);
}
exprAnalyzeAll(pTabList, &maskSet, &wc);
if( sqlite3_malloc_failed ){
if( sqlite3Tsd()->mallocFailed ){
goto whereBeginNoMem;
}

View File

@ -14,7 +14,7 @@
# special feature is used to see what happens in the library if a malloc
# were to really fail due to an out-of-memory situation.
#
# $Id: malloc.test,v 1.24 2005/09/08 00:13:28 drh Exp $
# $Id: malloc.test,v 1.25 2005/12/06 12:53:01 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -22,7 +22,7 @@ source $testdir/tester.tcl
# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {
puts "Skipping malloc tests: not compiled with -DSQLITE_DEBUG..."
puts "Skipping malloc tests: not compiled with -DSQLITE_MEMDEBUG..."
finish_test
return
}
@ -52,12 +52,16 @@ if {[info command sqlite_malloc_stat]==""} {
# successfully, the loop ends.
#
proc do_malloc_test {tn args} {
array unset ::mallocopts
array set ::mallocopts $args
set ::go 1
for {set ::n 1} {$::go} {incr ::n} {
for {set ::n 1} {$::go && $::n < 50000} {incr ::n} {
do_test malloc-$tn.$::n {
# Remove all traces of database files test.db and test2.db from the files
# system. Then open (empty database) "test.db" with the handle [db].
#
sqlite_malloc_fail 0
catch {db close}
catch {file delete -force test.db}
@ -66,6 +70,8 @@ proc do_malloc_test {tn args} {
catch {file delete -force test2.db-journal}
set ::DB [sqlite3 db test.db]
# Execute any -tclprep and -sqlprep scripts.
#
if {[info exists ::mallocopts(-tclprep)]} {
eval $::mallocopts(-tclprep)
}
@ -73,6 +79,9 @@ proc do_malloc_test {tn args} {
execsql $::mallocopts(-sqlprep)
}
# Now set the ${::n}th malloc() to fail and execute the -tclbody and
# -sqlbody scripts.
#
sqlite_malloc_fail $::n
set ::mallocbody {}
if {[info exists ::mallocopts(-tclbody)]} {
@ -81,7 +90,6 @@ proc do_malloc_test {tn args} {
if {[info exists ::mallocopts(-sqlbody)]} {
append ::mallocbody "db eval {$::mallocopts(-sqlbody)}"
}
set v [catch $::mallocbody msg]
set leftover [lindex [sqlite_malloc_stat] 2]

View File

@ -11,7 +11,7 @@
# This file attempts to check that the library can recover from a malloc()
# failure when sqlite3_global_recover() is invoked.
#
# $Id: malloc2.test,v 1.3 2005/06/06 14:45:43 drh Exp $
# $Id: malloc2.test,v 1.4 2005/12/06 12:53:01 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -87,21 +87,30 @@ proc do_malloc2_test {tn args} {
# Nothing should work now, because the allocator should refuse to
# allocate any memory.
#
# Update: SQLite now automatically recovers from a malloc() failure.
# So the statement in the test below would work.
if 0 {
do_test malloc2-$tn.$::n.3 {
catchsql {SELECT 'nothing should work'}
} {1 {out of memory}}
}
# Recover from the malloc failure.
#
# Update: The new malloc() failure handling means that a transaction may
# still be active even if a malloc() has failed. But when these tests were
# written this was not the case. So do a manual ROLLBACK here so that the
# tests pass.
do_test malloc2-$tn.$::n.4 {
if 0 {
db close
sqlite_malloc_fail -1
set ::DB [sqlite3 db test.db]
set dummy SQLITE_OK
} else {
sqlite3_global_recover
sqlite3_global_recover
catch {
execsql {
ROLLBACK;
}
}
} {SQLITE_OK}
expr 0
} {0}
# Checksum the database.
do_test malloc2-$tn.$::n.5 {
@ -264,79 +273,87 @@ do_test malloc2-5 {
########################################################################
# Check that if a statement is active sqlite3_global_recover doesn't reset
# the sqlite3_malloc_failed variable.
do_test malloc2-6.1 {
set ::STMT [sqlite3_prepare $::DB {SELECT * FROM def} -1 DUMMY]
sqlite3_step $::STMT
} {SQLITE_ROW}
do_test malloc2-6.2 {
sqlite3 db1 test.db
sqlite_malloc_fail 100
catchsql {
SELECT * FROM def;
} db1
} {1 {out of memory}}
do_test malloc2-6.3 {
sqlite3_global_recover
} {SQLITE_BUSY}
do_test malloc2-6.4 {
catchsql {
SELECT 'hello';
}
} {1 {out of memory}}
do_test malloc2-6.5 {
sqlite3_reset $::STMT
} {SQLITE_OK}
do_test malloc2-6.6 {
sqlite3_global_recover
} {SQLITE_OK}
do_test malloc2-6.7 {
catchsql {
SELECT 'hello';
}
} {0 hello}
do_test malloc2-6.8 {
sqlite3_step $::STMT
} {SQLITE_ERROR}
do_test malloc2-6.9 {
sqlite3_finalize $::STMT
} {SQLITE_SCHEMA}
do_test malloc2-6.10 {
db1 close
} {}
#
# Update: There is now no sqlite3_malloc_failed variable, so these tests
# are not run.
#
# do_test malloc2-6.1 {
# set ::STMT [sqlite3_prepare $::DB {SELECT * FROM def} -1 DUMMY]
# sqlite3_step $::STMT
# } {SQLITE_ROW}
# do_test malloc2-6.2 {
# sqlite3 db1 test.db
# sqlite_malloc_fail 100
# catchsql {
# SELECT * FROM def;
# } db1
# } {1 {out of memory}}
# do_test malloc2-6.3 {
# sqlite3_global_recover
# } {SQLITE_BUSY}
# do_test malloc2-6.4 {
# catchsql {
# SELECT 'hello';
# }
# } {1 {out of memory}}
# do_test malloc2-6.5 {
# sqlite3_reset $::STMT
# } {SQLITE_OK}
# do_test malloc2-6.6 {
# sqlite3_global_recover
# } {SQLITE_OK}
# do_test malloc2-6.7 {
# catchsql {
# SELECT 'hello';
# }
# } {0 hello}
# do_test malloc2-6.8 {
# sqlite3_step $::STMT
# } {SQLITE_ERROR}
# do_test malloc2-6.9 {
# sqlite3_finalize $::STMT
# } {SQLITE_SCHEMA}
# do_test malloc2-6.10 {
# db1 close
# } {}
########################################################################
# Check that if an in-memory database is being used it is not possible
# to recover from a malloc() failure.
ifcapable memorydb {
do_test malloc2-7.1 {
sqlite3 db1 :memory:
list
} {}
do_test malloc2-7.2 {
sqlite_malloc_fail 100
catchsql {
SELECT * FROM def;
}
} {1 {out of memory}}
do_test malloc2-7.3 {
sqlite3_global_recover
} {SQLITE_ERROR}
do_test malloc2-7.4 {
catchsql {
SELECT 'hello';
}
} {1 {out of memory}}
do_test malloc2-7.5 {
db1 close
} {}
do_test malloc2-7.6 {
sqlite3_global_recover
} {SQLITE_OK}
do_test malloc2-7.7 {
catchsql {
SELECT 'hello';
}
} {0 hello}
}
#
# Update: An in-memory database can now survive a malloc() failure, so these
# tests are not run.
#
# ifcapable memorydb {
# do_test malloc2-7.1 {
# sqlite3 db1 :memory:
# list
# } {}
# do_test malloc2-7.2 {
# sqlite_malloc_fail 100
# catchsql {
# SELECT * FROM def;
# }
# } {1 {out of memory}}
# do_test malloc2-7.3 {
# sqlite3_global_recover
# } {SQLITE_ERROR}
# do_test malloc2-7.4 {
# catchsql {
# SELECT 'hello';
# }
# } {1 {out of memory}}
# do_test malloc2-7.5 {
# db1 close
# } {}
# do_test malloc2-7.6 {
# sqlite3_global_recover
# } {SQLITE_OK}
# do_test malloc2-7.7 {
# catchsql {
# SELECT 'hello';
# }
# } {0 hello}
# }
finish_test

View File

@ -13,7 +13,7 @@
# This file tests the various conditions under which an SQLITE_SCHEMA
# error should be returned.
#
# $Id: schema.test,v 1.4 2005/01/29 01:54:18 danielk1977 Exp $
# $Id: schema.test,v 1.5 2005/12/06 12:53:01 danielk1977 Exp $
#---------------------------------------------------------------------
# When any of the following types of SQL statements or actions are
@ -29,8 +29,6 @@
# Deleting a collation sequence.......................schema-7.*
# Setting or changing the authorization function......schema-8.*
#
# Note: Test cases schema-6.* are missing right now.
#
# Test cases schema-9.* and schema-10.* test some specific bugs
# that came up during development.
#
@ -38,7 +36,6 @@
# change a collation sequence or user-function while SQL statements
# are executing. Adding new collations or functions is allowed.
#
# Note: Test cases schema-11.* are also missing right now.
set testdir [file dirname $argv0]
source $testdir/tester.tcl

View File

@ -198,6 +198,7 @@ proc report {} {
lappend summarymap($stack) $bytes
}
set sorted [list]
foreach stack [array names summarymap] {
set allocs $summarymap($stack)
set sum 0