diff options
author | drh <drh@noemail.net> | 2003-09-06 22:18:07 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2003-09-06 22:18:07 +0000 |
commit | 7c972dec5ca539a5f33507a00d5db2ba66373887 (patch) | |
tree | 989489c046b5beee09cf1bb010bd8d55603c4c1c /src | |
parent | 9a32464b543cda85c698bd14e3561c4ebff22da1 (diff) | |
download | sqlite-7c972dec5ca539a5f33507a00d5db2ba66373887.tar.gz sqlite-7c972dec5ca539a5f33507a00d5db2ba66373887.zip |
Update Makefile.in for the new vdbeaux.c file. Remove the experimental
"sqlite_instantiate()" routine and replace it with "sqlite_bind()" which
is more like ODBC and JDBC. (CVS 1095)
FossilOrigin-Name: 990bb11898a539bb0795a4a216fcd989943a0fb2
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 7 | ||||
-rw-r--r-- | src/expr.c | 4 | ||||
-rw-r--r-- | src/main.c | 30 | ||||
-rw-r--r-- | src/parse.y | 7 | ||||
-rw-r--r-- | src/sqlite.h.in | 42 | ||||
-rw-r--r-- | src/sqliteInt.h | 7 | ||||
-rw-r--r-- | src/test1.c | 41 | ||||
-rw-r--r-- | src/tokenize.c | 8 | ||||
-rw-r--r-- | src/vdbe.c | 15 | ||||
-rw-r--r-- | src/vdbe.h | 4 | ||||
-rw-r--r-- | src/vdbeInt.h | 6 | ||||
-rw-r--r-- | src/vdbeaux.c | 69 |
12 files changed, 129 insertions, 111 deletions
diff --git a/src/build.c b/src/build.c index 560fc305e..0e214676d 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.159 2003/08/24 16:38:18 drh Exp $ +** $Id: build.c,v 1.160 2003/09/06 22:18:08 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -51,6 +51,7 @@ void sqliteBeginParse(Parse *pParse, int explainFlag){ DbClearProperty(db, i, DB_Cookie); } } + pParse->nVar = 0; } /* @@ -86,7 +87,8 @@ void sqliteExec(Parse *pParse){ if( v && pParse->nErr==0 ){ FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqliteVdbeTrace(v, trace); - sqliteVdbeMakeReady(v, xCallback, pParse->pArg, pParse->explain); + sqliteVdbeMakeReady(v, pParse->nVar, xCallback, pParse->pArg, + pParse->explain); if( pParse->useCallback ){ if( pParse->explain ){ rc = sqliteVdbeList(v); @@ -110,6 +112,7 @@ void sqliteExec(Parse *pParse){ pParse->nMem = 0; pParse->nSet = 0; pParse->nAgg = 0; + pParse->nVar = 0; } /* diff --git a/src/expr.c b/src/expr.c index 46bd04d47..398bf8f62 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.99 2003/09/06 01:10:47 drh Exp $ +** $Id: expr.c,v 1.100 2003/09/06 22:18:08 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1046,7 +1046,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ break; } case TK_VARIABLE: { - sqliteVdbeAddOp(v, OP_Variable, atoi(&pExpr->token.z[1]), 0); + sqliteVdbeAddOp(v, OP_Variable, pExpr->iTable, 0); break; } case TK_LT: diff --git a/src/main.c b/src/main.c index 29a4d2ca0..1b0c692e8 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.141 2003/09/06 01:10:47 drh Exp $ +** $Id: main.c,v 1.142 2003/09/06 22:18:08 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -695,31 +695,6 @@ int sqlite_compile( return sqliteMain(db, zSql, 0, 0, pzTail, ppVm, pzErrMsg); } -/* -** If the SQL that was handed to sqlite_compile contains variables of -** the form $1, $2, $3, etc. then this routine assigns values to those -** variables. azValue[0] is assigned to $1. azValue[1] is assigned -** to $2. And so forth. The value of variable $0 will always be NULL. -** The values of any variable $N where N>nValue will be NULL. If any -** azValue[] is a NULL pointer, then the corresponding variable will be -** NULL. -** -** This routine can only be called immediately after sqlite_compile() -** or sqlite_reset() and before any calls to sqlite_step(). -** -** This routine makes copies of all strings in azValue[] so the values -** passed in can be changed or deleted immediately after this call. The -** copies are deallocated when sqlite_finalize() or sqlite_reset() is -** invoked. -*/ -int sqlite_instantiate( - sqlite_vm *pVm, - int nValue, - const char **azValue -){ - return sqliteVdbeSetVariables((Vdbe*)pVm, nValue, azValue); -} - /* ** The following routine destroys a virtual machine that is created by @@ -753,7 +728,7 @@ int sqlite_reset( char **pzErrMsg /* OUT: Write error messages here */ ){ int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg); - sqliteVdbeMakeReady((Vdbe*)pVm, 0, 0, 0); + sqliteVdbeMakeReady((Vdbe*)pVm, -1, 0, 0, 0); sqliteStrRealloc(pzErrMsg); return rc; } @@ -790,6 +765,7 @@ const char *sqlite_error_string(int rc){ case SQLITE_NOLFS: z = "kernel lacks large file support"; break; case SQLITE_AUTH: z = "authorization denied"; break; case SQLITE_FORMAT: z = "auxiliary database format error"; break; + case SQLITE_RANGE: z = "bind index out of range"; break; default: z = "unknown error"; break; } return z; diff --git a/src/parse.y b/src/parse.y index 5ea4f410f..21c033b10 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.100 2003/09/06 01:10:48 drh Exp $ +** @(#) $Id: parse.y,v 1.101 2003/09/06 22:18:08 drh Exp $ */ %token_prefix TK_ %token_type {Token} @@ -541,7 +541,10 @@ expr(A) ::= expr(B) ORACLE_OUTER_JOIN. expr(A) ::= INTEGER(X). {A = sqliteExpr(TK_INTEGER, 0, 0, &X);} expr(A) ::= FLOAT(X). {A = sqliteExpr(TK_FLOAT, 0, 0, &X);} expr(A) ::= STRING(X). {A = sqliteExpr(TK_STRING, 0, 0, &X);} -expr(A) ::= VARIABLE(X). {A = sqliteExpr(TK_VARIABLE, 0, 0, &X);} +expr(A) ::= VARIABLE(X). { + A = sqliteExpr(TK_VARIABLE, 0, 0, &X); + if( A ) A->iTable = ++pParse->nVar; +} expr(A) ::= ID(X) LP exprlist(Y) RP(E). { A = sqliteExprFunction(Y, &X); sqliteExprSpan(A,&X,&E); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index bcf8b38a2..3832ee6b9 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.51 2003/09/06 01:10:48 drh Exp $ +** @(#) $Id: sqlite.h.in,v 1.52 2003/09/06 22:18:08 drh Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -166,6 +166,7 @@ int sqlite_exec( #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ #define SQLITE_FORMAT 24 /* Auxiliary database format error */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite_bind out of range */ #define SQLITE_ROW 100 /* sqlite_step() has another row ready */ #define SQLITE_DONE 101 /* sqlite_step() has finished executing */ @@ -695,31 +696,38 @@ int sqlite_finalize(sqlite_vm*, char **pzErrMsg); ** ** If sqlite_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL. ** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ -int sqlite_reset(sqlite_vm *, char **pzErrMsg); +int sqlite_reset(sqlite_vm*, char **pzErrMsg); /* -** If the SQL that was handed to sqlite_compile contains variables of -** the form $1, $2, $3, etc. then this routine assigns values to those -** variables. azValue[0] is assigned to $1. azValue[1] is assigned -** to $2. And so forth. The value of variable $0 will always be NULL. -** The values of any variable $N where N>nValue will be NULL. If any -** azValue[] is a NULL pointer, then the corresponding variable will be -** NULL. +** If the SQL that was handed to sqlite_compile contains variables that +** are represeted in the SQL text by a question mark ('?'). This routine +** is used to assign values to those variables. +** +** The first parameter is a virtual machine obtained from sqlite_compile(). +** The 2nd "idx" parameter determines which variable in the SQL statement +** to bind the value to. The left most '?' is 1. The 3rd parameter is +** the value to assign to that variable. The 4th parameter is the number +** of bytes in the value, including the terminating \000 for strings. +** Finally, the 5th "copy" parameter is TRUE if SQLite should make its +** own private copy of this value, or false if the space that the 3rd +** parameter points to will be unchanging and can be used directly by +** SQLite. +** +** Unbound variables are treated as having a value of NULL. To explicitly +** set a variable to NULL, call this routine with the 3rd parameter as a +** NULL pointer. +** +** If the 4th "len" parameter is -1, then strlen() is used to find the +** length. ** ** This routine can only be called immediately after sqlite_compile() ** or sqlite_reset() and before any calls to sqlite_step(). ** -** This routine makes copies of all strings in azValue[] so the values -** passed in can be changed or deleted immediately after this call. The -** copies are deallocated when sqlite_finalize() or sqlite_reset() is -** invoked. -** ******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** */ -int sqlite_instantiate(sqlite_vm*, int, const char**); - - +int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy); #ifdef __cplusplus } /* End of the 'extern "C"' block */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 65944bec8..500bcf475 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.197 2003/08/23 22:40:54 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.198 2003/09/06 22:18:08 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -604,7 +604,9 @@ struct Token { ** it can be accessed after all aggregates are computed. ** ** If the expression is a function, the Expr.iTable is an integer code -** representing which function. +** representing which function. If the expression is an unbound variable +** marker (a question mark character '?' in the original SQL) then the +** Expr.iTable holds the index number for that variable. ** ** The Expr.pSelect field points to a SELECT statement. The SELECT might ** be the right operand of an IN operator. Or, if a scalar SELECT appears @@ -866,6 +868,7 @@ struct Parse { int nMem; /* Number of memory cells used so far */ int nSet; /* Number of sets used so far */ int nAgg; /* Number of aggregate expressions */ + int nVar; /* Number of '?' variables seen in the SQL so far */ AggExpr *aAgg; /* An array of aggregate expressions */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ diff --git a/src/test1.c b/src/test1.c index d768d3440..e8af1fc8f 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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.27 2003/09/06 01:10:48 drh Exp $ +** $Id: test1.c,v 1.28 2003/09/06 22:18:08 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -806,11 +806,22 @@ static int test_reset( } /* -** Usage: sqlite_instantiate VM ARGS... +** This is the "static_bind_value" that variables are bound to when +** the FLAG option of sqlite_bind is "static" +*/ +static char *sqlite_static_bind_value = 0; + +/* +** Usage: sqlite_bind VM IDX VALUE FLAGS ** -** Set the values of variables (ex: $1, $2, etc) in the original SQL string. +** Sets the value of the IDX-th occurance of "?" in the original SQL +** string. VALUE is the new value. If FLAGS=="null" then VALUE is +** ignored and the value is set to NULL. If FLAGS=="static" then +** the value is set to the value of a static variable named +** "sqlite_static_bind_value". If FLAGS=="normal" then a copy +** of the VALUE is made. */ -static int test_instantiate( +static int test_bind( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -818,13 +829,25 @@ static int test_instantiate( ){ sqlite_vm *vm; int rc; - if( argc<2 ){ + int idx; + if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " VM ARGS...\"", 0); + " VM IDX VALUE (null|static|normal)\"", 0); return TCL_ERROR; } if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR; - rc = sqlite_instantiate(vm, argc-2, &argv[2]); + if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; + if( strcmp(argv[4],"null")==0 ){ + rc = sqlite_bind(vm, idx, 0, 0, 0); + }else if( strcmp(argv[4],"static")==0 ){ + rc = sqlite_bind(vm, idx, sqlite_static_bind_value, -1, 0); + }else if( strcmp(argv[4],"normal")==0 ){ + rc = sqlite_bind(vm, idx, argv[3], -1, 1); + }else{ + Tcl_AppendResult(interp, "4th argument should be " + "\"null\" or \"static\" or \"normal\"", 0); + return TCL_ERROR; + } if( rc ){ char zBuf[50]; sprintf(zBuf, "(%d) ", rc); @@ -887,7 +910,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite_compile", (Tcl_CmdProc*)test_compile }, { "sqlite_step", (Tcl_CmdProc*)test_step }, { "sqlite_finalize", (Tcl_CmdProc*)test_finalize }, - { "sqlite_instantiate", (Tcl_CmdProc*)test_instantiate }, + { "sqlite_bind", (Tcl_CmdProc*)test_bind }, { "sqlite_reset", (Tcl_CmdProc*)test_reset }, { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, }; @@ -900,5 +923,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ (char*)&sqlite_search_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_open_file_count", (char*)&sqlite_open_file_count, TCL_LINK_INT); + Tcl_LinkVar(interp, "sqlite_static_bind_value", + (char*)&sqlite_static_bind_value, TCL_LINK_STRING); return TCL_OK; } diff --git a/src/tokenize.c b/src/tokenize.c index 7a187186e..24433a07f 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.61 2003/09/06 01:10:48 drh Exp $ +** $Id: tokenize.c,v 1.62 2003/09/06 22:18:08 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -380,11 +380,9 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_ID; return i; } - case '$': { - if( !isdigit(z[1]) ) break; - for(i=1; z[i] && isdigit(z[i]); i++){} + case '?': { *tokenType = TK_VARIABLE; - return i; + return 1; } default: { if( !isIdChar[*z] ){ diff --git a/src/vdbe.c b/src/vdbe.c index 305168dfc..e1f1154a4 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.239 2003/09/06 20:12:01 drh Exp $ +** $Id: vdbe.c,v 1.240 2003/09/06 22:18:08 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -711,14 +711,17 @@ case OP_String: { ** ** Push the value of variable P1 onto the stack. A variable is ** an unknown in the original SQL string as handed to sqlite_compile(). -** The first variable is $1, the second is $2, and so forth. The -** value of the variables is determined by sqlite_instantiate(). +** Any occurance of the '?' character in the original SQL is considered +** a variable. Variables in the SQL string are number from left to +** right beginning with 1. The values of variables are set using the +** sqlite_bind() API. */ case OP_Variable: { int i = ++p->tos; - if( pOp->p1>0 && pOp->p1<=p->nVariable && p->azVariable[pOp->p1-1]!=0 ){ - zStack[i] = p->azVariable[pOp->p1-1]; - aStack[i].n = strlen(zStack[i]) + 1; + int j = pOp->p1 - 1; + if( j>=0 && j<p->nVar && p->azVar[j]!=0 ){ + zStack[i] = p->azVar[j]; + aStack[i].n = p->anVar[j]; aStack[i].flags = STK_Str | STK_Static; }else{ zStack[i] = 0; diff --git a/src/vdbe.h b/src/vdbe.h index 494313dcb..87fea2517 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.67 2003/09/06 01:10:49 drh Exp $ +** $Id: vdbe.h,v 1.68 2003/09/06 22:18:08 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -84,7 +84,7 @@ int sqliteVdbeFindOp(Vdbe*, int, int); VdbeOp *sqliteVdbeGetOp(Vdbe*, int); int sqliteVdbeMakeLabel(Vdbe*); void sqliteVdbeDelete(Vdbe*); -void sqliteVdbeMakeReady(Vdbe*,sqlite_callback,void*,int); +void sqliteVdbeMakeReady(Vdbe*,int,sqlite_callback,void*,int); int sqliteVdbeExec(Vdbe*); int sqliteVdbeList(Vdbe*); int sqliteVdbeFinalize(Vdbe*,char**); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 20aebdb4f..d168387cd 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -235,8 +235,10 @@ struct Vdbe { FILE *pFile; /* At most one open file handler */ int nField; /* Number of file fields */ char **azField; /* Data for each file field */ - int nVariable; /* Number of entries in azVariable[] */ - char **azVariable; /* Values for the OP_Variable opcode */ + int nVar; /* Number of entries in azVariable[] */ + char **azVar; /* Values for the OP_Variable opcode */ + int *anVar; /* Length of each value in azVariable[] */ + u8 *abVar; /* TRUE if azVariable[i] needs to be sqliteFree()ed */ char *zLine; /* A single line from the input file */ int nLineAlloc; /* Number of spaces allocated for zLine */ int magic; /* Magic number for sanity checking */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9fedb8dd0..dd6737632 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -568,6 +568,7 @@ int sqliteVdbeList( */ void sqliteVdbeMakeReady( Vdbe *p, /* The VDBE */ + int nVar, /* Number of '?' see in the SQL statement */ sqlite_callback xCallback, /* Result callback */ void *pCallbackArg, /* 1st argument to xCallback() */ int isExplain /* True if the EXPLAIN keywords is present */ @@ -591,10 +592,17 @@ void sqliteVdbeMakeReady( ** ** Allocation all the stack space we will ever need. */ + p->nVar = nVar>=0 ? nVar : p->nVar; n = isExplain ? 10 : p->nOp; - p->aStack = sqliteMalloc( n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) ); + p->aStack = sqliteMalloc( + n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) /* aStack and zStack */ + + p->nVar*(sizeof(char*)+sizeof(int)+1) /* azVar, anVar, abVar */ + ); p->zStack = (char**)&p->aStack[n]; p->azColName = (char**)&p->zStack[n]; + p->azVar = (char**)&p->azColName[n]; + p->anVar = (int*)&p->azVar[p->nVar]; + p->abVar = (u8*)&p->anVar[p->nVar]; sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0); p->agg.pSearch = 0; @@ -740,15 +748,6 @@ static void closeAllCursors(Vdbe *p){ } /* -** Delete the variables in p->azVariable[] -*/ -static void ClearVariableArray(Vdbe *p){ - sqliteFree(p->azVariable); - p->nVariable = 0; - p->azVariable = 0; -} - -/* ** Clean up the VM after execution. ** ** This routine will automatically close any cursors, lists, and/or @@ -808,7 +807,6 @@ static void Cleanup(Vdbe *p){ } sqliteFree(p->zErrMsg); p->zErrMsg = 0; - ClearVariableArray(p); } /* @@ -927,37 +925,33 @@ int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){ ** ** This routine overrides any prior call. */ -int sqliteVdbeSetVariables(Vdbe *p, int nValue, const char **azValue){ - int i, n; - char *z; - if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 || p->nVariable!=0 ){ +int sqlite_bind(sqlite_vm *pVm, int i, const char *zVal, int len, int copy){ + Vdbe *p = (Vdbe*)pVm; + if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){ return SQLITE_MISUSE; } - ClearVariableArray(p); - if( nValue==0 ){ - p->nVariable = 0; - p->azVariable = 0; + if( i<1 || i>p->nVar ){ + return SQLITE_RANGE; } - for(i=n=0; i<nValue; i++){ - if( azValue[i] ) n += strlen(azValue[i]) + 1; + i--; + if( p->abVar[i] ){ + sqliteFree(p->azVar[i]); } - p->azVariable = sqliteMalloc( sizeof(p->azVariable[0])*nValue + n ); - if( p->azVariable==0 ){ - p->nVariable = 0; - return SQLITE_NOMEM; + if( zVal==0 ){ + copy = 0; + len = 0; } - z = (char*)&p->azVariable[nValue]; - for(i=0; i<nValue; i++){ - if( azValue[i]==0 ){ - p->azVariable[i] = 0; - }else{ - p->azVariable[i] = z; - n = strlen(azValue[i]); - memcpy(z, azValue[i], n+1); - z += n+1; - } + if( len<0 ){ + len = strlen(zVal)+1; + } + if( copy ){ + p->azVar[i] = sqliteMalloc( len ); + if( p->azVar[i] ) memcpy(p->azVar[i], zVal, len); + }else{ + p->azVar[i] = zVal; } - p->nVariable = nValue; + p->abVar[i] = copy; + p->anVar[i] = len; return SQLITE_OK; } @@ -988,6 +982,9 @@ void sqliteVdbeDelete(Vdbe *p){ sqliteFree(p->aOp[i].p3); } } + for(i=0; i<p->nVar; i++){ + if( p->abVar[i] ) sqliteFree(p->azVar[i]); + } sqliteFree(p->aOp); sqliteFree(p->aLabel); sqliteFree(p->aStack); |