From c890fec362583a0282b3caff1085aedb0200ae26 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Aug 2008 20:10:08 +0000 Subject: [PATCH] Bring test coverage up to 99%. (CVS 5522) FossilOrigin-Name: 2cd6bae80984126023bcf479e5f3db5eaa5c4134 --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/btree.c | 29 ++++++++++++++++++++--------- src/btreeInt.h | 3 ++- src/vdbe.c | 6 ++++-- src/vdbe.h | 4 ++-- src/vdbeapi.c | 4 ++-- src/vdbeaux.c | 29 ++++++++++++----------------- src/vdbemem.c | 12 +++--------- test/attachmalloc.test | 3 ++- test/mallocH.test | 24 +++++++++++++++++++++++- 11 files changed, 85 insertions(+), 59 deletions(-) diff --git a/manifest b/manifest index 595b29a072..5edee71f8c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\sin\stest\sscripts.\s\sAdd\snew\stest\scases\sto\simprove\stest\scoverage.\s(CVS\s5521) -D 2008-08-01T18:47:02 +C Bring\stest\scoverage\sup\sto\s99%.\s(CVS\s5522) +D 2008-08-01T20:10:08 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in bbb62eecc851379aef5a48a1bf8787eb13e6ec06 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -96,9 +96,9 @@ F src/attach.c a85c14612e7e3410e0c3d2e0241832fa9688bd14 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627 F src/bitvec.c 95c86bd18d8fedf0533f5af196192546e10a7e7d F src/btmutex.c 709cad2cdca0afd013f0f612363810e53f59ec53 -F src/btree.c 540186cc76840ef9c6be5ec55793de79e33cf409 +F src/btree.c 0be00cb6a5cd130127a06eb5f661cb5e4a9d0259 F src/btree.h 03256ed7ee42b5ecacbe887070b0f8249e7d069d -F src/btreeInt.h 6e4cb69a9192a8d609c27034ae5f921cf0ecdde1 +F src/btreeInt.h ab18c7b4980314e9e4b402e5dcde09f3c2545576 F src/build.c 77d5518a64c0a905024bee80f6df2e794f4f5d43 F src/callback.c c9f75a4c403f166af3761df47d78a806587d63af F src/complete.c cb14e06dbe79dee031031f0d9e686ff306afe07c @@ -183,14 +183,14 @@ F src/update.c 79b77a3cc8ed5f8903a7f37055fcedd69388dcae F src/utf.c a7004436a6ef2aee012ace93de274dd0f3c7624e F src/util.c afe659ccc05d1f8af9e8631dabfec3ee3a7144af F src/vacuum.c ef342828002debc97514617af3424aea8ef8522c -F src/vdbe.c 90296a45d28939fd631c05c235dab7e123f94f57 -F src/vdbe.h c46155c221418bea29ee3a749d5950fcf85a70e2 +F src/vdbe.c a548d1dd6c5d99b2bd38e522aba2fa401340c99c +F src/vdbe.h 647fcf33a551ba10a974162c56846cb9aef2276b F src/vdbeInt.h ab27f964458fd070c6660f80694ab85d56d5f4c5 -F src/vdbeapi.c 25dd01c8b12978c14ec30e9a50666b23da767b27 -F src/vdbeaux.c 78c9d6413b8720edfe5b2a40a14850d21b0079b7 +F src/vdbeapi.c 6a769ea6708f75b1e55268ec1c7bcf8e96fc7628 +F src/vdbeaux.c 81a433ce73b79df605cc9709af430362e771ecdc F src/vdbeblob.c f93110888ddc246215e9ba1f831d3d375bfd8355 F src/vdbefifo.c 20fda2a7c4c0bcee1b90eb7e545fefcdbf2e1de7 -F src/vdbemem.c bdf92746583b0187655d736c4a20a2622eb9ab69 +F src/vdbemem.c c37b2a266a49eaf0c0f5080157f9f1a908fdaac3 F src/vtab.c 914db4c9435c61a522e3cdaf103dac163d38aa30 F src/where.c a800184a2d023b15d6f2758b7a6c7ab011258fee F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 @@ -207,7 +207,7 @@ F test/async3.test 9ffa0977a78cc6351862a1583be2b1eecd41736d F test/attach.test 75a5d22f88e730967d68f2c9f95e786e3953d8e3 F test/attach2.test a295d2d7061adcee5884ef4a93c7c96a82765437 F test/attach3.test 7b92dc8e40c1ebca9732ca6f2d3fefbd46f196df -F test/attachmalloc.test 56c5e55563dba6d64641ef2f70ce06900df16912 +F test/attachmalloc.test f7f62363896475080b0d41907a85a9fd94625296 F test/auth.test 9eb4b6b99eee54c95711c74c4b9694acf4d850ed F test/auth2.test ee3ba272e2b975e913afc9b041ee75706e190005 F test/autoinc.test 42af2c407c4e37d0626f9cda57ed381e94522c9d @@ -411,7 +411,7 @@ F test/mallocD.test f78c295e8e18ea3029e65ca08278690e00c22100 F test/mallocE.test db1ed69d7eded1b080952e2a7c37f364ad241b08 F test/mallocF.test 2d5c590ebc2fc7f0dcebdf5aa8498b9aed69107e F test/mallocG.test 4584d0d8ddb8009f16ca0c8bab1fa37f6358efa2 -F test/mallocH.test 10df29d6d8ee429e30cfa51f1583fb96956d9ae1 +F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb F test/malloc_common.tcl 753eb1ff3481f6cddb65cff33b9ef9f72c5ccdf7 F test/manydb.test 8de36b8d33aab5ef295b11d9e95310aeded31af8 F test/memdb.test a67bda4ff90a38f2b19f6c7f95aa7289e051d893 @@ -616,7 +616,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 4f4a9ccae7d25b9856d1203f6b289d552c2b425e -R 18c217d4a8c206615c26839f44ff5969 +P b65f493c7519e8a5ee632a395b57d45269741dda +R 569ccbda0a2f36d2174f959575a5f332 U drh -Z 42613daae14dfac0693542545b969121 +Z f6ba4601378d31882289341741f7ff01 diff --git a/manifest.uuid b/manifest.uuid index cc28cd7892..0244b8bfd2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b65f493c7519e8a5ee632a395b57d45269741dda \ No newline at end of file +2cd6bae80984126023bcf479e5f3db5eaa5c4134 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 0e91a5f1fa..fc20190ce7 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.492 2008/07/28 19:34:53 drh Exp $ +** $Id: btree.c,v 1.493 2008/08/01 20:10:08 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -6492,6 +6492,9 @@ static void checkAppendMsg( } sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); va_end(ap); + if( pCheck->errMsg.mallocFailed ){ + pCheck->mallocFailed = 1; + } } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -6735,7 +6738,9 @@ static int checkTreePage( data = pPage->aData; hdr = pPage->hdrOffset; hit = sqlite3PageMalloc( pBt->pageSize ); - if( hit ){ + if( hit==0 ){ + pCheck->mallocFailed = 1; + }else{ memset(hit, 0, usableSize ); memset(hit, 1, get2byte(&data[hdr+5])); nCell = get2byte(&data[hdr+3]); @@ -6791,10 +6796,10 @@ static int checkTreePage( ** an array of pages numbers were each page number is the root page of ** a table. nRoot is the number of entries in aRoot. ** -** If everything checks out, this routine returns NULL. If something is -** amiss, an error message is written into memory obtained from malloc() -** and a pointer to that error message is returned. The calling function -** is responsible for freeing the error message when it is done. +** Write the number of error seen in *pnErr. Except for some memory +** allocation errors, nn error message is held in memory obtained from +** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is +** returned. */ char *sqlite3BtreeIntegrityCheck( Btree *p, /* The btree to be checked */ @@ -6813,14 +6818,16 @@ char *sqlite3BtreeIntegrityCheck( pBt->db = p->db; nRef = sqlite3PagerRefcount(pBt->pPager); if( lockBtreeWithRetry(p)!=SQLITE_OK ){ + *pnErr = 1; sqlite3BtreeLeave(p); - return sqlite3DbStrDup(0, "Unable to acquire a read lock on the database"); + return sqlite3DbStrDup(0, "cannot acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = pagerPagecount(sCheck.pPager); sCheck.mxErr = mxErr; sCheck.nErr = 0; + sCheck.mallocFailed = 0; *pnErr = 0; #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->nTrunc!=0 ){ @@ -6837,8 +6844,7 @@ char *sqlite3BtreeIntegrityCheck( unlockBtreeIfUnused(pBt); *pnErr = 1; sqlite3BtreeLeave(p); - return sqlite3MPrintf(p->db, "Unable to malloc %d bytes", - (sCheck.nPage+1)*sizeof(sCheck.anRef[0])); + return 0; } for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } i = PENDING_BYTE_PAGE(pBt); @@ -6900,6 +6906,11 @@ char *sqlite3BtreeIntegrityCheck( */ sqlite3BtreeLeave(p); sqlite3_free(sCheck.anRef); + if( sCheck.mallocFailed ){ + sqlite3StrAccumReset(&sCheck.errMsg); + *pnErr = sCheck.nErr+1; + return 0; + } *pnErr = sCheck.nErr; if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg); return sqlite3StrAccumFinish(&sCheck.errMsg); diff --git a/src/btreeInt.h b/src/btreeInt.h index 8ff963659c..663a41e081 100644 --- a/src/btreeInt.h +++ b/src/btreeInt.h @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btreeInt.h,v 1.29 2008/07/18 09:34:57 danielk1977 Exp $ +** $Id: btreeInt.h,v 1.30 2008/08/01 20:10:08 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -601,6 +601,7 @@ struct IntegrityCk { int *anRef; /* Number of times each page is referenced */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ + int mallocFailed; /* A memory allocation error has occurred */ StrAccum errMsg; /* Accumulate the error message text here */ }; diff --git a/src/vdbe.c b/src/vdbe.c index 878d34ce72..eb4cfe6afb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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.770 2008/08/01 17:37:41 danielk1977 Exp $ +** $Id: vdbe.c,v 1.771 2008/08/01 20:10:08 drh Exp $ */ #include "sqliteInt.h" #include @@ -4249,16 +4249,18 @@ case OP_IntegrityCk: { assert( (p->btreeMask & (1<p5))!=0 ); z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, pnErr->u.i, &nErr); + sqlite3DbFree(db, aRoot); pnErr->u.i -= nErr; sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); + }else if( z==0 ){ + goto no_mem; }else{ sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); - sqlite3DbFree(db, aRoot); break; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ diff --git a/src/vdbe.h b/src/vdbe.h index 91fdaf6d89..815b615550 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.134 2008/06/25 00:12:41 drh Exp $ +** $Id: vdbe.h,v 1.135 2008/08/01 20:10:08 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -177,7 +177,7 @@ int sqlite3VdbeCurrentAddr(Vdbe*); void sqlite3VdbeTrace(Vdbe*,FILE*); #endif void sqlite3VdbeResetStepResult(Vdbe*); -int sqlite3VdbeReset(Vdbe*, int); +int sqlite3VdbeReset(Vdbe*); void sqlite3VdbeSetNumCols(Vdbe*,int); int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int); void sqlite3VdbeCountChanges(Vdbe*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 2dce141325..9f1471dc93 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -13,7 +13,7 @@ ** This file contains code use to implement APIs that are part of the ** VDBE. ** -** $Id: vdbeapi.c,v 1.136 2008/07/28 19:34:54 drh Exp $ +** $Id: vdbeapi.c,v 1.137 2008/08/01 20:10:08 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -228,7 +228,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){ }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); - rc = sqlite3VdbeReset(v, 1); + rc = sqlite3VdbeReset(v); stmtLruAdd(v); sqlite3VdbeMakeReady(v, -1, 0, 0, 0); assert( (rc & (v->db->errMask))==rc ); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 22ff34a9e8..5dada4f07e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.403 2008/08/01 17:37:41 danielk1977 Exp $ +** $Id: vdbeaux.c,v 1.404 2008/08/01 20:10:08 drh Exp $ */ #include "sqliteInt.h" #include @@ -759,17 +759,13 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){ /* ** Release an array of N Mem elements */ -static void releaseMemArray(Mem *p, int N, int freebuffers){ +static void releaseMemArray(Mem *p, int N){ if( p && N ){ sqlite3 *db = p->db; int malloc_failed = db->mallocFailed; while( N-->0 ){ assert( N<2 || p[0].db==p[1].db ); - if( freebuffers ){ - sqlite3VdbeMemRelease(p); - }else{ - sqlite3VdbeMemReleaseExternal(p); - } + sqlite3VdbeMemRelease(p); p->flags = MEM_Null; p++; } @@ -824,7 +820,7 @@ int sqlite3VdbeList( ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ - releaseMemArray(pMem, p->nMem, 1); + releaseMemArray(pMem, p->nMem); do{ i = p->pc++; @@ -1132,14 +1128,14 @@ static void closeAllCursorsExceptActiveVtabs(Vdbe *p){ ** sorters that were left open. It also deletes the values of ** variables in the aVar[] array. */ -static void Cleanup(Vdbe *p, int freebuffers){ +static void Cleanup(Vdbe *p){ int i; sqlite3 *db = p->db; closeAllCursorsExceptActiveVtabs(p); for(i=1; i<=p->nMem; i++){ MemSetTypeFlag(&p->aMem[i], MEM_Null); } - releaseMemArray(&p->aMem[1], p->nMem, freebuffers); + releaseMemArray(&p->aMem[1], p->nMem); sqlite3VdbeFifoClear(&p->sFifo); if( p->contextStack ){ for(i=0; icontextStackTop; i++){ @@ -1166,7 +1162,7 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ int n; sqlite3 *db = p->db; - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbFree(db, p->aColName); n = nResColumn*COLNAME_N; p->nResColumn = nResColumn; @@ -1696,7 +1692,7 @@ void sqlite3VdbeResetStepResult(Vdbe *p){ ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ -int sqlite3VdbeReset(Vdbe *p, int freebuffers){ +int sqlite3VdbeReset(Vdbe *p){ sqlite3 *db; db = p->db; @@ -1737,7 +1733,7 @@ int sqlite3VdbeReset(Vdbe *p, int freebuffers){ /* Reclaim all memory used by the VDBE */ - Cleanup(p, freebuffers); + Cleanup(p); /* Save profiling information from this VDBE run. */ @@ -1775,12 +1771,11 @@ int sqlite3VdbeReset(Vdbe *p, int freebuffers){ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ - rc = sqlite3VdbeReset(p, 1); + rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); }else if( p->magic!=VDBE_MAGIC_INIT ){ return SQLITE_MISUSE; } - /* releaseMemArray(&p->aMem[1], p->nMem, 1); */ sqlite3VdbeDelete(p); return rc; } @@ -1832,12 +1827,12 @@ void sqlite3VdbeDelete(Vdbe *p){ } sqlite3DbFree(db, p->aOp); } - releaseMemArray(p->aVar, p->nVar, 1); + releaseMemArray(p->aVar, p->nVar); sqlite3DbFree(db, p->aLabel); if( p->aMem ){ sqlite3DbFree(db, &p->aMem[1]); } - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N, 1); + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); p->magic = VDBE_MAGIC_DEAD; diff --git a/src/vdbemem.c b/src/vdbemem.c index be6424c027..8b94e3e4a5 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -15,7 +15,7 @@ ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** -** $Id: vdbemem.c,v 1.120 2008/07/30 13:14:55 drh Exp $ +** $Id: vdbemem.c,v 1.121 2008/08/01 20:10:09 drh Exp $ */ #include "sqliteInt.h" #include @@ -631,14 +631,8 @@ int sqlite3VdbeMemSetStr( }else{ sqlite3VdbeMemRelease(pMem); pMem->z = (char *)z; - if( xDel==SQLITE_DYNAMIC ){ - pMem->zMalloc = pMem->z; - pMem->xDel = 0; - flags |= MEM_Dyn; - }else{ - pMem->xDel = xDel; - flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); - } + pMem->xDel = xDel; + flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); } pMem->n = nByte; diff --git a/test/attachmalloc.test b/test/attachmalloc.test index 56553d06c6..8e78d73f82 100644 --- a/test/attachmalloc.test +++ b/test/attachmalloc.test @@ -12,7 +12,7 @@ # focus of this script is testing the ATTACH statement and # specifically out-of-memory conditions within that command. # -# $Id: attachmalloc.test,v 1.7 2007/10/09 08:29:32 danielk1977 Exp $ +# $Id: attachmalloc.test,v 1.8 2008/08/01 20:10:09 drh Exp $ # set testdir [file dirname $argv0] @@ -35,6 +35,7 @@ do_malloc_test attachmalloc-1 -tclprep { if {[catch {sqlite3 db test.db}]} { error "out of memory" } + sqlite3_db_config_lookaside db 0 0 sqlite3_extended_result_codes db 1 } -sqlbody { ATTACH 'test2.db' AS two; diff --git a/test/mallocH.test b/test/mallocH.test index 6cac8e68a3..7017b381ab 100644 --- a/test/mallocH.test +++ b/test/mallocH.test @@ -11,7 +11,7 @@ # # This test script checks malloc failures in various obscure operations. # -# $Id: mallocH.test,v 1.1 2008/08/01 18:47:02 drh Exp $ +# $Id: mallocH.test,v 1.2 2008/08/01 20:10:09 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -48,4 +48,26 @@ do_malloc_test mallocH-3 -sqlbody { SELECT replace('ababa','a','xyzzy'); } +# Malloc failures during EXPLAIN. +# +ifcapable explain { + do_malloc_test mallocH-4 -sqlprep { + CREATE TABLE abc(a PRIMARY KEY, b, c); + } -sqlbody { + EXPLAIN SELECT * FROM abc AS t2 WHERE rowid=1; + EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE rowid=1; + } +} + +# Malloc failure during integrity_check pragma. +# +do_malloc_test mallocH-5 -sqlprep { + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); + CREATE TABLE t2(x,y); + INSERT INTO t1 VALUES(1,2); + INSERT INTO t2 SELECT * FROM t1; +} -sqlbody { + PRAGMA integrity_check; +} + finish_test