mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Use the VList object to replace Parse.azVar for tracking the mapping between
SQL parameter names and parameter numbers. There is a performance improvement, though there are still a few hiccups in the current code. FossilOrigin-Name: 68ecafa1425a41358c88f41efea3262f1b4490f2
This commit is contained in:
29
manifest
29
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Fix\sharmless\scompiler\swarnings.
|
C Use\sthe\sVList\sobject\sto\sreplace\sParse.azVar\sfor\stracking\sthe\smapping\sbetween\nSQL\sparameter\snames\sand\sparameter\snumbers.\s\sThere\sis\sa\sperformance\nimprovement,\sthough\sthere\sare\sstill\sa\sfew\shiccups\sin\sthe\scurrent\scode.
|
||||||
D 2016-12-22T14:53:25.934
|
D 2016-12-23T03:59:31.797
|
||||||
F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e
|
F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
|
F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
|
||||||
@@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a
|
|||||||
F src/date.c b48378aeac68fa20c811404955a9b62108df47d8
|
F src/date.c b48378aeac68fa20c811404955a9b62108df47d8
|
||||||
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d
|
||||||
F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5
|
F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5
|
||||||
F src/expr.c c7c11fbe8bd4d27d04f1370efcce5a05b4fca229
|
F src/expr.c e640b1c82b0f22f6c00b75989b0c13503bd5083e
|
||||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||||
F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
|
F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae
|
||||||
F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a
|
F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a
|
||||||
@@ -393,7 +393,7 @@ F src/shell.c bf79a69d1f9b53de958498752b78e9906c5d0aff
|
|||||||
F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc
|
F src/sqlite.h.in e8e2d108d82647f0a812fdb74accf91c1ec08ddc
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
F src/sqlite3ext.h 8648034aa702469afb553231677306cc6492a1ae
|
||||||
F src/sqliteInt.h adbe80409c2926d91e5485789e5bf69313cd54b0
|
F src/sqliteInt.h 2075e22d50833ca2d9956d0b7a6bfb845ad05dd2
|
||||||
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
|
||||||
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
|
||||||
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
|
||||||
@@ -448,18 +448,18 @@ F src/test_windirent.c 600398db0198ca1c77ca183831bf456746b6f5c4
|
|||||||
F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01
|
F src/test_windirent.h 7edc57e2faa727026dbd5d010dd0e2e665d5aa01
|
||||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||||
F src/tokenize.c 6eb0752c4fd191f789190c3708ee5b0060fd2829
|
F src/tokenize.c 5c2f516876fc27fbd7753913f032f49eb89e83b5
|
||||||
F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c
|
F src/treeview.c 4e44ade3bfe59d82005039f72e09333ce2b4162c
|
||||||
F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
|
F src/trigger.c c9f0810043b265724fdb1bdd466894f984dfc182
|
||||||
F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8
|
F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8
|
||||||
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
|
||||||
F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1
|
F src/util.c adf5ff9e457b69d3cab2afa45c9c4ce5da83da06
|
||||||
F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
|
F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
|
||||||
F src/vdbe.c 0106e0d4f0d39aced35c150a6919d2878df6b1e0
|
F src/vdbe.c 54b12d95dbf10533ab2584acbf31ae12b8bfe171
|
||||||
F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c
|
F src/vdbe.h 50ee139f9c68fff91be1d717ed3a6abbd496919c
|
||||||
F src/vdbeInt.h 42e498dbe96475dbb3fda3d85d8fd2a87eff60a2
|
F src/vdbeInt.h 281cb70332dc8b593b8c7afe776f3a2ba7d4255e
|
||||||
F src/vdbeapi.c 129a2a1103e29fe839e137c641ff42b8066667b5
|
F src/vdbeapi.c d6ebaa465f070eb1af8ba4e7b34583ece87bdd24
|
||||||
F src/vdbeaux.c 7f67112cc57b2fa37b777fbf03eb32c96b337cfe
|
F src/vdbeaux.c 1e2840804828d32332565485b7faa755a3acabdb
|
||||||
F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65
|
F src/vdbeblob.c f4f98ea672b242f807c08c92c7faaa79e5091b65
|
||||||
F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd
|
F src/vdbemem.c d3fd85b7b7ef3eb75de29c6d7e1d10d3ca78b4fd
|
||||||
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
|
F src/vdbesort.c eda25cb2d1727efca6f7862fea32b8aa33c0face
|
||||||
@@ -1539,7 +1539,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 52a12e47de88744187bd1c71f2820885cde414a8
|
P fa86db2f915c0a189c3be02b1aaa7f24d339d7d6
|
||||||
R d04805544fe17af2729028773b1348a0
|
R 4ff4f0f6aea9a4ccf6f07bfaa8f513d5
|
||||||
|
T *branch * VList
|
||||||
|
T *sym-VList *
|
||||||
|
T -sym-trunk *
|
||||||
U drh
|
U drh
|
||||||
Z 33ba125ec9059ffd904b774699d11e2c
|
Z d52e7f32e7ed6699ecd9b8a5a1a7ee92
|
||||||
|
@@ -1 +1 @@
|
|||||||
fa86db2f915c0a189c3be02b1aaa7f24d339d7d6
|
68ecafa1425a41358c88f41efea3262f1b4490f2
|
35
src/expr.c
35
src/expr.c
@@ -934,7 +934,7 @@ Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *pToken){
|
|||||||
** variable number.
|
** variable number.
|
||||||
**
|
**
|
||||||
** Wildcards of the form "?nnn" are assigned the number "nnn". We make
|
** 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
|
** sure "nnn" is not too big to avoid a denial of service attack when
|
||||||
** the SQL statement comes from an external source.
|
** the SQL statement comes from an external source.
|
||||||
**
|
**
|
||||||
** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
|
** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
|
||||||
@@ -981,30 +981,13 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
|
|||||||
** number as the prior appearance of the same name, or if the name
|
** number as the prior appearance of the same name, or if the name
|
||||||
** has never appeared before, reuse the same variable number
|
** has never appeared before, reuse the same variable number
|
||||||
*/
|
*/
|
||||||
ynVar i;
|
x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n);
|
||||||
for(i=x=0; i<pParse->nzVar; i++){
|
if( x==0 ){
|
||||||
if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
|
x = (ynVar)(++pParse->nVar);
|
||||||
x = (ynVar)i+1;
|
pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( x==0 ) x = (ynVar)(++pParse->nVar);
|
|
||||||
}
|
|
||||||
pExpr->iColumn = x;
|
pExpr->iColumn = x;
|
||||||
if( x>pParse->nzVar ){
|
|
||||||
char **a;
|
|
||||||
a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
|
|
||||||
if( a==0 ){
|
|
||||||
assert( db->mallocFailed ); /* Error reported through mallocFailed */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pParse->azVar = a;
|
|
||||||
memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
|
|
||||||
pParse->nzVar = x;
|
|
||||||
}
|
|
||||||
if( pParse->azVar[x-1]==0 ){
|
|
||||||
pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
|
if( pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
|
||||||
sqlite3ErrorMsg(pParse, "too many SQL variables");
|
sqlite3ErrorMsg(pParse, "too many SQL variables");
|
||||||
@@ -3430,9 +3413,11 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
|
|||||||
assert( pExpr->u.zToken[0]!=0 );
|
assert( pExpr->u.zToken[0]!=0 );
|
||||||
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
|
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
|
||||||
if( pExpr->u.zToken[1]!=0 ){
|
if( pExpr->u.zToken[1]!=0 ){
|
||||||
assert( pExpr->u.zToken[0]=='?'
|
const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
|
||||||
|| strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 );
|
if( z ){
|
||||||
sqlite3VdbeAppendP4(v, pParse->azVar[pExpr->iColumn-1], P4_STATIC);
|
assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
|
||||||
|
sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
@@ -1046,6 +1046,14 @@ typedef struct Walker Walker;
|
|||||||
typedef struct WhereInfo WhereInfo;
|
typedef struct WhereInfo WhereInfo;
|
||||||
typedef struct With With;
|
typedef struct With With;
|
||||||
|
|
||||||
|
/* A VList object records a mapping between parameters/variables/wildcards
|
||||||
|
** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
|
||||||
|
** variable number associated with that parameter. See the format description
|
||||||
|
** on the sqlite3VListAdd() routine for more information. A VList is really
|
||||||
|
** just an array of integers.
|
||||||
|
*/
|
||||||
|
typedef int VList;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Defer sourcing vdbe.h and btree.h until after the "u8" and
|
** Defer sourcing vdbe.h and btree.h until after the "u8" and
|
||||||
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
|
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
|
||||||
@@ -2952,7 +2960,6 @@ struct Parse {
|
|||||||
|
|
||||||
Token sLastToken; /* The last token parsed */
|
Token sLastToken; /* The last token parsed */
|
||||||
ynVar nVar; /* Number of '?' variables seen in the SQL so far */
|
ynVar nVar; /* Number of '?' variables seen in the SQL so far */
|
||||||
int nzVar; /* Number of available slots in azVar[] */
|
|
||||||
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
|
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
|
||||||
u8 explain; /* True if the EXPLAIN flag is found on the query */
|
u8 explain; /* True if the EXPLAIN flag is found on the query */
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
@@ -2964,7 +2971,7 @@ struct Parse {
|
|||||||
int iSelectId; /* ID of current select for EXPLAIN output */
|
int iSelectId; /* ID of current select for EXPLAIN output */
|
||||||
int iNextSelectId; /* Next available select ID for EXPLAIN output */
|
int iNextSelectId; /* Next available select ID for EXPLAIN output */
|
||||||
#endif
|
#endif
|
||||||
char **azVar; /* Pointers to names of parameters */
|
VList *pVList; /* Mapping between variable names and numbers */
|
||||||
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
|
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
|
||||||
const char *zTail; /* All SQL text past the last semicolon parsed */
|
const char *zTail; /* All SQL text past the last semicolon parsed */
|
||||||
Table *pNewTable; /* A table being constructed by CREATE TABLE */
|
Table *pNewTable; /* A table being constructed by CREATE TABLE */
|
||||||
@@ -3864,6 +3871,9 @@ LogEst sqlite3LogEstFromDouble(double);
|
|||||||
defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
|
defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
|
||||||
u64 sqlite3LogEstToInt(LogEst);
|
u64 sqlite3LogEstToInt(LogEst);
|
||||||
#endif
|
#endif
|
||||||
|
VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
|
||||||
|
const char *sqlite3VListNumToName(VList*,int);
|
||||||
|
int sqlite3VListNameToNum(VList*,const char*,int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Routines to read and write variable-length integers. These used to
|
** Routines to read and write variable-length integers. These used to
|
||||||
|
@@ -500,8 +500,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
|||||||
assert( pParse->pNewTable==0 );
|
assert( pParse->pNewTable==0 );
|
||||||
assert( pParse->pNewTrigger==0 );
|
assert( pParse->pNewTrigger==0 );
|
||||||
assert( pParse->nVar==0 );
|
assert( pParse->nVar==0 );
|
||||||
assert( pParse->nzVar==0 );
|
assert( pParse->pVList==0 );
|
||||||
assert( pParse->azVar==0 );
|
|
||||||
while( 1 ){
|
while( 1 ){
|
||||||
assert( i>=0 );
|
assert( i>=0 );
|
||||||
if( zSql[i]!=0 ){
|
if( zSql[i]!=0 ){
|
||||||
@@ -588,8 +587,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
|||||||
|
|
||||||
if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
|
if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
|
||||||
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
|
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
|
||||||
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
|
sqlite3DbFree(db, pParse->pVList);
|
||||||
sqlite3DbFree(db, pParse->azVar);
|
|
||||||
while( pParse->pAinc ){
|
while( pParse->pAinc ){
|
||||||
AutoincInfo *p = pParse->pAinc;
|
AutoincInfo *p = pParse->pAinc;
|
||||||
pParse->pAinc = p->pNext;
|
pParse->pAinc = p->pNext;
|
||||||
|
89
src/util.c
89
src/util.c
@@ -1453,3 +1453,92 @@ u64 sqlite3LogEstToInt(LogEst x){
|
|||||||
return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
|
return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
|
||||||
}
|
}
|
||||||
#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
|
#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Add a new name/number pair to a VList. This might require that the
|
||||||
|
** VList object be reallocated, so return the new VList. If an OOM
|
||||||
|
** error occurs, the original VList freed, NULL is returned, and the
|
||||||
|
** db->mallocFailed flag is set.
|
||||||
|
**
|
||||||
|
** A VList is really just an array of integers. To destroy a VList,
|
||||||
|
** simply pass it to sqlite3DbFree().
|
||||||
|
**
|
||||||
|
** The first integer is the number of integers allocated for the whole
|
||||||
|
** VList. The second integer is the number of integers actually used.
|
||||||
|
** Each name/number pair is encoded by subsequent groups of 3 or more
|
||||||
|
** integers.
|
||||||
|
**
|
||||||
|
** Each name/number pair starts with two integers which are the number
|
||||||
|
** value for the pair and the size of the name/number pair, respectively.
|
||||||
|
** The text name overlays one or more following integers. The text name
|
||||||
|
** is always zero-terminated.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
VList *sqlite3VListAdd(
|
||||||
|
sqlite3 *db, /* The database connection used for malloc() */
|
||||||
|
VList *pIn, /* The input VList. Might be NULL */
|
||||||
|
const char *zName, /* Name of symbol to add */
|
||||||
|
int nName, /* Bytes of text in zName */
|
||||||
|
int iVal /* Value to associate with zName */
|
||||||
|
){
|
||||||
|
int nInt; /* number of sizeof(int) objects needed for zName */
|
||||||
|
char *z;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nInt = nName/4 + 3;
|
||||||
|
if( pIn==0 || pIn[1]+nInt > pIn[0] ){
|
||||||
|
/* Enlarge the allocation */
|
||||||
|
int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
|
||||||
|
VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
|
||||||
|
if( pOut==0 ){
|
||||||
|
sqlite3DbFree(db, pIn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( pIn==0 ) pOut[1] = 2;
|
||||||
|
pIn = pOut;
|
||||||
|
pIn[0] = nAlloc;
|
||||||
|
}
|
||||||
|
i = pIn[1];
|
||||||
|
pIn[i] = iVal;
|
||||||
|
pIn[i+1] = nInt;
|
||||||
|
z = (char*)&pIn[i+2];
|
||||||
|
pIn[1] = i+nInt;
|
||||||
|
assert( pIn[1]<=pIn[0] );
|
||||||
|
memcpy(z, zName, nName);
|
||||||
|
z[nName] = 0;
|
||||||
|
return pIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return a pointer to the name of a variable in the given VList that
|
||||||
|
** has the value iVal. Or return a NULL if there is no such variable in
|
||||||
|
** the list
|
||||||
|
*/
|
||||||
|
const char *sqlite3VListNumToName(VList *pIn, int iVal){
|
||||||
|
int i, mx;
|
||||||
|
if( pIn==0 ) return 0;
|
||||||
|
mx = pIn[1];
|
||||||
|
i = 2;
|
||||||
|
do{
|
||||||
|
if( pIn[i]==iVal ) return (char*)&pIn[i+2];
|
||||||
|
i += pIn[i+1];
|
||||||
|
}while( i<mx );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Return the number of the variable named zName, if it is in VList.
|
||||||
|
** or return 0 if there is no such variable.
|
||||||
|
*/
|
||||||
|
int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){
|
||||||
|
int i, mx;
|
||||||
|
if( pIn==0 ) return 0;
|
||||||
|
mx = pIn[1];
|
||||||
|
i = 2;
|
||||||
|
do{
|
||||||
|
const char *z = (const char*)&pIn[i+2];
|
||||||
|
if( strncmp(z,zName,nName)==0 && z[nName]==0 ) return pIn[i];
|
||||||
|
i += pIn[i+1];
|
||||||
|
}while( i<mx );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -1190,7 +1190,7 @@ case OP_Variable: { /* out2 */
|
|||||||
Mem *pVar; /* Value being transferred */
|
Mem *pVar; /* Value being transferred */
|
||||||
|
|
||||||
assert( pOp->p1>0 && pOp->p1<=p->nVar );
|
assert( pOp->p1>0 && pOp->p1<=p->nVar );
|
||||||
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
|
assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
|
||||||
pVar = &p->aVar[pOp->p1 - 1];
|
pVar = &p->aVar[pOp->p1 - 1];
|
||||||
if( sqlite3VdbeMemTooBig(pVar) ){
|
if( sqlite3VdbeMemTooBig(pVar) ){
|
||||||
goto too_big;
|
goto too_big;
|
||||||
|
@@ -346,7 +346,6 @@ struct Vdbe {
|
|||||||
Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
|
Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
|
||||||
Parse *pParse; /* Parsing context used to create this Vdbe */
|
Parse *pParse; /* Parsing context used to create this Vdbe */
|
||||||
ynVar nVar; /* Number of entries in aVar[] */
|
ynVar nVar; /* Number of entries in aVar[] */
|
||||||
ynVar nzVar; /* Number of entries in azVar[] */
|
|
||||||
u32 magic; /* Magic number for sanity checking */
|
u32 magic; /* Magic number for sanity checking */
|
||||||
int nMem; /* Number of memory locations currently allocated */
|
int nMem; /* Number of memory locations currently allocated */
|
||||||
int nCursor; /* Number of slots in apCsr[] */
|
int nCursor; /* Number of slots in apCsr[] */
|
||||||
@@ -371,7 +370,7 @@ struct Vdbe {
|
|||||||
char *zErrMsg; /* Error message written here */
|
char *zErrMsg; /* Error message written here */
|
||||||
VdbeCursor **apCsr; /* One element of this array for each open cursor */
|
VdbeCursor **apCsr; /* One element of this array for each open cursor */
|
||||||
Mem *aVar; /* Values for the OP_Variable opcode. */
|
Mem *aVar; /* Values for the OP_Variable opcode. */
|
||||||
char **azVar; /* Name of variables */
|
VList *pVList; /* Name of variables */
|
||||||
#ifndef SQLITE_OMIT_TRACE
|
#ifndef SQLITE_OMIT_TRACE
|
||||||
i64 startTime; /* Time when query started - used for profiling */
|
i64 startTime; /* Time when query started - used for profiling */
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1470,10 +1470,8 @@ int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
|
|||||||
*/
|
*/
|
||||||
const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
|
const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
|
||||||
Vdbe *p = (Vdbe*)pStmt;
|
Vdbe *p = (Vdbe*)pStmt;
|
||||||
if( p==0 || i<1 || i>p->nzVar ){
|
if( p==0 ) return 0;
|
||||||
return 0;
|
return sqlite3VListNumToName(p->pVList, i);
|
||||||
}
|
|
||||||
return p->azVar[i-1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1482,19 +1480,8 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
|
|||||||
** return 0.
|
** return 0.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
|
int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
|
||||||
int i;
|
if( p==0 || zName==0 ) return 0;
|
||||||
if( p==0 ){
|
return sqlite3VListNameToNum(p->pVList, zName, nName);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if( zName ){
|
|
||||||
for(i=0; i<p->nzVar; i++){
|
|
||||||
const char *z = p->azVar[i];
|
|
||||||
if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
|
|
||||||
return i+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
|
int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
|
||||||
return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
|
return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
|
||||||
|
@@ -1975,10 +1975,8 @@ void sqlite3VdbeMakeReady(
|
|||||||
x.nFree = x.nNeeded;
|
x.nFree = x.nNeeded;
|
||||||
}while( !db->mallocFailed );
|
}while( !db->mallocFailed );
|
||||||
|
|
||||||
p->nzVar = pParse->nzVar;
|
p->pVList = pParse->pVList;
|
||||||
p->azVar = pParse->azVar;
|
pParse->pVList = 0;
|
||||||
pParse->nzVar = 0;
|
|
||||||
pParse->azVar = 0;
|
|
||||||
p->explain = pParse->explain;
|
p->explain = pParse->explain;
|
||||||
if( db->mallocFailed ){
|
if( db->mallocFailed ){
|
||||||
p->nVar = 0;
|
p->nVar = 0;
|
||||||
@@ -2982,8 +2980,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
|
|||||||
}
|
}
|
||||||
if( p->magic!=VDBE_MAGIC_INIT ){
|
if( p->magic!=VDBE_MAGIC_INIT ){
|
||||||
releaseMemArray(p->aVar, p->nVar);
|
releaseMemArray(p->aVar, p->nVar);
|
||||||
for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
|
sqlite3DbFree(db, p->pVList);
|
||||||
sqlite3DbFree(db, p->azVar);
|
|
||||||
sqlite3DbFree(db, p->pFree);
|
sqlite3DbFree(db, p->pFree);
|
||||||
}
|
}
|
||||||
vdbeFreeOpArray(db, p->aOp, p->nOp);
|
vdbeFreeOpArray(db, p->aOp, p->nOp);
|
||||||
|
Reference in New Issue
Block a user