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
This commit is contained in:
drh 2003-09-06 22:18:07 +00:00
parent 9a32464b54
commit 7c972dec5c
15 changed files with 163 additions and 135 deletions

View File

@ -82,7 +82,7 @@ LIBOBJ = attach.lo auth.lo btree.lo build.lo copy.lo \
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.
@ -126,6 +126,7 @@ SRC = \
$(TOP)/src/util.c \
$(TOP)/src/vacuum.c \
$(TOP)/src/vdbe.c \
$(TOP)/src/vdbeaux.c \
$(TOP)/src/vdbe.h \
$(TOP)/src/where.c
@ -154,6 +155,12 @@ HDR = \
$(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.
#
@ -185,10 +192,10 @@ sqlite: $(TOP)/src/shell.c libsqlite.la sqlite.h
# 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
@ -268,9 +275,12 @@ tokenize.lo: $(TOP)/src/tokenize.c $(HDR)
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

View File

@ -1,6 +1,6 @@
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
@ -26,45 +26,45 @@ F src/auth.c c8f50d4507e37779d96ff3c55417bc2b612dfed6
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
@ -172,7 +172,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
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

View File

@ -1 +1 @@
bfd69391d3d63675f206ffd8ff0401ea1cbcc073
990bb11898a539bb0795a4a216fcd989943a0fb2

View File

@ -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;
}
/*

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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...
**
** Set the values of variables (ex: $1, $2, etc) in the original SQL string.
** This is the "static_bind_value" that variables are bound to when
** the FLAG option of sqlite_bind is "static"
*/
static int test_instantiate(
static char *sqlite_static_bind_value = 0;
/*
** Usage: sqlite_bind VM IDX VALUE FLAGS
**
** 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_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;
}

View File

@ -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] ){

View File

@ -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;

View File

@ -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**);

View File

@ -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 */

View File

@ -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;
@ -739,15 +747,6 @@ static void closeAllCursors(Vdbe *p){
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.
**
@ -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;
}
p->nVariable = nValue;
if( copy ){
p->azVar[i] = sqliteMalloc( len );
if( p->azVar[i] ) memcpy(p->azVar[i], zVal, len);
}else{
p->azVar[i] = zVal;
}
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);