diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/vdbeapi.c | 8 | ||||
-rw-r--r-- | src/vdbetrace.c | 49 |
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); |