diff --git a/manifest b/manifest index 2a57b8910a..f2f7fe2498 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\scrashtest\starget\sto\sMakefile.in.\s\sAdd\sLL\ssuffix\sto\slong\slong\sconstants\nin\sthe\svdbe.\s\sComment\schanges\sto\svdbeaux.c.\s(CVS\s1780) -D 2004-06-30T11:41:55 +C Coverage\simprovements\sfor\smalloc\sand\svdbemem.c\s(CVS\s1781) +D 2004-06-30T11:54:07 F Makefile.in f5788bf4daea9b25424df5ccb529ac3438efb2b2 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -38,7 +38,7 @@ F src/hash.c 148e3512f1b4e90f8477f852c70b36a137b116a7 F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/insert.c d99ffe87e1e1397f4233afcd06841d52d6b17b18 F src/legacy.c ad23746f15f67e34577621b1875f639c94839e1f -F src/main.c adb17bee0606a685d8872bdac9f23464e2c6a748 +F src/main.c 9cb3598be553c6e247e7ad7e9c41a9a0c38c7211 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070 F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345 F src/os_common.h fe9604754116bd2f2702d58f82d2d8b89998cb21 @@ -50,7 +50,7 @@ F src/os_unix.c 7df6ae05faa5b84164193d3694cb71b66661bbf3 F src/os_unix.h 00c1f82b526ab2fb7ee5ddd555ea4ed68363c93a F src/os_win.c 84549f6cc815237533c5d0eb3697352b03478d96 F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44 -F src/pager.c 7f30e724959a04011dd077a923ea16b53561ee6c +F src/pager.c 5f8cdc92ee9efb5a7849dc8b561b53122b700c78 F src/pager.h 269b6cfc114dba0148203446e41dd19f9647dd53 F src/parse.y 51c8e696276c409618e66a4ccf316fcff245506e F src/pragma.c 8326df8c400f573eb43004dfb8e53e5102acb3e4 @@ -61,7 +61,7 @@ F src/shell.c ebec5da57ea401f4886eefc790917b939d94d595 F src/sqlite.h.in b70fded2bdfeaddfb06adea3888118b722975136 F src/sqliteInt.h 9dcfcc67fc995b9079074d6b9619a1d4335583d0 F src/table.c 4521c278892f60e4d630788c0ea5cf4db1e75c49 -F src/tclsqlite.c f72288553ca3cdaf686baab4b1797dd98140c501 +F src/tclsqlite.c 0bdfed5cc93826a261dead2ad31502056bcf6e92 F src/test1.c 470430e194e43abb7d05b993fb360344f3d58834 F src/test2.c dafd8bd314a554bf376c6d3a8c83fd69219f5a40 F src/test3.c d0c56667e89f79ad0f060fdf010d1c34a4bc2988 @@ -76,9 +76,9 @@ F src/vacuum.c b8546f4921719458cc537b9e736df52a8256399c F src/vdbe.c 4e756ef91c9eb9ffd3dd5be17bda9d5bf2755a3e F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52 F src/vdbeInt.h 7160653a006b6d2c4a00d204112a095bdf842ab6 -F src/vdbeapi.c 7c3c3d818fad427881b65c51999d06bf393ebeaf +F src/vdbeapi.c 1d2a0bc5033a677f414c592aacd5d02f07ebbef5 F src/vdbeaux.c 4de85e30ca4a83ea0a45eceb7e88ac7a48f4c237 -F src/vdbemem.c 053f8adcb644bca1c1e4ad08f4016cb7ee6bf1b8 +F src/vdbemem.c bbf621377343bee046547712a144a94f387bb1eb F src/where.c 6507074d8ce3f78e7a4cd33f667f11e62020553e F test/all.test 3b692eb43583b52c99c344b2fa8934512d179016 F test/attach.test 3acdffccbf5f78b07746771b9490758718e28856 @@ -233,7 +233,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P a3c38a6d286ab37a9cdcc8b2243ea3258cc61ff0 -R f3dc92bc418113954f3540b52554dd34 -U drh -Z 78fbbed92b6b5d99dca4a6b3397cf5af +P 42553001954356c942b874e95277efe235ef7692 +R 60019ba81d7b4ee61c8fcace4daff4a1 +U danielk1977 +Z 3bf0bd77bf9abeca54609b89ed1a42c8 diff --git a/manifest.uuid b/manifest.uuid index 3f39f5f8ca..b0c5cc4830 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42553001954356c942b874e95277efe235ef7692 \ No newline at end of file +a98dd004c4d328eb44a71fecdbf8c5ab416dc524 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 4909688da7..2beacd564b 100644 --- a/src/main.c +++ b/src/main.c @@ -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.243 2004/06/30 09:49:24 danielk1977 Exp $ +** $Id: main.c,v 1.244 2004/06/30 11:54:07 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -748,7 +748,7 @@ int sqlite3_create_function( } p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); - if( p==0 ) return 1; + if( p==0 ) return SQLITE_NOMEM; p->xFunc = xFunc; p->xStep = xStep; p->xFinalize = xFinal; @@ -1180,6 +1180,9 @@ static int openDatabase( } opendb_out: + if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){ + sqlite3Error(db, SQLITE_NOMEM, 0); + } *ppDb = db; return sqlite3_errcode(db); } diff --git a/src/pager.c b/src/pager.c index 94bdbda61c..b7a83ffb95 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.148 2004/06/30 09:49:24 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.149 2004/06/30 11:54:07 danielk1977 Exp $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" @@ -1383,7 +1383,7 @@ static int sqlite3pager_opentemp(char *zFile, OsFile *fd){ cnt--; sqlite3OsTempFileName(zFile); rc = sqlite3OsOpenExclusive(zFile, fd, 1); - }while( cnt>0 && rc!=SQLITE_OK ); + }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM ); return rc; } diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a1c0bb3cb6..652f65f099 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -11,7 +11,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.93 2004/06/29 13:41:21 danielk1977 Exp $ +** $Id: tclsqlite.c,v 1.94 2004/06/30 11:54:07 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ @@ -1081,7 +1081,10 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ #ifdef SQLITE_TEST { extern void Md5_Register(sqlite*); + int mallocfail = sqlite3_iMallocFail; + sqlite3_iMallocFail = 0; Md5_Register(p->db); + sqlite3_iMallocFail = mallocfail; } #endif p->interp = interp; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 6f0fbb20a9..e8e389ca37 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -29,18 +29,10 @@ const void *sqlite3_value_blob(sqlite3_value *pVal){ } } int sqlite3_value_bytes(sqlite3_value *pVal){ - Mem *p = (Mem*)pVal; - if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text(pVal) ){ - return p->n; - } - return 0; + return sqlite3ValueBytes(pVal, SQLITE_UTF8); } int sqlite3_value_bytes16(sqlite3_value *pVal){ - Mem *p = (Mem*)pVal; - if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text16(pVal) ){ - return ((Mem *)pVal)->n; - } - return 0; + return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); } double sqlite3_value_double(sqlite3_value *pVal){ return sqlite3VdbeRealValue((Mem*)pVal); diff --git a/src/vdbemem.c b/src/vdbemem.c index 7f26c7dd69..44848b34a5 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -104,88 +104,75 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){ ** Make sure the given Mem is \u0000 terminated. */ int sqlite3VdbeMemNulTerminate(Mem *pMem){ - if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & (MEM_Str|MEM_Blob))==0 ){ + /* In SQLite, a string without a nul terminator occurs when a string + ** is loaded from disk (in this case the memory management is ephemeral), + ** or when it is supplied by the user as a bound variable or function + ** return value. Therefore, the memory management of the string must be + ** either ephemeral, static or controlled by a user-supplied destructor. + */ + assert( + !(pMem->flags&MEM_Str) || /* it's not a string, or */ + (pMem->flags&MEM_Term) || /* it's nul term. already, or */ + (pMem->flags&(MEM_Ephem|MEM_Static)) || /* it's static or ephem, or */ + (pMem->flags&MEM_Dyn && pMem->xDel) /* external management */ + ); + if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){ return SQLITE_OK; /* Nothing to do */ } if( pMem->flags & (MEM_Static|MEM_Ephem) ){ return sqlite3VdbeMemMakeWriteable(pMem); }else{ - if( pMem->flags & MEM_Dyn ){ - if( pMem->xDel ){ - char *z = sqliteMalloc(pMem->n+2); - if( !z ) return SQLITE_NOMEM; - memcpy(z, pMem->z, pMem->n); - pMem->xDel(pMem->z); - pMem->xDel = 0; - pMem->z = z; - }else{ - pMem->z = sqliteRealloc(pMem->z, pMem->n+2); - if( !pMem->z ) return SQLITE_NOMEM; - } - }else{ - assert( pMem->flags & MEM_Short ); - if( pMem->n+2>NBFS ){ - char *z = sqliteMalloc(pMem->n+2); - if( !z ) return SQLITE_NOMEM; - memcpy(z, pMem->z, pMem->n); - pMem->flags &= !(MEM_Short); - pMem->flags |= MEM_Dyn; - pMem->xDel = 0; - pMem->z = z; - } - } - pMem->z[pMem->n++] = 0; - pMem->z[pMem->n++] = 0; + char *z = sqliteMalloc(pMem->n+2); + if( !z ) return SQLITE_NOMEM; + memcpy(z, pMem->z, pMem->n); + z[pMem->n] = 0; + z[pMem->n+1] = 0; + pMem->xDel(pMem->z); + pMem->xDel = 0; + pMem->z = z; } return SQLITE_OK; } /* -** Add MEM_Str to the set of representations for the given Mem. -** A NULL is converted into an empty string. Numbers are converted -** using sqlite3_snprintf(). Converting a BLOB to a string is a -** no-op. +** Add MEM_Str to the set of representations for the given Mem. Numbers +** are converted using sqlite3_snprintf(). Converting a BLOB to a string +** is a no-op. ** ** Existing representations MEM_Int and MEM_Real are *not* invalidated. -** But MEM_Null is. +** +** A MEM_Null value will never be passed to this function. This function is +** used for converting values to text for returning to the user (i.e. via +** sqlite3_value_text()), or for ensuring that values to be used as btree +** keys are strings. In the former case a NULL pointer is returned the +** user and the later is an internal programming error. */ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ int rc = SQLITE_OK; int fg = pMem->flags; + u8 *z = pMem->zShort; assert( !(fg&(MEM_Str|MEM_Blob)) ); - assert( fg&(MEM_Int|MEM_Real|MEM_Null) ); + assert( fg&(MEM_Int|MEM_Real) ); - if( fg & MEM_Null ){ - /* A NULL value is converted to a zero length string */ - u8 *z = pMem->zShort; - z[0] = 0; - z[1] = 0; - pMem->flags = MEM_Str | MEM_Short | MEM_Term; - pMem->z = z; - pMem->n = 0; - pMem->enc = enc; + /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 + ** string representation of the value. Then, if the required encoding + ** is UTF-16le or UTF-16be do a translation. + ** + ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. + */ + if( fg & MEM_Real || (pMem->type==SQLITE_FLOAT) ){ + sqlite3_snprintf(NBFS, z, "%.15g", pMem->r); }else{ - /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 - ** string representation of the value. Then, if the required encoding - ** is UTF-16le or UTF-16be do a translation. - ** - ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. - */ - u8 *z = pMem->zShort; - if( fg & MEM_Real || (pMem->type==SQLITE_FLOAT) ){ - sqlite3_snprintf(NBFS, z, "%.15g", pMem->r); - }else{ - assert( fg & MEM_Int ); - sqlite3_snprintf(NBFS, z, "%lld", pMem->i); - } - pMem->n = strlen(z); - pMem->z = z; - pMem->enc = SQLITE_UTF8; - pMem->flags |= MEM_Str | MEM_Short | MEM_Term; - sqlite3VdbeChangeEncoding(pMem, enc); + assert( fg & MEM_Int ); + sqlite3_snprintf(NBFS, z, "%lld", pMem->i); } + pMem->n = strlen(z); + pMem->z = z; + pMem->enc = SQLITE_UTF8; + pMem->flags |= MEM_Str | MEM_Short | MEM_Term; + sqlite3VdbeChangeEncoding(pMem, enc); return rc; } @@ -331,16 +318,12 @@ int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ ** deleted. pFrom contains an SQL NULL when this routine returns. */ int sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ - int rc = SQLITE_OK; - if( !(pFrom->flags&MEM_Dyn && pFrom->xDel) ){ - memcpy(pTo, pFrom, sizeof(Mem)); - if( pFrom->flags & MEM_Short ){ - pTo->z = pTo->zShort; - } - }else{ - rc = sqlite3VdbeMemCopy(pTo, pFrom); - sqlite3VdbeMemRelease(pFrom); + memcpy(pTo, pFrom, sizeof(Mem)); + if( pFrom->flags & MEM_Short ){ + pTo->z = pTo->zShort; } + pFrom->flags = MEM_Null; + pFrom->xDel = 0; return SQLITE_OK; }