From f44795013f44c78f54143a2612a5910831a5f9f8 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 27 May 2004 03:12:53 +0000 Subject: [PATCH] Fixes to the MEM changes. The library now links. (CVS 1470) FossilOrigin-Name: f33d15d95f195e26e1ef396158597a2caa06f374 --- manifest | 28 +++--- manifest.uuid | 2 +- src/expr.c | 10 +-- src/func.c | 30 +++---- src/sqlite.h.in | 74 ++++++++-------- src/util.c | 4 +- src/vdbe.c | 221 ++++++++++++++++-------------------------------- src/vdbeInt.h | 11 +-- src/vdbeapi.c | 42 ++++----- src/vdbeaux.c | 12 +-- src/vdbemem.c | 63 +++++++------- 11 files changed, 210 insertions(+), 287 deletions(-) diff --git a/manifest b/manifest index a5e58214cc..e261002aac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sMEM\schanges\sin\sthe\svdbe.c.\s\sStill\swill\snot\scompile.\s(CVS\s1469) -D 2004-05-27T01:53:56 +C Fixes\sto\sthe\sMEM\schanges.\s\sThe\slibrary\snow\slinks.\s(CVS\s1470) +D 2004-05-27T03:12:54 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -31,8 +31,8 @@ F src/copy.c 6eb7cc08ae6dc60bf83ecadf4508a0bef909dbd2 F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 -F src/expr.c 90573f18f946c94848d5ca1c925a141ef5dfe111 -F src/func.c a25ec101ac83e62abb249d4d3e5204c60a772224 +F src/expr.c 70d6c955c046c07d51521c99786716f49e44023c +F src/func.c 0910036111443d294739f03d7c9c5b4f759b79cb F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/insert.c dd117e8b3f50e943e6cf5fbcf4bbdc0b907b0b4c @@ -55,7 +55,7 @@ F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c e90e2a147273cdcdb1ee9e14574ab28f04382e63 F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f -F src/sqlite.h.in 68e165dc4dc2d477c95c76b9ede13eed5fbaabf4 +F src/sqlite.h.in a7dc2479fd94f617755a20425f99719d26416a34 F src/sqliteInt.h dbf4fd06e89cdab13f4f1129d76bf79a38ec2b39 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c 86daf7bf6ba715bf0f0c7a47beb1d947a15cb868 @@ -68,14 +68,14 @@ F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847 F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f F src/update.c 96461bcf4e946697e83c09c77c7e61b545a2f66e F src/utf.c 73d70f2764cb34b072e2d7b0f0c23c389cfc1baa -F src/util.c caef24dcf3d7dfb7ac747ed36c080d95457fac71 +F src/util.c 1f6e8febdd15be17e5ee867a7e015596d2bb62de F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad -F src/vdbe.c 06f02181b5fe39b99cb98714bf36e95005e03ef7 +F src/vdbe.c e9d8818bbdf5b4d9123786009d581140487d6f1f F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb -F src/vdbeInt.h d62f70eb935bf056d9eb7dfb9783393274685e1d -F src/vdbeapi.c 56b7de7af5800fbbf79fd953da95ee61c379a387 -F src/vdbeaux.c de2d82e4cf5815595ae74bd5f663042428efb6a8 -F src/vdbemem.c 3474db5cdb19a8aa1b1e8e78189e1e8cda2394aa +F src/vdbeInt.h 8941eb5515430faa1a1b7645b773e7a0933d8221 +F src/vdbeapi.c d3deff8e52e5d58af23c84bcbbd0002193b04a21 +F src/vdbeaux.c 02ad53b5c0ec453b8a4fb4c361c7e0ce223e74c9 +F src/vdbemem.c b7a94817d8ff47ab5b25b814028a7c4320503804 F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 @@ -205,7 +205,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 74097ecdb0b1e0eec143c5a3f8ca2f0d63d6f38d -R 98aa4ae2a65faf4f8c17b075955c2246 +P dbdd1a7f316e576d0611748ec63c9ef00d4c10db +R b31d420b5a3ee4ab74bd71f733217eb1 U drh -Z eb27f7bb480c5083f24dd280c1f9cf51 +Z 9c2574737dba2ee53b82558a62ddf903 diff --git a/manifest.uuid b/manifest.uuid index 698e80ef2b..58c5fee64c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbdd1a7f316e576d0611748ec63c9ef00d4c10db \ No newline at end of file +f33d15d95f195e26e1ef396158597a2caa06f374 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8a97ca9e0d..2058e8acd5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -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.128 2004/05/26 16:54:43 drh Exp $ +** $Id: expr.c,v 1.129 2004/05/27 03:12:54 drh Exp $ */ #include "sqliteInt.h" #include @@ -1224,13 +1224,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0); assert( pDef!=0 ); nExpr = sqlite3ExprCodeExprList(pParse, pList); - /* FIX ME: The following is a temporary hack. */ - if( 0==sqlite3StrNICmp(zId, "classof", nId) ){ - assert( nExpr==1 ); - sqlite3VdbeAddOp(v, OP_Class, nExpr, 0); - }else{ - sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_FUNCDEF); - } + sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_FUNCDEF); break; } case TK_SELECT: { diff --git a/src/func.c b/src/func.c index b9f56ef7f0..6ab0829422 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.58 2004/05/26 23:25:31 drh Exp $ +** $Id: func.c,v 1.59 2004/05/27 03:12:55 drh Exp $ */ #include #include @@ -46,7 +46,7 @@ static void minmaxFunc( iBest = i; } } - sqlite3_result(context, argv[iBest]); + sqlite3_result_value(context, argv[iBest]); } /* @@ -76,7 +76,6 @@ static void lengthFunc( int argc, sqlite3_value **argv ){ - const char *z; int len; assert( argc==1 ); @@ -84,13 +83,13 @@ static void lengthFunc( case SQLITE3_BLOB: case SQLITE3_INTEGER: case SQLITE3_FLOAT: { - sqlite3_result_int32(context, sqlite3_value_bytes(argv[0])); + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); break; } case SQLITE3_TEXT: { const char *z = sqlite3_value_text(argv[0]); for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; } - sqlite3_result_int32(context, len); + sqlite3_result_int(context, len); break; } default: { @@ -104,7 +103,6 @@ static void lengthFunc( ** Implementation of the abs() function */ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - const char *z; assert( argc==1 ); switch( sqlite3_value_type(argv[0]) ){ case SQLITE3_INTEGER: { @@ -228,7 +226,7 @@ static void ifnullFunc( int i; for(i=0; in : 0); + sqlite3_result_int(context, p ? p->n : 0); } /* @@ -623,7 +621,7 @@ static void minMaxFinalize(sqlite3_context *context){ sqlite3_value *pRes; pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem)); if( pRes->flags ){ - sqlite3_result(context, pRes); + sqlite3_result_value(context, pRes); } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 444ba5a567..9068c2790f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.82 2004/05/26 23:25:31 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.83 2004/05/27 03:12:55 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -604,6 +604,13 @@ int sqlite3_prepare16( const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); +/* +** Pointers to the following two opaque structures are used to communicate +** with the implementations of user-defined functions. +*/ +typedef struct sqlite3_context sqlite3_context; +typedef struct Mem sqlite3_value; + /* ** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(), ** one or more literals can be replace by a wildcard "?" or ":N:" where @@ -624,14 +631,14 @@ int sqlite3_prepare16( ** an sqlite3_prepare() or sqlite3_reset(). Unbound wildcards are interpreted ** as NULL. */ -void sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, int eCopy); -void sqlite3_bind_double(sqlite3_stmt*, int, double); -void sqlite3_bind_int(sqlite3_stmt*, int, int); -void sqlite3_bind_int64(sqlite3_stmt*, int, long long int); -void sqlite3_bind_null(sqlite3_stmt*, int); -void sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, int eCopy); -void sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, int eCopy); -void sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, int eCopy); +int sqlite3_bind_double(sqlite3_stmt*, int, double); +int sqlite3_bind_int(sqlite3_stmt*, int, int); +int sqlite3_bind_int64(sqlite3_stmt*, int, long long int); +int sqlite3_bind_null(sqlite3_stmt*, int); +int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, int eCopy); +int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, int eCopy); +int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); /* ** Return the number of columns in the result set returned by the compiled @@ -738,11 +745,11 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** Values are stored in the database in one of the following fundamental ** types. */ -#define SQLITE_INTEGER 1 -#define SQLITE_FLOAT 2 -#define SQLITE_TEXT 3 -#define SQLITE_BLOB 4 -#define SQLITE_NULL 5 +#define SQLITE3_INTEGER 1 +#define SQLITE3_FLOAT 2 +#define SQLITE3_TEXT 3 +#define SQLITE3_BLOB 4 +#define SQLITE3_NULL 5 /* ** The next group of routines returns information about the information @@ -801,14 +808,14 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** _text() Return the value as UTF-8 text. ** _text16() Return the value as UTF-16 text. */ -void *sqlite3_column_blob(sqlite3_stmt*, int iCol) -int sqlite3_column_bytes(sqlite3_stmt*, int iCol) -int sqlite3_column_bytes16(sqlite3_stmt*, int iCol) -double sqlite3_column_double(sqlite3_stmt*, int iCol) -int sqlite3_column_int(sqlite3_stmt*, int iCol) -long long int sqlite3_column_int64(sqlite3_stmt*, int iCol) -const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol) -const void *sqlite3_column_text16(sqlite3_stmt*, int iCol) +const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +double sqlite3_column_double(sqlite3_stmt*, int iCol); +int sqlite3_column_int(sqlite3_stmt*, int iCol); +long long int sqlite3_column_int64(sqlite3_stmt*, int iCol); +const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); int sqlite3_column_type(sqlite3_stmt*, int iCol); /* @@ -836,13 +843,6 @@ int sqlite3_finalize(sqlite3_stmt *pStmt); */ int sqlite3_reset(sqlite3_stmt *pStmt); -/* -** Pointers to the following two opaque structures are used to communicate -** with the implementations of user-defined functions. -*/ -typedef struct sqlite3_context sqlite3_context; -typedef struct Mem sqlite3_value; - /* ** The following two functions are used to add user functions or aggregates ** implemented in C to the SQL langauge interpreted by SQLite. The @@ -909,14 +909,14 @@ int sqlite3_aggregate_count(sqlite3_context*); ** sqlite3_value* pointer instead of an sqlite3_stmt* and an integer ** column number. */ -void *sqlite3_value_blob(sqlite3_value*) -int sqlite3_value_bytes(sqlite3_value*) -int sqlite3_value_bytes16(sqlite3_value*) -double sqlite3_value_double(sqlite3_value*) -int sqlite3_value_int(sqlite3_value*) -long long int sqlite3_value_int64(sqlite3_value*) -const unsigned char *sqlite3_value_text(sqlite3_value*) -const void *sqlite3_value_text16(sqlite3_value*) +const void *sqlite3_value_blob(sqlite3_value*); +int sqlite3_value_bytes(sqlite3_value*); +int sqlite3_value_bytes16(sqlite3_value*); +double sqlite3_value_double(sqlite3_value*); +int sqlite3_value_int(sqlite3_value*); +long long int sqlite3_value_int64(sqlite3_value*); +const unsigned char *sqlite3_value_text(sqlite3_value*); +const void *sqlite3_value_text16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*); /* diff --git a/src/util.c b/src/util.c index 0d1a5b9748..da3b046aaa 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.89 2004/05/27 01:53:56 drh Exp $ +** $Id: util.c,v 1.90 2004/05/27 03:12:55 drh Exp $ */ #include "sqliteInt.h" #include @@ -740,7 +740,7 @@ int sqlite3FitsIn64Bits(const char *zNum){ */ int sqlite3GetInt64(const char *zNum, i64 *pValue){ if( sqlite3FitsIn64Bits(zNum) ){ - sqlite3atoi64(zNum, pValue, TEXT_Utf8); + sqlite3atoi64(zNum, pValue); return 1; } return 0; diff --git a/src/vdbe.c b/src/vdbe.c index dbcab5066b..4d60260946 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.337 2004/05/27 01:53:56 drh Exp $ +** $Id: vdbe.c,v 1.338 2004/05/27 03:12:55 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -80,7 +80,8 @@ int sqlite3_interrupt_count = 0; ** already. Return non-zero if a malloc() fails. */ #define Stringify(P, enc) \ - (!((P)->flags&(MEM_Str|MEM_Blob)) && sqlite3VdbeMemStringify(P,enc)) + if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \ + { goto no_mem; } /* ** Convert the given stack entity into a string that has been obtained @@ -309,7 +310,7 @@ static void applyAffinity(Mem *pRec, char affinity, u8 enc){ ** representation. */ if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){ - Stringify(pRec, enc); + sqlite3VdbeMemStringify(pRec, enc); } pRec->flags &= ~(MEM_Real|MEM_Int); @@ -432,24 +433,27 @@ static int getBtreeMem( pMem->flags = MEM_Blob|MEM_Ephem; }else{ int rc; - if( amt>NBFS ){ - zData = (char *)sqliteMallocRaw(amt); + if( amt>NBFS-2 ){ + zData = (char *)sqliteMallocRaw(amt+2); if( !zData ){ return SQLITE_NOMEM; } - pMem->flags = MEM_Blob|MEM_Dyn; + pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term; }else{ zData = &(pMem->zShort[0]); - pMem->flags = MEM_Blob|MEM_Short; + pMem->flags = MEM_Blob|MEM_Short|MEM_Term; } pMem->z = zData; + pMem->enc = 0; + pMem->type = SQLITE3_BLOB; if( key ){ rc = sqlite3BtreeKey(pCur, offset, amt, zData); }else{ rc = sqlite3BtreeData(pCur, offset, amt, zData); } - + zData[amt] = 0; + zData[amt+1] = 0; if( rc!=SQLITE_OK ){ if( amt>NBFS ){ sqliteFree(zData); @@ -715,67 +719,54 @@ case OP_Halt: { } } -/* Opcode: String * * P3 -** -** The string value P3 is pushed onto the stack. If P3==0 then a -** NULL is pushed onto the stack. -*/ -/* Opcode: Real * * P3 -** -** The string value P3 is converted to a real and pushed on to the stack. -*/ /* Opcode: Integer P1 * P3 ** ** The integer value P1 is pushed onto the stack. If P3 is not zero ** then it is assumed to be a string representation of the same integer. ** If P1 is zero and P3 is not zero, then the value is derived from P3. */ -case OP_Integer: -case OP_Real: -case OP_String: { - char *z = pOp->p3; - u8 op = pOp->opcode; - +case OP_Integer: { pTos++; - pTos->flags = 0; - - /* If this is an OP_Real or OP_Integer opcode, set the pTos->r or pTos->i - ** values respectively. - */ - if( op==OP_Real ){ - assert( z ); - assert( sqlite3IsNumber(z, 0, TEXT_Utf8) ); - pTos->r = sqlite3AtoF(z, 0); - pTos->flags = MEM_Real; - }else if( op==OP_Integer ){ + if( pOp->p3==0 ){ pTos->flags = MEM_Int; pTos->i = pOp->p1; - if( pTos->i==0 && pOp->p3 ){ - sqlite3GetInt64(pOp->p3, &pTos->i); - } - } - - if( z ){ - /* FIX ME: For now the code in expr.c always puts UTF-8 in P3. It - ** should transform text to the native encoding before doing so. - */ - if( db->enc!=TEXT_Utf8 ){ - rc = sqlite3utfTranslate(z, -1, TEXT_Utf8, (void **)&pTos->z, - &pTos->n, db->enc); - if( rc!=SQLITE_OK ){ - assert( !pTos->z ); - goto abort_due_to_error; - } - pTos->flags |= MEM_Str | MEM_Dyn | MEM_Term; - }else{ - pTos->z = z; - pTos->n = strlen(z) + 1; - pTos->flags |= MEM_Str | MEM_Static | MEM_Term; - } - }else if( op==OP_String ){ - pTos->flags = MEM_Null; + pTos->type = SQLITE3_INTEGER; + }else{ + pTos->flags = MEM_Str|MEM_Static|MEM_Term; + pTos->z = pOp->p3; + pTos->n = strlen(pTos->z); + pTos->enc = TEXT_Utf8; + Integerify(pTos, 0); } + break; +} +/* Opcode: Real * * P3 +** +** The string value P3 is converted to a real and pushed on to the stack. +*/ +case OP_Real: { + pTos++; + pTos->flags = MEM_Str|MEM_Static|MEM_Term; + pTos->z = pOp->p3; + pTos->n = strlen(pTos->z); + pTos->enc = TEXT_Utf8; + Realify(pTos, 0); + break; +} + +/* Opcode: String * * P3 +** +** The string value P3 is pushed onto the stack. If P3==0 then a +** NULL is pushed onto the stack. +*/ +case OP_String: { + pTos++; + pTos->flags = MEM_Str|MEM_Static|MEM_Term; + pTos->enc = TEXT_Utf8; + pTos->z = pOp->p3; + pTos->n = strlen(pTos->z); + sqlite3VdbeChangeEncoding(pTos, db->enc); break; } @@ -889,14 +880,15 @@ case OP_Dup: { pTos->flags &= ~MEM_Dyn; pTos->flags |= MEM_Ephem; }else if( pTos->flags & MEM_Short ){ - memcpy(pTos->zShort, pFrom->zShort, pTos->n); + memcpy(pTos->zShort, pFrom->zShort, pTos->n+2); pTos->z = pTos->zShort; }else if( (pTos->flags & MEM_Static)==0 ){ - pTos->z = sqliteMallocRaw(pFrom->n); + pTos->z = sqliteMallocRaw(pFrom->n+2); if( sqlite3_malloc_failed ) goto no_mem; memcpy(pTos->z, pFrom->z, pFrom->n); + memcpy(&pTos->z[pTos->n], "\0", 2); pTos->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short); - pTos->flags |= MEM_Dyn; + pTos->flags |= MEM_Dyn|MEM_Term; } } break; @@ -992,7 +984,6 @@ case OP_Callback: { for(i=0; ip1; i++){ Mem *pVal = &pTos[0-i]; - SetEncodingFlags(pVal, db->enc); sqlite3VdbeMemNulTerminate(pVal); } @@ -1089,7 +1080,7 @@ case OP_Concat: { } pTos++; pTos->n = j; - pTos->flags = MEM_Str|MEM_Dyn|MEM_Term + pTos->flags = MEM_Str|MEM_Dyn|MEM_Term; pTos->enc = db->enc; pTos->type = SQLITE3_TEXT; pTos->z = zNew; @@ -1239,7 +1230,6 @@ case OP_Function: { pArg = &pTos[1-n]; for(i=0; ienc); apVal[i] = pArg; } @@ -1265,11 +1255,6 @@ case OP_Function: { (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0); rc = SQLITE_ERROR; } - - if( pTos->flags&MEM_Str ){ - SetEncoding(pTos, encToFlags(db->enc)|MEM_Term); - } - break; } @@ -1414,7 +1399,7 @@ case OP_MustBeInt: { }else if( pTos->flags & MEM_Str ){ i64 v; if( sqlite3VdbeChangeEncoding(pTos, TEXT_Utf8) - || sqlite3VdbeNulTerminate(pTos) ){ + || sqlite3VdbeMemNulTerminate(pTos) ){ goto no_mem; } if( !sqlite3atoi64(pTos->z, &v) ){ @@ -1776,64 +1761,6 @@ case OP_NotNull: { break; } -/* Opcode: Class * * * -** -** Pop a single value from the top of the stack and push on one of the -** following strings, according to the storage class of the value just -** popped: -** -** "NULL", "INTEGER", "REAL", "TEXT", "BLOB" -** -** This opcode is probably temporary. -*/ -case OP_Class: { - int flags = pTos->flags; - int i; - - struct { - int mask; - char * zClass; - char * zClass16; - } classes[] = { - {MEM_Null, "NULL", "\0N\0U\0L\0L\0\0\0"}, - {MEM_Int, "INTEGER", "\0I\0N\0T\0E\0G\0E\0R\0\0\0"}, - {MEM_Real, "REAL", "\0R\0E\0A\0L\0\0\0"}, - {MEM_Str, "TEXT", "\0T\0E\0X\0T\0\0\0"}, - {MEM_Blob, "BLOB", "\0B\0L\0O\0B\0\0\0"} - }; - - Release(pTos); - pTos->flags = MEM_Str|MEM_Static|MEM_Term; - - for(i=0; i<5; i++){ - if( classes[i].mask&flags ){ - switch( db->enc ){ - case TEXT_Utf8: - pTos->z = classes[i].zClass; - break; - case TEXT_Utf16be: - pTos->z = classes[i].zClass16; - break; - case TEXT_Utf16le: - pTos->z = &(classes[i].zClass16[1]); - break; - default: - assert(0); - } - break; - } - } - assert( i<5 ); - - if( db->enc==TEXT_Utf8 ){ - pTos->n = strlen(pTos->z) + 1; - }else{ - pTos->n = sqlite3utf16ByteLen(pTos->z, -1) + 2; - } - - break; -} - /* Opcode: SetNumColumns P1 P2 * ** ** Before the OP_Column opcode can be executed on a cursor, this @@ -2277,7 +2204,7 @@ case OP_MakeIdxKey: { popStack(&pTos, nField+addRowid); } pTos++; - pTos->flags = MEM_Blob|MEM_Dyn; /* TODO: should eventually be MEM_Blob */ + pTos->flags = MEM_Blob|MEM_Dyn; pTos->z = zKey; pTos->n = nByte; @@ -3220,10 +3147,12 @@ case OP_PutStrKey: { pC->pData = pTos->z; pTos->flags = MEM_Null; }else{ - pC->pData = sqliteMallocRaw( pC->nData ); + pC->pData = sqliteMallocRaw( pC->nData+2 ); if( pC->pData ){ memcpy(pC->pData, pTos->z, pC->nData); } + pC->pData[pC->nData] = 0; + pC->pData[pC->nData+1] = 0; } pC->nullRow = 0; }else{ @@ -4000,17 +3929,15 @@ case OP_IntegrityCk: { if( z==0 || z[0]==0 ){ if( z ) sqliteFree(z); pTos->z = "ok"; - pTos->n = 3; - pTos->flags = MEM_Str | MEM_Static; + pTos->n = 2; + pTos->flags = MEM_Str | MEM_Static | MEM_Term; }else{ pTos->z = z; - pTos->n = strlen(z) + 1; - pTos->flags = MEM_Str | MEM_Dyn; - } - if( db->enc!=TEXT_Utf8 ){ - SetEncodingFlags(pTos, TEXT_Utf8); - SetEncoding(pTos, encToFlags(db->enc)|MEM_Term); + pTos->n = strlen(z); + pTos->flags = MEM_Str | MEM_Dyn | MEM_Term; } + pTos->enc = TEXT_Utf8; + sqlite3VdbeChangeEncoding(pTos, db->enc); sqliteFree(aRoot); break; } @@ -4419,6 +4346,7 @@ fileread_jump: ** from the input file. */ case OP_FileColumn: { +#if 0 /* Will be deleting this soon */ int i = pOp->p1; char *z; assert( i>=0 && inField ); @@ -4431,11 +4359,11 @@ case OP_FileColumn: { if( z ){ pTos->n = strlen(z) + 1; pTos->z = z; - pTos->flags = MEM_Utf8 | MEM_Str | MEM_Ephem | MEM_Term; - SetEncoding(pTos, encToFlags(db->enc)|MEM_Term); + pTos->flags = MEM_Str | MEM_Ephem | MEM_Term; }else{ pTos->flags = MEM_Null; } +#endif break; } @@ -4480,9 +4408,11 @@ case OP_MemStore: { if( pOp->p2 ){ pTos->flags = MEM_Null; }else{ - pMem->z = sqliteMallocRaw( pMem->n ); + pMem->z = sqliteMallocRaw( pMem->n+2 ); if( pMem->z==0 ) goto no_mem; memcpy(pMem->z, pTos->z, pMem->n); + memcpy(&pMem->z[pMem->n], "\000", 2); + pMem->flags |= MEM_Term; } }else if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; @@ -4591,7 +4521,6 @@ case OP_AggFunc: { for(i=0; ienc); } i = pTos->i; assert( i>=0 && iagg.nMem ); @@ -4669,9 +4598,6 @@ case OP_AggSet: { }else if( pMem->flags & MEM_Short ){ pMem->z = pMem->zShort; } - SetEncodingFlags(pMem, db->enc); - SetEncoding(pMem, MEM_Utf8|MEM_Term); - Release(pTos); pTos--; break; } @@ -4696,8 +4622,7 @@ case OP_AggGet: { pTos->flags |= MEM_Ephem; } if( pTos->flags&MEM_Str ){ - SetEncodingFlags(pTos, TEXT_Utf8); - SetEncoding(pTos, encToFlags(db->enc)|MEM_Term); + sqlite3VdbeChangeEncoding(pTos, db->enc); } break; } @@ -4812,6 +4737,8 @@ default: { /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */ assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort ); assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort ); + assert( (pTos->flags & MEM_Term)==0 || (pTos->flags & MEM_Str)==0 + || db->enc!=TEXT_Utf8 || strlen(pTos->z)==pTos->n ); }else{ /* Cannot define a string subtype for non-string objects */ assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 9dc55c24b5..1c0a680b66 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -352,14 +352,15 @@ int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*); int sqlite3VdbeRowCompare(void*,int,const void*,int, const void*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); -int sqlite3VdbeSetEncoding(Mem *, u8); +int sqlite3VdbeChangeEncoding(Mem *, int); int sqlite3VdbeMemCopy(Mem*, const Mem*); -int sqlite3VdbeMemNulTerminate(Mem *); +int sqlite3VdbeMemNulTerminate(Mem*); int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, int); -int sqlite3VdbeMemSetInt64(Mem*, long long int); -int sqlite3VdbeMemSetDouble(Mem*, double); +void sqlite3VdbeMemSetInt64(Mem*, long long int); +void sqlite3VdbeMemSetDouble(Mem*, double); +void sqlite3VdbeMemSetNull(Mem*); int sqlite3VdbeMemMakeWriteable(Mem*); int sqlite3VdbeMemDynamicify(Mem*); -int sqlite3VdbeMemStringify(Mem*); +int sqlite3VdbeMemStringify(Mem*, int); int sqlite3VdbeMemIntegerify(Mem*); int sqlite3VdbeMemRealify(Mem*); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index d21eb17308..bd34f942d3 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -44,17 +44,17 @@ int sqlite3_value_bytes16(sqlite3_value *pVal){ } double sqlite3_value_double(sqlite3_value *pVal){ Mem *pMem = (Mem *)pVal; - Realify(pMem, flagsToEnc(pMem->flags)); + sqlite3VdbeMemRealify(pMem); return pMem->r; } int sqlite3_value_int(sqlite3_value *pVal){ Mem *pMem = (Mem *)pVal; - Integerify(pMem, flagsToEnc(pMem->flags)); + sqlite3VdbeMemIntegerify(pMem); return (int)pVal->i; } long long int sqlite3_value_int64(sqlite3_value *pVal){ Mem *pMem = (Mem *)pVal; - Integerify(pMem, flagsToEnc(pMem->flags)); + sqlite3VdbeMemIntegerify(pMem); return pVal->i; } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ @@ -67,10 +67,10 @@ const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ /* If there is already a string representation, make sure it is in ** encoded in UTF-8. */ - SetEncoding(pVal, MEM_Utf8|MEM_Term); + sqlite3VdbeChangeEncoding(pVal, TEXT_Utf8); }else if( !(pVal->flags&MEM_Blob) ){ /* Otherwise, unless this is a blob, convert it to a UTF-8 string */ - Stringify(pVal, TEXT_Utf8); + sqlite3VdbeMemStringify(pVal, TEXT_Utf8); } return pVal->z; @@ -85,15 +85,17 @@ const void *sqlite3_value_text16(sqlite3_value* pVal){ /* If there is already a string representation, make sure it is in ** encoded in UTF-16 machine byte order. */ - SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term); + sqlite3VdbeChangeEncoding(pVal, TEXT_Utf16); }else if( !(pVal->flags&MEM_Blob) ){ /* Otherwise, unless this is a blob, convert it to a UTF-16 string */ - Stringify(pVal, TEXT_Utf16); + sqlite3VdbeMemStringify(pVal, TEXT_Utf16); } return (const void *)(pVal->z); } int sqlite3_value_type(sqlite3_value* pVal){ + return pVal->type; +#if 0 int f = ((Mem *)pVal)->flags; if( f&MEM_Null ){ return SQLITE3_NULL; @@ -111,6 +113,7 @@ int sqlite3_value_type(sqlite3_value* pVal){ return SQLITE3_BLOB; } assert(0); +#endif } /**************************** sqlite3_result_ ******************************* @@ -124,7 +127,7 @@ void sqlite3_result_blob( int eCopy ){ assert( n>0 ); - MemSetStr(&pCtx->s, z, n, 0, eCopy); + sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, eCopy); } void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ sqlite3VdbeMemSetDouble(&pCtx->s, rVal); @@ -137,14 +140,14 @@ void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ pCtx->isError = 1; sqlite3VdbeMemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1); } -void sqlite3_result_int32(sqlite3_context *pCtx, int iVal){ +void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal); } void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ sqlite3VdbeMemSetInt64(&pCtx->s, iVal); } void sqlite3_result_null(sqlite3_context *pCtx){ - sqilte3VdbeMemSetNull(&pCtx->s); + sqlite3VdbeMemSetNull(&pCtx->s); } void sqlite3_result_text( sqlite3_context *pCtx, @@ -152,7 +155,7 @@ void sqlite3_result_text( int n, int eCopy ){ - MemSetStr(&pCtx->s, z, n, TEXT_Utf8, eCopy); + sqlite3VdbeMemSetStr(&pCtx->s, z, n, TEXT_Utf8, eCopy); } void sqlite3_result_text16( sqlite3_context *pCtx, @@ -160,7 +163,7 @@ void sqlite3_result_text16( int n, int eCopy ){ - MemSetStr(&pCtx->s, z, n, TEXT_Utf16, eCopy); + sqlite3VdbeMemSetStr(&pCtx->s, z, n, TEXT_Utf16, eCopy); } void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ sqlite3VdbeMemCopy(&pCtx->s, pValue); @@ -442,7 +445,7 @@ static int vdbeUnbind(Vdbe *p, int i){ ** Bind a blob value to an SQL statement variable. */ int sqlite3_bind_blob( - sqlite3_stmt *p, + sqlite3_stmt *pStmt, int i, const void *zData, int nData, @@ -463,10 +466,9 @@ int sqlite3_bind_blob( int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; - Mem *pVar; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - sqlite3VdbeMemSetReal(&p->apVar[i-1], rValue); + sqlite3VdbeMemSetDouble(&p->apVar[i-1], rValue); } return SQLITE_OK; } @@ -478,7 +480,7 @@ int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, long long int iValue){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - sqlite3VdbeMemSetInt(&p->apVar[i-1], iValue); + sqlite3VdbeMemSetInt64(&p->apVar[i-1], iValue); } return rc; } @@ -505,7 +507,7 @@ int sqlite3_bind_text( if( rc ){ return rc; } - rc = sqlite3VdbeSetEncoding(pVar, p->db->enc); + rc = sqlite3VdbeChangeEncoding(pVar, p->db->enc); return rc; } int sqlite3_bind_text16( @@ -517,13 +519,13 @@ int sqlite3_bind_text16( ){ Vdbe *p = (Vdbe *)pStmt; Mem *pVar; - int rc; + int rc, txt_enc; rc = vdbeUnbind(p, i); if( rc ){ return rc; } - Mem *pVar = &p->apVar[i-1]; + pVar = &p->apVar[i-1]; /* There may or may not be a byte order mark at the start of the UTF-16. ** Either way set 'txt_enc' to the TEXT_Utf16* value indicating the @@ -542,6 +544,6 @@ int sqlite3_bind_text16( if( rc ){ return rc; } - rc = sqlite3VdbeSetEncoding(pVar, p->db->enc); + rc = sqlite3VdbeChangeEncoding(pVar, p->db->enc); return rc; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 256ec2b3d0..8c16d5836b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -571,7 +571,7 @@ int sqlite3VdbeList( Op *pOp = &p->aOp[i]; Mem *pMem = p->aStack; pMem->flags = MEM_Int; - pMem->type = SQLITE3_INT; + pMem->type = SQLITE3_INTEGER; pMem->i = i; /* Program counter */ pMem++; @@ -584,17 +584,17 @@ int sqlite3VdbeList( pMem->flags = MEM_Int; pMem->i = pOp->p1; /* P1 */ - pMem->type = SQLITE3_INT; + pMem->type = SQLITE3_INTEGER; pMem++; pMem->flags = MEM_Int; pMem->i = pOp->p2; /* P2 */ - pMem->type = SQLITE_INT; + pMem->type = SQLITE3_INTEGER; pMem++; pMem->flags = MEM_Short|MEM_Str|MEM_Term; /* P3 */ pMem->z = displayP3(pOp, pMem->zShort, sizeof(pMem->zShort)); - pMem->type = SQLITE_TEXT; + pMem->type = SQLITE3_TEXT; pMem->enc = TEXT_Utf8; p->nResColumn = 5; @@ -886,9 +886,9 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){ pColName = &(p->aColName[idx]); if( N==0 ){ - rc = MemSetStr(pColName, zName, -1, TEXT_Utf8, 1); + rc = sqlite3VdbeMemSetStr(pColName, zName, -1, TEXT_Utf8, 1); }else{ - rc = MemSetStr(pColName, zName, N, TEXT_Utf8, N>0); + rc = sqlite3VdbeMemSetStr(pColName, zName, N, TEXT_Utf8, N>0); } if( rc==SQLITE_OK && N==P3_DYNAMIC ){ pColName->flags = (pColName->flags&(~MEM_Static))|MEM_Dyn; diff --git a/src/vdbemem.c b/src/vdbemem.c index e801a1828a..c6bb66afa4 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -35,22 +35,20 @@ ** between formats. */ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ - u8 oldEnd; /* - /* If this is not a string, or if it is a string but the encoding is ** already correct, do nothing. */ if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ return SQLITE_OK; } - if( pMem->enc==TEXT_Utf8 || desiredEnd==TEXT_Utf8 ){ + if( pMem->enc==TEXT_Utf8 || desiredEnc==TEXT_Utf8 ){ /* If the current encoding does not match the desired encoding, then ** we will need to do some translation between encodings. */ char *z; int n; int rc = sqlite3utfTranslate(pMem->z, pMem->n, pMem->enc, - (void **)&z, &n, desiredEnd); + (void **)&z, &n, desiredEnc); if( rc!=SQLITE_OK ){ return rc; } @@ -67,7 +65,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ /* Must be translating between UTF-16le and UTF-16be. */ int i; u8 *pFrom, *pTo; - sqlite3VdbeMemMakeWritable(pMem); + sqlite3VdbeMemMakeWriteable(pMem); for(i=0, pFrom=pMem->z, pTo=&pMem->z[1]; in; i+=2, pFrom++, pTo++){ u8 temp = *pFrom; *pFrom = *pTo; @@ -83,7 +81,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ -int sqlite3VdbeMemMakeDynamicify(Mem *pMem){ +int sqlite3VdbeMemDynamicify(Mem *pMem){ int n; u8 *z; if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){ @@ -91,7 +89,7 @@ int sqlite3VdbeMemMakeDynamicify(Mem *pMem){ } assert( (pMem->flags & MEM_Dyn)==0 ); assert( pMem->flags & (MEM_Str|MEM_Blob) ); - z = sqliteMallocRaw( n+2 ) + z = sqliteMallocRaw( n+2 ); if( z==0 ){ return SQLITE_NOMEM; } @@ -101,6 +99,7 @@ int sqlite3VdbeMemMakeDynamicify(Mem *pMem){ z[n+1] = 0; pMem->z = z; pMem->flags &= ~(MEM_Ephem|MEM_Static|MEM_Short); + return SQLITE_OK; } /* @@ -109,7 +108,7 @@ int sqlite3VdbeMemMakeDynamicify(Mem *pMem){ ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ -int sqlite3VdbeMemMakeWritable(Mem *pMem){ +int sqlite3VdbeMemMakeWriteable(Mem *pMem){ int n; u8 *z; if( (pMem->flags & (MEM_Ephem|MEM_Static))==0 ){ @@ -121,7 +120,7 @@ int sqlite3VdbeMemMakeWritable(Mem *pMem){ z = pMem->zShort; pMem->flags |= MEM_Short|MEM_Term; }else{ - z = sqliteMallocRaw( n+2 ) + z = sqliteMallocRaw( n+2 ); if( z==0 ){ return SQLITE_NOMEM; } @@ -132,18 +131,19 @@ int sqlite3VdbeMemMakeWritable(Mem *pMem){ z[n+1] = 0; pMem->z = z; pMem->flags &= ~(MEM_Ephem|MEM_Static); + return SQLITE_OK; } /* ** 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 ){ + if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & (MEM_Str|MEM_Blob))==0 ){ return SQLITE_OK; /* Nothing to do */ } /* Only static or ephemeral strings can be unterminated */ assert( (pMem->flags & (MEM_Static|MEM_Ephem))!=0 ); - sqlite3VdbeMemMakeWriteable(pMem); + return sqlite3VdbeMemMakeWriteable(pMem); } /* @@ -186,14 +186,23 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ sqlite3_snprintf(NBFS, z, "%lld", pMem->i); } pMem->n = strlen(z); - pMem->z = n; + pMem->z = z; pMem->enc = TEXT_Utf8; pMem->flags |= MEM_Str | MEM_Short | MEM_Term; - sqlite3VdbeMemChangeEncoding(pMem, enc); + sqlite3VdbeChangeEncoding(pMem, enc); } return rc; } +/* +** Release any memory held by the Mem +*/ +static void releaseMem(Mem *p){ + if( p->flags & MEM_Dyn ){ + sqliteFree(p); + } +} + /* ** Convert the Mem to have representation MEM_Int only. All ** prior representations are invalidated. NULL is converted into 0. @@ -205,7 +214,7 @@ int sqlite3VdbeMemIntegerify(Mem *pMem){ pMem->i = (i64)pMem->r; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ if( sqlite3VdbeChangeEncoding(pMem, TEXT_Utf8) - || sqlite3VdbeNulTerminate(pMem) ){ + || sqlite3VdbeMemNulTerminate(pMem) ){ return SQLITE_NOMEM; } assert( pMem->z ); @@ -213,9 +222,10 @@ int sqlite3VdbeMemIntegerify(Mem *pMem){ }else{ pMem->i = 0; } - Release(pMem); + releaseMem(pMem); pMem->flags = MEM_Int; pMem->type = SQLITE3_INTEGER; + return SQLITE_OK; } /* @@ -229,28 +239,20 @@ int sqlite3VdbeMemRealify(Mem *pMem){ pMem->flags |= MEM_Real; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ if( sqlite3VdbeChangeEncoding(pMem, TEXT_Utf8) - || sqlite3VdbeNulTerminate(pMem) ){ + || sqlite3VdbeMemNulTerminate(pMem) ){ return SQLITE_NOMEM; } assert( pMem->z ); pMem->r = sqlite3AtoF(pMem->z, 0); - Release(pMem); + releaseMem(pMem); pMem->flags = MEM_Real; - pMem->type = SQLITE3_INTEGER; + pMem->type = SQLITE3_FLOAT; }else{ pMem->r = 0.0; pMem->flags = MEM_Real; - pMem->type = SQLITE3_INTEGER; - } -} - -/* -** Release any memory held by the Mem -*/ -static void releaseMem(Mem *p){ - if( p->flags & MEM_Dyn ){ - sqliteFree(p); + pMem->type = SQLITE3_FLOAT; } + return SQLITE_OK; } /* @@ -308,8 +310,6 @@ int sqlite3VdbeMemSetStr( u8 enc, /* Encoding of z. 0 for BLOBs */ int eCopy /* True if this function should make a copy of z */ ){ - Mem tmp; - releaseMem(pMem); if( !z ){ pMem->flags = MEM_Null; @@ -350,8 +350,9 @@ int sqlite3VdbeMemSetStr( assert(0); } if( eCopy ){ - sqlite3VdbeMemMakeWriteable(pMem); + return sqlite3VdbeMemMakeWriteable(pMem); } + return SQLITE_OK; } /*