Wildcards with the same name map into the same variable number. New
api sqlite3_bind_parameter_index() added to map wildcard names into wildcard index numbers. Support for "?nnn" wildcards. (CVS 1945) FossilOrigin-Name: 435b3f301fbb6953adc974c7f03589b06e9114c3
This commit is contained in:
parent
1807ce37b8
commit
fa6bc0000f
28
manifest
28
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sthe\sonecolumn\smethod\sin\sthe\sTCL\sinterface\sso\sthat\sit\sworks\sthe\ssame\nas\sthe\seval\smethod\sin\sall\sways\sexcept\sfor\sreturning\sjust\sthe\sfirst\svalue\nin\sthe\sresult\sset.\s(CVS\s1944)
|
||||
D 2004-09-07T13:20:35
|
||||
C Wildcards\swith\sthe\ssame\sname\smap\sinto\sthe\ssame\svariable\snumber.\s\sNew\napi\ssqlite3_bind_parameter_index()\sadded\sto\smap\swildcard\snames\sinto\nwildcard\sindex\snumbers.\s\sSupport\sfor\s"?nnn"\swildcards.\s(CVS\s1945)
|
||||
D 2004-09-07T16:19:53
|
||||
F Makefile.in 65a7c43fcaf9a710d62f120b11b6e435eeb4a450
|
||||
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
|
||||
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
|
||||
@ -34,7 +34,7 @@ F src/build.c c6940e4a663fa6b7dc3dff34f7dddbc45d331d48
|
||||
F src/date.c eb8d5fa1a6d5cfc09031c8852d10ff742a94b15b
|
||||
F src/delete.c e887f44aae1e33da1643df58abe86cd9cde45ad1
|
||||
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
|
||||
F src/expr.c 5b6881a229e49869c348825aa1f1af6bd6b4bc76
|
||||
F src/expr.c 9130794d8c86af2cbf2b8cdc66f2158167fd15b1
|
||||
F src/func.c 14bf20710a10fe66266e16da4364ca2dd8c4c36d
|
||||
F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
|
||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||
@ -54,22 +54,22 @@ F src/os_win.c 9e2887825b1a32f0ceb1b73b93ffe29a112cd86f
|
||||
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
|
||||
F src/pager.c ae06c85de0db43f61a7a3e5eacad3fd5615daf59
|
||||
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
|
||||
F src/parse.y 581a2ce014b843506805b2470c02b7865ad034d5
|
||||
F src/parse.y 9389af67bd49b8e5c9d2968b3315a30565b4a200
|
||||
F src/pragma.c 6385059dfd77eee9fe7e53c0469776315f136ae0
|
||||
F src/printf.c 17b28a1eedfe8129b05de981719306c18c3f1327
|
||||
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
|
||||
F src/select.c 6e3ec12a01c6d5b51459d6ddaca36040d9e7730e
|
||||
F src/shell.c 4f1a2760ced81c829defb47b0a3b61ffec61b604
|
||||
F src/sqlite.h.in 8bdf3fc4c76040f939cb1831eb97babf6a2fa858
|
||||
F src/sqliteInt.h 0840e651db8e16f88f2b8a2393ac98dfdbf01df0
|
||||
F src/sqlite.h.in e29a526593b806f148017ed8bada760ada84cf2f
|
||||
F src/sqliteInt.h abbb66373b410e242b617af0364def4f7af084fc
|
||||
F src/table.c 8168c6e824009f8485bff79fc60ea8fea6829b10
|
||||
F src/tclsqlite.c 9225350a3144b3c0dd07a3cc88d2c219d57e2f0d
|
||||
F src/test1.c 0a7ae23d822177ecf3e8b577d026f0c8a39fe5c3
|
||||
F src/test1.c e7df5556002c50e917420f6f0edcc63047567659
|
||||
F src/test2.c f4c2f3928f1998fd8cb75a81e33a60e025ea85d4
|
||||
F src/test3.c 94d0a2a90bccd85802488cb42c69ec8afd2e4646
|
||||
F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
|
||||
F src/test5.c b001fa7f1b9e2dc5c2331de62fc641b5ab2bd7a1
|
||||
F src/tokenize.c 566ca7d1354dcb990475a52990056fc387d49df1
|
||||
F src/tokenize.c 60525d9966d90f548f44cc37116378379424c2a1
|
||||
F src/trigger.c 98dd620bebd9f3dadaacf0db3958b916cf1e7b7f
|
||||
F src/update.c 0e00300763d2ce0dbd6a0598882a5039580b225e
|
||||
F src/utf.c 328890099db492dda5620ee5f924e244c6e57ff7
|
||||
@ -78,7 +78,7 @@ F src/vacuum.c 819a3f411cb8d2d714e55f0805e8c23a642dd7ba
|
||||
F src/vdbe.c b19de04c57b4136a8e0203d5e3b76dd82bded1b5
|
||||
F src/vdbe.h 067ca8d6750ba4f69a50284765e5883dee860181
|
||||
F src/vdbeInt.h e09362d6323a725de3c30b0cc381a691e86ed697
|
||||
F src/vdbeapi.c e3fa5b775161bc8337c20f2e46a68bb4746b2094
|
||||
F src/vdbeapi.c 20bf8901592c7f38e8aabb448a913327ab19f0a7
|
||||
F src/vdbeaux.c 4080a6162d96818f875a95ead4f67cb9ca8ecf15
|
||||
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
|
||||
F src/where.c 12e214870c84546858ddb9f121165a1fbfce6811
|
||||
@ -89,7 +89,7 @@ F test/attach3.test 6d060986ff004ebb89e1876a331d96c6bb62269e
|
||||
F test/auth.test e74b015545f608c06d5b84d17acdf7146eb818af
|
||||
F test/bigfile.test 62722ac4b420dfbcdceb137b8634e2cf2865fe27
|
||||
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
|
||||
F test/bind.test 7968edd61eb83b6e09165e4ba38e327dace6fb35
|
||||
F test/bind.test d7e7f44817a6dbe0faedbb699ad2b559e5a3a7bb
|
||||
F test/blob.test 8727a7b46b2073a369cfc9bcb6f54dd366b9d884
|
||||
F test/btree.test 97b563e1ab999bf8764b129e8c4b4be0a116a52a
|
||||
F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
|
||||
@ -217,7 +217,7 @@ F www/arch2b.fig d22a2c9642d584b89d4088b1e51e2bb0f7c04bed
|
||||
F www/audit.tcl 90e09d580f79c7efec0c7d6f447b7ec5c2dce5c0
|
||||
F www/c_interface.tcl 83b39203e1ded4c2dab97f42edf31279a308efcb
|
||||
F www/capi3.tcl 5c1cb163f4d2a54e2d0e22dcc399dd71245c8b89
|
||||
F www/capi3ref.tcl bead38516efb0227ffa6ac76beb3f7ea405bb389
|
||||
F www/capi3ref.tcl aa6ea82ea34ff71357300b8f1ab9fd8232a9eec8
|
||||
F www/changes.tcl 3641bc28b86b40c82d546727da45ea0f0aa9a9f4
|
||||
F www/common.tcl f786e6be86fb2627ceb30e770e9efa83b9c67a3a
|
||||
F www/conflict.tcl fb8a2ba83746c7fdfd9e52fa7f6aaf5c422b8246
|
||||
@ -248,7 +248,7 @@ F www/tclsqlite.tcl 560ecd6a916b320e59f2917317398f3d59b7cc25
|
||||
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
|
||||
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
|
||||
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
|
||||
P d53047cbbc4e618c7bb5161b6f82876bb113db25
|
||||
R 303fc0394eb00108b3dd869bec641bd9
|
||||
P f323e4f86a08fe6448cbd4ff7cab459e8039d9f1
|
||||
R b14b673cf74913bc0aa77288120014ba
|
||||
U drh
|
||||
Z 3769d67a37ed8f4ac0e4d151ebaba45a
|
||||
Z abec07c7d353cf60af4ed426f1ba4bbf
|
||||
|
@ -1 +1 @@
|
||||
f323e4f86a08fe6448cbd4ff7cab459e8039d9f1
|
||||
435b3f301fbb6953adc974c7f03589b06e9114c3
|
71
src/expr.c
71
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.160 2004/09/06 17:24:13 drh Exp $
|
||||
** $Id: expr.c,v 1.161 2004/09/07 16:19:53 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@ -273,6 +273,75 @@ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/*
|
||||
** Assign a variable number to an expression that encodes a wildcard
|
||||
** in the original SQL statement.
|
||||
**
|
||||
** Wildcards consisting of a single "?" are assigned the next sequential
|
||||
** variable number.
|
||||
**
|
||||
** Wildcards of the form "?nnn" are assigned the number "nnn". We make
|
||||
** sure "nnn" is not too be to avoid a denial of service attack when
|
||||
** the SQL statement comes from an external source.
|
||||
**
|
||||
** Wildcards of the form ":aaa" or "$aaa" are assigned the same number
|
||||
** as the previous instance of the same wildcard. Or if this is the first
|
||||
** instance of the wildcard, the next sequenial variable number is
|
||||
** assigned.
|
||||
*/
|
||||
void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
|
||||
Token *pToken;
|
||||
if( pExpr==0 ) return;
|
||||
pToken = &pExpr->token;
|
||||
assert( pToken->n>=1 );
|
||||
assert( pToken->z!=0 );
|
||||
assert( pToken->z[0]!=0 );
|
||||
if( pToken->n==1 ){
|
||||
/* Wildcard of the form "?". Assign the next variable number */
|
||||
pExpr->iTable = ++pParse->nVar;
|
||||
}else if( pToken->z[0]=='?' ){
|
||||
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
|
||||
** use it as the variable number */
|
||||
int i;
|
||||
pExpr->iTable = i = atoi(&pToken->z[1]);
|
||||
if( i<1 || i>SQLITE_MAX_VARIABLE_NUMBER ){
|
||||
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
|
||||
SQLITE_MAX_VARIABLE_NUMBER);
|
||||
}
|
||||
if( i>pParse->nVar ){
|
||||
pParse->nVar = i;
|
||||
}
|
||||
}else{
|
||||
/* Wildcards of the form ":aaa" or "$aaa". Reuse the same variable
|
||||
** number as the prior appearance of the same name, or if the name
|
||||
** has never appeared before, reuse the same variable number
|
||||
*/
|
||||
int i, n;
|
||||
n = pToken->n;
|
||||
for(i=0; i<pParse->nVarExpr; i++){
|
||||
Expr *pE;
|
||||
if( (pE = pParse->apVarExpr[i])!=0
|
||||
&& pE->token.n==n
|
||||
&& memcmp(pE->token.z, pToken->z, n)==0 ){
|
||||
pExpr->iTable = pE->iTable;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( i>=pParse->nVarExpr ){
|
||||
pExpr->iTable = ++pParse->nVar;
|
||||
if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){
|
||||
pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10;
|
||||
pParse->apVarExpr = sqliteRealloc(pParse->apVarExpr,
|
||||
pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
|
||||
}
|
||||
if( !sqlite3_malloc_failed ){
|
||||
assert( pParse->apVarExpr!=0 );
|
||||
pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Recursively delete an expression tree.
|
||||
*/
|
||||
|
@ -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.135 2004/08/25 04:07:02 drh Exp $
|
||||
** @(#) $Id: parse.y,v 1.136 2004/09/07 16:19:54 drh Exp $
|
||||
*/
|
||||
%token_prefix TK_
|
||||
%token_type {Token}
|
||||
@ -560,9 +560,7 @@ expr(A) ::= BLOB(X). {A = sqlite3Expr(@X, 0, 0, &X);}
|
||||
expr(A) ::= VARIABLE(X). {
|
||||
Token *pToken = &X;
|
||||
Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
|
||||
if( pExpr ){
|
||||
pExpr->iTable = ++pParse->nVar;
|
||||
}
|
||||
sqlite3ExprAssignVarNumber(pParse, pExpr);
|
||||
}
|
||||
expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
|
||||
A = sqlite3ExprFunction(Y, &X);
|
||||
|
@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the SQLite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.118 2004/09/06 17:34:13 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.119 2004/09/07 16:19:54 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@ -640,12 +640,19 @@ int sqlite3_bind_parameter_count(sqlite3_stmt*);
|
||||
|
||||
/*
|
||||
** Return the name of the i-th parameter. Ordinary wildcards "?" are
|
||||
** nameless and a NULL is returned. For wildcards of the form :N: or
|
||||
** nameless and a NULL is returned. For wildcards of the form :N or
|
||||
** $vvvv the complete text of the wildcard is returned.
|
||||
** NULL is returned if the index is out of range.
|
||||
*/
|
||||
const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
|
||||
|
||||
/*
|
||||
** Return the index of a parameter with the given name. The name
|
||||
** must match exactly. If no parameter with the given name is found,
|
||||
** return 0.
|
||||
*/
|
||||
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
|
||||
|
||||
/*
|
||||
** Return the number of columns in the result set returned by the compiled
|
||||
** SQL statement. This routine returns 0 if pStmt is an SQL statement
|
||||
|
@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.319 2004/09/06 17:24:13 drh Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.320 2004/09/07 16:19:54 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@ -67,6 +67,11 @@
|
||||
*/
|
||||
#define MAX_ATTACHED 10
|
||||
|
||||
/*
|
||||
** The maximum value of a ?nnn wildcard that the parser will accept.
|
||||
*/
|
||||
#define SQLITE_MAX_VARIABLE_NUMBER 999
|
||||
|
||||
/*
|
||||
** When building SQLite for embedded systems where memory is scarce,
|
||||
** you can define one or more of the following macros to omit extra
|
||||
@ -990,6 +995,9 @@ struct Parse {
|
||||
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 */
|
||||
int nVarExpr; /* Number of used slots in apVarExpr[] */
|
||||
int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */
|
||||
Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */
|
||||
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 */
|
||||
@ -1209,6 +1217,7 @@ Expr *sqlite3Expr(int, Expr*, Expr*, Token*);
|
||||
Expr *sqlite3ExprAnd(Expr*, Expr*);
|
||||
void sqlite3ExprSpan(Expr*,Token*,Token*);
|
||||
Expr *sqlite3ExprFunction(ExprList*, Token*);
|
||||
void sqlite3ExprAssignVarNumber(Parse*, Expr*);
|
||||
void sqlite3ExprDelete(Expr*);
|
||||
ExprList *sqlite3ExprListAppend(ExprList*,Expr*,Token*);
|
||||
void sqlite3ExprListDelete(ExprList*);
|
||||
|
30
src/test1.c
30
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.101 2004/09/06 17:24:13 drh Exp $
|
||||
** $Id: test1.c,v 1.102 2004/09/07 16:19:54 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@ -1645,6 +1645,33 @@ static int test_bind_parameter_name(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_bind_parameter_index STMT NAME
|
||||
**
|
||||
** Return the index of the wildcard called NAME. Return 0 if there is
|
||||
** no such wildcard.
|
||||
*/
|
||||
static int test_bind_parameter_index(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
|
||||
if( objc!=3 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewIntObj(
|
||||
sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2]))
|
||||
)
|
||||
);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_errcode DB
|
||||
**
|
||||
@ -2463,6 +2490,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_bind_blob", test_bind_blob ,0 },
|
||||
{ "sqlite3_bind_parameter_count", test_bind_parameter_count, 0},
|
||||
{ "sqlite3_bind_parameter_name", test_bind_parameter_name, 0},
|
||||
{ "sqlite3_bind_parameter_index", test_bind_parameter_index, 0},
|
||||
{ "sqlite3_errcode", test_errcode ,0 },
|
||||
{ "sqlite3_errmsg", test_errmsg ,0 },
|
||||
{ "sqlite3_errmsg16", test_errmsg16 ,0 },
|
||||
|
@ -15,7 +15,7 @@
|
||||
** individual tokens and sends those tokens one-by-one over to the
|
||||
** parser for analysis.
|
||||
**
|
||||
** $Id: tokenize.c,v 1.85 2004/09/06 17:24:13 drh Exp $
|
||||
** $Id: tokenize.c,v 1.86 2004/09/07 16:19:54 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@ -371,7 +371,8 @@ static int sqliteGetToken(const unsigned char *z, int *tokenType){
|
||||
}
|
||||
case '?': {
|
||||
*tokenType = TK_VARIABLE;
|
||||
return 1;
|
||||
for(i=1; isdigit(z[i]); i++){}
|
||||
return i;
|
||||
}
|
||||
case ':': {
|
||||
for(i=1; (z[i]&0x80)!=0 || isIdChar[z[i]]; i++){}
|
||||
@ -474,7 +475,13 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
||||
return 1;
|
||||
}
|
||||
pParse->sLastToken.dyn = 0;
|
||||
assert( pParse->sLastToken.dyn==0 );
|
||||
assert( pParse->pNewTable==0 );
|
||||
assert( pParse->pNewTrigger==0 );
|
||||
assert( pParse->nVar==0 );
|
||||
assert( pParse->nVarExpr==0 );
|
||||
assert( pParse->nVarExprAlloc==0 );
|
||||
assert( pParse->apVarExpr==0 );
|
||||
pParse->zTail = pParse->zSql = zSql;
|
||||
while( sqlite3_malloc_failed==0 && zSql[i]!=0 ){
|
||||
assert( i>=0 );
|
||||
@ -541,14 +548,9 @@ abort_parse:
|
||||
sqlite3VdbeDelete(pParse->pVdbe);
|
||||
pParse->pVdbe = 0;
|
||||
}
|
||||
if( pParse->pNewTable ){
|
||||
sqlite3DeleteTable(pParse->db, pParse->pNewTable);
|
||||
pParse->pNewTable = 0;
|
||||
}
|
||||
if( pParse->pNewTrigger ){
|
||||
sqlite3DeleteTrigger(pParse->pNewTrigger);
|
||||
pParse->pNewTrigger = 0;
|
||||
}
|
||||
sqlite3DeleteTable(pParse->db, pParse->pNewTable);
|
||||
sqlite3DeleteTrigger(pParse->pNewTrigger);
|
||||
sqliteFree(pParse->apVarExpr);
|
||||
if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){
|
||||
pParse->rc = SQLITE_ERROR;
|
||||
}
|
||||
|
@ -525,16 +525,11 @@ int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the name of a wildcard parameter. Return NULL if the index
|
||||
** is out of range or if the wildcard is unnamed.
|
||||
**
|
||||
** The result is always UTF-8.
|
||||
** Create a mapping from variable numbers to variable names
|
||||
** in the Vdbe.azVar[] array, if such a mapping does not already
|
||||
** exist.
|
||||
*/
|
||||
const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
if( p==0 || i<1 || i>p->nVar ){
|
||||
return 0;
|
||||
}
|
||||
static void createVarMap(Vdbe *p){
|
||||
if( !p->okVar ){
|
||||
int j;
|
||||
Op *pOp;
|
||||
@ -546,5 +541,39 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
|
||||
}
|
||||
p->okVar = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the name of a wildcard parameter. Return NULL if the index
|
||||
** is out of range or if the wildcard is unnamed.
|
||||
**
|
||||
** The result is always UTF-8.
|
||||
*/
|
||||
const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
if( p==0 || i<1 || i>p->nVar ){
|
||||
return 0;
|
||||
}
|
||||
createVarMap(p);
|
||||
return p->azVar[i-1];
|
||||
}
|
||||
|
||||
/*
|
||||
** Given a wildcard parameter name, return the index of the variable
|
||||
** with that name. If there is no variable with the given name,
|
||||
** return 0.
|
||||
*/
|
||||
int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
|
||||
Vdbe *p = (Vdbe*)pStmt;
|
||||
int i;
|
||||
if( p==0 ){
|
||||
return 0;
|
||||
}
|
||||
createVarMap(p);
|
||||
for(i=0; i<p->nVar; i++){
|
||||
if( strcmp(p->azVar[i],zName)==0 ){
|
||||
return i+1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
104
test/bind.test
104
test/bind.test
@ -11,7 +11,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script testing the sqlite_bind API.
|
||||
#
|
||||
# $Id: bind.test,v 1.18 2004/08/25 04:07:03 drh Exp $
|
||||
# $Id: bind.test,v 1.19 2004/09/07 16:19:54 drh Exp $
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -115,6 +115,18 @@ do_test bind-2.1.3 {
|
||||
do_test bind-2.1.4 {
|
||||
sqlite3_bind_parameter_name $VM 3
|
||||
} {${x}}
|
||||
do_test bind-2.1.5 {
|
||||
sqlite3_bind_parameter_index $VM {$one}
|
||||
} 1
|
||||
do_test bind-2.1.6 {
|
||||
sqlite3_bind_parameter_index $VM {$::two}
|
||||
} 2
|
||||
do_test bind-2.1.7 {
|
||||
sqlite3_bind_parameter_index $VM {${x}}
|
||||
} 3
|
||||
do_test bind-2.1.8 {
|
||||
sqlite3_bind_parameter_index $VM {:hi}
|
||||
} 0
|
||||
|
||||
# 32 bit Integers
|
||||
do_test bind-2.2 {
|
||||
@ -280,10 +292,98 @@ do_test bind-8.15 {
|
||||
catch { sqlite3_bind_double $VM 4 6.0 }
|
||||
} {1}
|
||||
|
||||
do_test bind-9.99 {
|
||||
do_test bind-8.99 {
|
||||
sqlite3_finalize $VM
|
||||
} SQLITE_OK
|
||||
|
||||
do_test bind-9.1 {
|
||||
execsql {
|
||||
CREATE TABLE t2(a,b,c,d,e,f);
|
||||
}
|
||||
set rc [catch {
|
||||
sqlite3_prepare $DB {
|
||||
INSERT INTO t2(a) VALUES(?0)
|
||||
} -1 TAIL
|
||||
} msg]
|
||||
lappend rc $msg
|
||||
} {1 {(1) variable number must be between ?1 and ?999}}
|
||||
do_test bind-9.2 {
|
||||
set rc [catch {
|
||||
sqlite3_prepare $DB {
|
||||
INSERT INTO t2(a) VALUES(?1000)
|
||||
} -1 TAIL
|
||||
} msg]
|
||||
lappend rc $msg
|
||||
} {1 {(1) variable number must be between ?1 and ?999}}
|
||||
do_test bind-9.3 {
|
||||
set VM [
|
||||
sqlite3_prepare $DB {
|
||||
INSERT INTO t2(a,b) VALUES(?1,?999)
|
||||
} -1 TAIL
|
||||
]
|
||||
sqlite3_bind_parameter_count $VM
|
||||
} {999}
|
||||
catch {sqlite3_finalize $VM}
|
||||
do_test bind-9.4 {
|
||||
set VM [
|
||||
sqlite3_prepare $DB {
|
||||
INSERT INTO t2(a,b,c,d) VALUES(?1,?999,?,?)
|
||||
} -1 TAIL
|
||||
]
|
||||
sqlite3_bind_parameter_count $VM
|
||||
} {1001}
|
||||
do_test bind-9.5 {
|
||||
sqlite3_bind_int $VM 1 1
|
||||
sqlite3_bind_int $VM 999 999
|
||||
sqlite3_bind_int $VM 1000 1000
|
||||
sqlite3_bind_int $VM 1001 1001
|
||||
sqlite3_step $VM
|
||||
} SQLITE_DONE
|
||||
do_test bind-9.6 {
|
||||
sqlite3_finalize $VM
|
||||
} SQLITE_OK
|
||||
do_test bind-9.7 {
|
||||
execsql {SELECT * FROM t2}
|
||||
} {1 999 1000 1001 {} {}}
|
||||
|
||||
do_test bind-10.1 {
|
||||
catch {sqlite3_finalize $VM}
|
||||
set VM [
|
||||
sqlite3_prepare $DB {
|
||||
INSERT INTO t2(a,b,c,d,e,f) VALUES(:abc,$abc,:abc,$ab,$abc,:abc)
|
||||
} -1 TAIL
|
||||
]
|
||||
sqlite3_bind_parameter_count $VM
|
||||
} 3
|
||||
do_test bind-10.2 {
|
||||
sqlite3_bind_parameter_index $VM :abc
|
||||
} 1
|
||||
do_test bind-10.3 {
|
||||
sqlite3_bind_parameter_index $VM {$abc}
|
||||
} 2
|
||||
do_test bind-10.4 {
|
||||
sqlite3_bind_parameter_index $VM {$ab}
|
||||
} 3
|
||||
do_test bind-10.5 {
|
||||
sqlite3_bind_parameter_name $VM 1
|
||||
} :abc
|
||||
do_test bind-10.6 {
|
||||
sqlite3_bind_parameter_name $VM 2
|
||||
} {$abc}
|
||||
do_test bind-10.7 {
|
||||
sqlite3_bind_parameter_name $VM 3
|
||||
} {$ab}
|
||||
do_test bind-10.8 {
|
||||
sqlite3_bind_int $VM 1 1
|
||||
sqlite3_bind_int $VM 2 2
|
||||
sqlite3_bind_int $VM 3 3
|
||||
sqlite3_step $VM
|
||||
} SQLITE_DONE
|
||||
do_test bind-10.9 {
|
||||
sqlite3_finalize $VM
|
||||
} SQLITE_OK
|
||||
do_test bind-10.10 {
|
||||
execsql {SELECT * FROM t2}
|
||||
} {1 999 1000 1001 {} {} 1 2 1 3 2 1}
|
||||
|
||||
finish_test
|
||||
|
@ -1,4 +1,4 @@
|
||||
set rcsid {$Id: capi3ref.tcl,v 1.10 2004/08/28 16:19:01 drh Exp $}
|
||||
set rcsid {$Id: capi3ref.tcl,v 1.11 2004/09/07 16:19:54 drh Exp $}
|
||||
source common.tcl
|
||||
header {C/C++ Interface For SQLite Version 3}
|
||||
puts {
|
||||
@ -124,13 +124,22 @@ api {} {
|
||||
} {
|
||||
Return the name of the n-th wildcard in the precompiled statement.
|
||||
Wildcards of the form ":AAA" have a name which is the string ":AAA".
|
||||
Wildcards of the form "?" have no name.
|
||||
Wildcards of the form "?" or "?NNN" have no name.
|
||||
|
||||
If the value n is out of range or if the n-th wildcard is nameless,
|
||||
then NULL is returned. The returned string is always in the
|
||||
UTF-8 encoding.
|
||||
}
|
||||
|
||||
api {} {
|
||||
int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
|
||||
} {
|
||||
Return the index of the wildcard with the given name.
|
||||
The name must match exactly.
|
||||
If there is no wildcard with the given name, return 0.
|
||||
The string zName is always in the UTF-8 encoding.
|
||||
}
|
||||
|
||||
api {} {
|
||||
int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
|
||||
} {
|
||||
|
Loading…
x
Reference in New Issue
Block a user