aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/vdbeapi.c8
-rw-r--r--src/vdbetrace.c49
3 files changed, 26 insertions, 32 deletions
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 3adba1c62..334a39a0f 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -2961,6 +2961,7 @@ int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
int sqlite3VtabBegin(sqlite3 *, VTable *);
FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
+int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
int sqlite3Reprepare(Vdbe*);
void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 8bf3024e7..a8667080b 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -1120,8 +1120,7 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
** 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 sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
int i;
if( p==0 ){
return 0;
@@ -1130,13 +1129,16 @@ int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
if( zName ){
for(i=0; i<p->nVar; i++){
const char *z = p->azVar[i];
- if( z && strcmp(z,zName)==0 ){
+ if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){
return i+1;
}
}
}
return 0;
}
+int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
+ return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
+}
/*
** Transfer all bindings from the first statement over to the second.
diff --git a/src/vdbetrace.c b/src/vdbetrace.c
index e788a33c7..4da881622 100644
--- a/src/vdbetrace.c
+++ b/src/vdbetrace.c
@@ -24,15 +24,19 @@
** a host parameter. If the text contains no host parameters, return
** the total number of bytes in the text.
*/
-static int findNextHostParameter(const char *zSql){
+static int findNextHostParameter(const char *zSql, int *pnToken){
int tokenType;
int nTotal = 0;
int n;
+ *pnToken = 0;
while( zSql[0] ){
n = sqlite3GetToken((u8*)zSql, &tokenType);
assert( n>0 && tokenType!=TK_ILLEGAL );
- if( tokenType==TK_VARIABLE ) break;
+ if( tokenType==TK_VARIABLE ){
+ *pnToken = n;
+ break;
+ }
nTotal += n;
zSql += n;
}
@@ -40,9 +44,9 @@ static int findNextHostParameter(const char *zSql){
}
/*
-** Return a pointer to a string in memory obtained form sqlite3Malloc() which
+** Return a pointer to a string in memory obtained form sqlite3DbMalloc() which
** holds a copy of zRawSql but with host parameters expanded to their
-** current values.
+** current bindings.
**
** The calling function is responsible for making sure the memory returned
** is eventually freed.
@@ -63,10 +67,9 @@ char *sqlite3VdbeExpandSql(
int idx; /* Index of a host parameter */
int nextIndex = 1; /* Index of next ? host parameter */
int n; /* Length of a token prefix */
+ int nToken; /* Length of the parameter token */
int i; /* Loop counter */
- int dummy; /* For holding a unused return value */
Mem *pVar; /* Value of a host parameter */
- VdbeOp *pOp; /* For looping over opcodes */
StrAccum out; /* Accumulate the output here */
char zBase[100]; /* Initial working space */
@@ -75,19 +78,16 @@ char *sqlite3VdbeExpandSql(
db->aLimit[SQLITE_LIMIT_LENGTH]);
out.db = db;
while( zRawSql[0] ){
- n = findNextHostParameter(zRawSql);
+ n = findNextHostParameter(zRawSql, &nToken);
assert( n>0 );
sqlite3StrAccumAppend(&out, zRawSql, n);
zRawSql += n;
- if( zRawSql[0]==0 ) break;
+ assert( zRawSql[0] || nToken==0 );
+ if( nToken==0 ) break;
if( zRawSql[0]=='?' ){
- zRawSql++;
- if( sqlite3Isdigit(zRawSql[0]) ){
- idx = 0;
- while( sqlite3Isdigit(zRawSql[0]) ){
- idx = idx*10 + zRawSql[0] - '0';
- zRawSql++;
- }
+ if( nToken>1 ){
+ assert( sqlite3Isdigit(zRawSql[1]) );
+ sqlite3GetInt32(&zRawSql[1], &idx);
}else{
idx = nextIndex;
}
@@ -96,20 +96,10 @@ char *sqlite3VdbeExpandSql(
testcase( zRawSql[0]==':' );
testcase( zRawSql[0]=='$' );
testcase( zRawSql[0]=='@' );
- n = sqlite3GetToken((u8*)zRawSql, &dummy);
- idx = 0;
- for(i=0, pOp=p->aOp; ALWAYS(i<p->nOp); i++, pOp++){
- if( pOp->opcode!=OP_Variable ) continue;
- if( pOp->p3>1 ) continue;
- if( pOp->p4.z==0 ) continue;
- if( memcmp(pOp->p4.z, zRawSql, n)==0 && pOp->p4.z[n]==0 ){
- idx = pOp->p1;
- break;
- }
- }
+ idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
assert( idx>0 );
- zRawSql += n;
}
+ zRawSql += nToken;
nextIndex = idx + 1;
assert( idx>0 && idx<=p->nVar );
pVar = &p->aVar[idx-1];
@@ -121,11 +111,12 @@ char *sqlite3VdbeExpandSql(
sqlite3XPrintf(&out, "%!.15g", pVar->r);
}else if( pVar->flags & MEM_Str ){
#ifndef SQLITE_OMIT_UTF16
- if( ENC(db)!=SQLITE_UTF8 ){
+ u8 enc = ENC(db);
+ if( enc!=SQLITE_UTF8 ){
Mem utf8;
memset(&utf8, 0, sizeof(utf8));
utf8.db = db;
- sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, ENC(db), SQLITE_STATIC);
+ sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8);
sqlite3XPrintf(&out, "'%.*q'", utf8.n, utf8.z);
sqlite3VdbeMemRelease(&utf8);