aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/attach.c4
-rw-r--r--src/delete.c12
-rw-r--r--src/expr.c27
-rw-r--r--src/func.c27
-rw-r--r--src/insert.c80
-rw-r--r--src/main.c5
-rw-r--r--src/os.c16
-rw-r--r--src/prepare.c6
-rw-r--r--src/printf.c103
-rw-r--r--src/select.c25
-rw-r--r--src/shell.c6
-rw-r--r--src/sqliteInt.h26
-rw-r--r--src/tclsqlite.c9
-rw-r--r--src/update.c8
-rw-r--r--src/vdbe.c4
-rw-r--r--src/vdbe.h2
-rw-r--r--src/vdbeInt.h6
-rw-r--r--src/vdbeaux.c78
-rw-r--r--src/vdbeblob.c2
-rw-r--r--src/vdbetrace.c20
-rw-r--r--src/where.c1
21 files changed, 329 insertions, 138 deletions
diff --git a/src/attach.c b/src/attach.c
index 223c16648..89050fd9d 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -38,10 +38,6 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
if( pExpr ){
if( pExpr->op!=TK_ID ){
rc = sqlite3ResolveExprNames(pName, pExpr);
- if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
- return SQLITE_ERROR;
- }
}else{
pExpr->op = TK_STRING;
}
diff --git a/src/delete.c b/src/delete.c
index e43072235..7d14c50df 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -780,7 +780,6 @@ int sqlite3GenerateIndexKey(
Table *pTab = pIdx->pTable;
int regBase;
int nCol;
- Index *pPk;
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
@@ -794,16 +793,9 @@ int sqlite3GenerateIndexKey(
}
nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
regBase = sqlite3GetTempRange(pParse, nCol);
- pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
for(j=0; j<nCol; j++){
- i16 idx = pIdx->aiColumn[j];
- if( pPk ) idx = sqlite3ColumnOfIndex(pPk, idx);
- if( idx<0 || idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regBase+j);
- }else{
- sqlite3VdbeAddOp3(v, OP_Column, iDataCur, idx, regBase+j);
- sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[j], -1);
- }
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j],
+ regBase+j);
}
if( regOut ){
const char *zAff;
diff --git a/src/expr.c b/src/expr.c
index 6c8a8cce7..8ee73acb7 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2170,6 +2170,11 @@ void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
*/
void sqlite3ExprCachePush(Parse *pParse){
pParse->iCacheLevel++;
+#ifdef SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("PUSH to %d\n", pParse->iCacheLevel);
+ }
+#endif
}
/*
@@ -2183,6 +2188,11 @@ void sqlite3ExprCachePop(Parse *pParse, int N){
assert( N>0 );
assert( pParse->iCacheLevel>=N );
pParse->iCacheLevel -= N;
+#ifdef SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("POP to %d\n", pParse->iCacheLevel);
+ }
+#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iLevel>pParse->iCacheLevel ){
cacheEntryClear(pParse, p);
@@ -2277,6 +2287,11 @@ void sqlite3ExprCacheClear(Parse *pParse){
int i;
struct yColCache *p;
+#if SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("CLEAR\n");
+ }
+#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg ){
cacheEntryClear(pParse, p);
@@ -3413,7 +3428,17 @@ int sqlite3ExprCodeExprList(
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
- sqlite3VdbeAddOp2(pParse->pVdbe, copyOp, inReg, target+i);
+ VdbeOp *pOp;
+ Vdbe *v = pParse->pVdbe;
+ if( copyOp==OP_Copy
+ && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
+ && pOp->p1+pOp->p3+1==inReg
+ && pOp->p2+pOp->p3+1==target+i
+ ){
+ pOp->p3++;
+ }else{
+ sqlite3VdbeAddOp2(v, copyOp, inReg, target+i);
+ }
}
}
}
diff --git a/src/func.c b/src/func.c
index 951af97b3..1d6ec9f6e 100644
--- a/src/func.c
+++ b/src/func.c
@@ -219,6 +219,32 @@ static void instrFunc(
}
/*
+** Implementation of the printf() function.
+*/
+static void printfFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ PrintfArguments x;
+ StrAccum str;
+ const char *zFormat;
+ int n;
+
+ if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
+ x.nArg = argc-1;
+ x.nUsed = 0;
+ x.apArg = argv+1;
+ sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH);
+ str.db = sqlite3_context_db_handle(context);
+ sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
+ n = str.nChar;
+ sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+ SQLITE_DYNAMIC);
+ }
+}
+
+/*
** Implementation of the substr() function.
**
** substr(x,p1,p2) returns p2 characters of x[] beginning with p1.
@@ -1648,6 +1674,7 @@ void sqlite3RegisterGlobalFunctions(void){
FUNCTION(instr, 2, 0, 0, instrFunc ),
FUNCTION(substr, 2, 0, 0, substrFunc ),
FUNCTION(substr, 3, 0, 0, substrFunc ),
+ FUNCTION(printf, -1, 0, 0, printfFunc ),
FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
FUNCTION(char, -1, 0, 0, charFunc ),
FUNCTION(abs, 1, 0, 0, absFunc ),
diff --git a/src/insert.c b/src/insert.c
index df1b3fc9c..c23d1b09f 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -1515,47 +1515,49 @@ void sqlite3GenerateConstraintChecks(
/* Generate code to handle collisions */
regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
- if( HasRowid(pTab) ){
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
- /* Conflict only if the rowid of the existing index entry
- ** is different from old-rowid */
- if( isUpdate ){
- sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
- }
- }else{
- int x;
- /* Extract the PRIMARY KEY from the end of the index entry and
- ** store it in registers regR..regR+nPk-1 */
- if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){
- for(i=0; i<pPk->nKeyCol; i++){
- x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
- sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
- VdbeComment((v, "%s.%s", pTab->zName,
- pTab->aCol[pPk->aiColumn[i]].zName));
+ if( isUpdate || onError==OE_Replace ){
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
+ /* Conflict only if the rowid of the existing index entry
+ ** is different from old-rowid */
+ if( isUpdate ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
}
- }
- if( isUpdate ){
- /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
- ** table, only conflict if the new PRIMARY KEY values are actually
- ** different from the old.
- **
- ** For a UNIQUE index, only conflict if the PRIMARY KEY values
- ** of the matched index row are different from the original PRIMARY
- ** KEY values of this row before the update. */
- int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
- int op = OP_Ne;
- int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
-
- for(i=0; i<pPk->nKeyCol; i++){
- char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
- x = pPk->aiColumn[i];
- if( i==(pPk->nKeyCol-1) ){
- addrJump = addrUniqueOk;
- op = OP_Eq;
+ }else{
+ int x;
+ /* Extract the PRIMARY KEY from the end of the index entry and
+ ** store it in registers regR..regR+nPk-1 */
+ if( pIdx!=pPk ){
+ for(i=0; i<pPk->nKeyCol; i++){
+ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
+ VdbeComment((v, "%s.%s", pTab->zName,
+ pTab->aCol[pPk->aiColumn[i]].zName));
+ }
+ }
+ if( isUpdate ){
+ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
+ ** table, only conflict if the new PRIMARY KEY values are actually
+ ** different from the old.
+ **
+ ** For a UNIQUE index, only conflict if the PRIMARY KEY values
+ ** of the matched index row are different from the original PRIMARY
+ ** KEY values of this row before the update. */
+ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
+ int op = OP_Ne;
+ int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
+
+ for(i=0; i<pPk->nKeyCol; i++){
+ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
+ x = pPk->aiColumn[i];
+ if( i==(pPk->nKeyCol-1) ){
+ addrJump = addrUniqueOk;
+ op = OP_Eq;
+ }
+ sqlite3VdbeAddOp4(v, op,
+ regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
+ );
}
- sqlite3VdbeAddOp4(v, op,
- regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
- );
}
}
}
diff --git a/src/main.c b/src/main.c
index c62aa3648..b7fe5072b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1062,8 +1062,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** Return a static string containing the name corresponding to the error code
** specified in the argument.
*/
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \
- defined(SQLITE_DEBUG_OS_TRACE)
+#if defined(SQLITE_TEST)
const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
@@ -2662,6 +2661,8 @@ static int openDatabase(
SQLITE_DEFAULT_LOCKING_MODE);
#endif
+ if( rc ) sqlite3Error(db, rc, 0);
+
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
diff --git a/src/os.c b/src/os.c
index be2ea4cfc..b6c28a1dc 100644
--- a/src/os.c
+++ b/src/os.c
@@ -107,7 +107,21 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
** routine has no return value since the return value would be meaningless.
*/
int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
- DO_OS_MALLOC_TEST(id);
+#ifdef SQLITE_TEST
+ if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
+ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
+ ** is using a regular VFS, it is called after the corresponding
+ ** transaction has been committed. Injecting a fault at this point
+ ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
+ ** but the transaction is committed anyway.
+ **
+ ** The core must call OsFileControl() though, not OsFileControlHint(),
+ ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
+ ** means the commit really has failed and an error should be returned
+ ** to the user. */
+ DO_OS_MALLOC_TEST(id);
+ }
+#endif
return id->pMethods->xFileControl(id, op, pArg);
}
void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
diff --git a/src/prepare.c b/src/prepare.c
index 7ea7f3bd6..c7ba53a1f 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -528,7 +528,11 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
** Free all memory allocations in the pParse object
*/
void sqlite3ParserReset(Parse *pParse){
- if( pParse ) sqlite3ExprListDelete(pParse->db, pParse->pConstExpr);
+ if( pParse ){
+ sqlite3 *db = pParse->db;
+ sqlite3DbFree(db, pParse->aLabel);
+ sqlite3ExprListDelete(db, pParse->pConstExpr);
+ }
}
/*
diff --git a/src/printf.c b/src/printf.c
index 3279a54f2..8cfa542b4 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -151,12 +151,29 @@ void sqlite3AppendSpace(StrAccum *pAccum, int N){
/*
** Set the StrAccum object to an error mode.
*/
-void setStrAccumError(StrAccum *p, u8 eError){
+static void setStrAccumError(StrAccum *p, u8 eError){
p->accError = eError;
p->nAlloc = 0;
}
/*
+** Extra argument values from a PrintfArguments object
+*/
+static sqlite3_int64 getIntArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0;
+ return sqlite3_value_int64(p->apArg[p->nUsed++]);
+}
+static double getDoubleArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0.0;
+ return sqlite3_value_double(p->apArg[p->nUsed++]);
+}
+static char *getTextArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0;
+ return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
+}
+
+
+/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
*/
@@ -169,10 +186,10 @@ void setStrAccumError(StrAccum *p, u8 eError){
** Render a string given by "fmt" into the StrAccum object.
*/
void sqlite3VXPrintf(
- StrAccum *pAccum, /* Accumulate results here */
- int useExtended, /* Allow extended %-conversions */
- const char *fmt, /* Format string */
- va_list ap /* arguments */
+ StrAccum *pAccum, /* Accumulate results here */
+ u32 bFlags, /* SQLITE_PRINTF_* flags */
+ const char *fmt, /* Format string */
+ va_list ap /* arguments */
){
int c; /* Next character in the format string */
char *bufpt; /* Pointer to the conversion buffer */
@@ -190,6 +207,8 @@ void sqlite3VXPrintf(
etByte flag_longlong; /* True if the "ll" flag is present */
etByte done; /* Loop termination flag */
etByte xtype = 0; /* Conversion paradigm */
+ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
+ u8 useIntern; /* Ok to use internal conversions (ex: %T) */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
sqlite_uint64 longvalue; /* Value for integer types */
LONGDOUBLE_TYPE realvalue; /* Value for real types */
@@ -204,9 +223,18 @@ void sqlite3VXPrintf(
etByte flag_dp; /* True if decimal point should be shown */
etByte flag_rtz; /* True if trailing zeros should be removed */
#endif
+ PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
char buf[etBUFSIZE]; /* Conversion buffer */
bufpt = 0;
+ if( bFlags ){
+ if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
+ pArgList = va_arg(ap, PrintfArguments*);
+ }
+ useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
+ }else{
+ bArgList = useIntern = 0;
+ }
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
int amt;
@@ -238,7 +266,11 @@ void sqlite3VXPrintf(
/* Get the field width */
width = 0;
if( c=='*' ){
- width = va_arg(ap,int);
+ if( bArgList ){
+ width = (int)getIntArg(pArgList);
+ }else{
+ width = va_arg(ap,int);
+ }
if( width<0 ){
flag_leftjustify = 1;
width = -width;
@@ -255,7 +287,11 @@ void sqlite3VXPrintf(
precision = 0;
c = *++fmt;
if( c=='*' ){
- precision = va_arg(ap,int);
+ if( bArgList ){
+ precision = (int)getIntArg(pArgList);
+ }else{
+ precision = va_arg(ap,int);
+ }
if( precision<0 ) precision = -precision;
c = *++fmt;
}else{
@@ -286,7 +322,7 @@ void sqlite3VXPrintf(
for(idx=0; idx<ArraySize(fmtinfo); idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
- if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
+ if( useIntern || (infop->flags & FLAG_INTERN)==0 ){
xtype = infop->type;
}else{
return;
@@ -326,7 +362,9 @@ void sqlite3VXPrintf(
case etRADIX:
if( infop->flags & FLAG_SIGNED ){
i64 v;
- if( flag_longlong ){
+ if( bArgList ){
+ v = getIntArg(pArgList);
+ }else if( flag_longlong ){
v = va_arg(ap,i64);
}else if( flag_long ){
v = va_arg(ap,long int);
@@ -347,7 +385,9 @@ void sqlite3VXPrintf(
else prefix = 0;
}
}else{
- if( flag_longlong ){
+ if( bArgList ){
+ longvalue = (u64)getIntArg(pArgList);
+ }else if( flag_longlong ){
longvalue = va_arg(ap,u64);
}else if( flag_long ){
longvalue = va_arg(ap,unsigned long int);
@@ -407,7 +447,11 @@ void sqlite3VXPrintf(
case etFLOAT:
case etEXP:
case etGENERIC:
- realvalue = va_arg(ap,double);
+ if( bArgList ){
+ realvalue = getDoubleArg(pArgList);
+ }else{
+ realvalue = va_arg(ap,double);
+ }
#ifdef SQLITE_OMIT_FLOATING_POINT
length = 0;
#else
@@ -562,7 +606,9 @@ void sqlite3VXPrintf(
#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
break;
case etSIZE:
- *(va_arg(ap,int*)) = pAccum->nChar;
+ if( !bArgList ){
+ *(va_arg(ap,int*)) = pAccum->nChar;
+ }
length = width = 0;
break;
case etPERCENT:
@@ -571,7 +617,12 @@ void sqlite3VXPrintf(
length = 1;
break;
case etCHARX:
- c = va_arg(ap,int);
+ if( bArgList ){
+ bufpt = getTextArg(pArgList);
+ c = bufpt ? bufpt[0] : 0;
+ }else{
+ c = va_arg(ap,int);
+ }
buf[0] = (char)c;
if( precision>=0 ){
for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
@@ -583,10 +634,14 @@ void sqlite3VXPrintf(
break;
case etSTRING:
case etDYNSTRING:
- bufpt = va_arg(ap,char*);
+ if( bArgList ){
+ bufpt = getTextArg(pArgList);
+ }else{
+ bufpt = va_arg(ap,char*);
+ }
if( bufpt==0 ){
bufpt = "";
- }else if( xtype==etDYNSTRING ){
+ }else if( xtype==etDYNSTRING && !bArgList ){
zExtra = bufpt;
}
if( precision>=0 ){
@@ -602,7 +657,13 @@ void sqlite3VXPrintf(
int needQuote;
char ch;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
- char *escarg = va_arg(ap,char*);
+ char *escarg;
+
+ if( bArgList ){
+ escarg = getTextArg(pArgList);
+ }else{
+ escarg = va_arg(ap,char*);
+ }
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
k = precision;
@@ -637,6 +698,7 @@ void sqlite3VXPrintf(
}
case etTOKEN: {
Token *pToken = va_arg(ap, Token*);
+ assert( bArgList==0 );
if( pToken && pToken->n ){
sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
}
@@ -647,6 +709,7 @@ void sqlite3VXPrintf(
SrcList *pSrc = va_arg(ap, SrcList*);
int k = va_arg(ap, int);
struct SrcList_item *pItem = &pSrc->a[k];
+ assert( bArgList==0 );
assert( k>=0 && k<pSrc->nSrc );
if( pItem->zDatabase ){
sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
@@ -810,7 +873,7 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
acc.db = db;
- sqlite3VXPrintf(&acc, 1, zFormat, ap);
+ sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.accError==STRACCUM_NOMEM ){
db->mallocFailed = 1;
@@ -966,14 +1029,12 @@ void sqlite3DebugPrintf(const char *zFormat, ...){
}
#endif
-#ifndef SQLITE_OMIT_TRACE
/*
** variable-argument wrapper around sqlite3VXPrintf().
*/
-void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
+void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
va_list ap;
va_start(ap,zFormat);
- sqlite3VXPrintf(p, 1, zFormat, ap);
+ sqlite3VXPrintf(p, bFlags, zFormat, ap);
va_end(ap);
}
-#endif
diff --git a/src/select.c b/src/select.c
index aa8e54b02..d07511674 100644
--- a/src/select.c
+++ b/src/select.c
@@ -598,7 +598,6 @@ static void selectInnerLoop(
/* If the destination is an EXISTS(...) expression, the actual
** values returned by the SELECT are not required.
*/
- sqlite3ExprCacheClear(pParse);
sqlite3ExprCodeExprList(pParse, pEList, regResult,
(eDest==SRT_Output)?SQLITE_ECEL_DUP:0);
}
@@ -1565,7 +1564,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
Vdbe *sqlite3GetVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe;
if( v==0 ){
- v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
+ v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
#ifndef SQLITE_OMIT_TRACE
if( v ){
sqlite3VdbeAddOp0(v, OP_Trace);
@@ -3823,14 +3822,23 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pFunc;
- if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
- return;
- }
+ int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
+ if( nReg==0 ) return;
+#ifdef SQLITE_DEBUG
+ /* Verify that all AggInfo registers are within the range specified by
+ ** AggInfo.mnReg..AggInfo.mxReg */
+ assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
for(i=0; i<pAggInfo->nColumn; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
+ assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg );
}
+ for(i=0; i<pAggInfo->nFunc; i++){
+ assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg );
+ }
+#endif
+ sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
if( pFunc->iDistinct>=0 ){
Expr *pE = pFunc->pExpr;
assert( !ExprHasProperty(pE, EP_xIsSelect) );
@@ -3876,7 +3884,6 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
struct AggInfo_col *pC;
pAggInfo->directMode = 1;
- sqlite3ExprCacheClear(pParse);
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
int nArg;
int addrNext = 0;
@@ -4409,6 +4416,7 @@ int sqlite3Select(
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
+ sAggInfo.mnReg = pParse->nMem+1;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
@@ -4423,6 +4431,7 @@ int sqlite3Select(
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
}
+ sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
diff --git a/src/shell.c b/src/shell.c
index 7826fdf20..00cff6a8e 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3038,7 +3038,10 @@ static int process_input(struct callback_data *p, FILE *in){
seenInterrupt = 0;
}
lineno++;
- if( nSql==0 && _all_whitespace(zLine) ) continue;
+ if( nSql==0 && _all_whitespace(zLine) ){
+ if( p->echoOn ) printf("%s\n", zLine);
+ continue;
+ }
if( zLine && zLine[0]=='.' && nSql==0 ){
if( p->echoOn ) printf("%s\n", zLine);
rc = do_meta_command(zLine, p);
@@ -3100,6 +3103,7 @@ static int process_input(struct callback_data *p, FILE *in){
}
nSql = 0;
}else if( nSql && _all_whitespace(zSql) ){
+ if( p->echoOn ) printf("%s\n", zSql);
nSql = 0;
}
}
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 98dc451a4..876911a46 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -743,6 +743,7 @@ typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
typedef struct PreUpdate PreUpdate;
+typedef struct PrintfArguments PrintfArguments;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
@@ -1695,6 +1696,7 @@ struct AggInfo {
int sortingIdx; /* Cursor number of the sorting index */
int sortingIdxPTab; /* Cursor number of pseudo-table */
int nSortingColumn; /* Number of columns in the sorting index */
+ int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */
ExprList *pGroupBy; /* The group by clause */
struct AggInfo_col { /* For each column used in source tables */
Table *pTab; /* Source table */
@@ -2296,6 +2298,9 @@ struct Parse {
int nMem; /* Number of memory cells used so far */
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
+ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
+ int nLabel; /* Number of labels used */
+ int *aLabel; /* Space to hold the labels */
int ckBase; /* Base register of data during check constraints */
int iPartIdxTab; /* Table corresponding to a partial index */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
@@ -2776,10 +2781,20 @@ void sqlite3StatusSet(int, int);
# define sqlite3IsNaN(X) 0
#endif
-void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
-#ifndef SQLITE_OMIT_TRACE
-void sqlite3XPrintf(StrAccum*, const char*, ...);
-#endif
+/*
+** An instance of the following structure holds information about SQL
+** functions arguments that are the parameters to the printf() function.
+*/
+struct PrintfArguments {
+ int nArg; /* Total number of arguments */
+ int nUsed; /* Number of arguments used so far */
+ sqlite3_value **apArg; /* The argument values */
+};
+
+#define SQLITE_PRINTF_INTERNAL 0x01
+#define SQLITE_PRINTF_SQLFUNC 0x02
+void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
+void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
char *sqlite3MPrintf(sqlite3*,const char*, ...);
char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
@@ -3138,8 +3153,7 @@ void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
u8 sqlite3HexToInt(int h);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \
- defined(SQLITE_DEBUG_OS_TRACE)
+#if defined(SQLITE_TEST)
const char *sqlite3ErrName(int);
#endif
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 5efc113a6..809d6b59e 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -1574,9 +1574,9 @@ static int DbUseNre(void){
*/
# define SQLITE_TCL_NRE 0
# define DbUseNre() 0
-# define Tcl_NRAddCallback(a,b,c,d,e,f) 0
+# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
# define Tcl_NREvalObj(a,b,c) 0
-# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0
+# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
#endif
/*
@@ -2855,7 +2855,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** or savepoint. */
if( DbUseNre() ){
Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
- Tcl_NREvalObj(interp, pScript, 0);
+ (void)Tcl_NREvalObj(interp, pScript, 0);
}else{
rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
}
@@ -3517,8 +3517,7 @@ static void MD5Final(unsigned char digest[16], MD5Context *ctx){
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
- ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
- ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
+ memcpy(ctx->in + 14*4, ctx->bits, 8);
MD5Transform(ctx->buf, (uint32 *)ctx->in);
byteReverse((unsigned char *)ctx->buf, 4);
diff --git a/src/update.c b/src/update.c
index e80822d9b..3d8e6d5e7 100644
--- a/src/update.c
+++ b/src/update.c
@@ -72,7 +72,7 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
}
#ifndef SQLITE_OMIT_FLOATING_POINT
- if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
+ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
@@ -496,10 +496,10 @@ void sqlite3Update(
newmask = sqlite3TriggerColmask(
pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
);
- sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
+ /*sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);*/
for(i=0; i<pTab->nCol; i++){
if( i==pTab->iPKey ){
- /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}else{
j = aXRef[i];
if( j>=0 ){
@@ -513,6 +513,8 @@ void sqlite3Update(
testcase( i==31 );
testcase( i==32 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}
}
}
diff --git a/src/vdbe.c b/src/vdbe.c
index e35e324fa..674c252eb 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -1121,7 +1121,7 @@ case OP_Move: {
}
/* Opcode: Copy P1 P2 P3 * *
-** Synopsis: r[P2@P3]=r[P1@P3]
+** Synopsis: r[P2@P3+1]=r[P1@P3+1]
**
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
@@ -2464,7 +2464,7 @@ case OP_Column: {
VdbeMemRelease(pDest);
sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
}else{
- /* This branch happens only when content is on overflow pages */
+ /* This branch happens only when content is on overflow pages */
t = aType[p2];
if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
&& ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
diff --git a/src/vdbe.h b/src/vdbe.h
index 834370163..80f4faf90 100644
--- a/src/vdbe.h
+++ b/src/vdbe.h
@@ -162,7 +162,7 @@ typedef struct VdbeOpList VdbeOpList;
** Prototypes for the VDBE interface. See comments on the implementation
** for a description of what each of these routines does.
*/
-Vdbe *sqlite3VdbeCreate(sqlite3*);
+Vdbe *sqlite3VdbeCreate(Parse*);
int sqlite3VdbeAddOp0(Vdbe*,int);
int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 0f89c3a24..815fbc55e 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -312,12 +312,9 @@ struct Vdbe {
Mem **apArg; /* Arguments to currently executing user function */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
+ Parse *pParse; /* Parsing context used to create this Vdbe */
int nMem; /* Number of memory locations currently allocated */
int nOp; /* Number of instructions in the program */
- int nOpAlloc; /* Number of slots allocated for aOp[] */
- int nLabel; /* Number of labels used */
- int *aLabel; /* Space to hold the labels */
- u16 nResColumn; /* Number of columns in one row of the result set */
int nCursor; /* Number of slots in apCsr[] */
u32 magic; /* Magic number for sanity checking */
char *zErrMsg; /* Error message written here */
@@ -330,6 +327,7 @@ struct Vdbe {
u32 cacheCtr; /* VdbeCursor row cache generation counter */
int pc; /* The program counter */
int rc; /* Value to return */
+ u16 nResColumn; /* Number of columns in one row of the result set */
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
bft explain:2; /* True if EXPLAIN present on SQL command */
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 5fc7a3198..24ebbba13 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -20,7 +20,8 @@
/*
** Create a new virtual database engine.
*/
-Vdbe *sqlite3VdbeCreate(sqlite3 *db){
+Vdbe *sqlite3VdbeCreate(Parse *pParse){
+ sqlite3 *db = pParse->db;
Vdbe *p;
p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
if( p==0 ) return 0;
@@ -32,6 +33,10 @@ Vdbe *sqlite3VdbeCreate(sqlite3 *db){
p->pPrev = 0;
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
+ p->pParse = pParse;
+ assert( pParse->aLabel==0 );
+ assert( pParse->nLabel==0 );
+ assert( pParse->nOpAlloc==0 );
return p;
}
@@ -88,13 +93,14 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
** unchanged (this is so that any opcodes already allocated can be
** correctly deallocated along with the rest of the Vdbe).
*/
-static int growOpArray(Vdbe *p){
+static int growOpArray(Vdbe *v){
VdbeOp *pNew;
+ Parse *p = v->pParse;
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
- pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
+ pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
if( pNew ){
p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
- p->aOp = pNew;
+ v->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
@@ -133,7 +139,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
i = p->nOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( op>0 && op<0xff );
- if( p->nOpAlloc<=i ){
+ if( p->pParse->nOpAlloc<=i ){
if( growOpArray(p) ){
return 1;
}
@@ -152,6 +158,15 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
#endif
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ int jj, kk;
+ Parse *pParse = p->pParse;
+ for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
+ struct yColCache *x = pParse->aColCache + jj;
+ if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
+ printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
+ kk++;
+ }
+ if( kk ) printf("\n");
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
test_addop_breakpoint();
}
@@ -235,9 +250,10 @@ int sqlite3VdbeAddOp4Int(
**
** Zero is returned if a malloc() fails.
*/
-int sqlite3VdbeMakeLabel(Vdbe *p){
+int sqlite3VdbeMakeLabel(Vdbe *v){
+ Parse *p = v->pParse;
int i = p->nLabel++;
- assert( p->magic==VDBE_MAGIC_INIT );
+ assert( v->magic==VDBE_MAGIC_INIT );
if( (i & (i-1))==0 ){
p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
(i*2+1)*sizeof(p->aLabel[0]));
@@ -253,12 +269,13 @@ int sqlite3VdbeMakeLabel(Vdbe *p){
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
-void sqlite3VdbeResolveLabel(Vdbe *p, int x){
+void sqlite3VdbeResolveLabel(Vdbe *v, int x){
+ Parse *p = v->pParse;
int j = -1-x;
- assert( p->magic==VDBE_MAGIC_INIT );
+ assert( v->magic==VDBE_MAGIC_INIT );
assert( j<p->nLabel );
if( j>=0 && p->aLabel ){
- p->aLabel[j] = p->nOp;
+ p->aLabel[j] = v->nOp;
}
}
@@ -407,7 +424,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
- int *aLabel = p->aLabel;
+ Parse *pParse = p->pParse;
+ int *aLabel = pParse->aLabel;
p->readOnly = 1;
p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
@@ -470,12 +488,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
- assert( -1-pOp->p2<p->nLabel );
+ assert( -1-pOp->p2<pParse->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
}
}
- sqlite3DbFree(p->db, p->aLabel);
- p->aLabel = 0;
+ sqlite3DbFree(p->db, pParse->aLabel);
+ pParse->aLabel = 0;
+ pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || p->btreeMask==0 );
}
@@ -519,7 +538,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
int addr;
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){
+ if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){
return 0;
}
addr = p->nOp;
@@ -873,7 +892,17 @@ static int translateP(char c, const Op *pOp){
}
/*
-** Compute a string for the "comment" field of a VDBE opcode listing
+** Compute a string for the "comment" field of a VDBE opcode listing.
+**
+** The Synopsis: field in comments in the vdbe.c source file gets converted
+** to an extra string that is appended to the sqlite3OpcodeName(). In the
+** absence of other comments, this synopsis becomes the comment on the opcode.
+** Some translation occurs:
+**
+** "PX" -> "r[X]"
+** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
+** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
+** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
*/
static int displayComment(
const Op *pOp, /* The opcode to be commented */
@@ -907,7 +936,13 @@ static int displayComment(
ii += 3;
jj += sqlite3Strlen30(zTemp+jj);
v2 = translateP(zSynopsis[ii], pOp);
- if( v2>1 ) sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){
+ ii += 2;
+ v2++;
+ }
+ if( v2>1 ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ }
}else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
ii += 4;
}
@@ -1139,6 +1174,9 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
#else
zCom[0] = 0
#endif
+ /* NB: The sqlite3OpcodeName() function is implemented by code created
+ ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
+ ** information from the vdbe.c source text */
fprintf(pOut, zFormat1, pc,
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
zCom
@@ -1570,6 +1608,7 @@ void sqlite3VdbeMakeReady(
assert( p->nOp>0 );
assert( pParse!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
+ assert( pParse==p->pParse );
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
@@ -1593,8 +1632,8 @@ void sqlite3VdbeMakeReady(
/* Allocate space for memory registers, SQL variables, VDBE cursors and
** an array to marshal SQL function arguments in.
*/
- zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
- zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */
+ zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
+ zEnd = (u8*)&p->aOp[pParse->nOpAlloc]; /* First byte past end of zCsr[] */
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
@@ -2597,7 +2636,6 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
}
for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
vdbeFreeOpArray(db, p->aOp, p->nOp);
- sqlite3DbFree(db, p->aLabel);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
sqlite3DbFree(db, p->pFree);
diff --git a/src/vdbeblob.c b/src/vdbeblob.c
index a1c44ebf3..98c4f40ad 100644
--- a/src/vdbeblob.c
+++ b/src/vdbeblob.c
@@ -259,7 +259,7 @@ int sqlite3_blob_open(
}
}
- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db);
+ pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse);
assert( pBlob->pStmt || db->mallocFailed );
if( pBlob->pStmt ){
Vdbe *v = (Vdbe *)pBlob->pStmt;
diff --git a/src/vdbetrace.c b/src/vdbetrace.c
index a7ff0a685..4a39e2652 100644
--- a/src/vdbetrace.c
+++ b/src/vdbetrace.c
@@ -125,9 +125,9 @@ char *sqlite3VdbeExpandSql(
if( pVar->flags & MEM_Null ){
sqlite3StrAccumAppend(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){
- sqlite3XPrintf(&out, "%lld", pVar->u.i);
+ sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
- sqlite3XPrintf(&out, "%!.15g", pVar->r);
+ sqlite3XPrintf(&out, 0, "%!.15g", pVar->r);
}else if( pVar->flags & MEM_Str ){
int nOut; /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16
@@ -148,15 +148,17 @@ char *sqlite3VdbeExpandSql(
while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
}
#endif
- sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
+ sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z);
#ifdef SQLITE_TRACE_SIZE_LIMIT
- if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+ if( nOut<pVar->n ){
+ sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
+ }
#endif
#ifndef SQLITE_OMIT_UTF16
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
#endif
}else if( pVar->flags & MEM_Zero ){
- sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
+ sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero);
}else{
int nOut; /* Number of bytes of the blob to include in output */
assert( pVar->flags & MEM_Blob );
@@ -166,11 +168,13 @@ char *sqlite3VdbeExpandSql(
if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
#endif
for(i=0; i<nOut; i++){
- sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
+ sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff);
}
sqlite3StrAccumAppend(&out, "'", 1);
#ifdef SQLITE_TRACE_SIZE_LIMIT
- if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+ if( nOut<pVar->n ){
+ sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
+ }
#endif
}
}
@@ -229,7 +233,7 @@ void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
}
va_start(ap, zFormat);
- sqlite3VXPrintf(&p->str, 1, zFormat, ap);
+ sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap);
va_end(ap);
}
}
diff --git a/src/where.c b/src/where.c
index afe664aa0..59028b992 100644
--- a/src/where.c
+++ b/src/where.c
@@ -3928,6 +3928,7 @@ static int whereLoopAddBtreeIndex(
&& saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */
+ && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
pNew->u.btree.nEq++;