diff options
author | drh <drh@noemail.net> | 2016-12-23 03:59:31 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2016-12-23 03:59:31 +0000 |
commit | 9bf755cc4467dd1e2d2fb8257f14ef974ec8bc41 (patch) | |
tree | fe4338736e7319a9d947ecbf8a7a3231a4eceef9 /src/util.c | |
parent | 344a1bf133771614774acd3233fc098eae26e5f7 (diff) | |
download | sqlite-9bf755cc4467dd1e2d2fb8257f14ef974ec8bc41.tar.gz sqlite-9bf755cc4467dd1e2d2fb8257f14ef974ec8bc41.zip |
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
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c index a614f1461..5ece9226f 100644 --- a/src/util.c +++ b/src/util.c @@ -1453,3 +1453,92 @@ u64 sqlite3LogEstToInt(LogEst x){ return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); } #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; +} |