delete.lo expr.lo func.lo hash.lo insert.lo \
main.lo opcodes.lo os.lo pager.lo parse.lo pragma.lo \
printf.lo random.lo select.lo table.lo tokenize.lo \
- update.lo util.lo vacuum.lo vdbe.lo \
+ update.lo util.lo vacuum.lo vdbe.lo vdbeaux.lo \
where.lo trigger.lo
# Only build the in-core DB if it is required.
$(TOP)/src/util.c \
$(TOP)/src/vacuum.c \
$(TOP)/src/vdbe.c \
+ $(TOP)/src/vdbeaux.c \
$(TOP)/src/vdbe.h \
$(TOP)/src/where.c
$(TOP)/src/vdbe.h \
parse.h
+# Header files used by the VDBE submodule
+#
+VDBEHDR = \
+ $(HDR) \
+ $(TOP)/src/vdbeInt.h
+
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
# files are automatically generated. This target takes care of
# all that automatic generation.
#
-target_source: $(SRC) $(HDR)
+target_source: $(SRC) $(VDBEHDR)
rm -rf tsrc
mkdir tsrc
- cp $(SRC) $(HDR) tsrc
+ cp $(SRC) $(VDBEHDR) tsrc
rm tsrc/sqlite.h.in tsrc/parse.y
cp parse.c opcodes.c tsrc
util.lo: $(TOP)/src/util.c $(HDR)
$(LIBTOOL) $(TCC) -c $(TOP)/src/util.c
-vdbe.lo: $(TOP)/src/vdbe.c $(HDR)
+vdbe.lo: $(TOP)/src/vdbe.c $(VDBEHDR)
$(LIBTOOL) $(TCC) -c $(TOP)/src/vdbe.c
+vdbeaux.lo: $(TOP)/src/vdbe.c $(VDBEHDR)
+ $(LIBTOOL) $(TCC) -c $(TOP)/src/vdbeaux.c
+
where.lo: $(TOP)/src/where.c $(HDR)
$(LIBTOOL) $(TCC) -c $(TOP)/src/where.c
-C Split\salmost\s1300\slines\sof\scode\sout\sof\svdbe.c\sinto\sseparate\sfiles\nvdbeInt.h\sand\svdbeaux.c.\s(CVS\s1094)
-D 2003-09-06T20:12:01
-F Makefile.in f7e916ae863393827fa6a4cb292e3398096edcf1
+C Update\sMakefile.in\sfor\sthe\snew\svdbeaux.c\sfile.\s\sRemove\sthe\sexperimental\n"sqlite_instantiate()"\sroutine\sand\sreplace\sit\swith\s"sqlite_bind()"\swhich\nis\smore\slike\sODBC\sand\sJDBC.\s(CVS\s1095)
+D 2003-09-06T22:18:08
+F Makefile.in 0cf2ffb6dc35694895e0dac488bc1259b6a4eb90
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F VERSION 97d209249f825001288ff942df07b48e1083af5c
F src/btree.c ba1cc0c71c3d2742b9a9047832335dc7d3656c45
F src/btree.h 9b7c09f1e64274d7bb74a57bbfc63778f67b1048
F src/btree_rb.c 550ce12841a87380554abae4442571567463de3a
-F src/build.c 7cdc95266496f53673a66202477b137d514898cf
+F src/build.c 9def3a3b8fba59325ed686049b88c2e7aff9af12
F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73
F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc
F src/encode.c 25ea901a9cefb3d93774afa4a06b57cb58acf544
-F src/expr.c 0c10a35c15756e90940d946cdec1e5c7d860ddc9
+F src/expr.c 8acdc2f7b2e756fc62336c728ab6a579979a5719
F src/func.c 377ea94127351de27892a62a63f931e0fbaa33d4
F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3
F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8
F src/insert.c dc200ae04a36bd36e575272a069e20c528b7fbdf
-F src/main.c e472b0c86b811a76b6a17760c945acfabd8ba935
+F src/main.c ae92469674db9987de2848e373cd41a394621e32
F src/md5.c fe4f9c9c6f71dfc26af8da63e4d04489b1430565
F src/os.c 97df440bc71f65e22df5d3d920ce39551c0a5f5a
F src/os.h 729395fefcca4b81ae056aa9ff67b72bb40dd9e0
F src/pager.c 62702dff51d50694d039bc210f31990d1fbba2dd
F src/pager.h 5da62c83443f26b1792cfd72c96c422f91aadd31
-F src/parse.y 5cd707f0e5444b1dd168e414dd2c055fb158db5c
+F src/parse.y 121daf2125dc2023029398a2ef38feb86cb5306a
F src/pragma.c cee60f17679210e8acd30d5bdee855716d0c898c
F src/printf.c 12e45d482ac8abcc6f786fc99e5bed7dd9a51af0
F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
F src/select.c 2fa83d6c972d3e3f379faee32e3621411490dedb
F src/shell.c c2ba26c850874964f5ec1ebf6c43406f28e44c4a
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
-F src/sqlite.h.in 72c07cf3b70c42a0e829270527f7b40a55d4a2d6
-F src/sqliteInt.h e68eb1eeba806905acc9ed491f4c5b96587020df
+F src/sqlite.h.in f8ae61546942e5a81df0ce3118048bec8dc87be4
+F src/sqliteInt.h 8901c15945b3b0f7ef4c13ebbc2deeb4765014d5
F src/table.c 4301926464d88d2c2c7cd21c3360aa75bf068b95
F src/tclsqlite.c ec9e5b796bf9ec1483927e986828a205d4a7422a
-F src/test1.c 751e11106c637d8ee64ecf95597b0133c544ab9f
+F src/test1.c f9d5816610f7ec4168ab7b098d5207a5708712b6
F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
-F src/tokenize.c ea4e89b37db050fb99ae4c916bd7671375845aaf
+F src/tokenize.c 74152bde07da0623aaa60fb6ab71d5af1c035546
F src/trigger.c 474581eaab388233df01bb019e558af2965decbf
F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
F src/util.c f16efa2d60bfd4e31ae06b07ed149557e828d294
F src/vacuum.c e4724eade07e4cf8897060a8cf632dbd92408eeb
-F src/vdbe.c 00c547e77d4100b6671c1509df5993ab315a166c
-F src/vdbe.h 3c51cb382316dbf3860e4ece72e658b4bf014501
-F src/vdbeInt.h 15cd01061b2f0acb967bdc5195fe1e891bb707a1
-F src/vdbeaux.c ebf5eab163fa8435e4fc24bcebe4eab4147d871b
+F src/vdbe.c 4570d4361838327f45aa3788034e108c048b4d3f
+F src/vdbe.h 3957844e46fea71fd030e78f6a3bd2f7e320fb43
+F src/vdbeInt.h 2824bf88895b901b3a8c9e44527c67530e1c0dcb
+F src/vdbeaux.c 402daaa4f9c861a5182c47456d372715d2cd571f
F src/where.c 83b2a2d26d5c3bea33457a83e541bb1dcf7b1248
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test c26848402e7ac829e043e1fa5e0eb87032e5d81d
F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
-P 912f47c72d3597c6d5acff765d94922bd660339a
-R 197956f145d2d77ab02def05dccb6402
+P bfd69391d3d63675f206ffd8ff0401ea1cbcc073
+R dac64908088b314675a59ad2bf8654f6
U drh
-Z 7934264d068323cc21204d69f10c800f
+Z 438620e1ac865f39fe826e6f5d8d262a
-bfd69391d3d63675f206ffd8ff0401ea1cbcc073
\ No newline at end of file
+990bb11898a539bb0795a4a216fcd989943a0fb2
\ No newline at end of file
** 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>
DbClearProperty(db, i, DB_Cookie);
}
}
+ pParse->nVar = 0;
}
/*
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);
pParse->nMem = 0;
pParse->nSet = 0;
pParse->nAgg = 0;
+ pParse->nVar = 0;
}
/*
** 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>
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:
** 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"
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
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;
}
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;
** 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}
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);
** 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_
#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 */
**
** 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 */
*************************************************************************
** 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"
** 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
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 */
** 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"
}
/*
-** 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 */
){
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);
{ "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 },
};
(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;
}
** 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"
*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] ){
** 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"
**
** 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;
** 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_
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**);
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 */
*/
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 */
**
** 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;
p->nCursor = 0;
}
-/*
-** 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.
**
}
sqliteFree(p->zErrMsg);
p->zErrMsg = 0;
- ClearVariableArray(p);
}
/*
**
** 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;
}
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);