aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expr.c14
-rw-r--r--src/prepare.c8
-rw-r--r--src/resolve.c4
-rw-r--r--src/select.c12
-rw-r--r--src/shell.c.in29
-rw-r--r--src/sqliteInt.h4
-rw-r--r--src/test_bestindex.c3
-rw-r--r--src/vdbe.c30
-rw-r--r--src/vdbeaux.c4
-rw-r--r--src/vtab.c5
-rw-r--r--src/where.c2
11 files changed, 71 insertions, 44 deletions
diff --git a/src/expr.c b/src/expr.c
index 2157cf4ed..7cd50e660 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1443,11 +1443,11 @@ void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
**
** The pExpr might be deleted immediately on an OOM error.
**
-** The deferred delete is (currently) implemented by adding the
-** pExpr to the pParse->pConstExpr list with a register number of 0.
+** Return 0 if the delete was successfully deferred. Return non-zero
+** if the delete happened immediately because of an OOM.
*/
-void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
- sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
+int sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){
+ return 0==sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr);
}
/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the
@@ -6680,9 +6680,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
&& pAggInfo->aCol[iAgg].pCExpr==pExpr
){
pExpr = sqlite3ExprDup(db, pExpr, 0);
- if( pExpr ){
+ if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){
pAggInfo->aCol[iAgg].pCExpr = pExpr;
- sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}else{
@@ -6691,9 +6690,8 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
&& pAggInfo->aFunc[iAgg].pFExpr==pExpr
){
pExpr = sqlite3ExprDup(db, pExpr, 0);
- if( pExpr ){
+ if( pExpr && !sqlite3ExprDeferredDelete(pParse, pExpr) ){
pAggInfo->aFunc[iAgg].pFExpr = pExpr;
- sqlite3ExprDeferredDelete(pParse, pExpr);
}
}
}
diff --git a/src/prepare.c b/src/prepare.c
index 87569ee91..df9c98f74 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -633,7 +633,13 @@ void *sqlite3ParserAddCleanup(
void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */
void *pPtr /* Pointer to object to be cleaned up */
){
- ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
+ ParseCleanup *pCleanup;
+ if( sqlite3FaultSim(300) ){
+ pCleanup = 0;
+ sqlite3OomFault(pParse->db);
+ }else{
+ pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup));
+ }
if( pCleanup ){
pCleanup->pNext = pParse->pCleanup;
pParse->pCleanup = pCleanup;
diff --git a/src/resolve.c b/src/resolve.c
index 898c78654..546731afe 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -1281,11 +1281,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif
}
}
-#ifndef SQLITE_OMIT_WINDOWFUNC
- else if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ else if( ExprHasProperty(pExpr, EP_WinFunc) || pExpr->pLeft ){
is_agg = 1;
}
-#endif
sqlite3WalkExprList(pWalker, pList);
if( is_agg ){
if( pExpr->pLeft ){
diff --git a/src/select.c b/src/select.c
index 8ee59cf68..9278ea18b 100644
--- a/src/select.c
+++ b/src/select.c
@@ -2324,8 +2324,7 @@ void sqlite3SubqueryColumnTypes(
NameContext sNC;
assert( pSelect!=0 );
- testcase( (pSelect->selFlags & SF_Resolved)==0 );
- assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT );
+ assert( (pSelect->selFlags & SF_Resolved)!=0 );
assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 );
assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB );
if( db->mallocFailed || IN_RENAME_OBJECT ) return;
@@ -2381,12 +2380,12 @@ void sqlite3SubqueryColumnTypes(
}
}
if( zType ){
- i64 m = sqlite3Strlen30(zType);
+ const i64 k = sqlite3Strlen30(zType);
n = sqlite3Strlen30(pCol->zCnName);
- pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
+ pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2);
pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
if( pCol->zCnName ){
- memcpy(&pCol->zCnName[n+1], zType, m+1);
+ memcpy(&pCol->zCnName[n+1], zType, k+1);
pCol->colFlags |= COLFLAG_HASTYPE;
}
}
@@ -6412,8 +6411,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
if( p->selFlags & SF_HasTypeInfo ) return;
p->selFlags |= SF_HasTypeInfo;
pParse = pWalker->pParse;
- testcase( (p->selFlags & SF_Resolved)==0 );
- assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT );
+ assert( (p->selFlags & SF_Resolved) );
pTabList = p->pSrc;
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab;
diff --git a/src/shell.c.in b/src/shell.c.in
index 2f91ac8ba..298485344 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -7940,7 +7940,10 @@ static struct {
int iCnt; /* Trigger the fault only if iCnt is already zero */
int iInterval; /* Reset iCnt to this value after each fault */
int eVerbose; /* When to print output */
-} faultsim_state = {-1, 0, 0, 0, 0};
+ int nHit; /* Number of hits seen so far */
+ int nRepeat; /* Turn off after this many hits. 0 for never */
+ int nSkip; /* Skip this many before first fault */
+} faultsim_state = {-1, 0, 0, 0, 0, 0, 0};
/*
** This is the fault-sim callback
@@ -7949,8 +7952,8 @@ static int faultsim_callback(int iArg){
if( faultsim_state.iId>0 && faultsim_state.iId!=iArg ){
return SQLITE_OK;
}
- if( faultsim_state.iCnt>0 ){
- faultsim_state.iCnt--;
+ if( faultsim_state.iCnt ){
+ if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--;
if( faultsim_state.eVerbose>=2 ){
oputf("FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt);
}
@@ -7960,6 +7963,10 @@ static int faultsim_callback(int iArg){
oputf("FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr);
}
faultsim_state.iCnt = faultsim_state.iInterval;
+ faultsim_state.nHit++;
+ if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){
+ faultsim_state.iCnt = -1;
+ }
return faultsim_state.iErr;
}
@@ -11121,17 +11128,23 @@ static int do_meta_command(char *zLine, ShellState *p){
if( cli_strcmp(z,"off")==0 ){
sqlite3_test_control(testctrl, 0);
}else if( cli_strcmp(z,"on")==0 ){
- faultsim_state.iCnt = faultsim_state.iInterval;
+ faultsim_state.iCnt = faultsim_state.nSkip;
if( faultsim_state.iErr==0 ) faultsim_state.iErr = 1;
+ faultsim_state.nHit = 0;
sqlite3_test_control(testctrl, faultsim_callback);
}else if( cli_strcmp(z,"reset")==0 ){
- faultsim_state.iCnt = faultsim_state.iInterval;
+ faultsim_state.iCnt = faultsim_state.nSkip;
+ faultsim_state.nHit = 0;
+ sqlite3_test_control(testctrl, faultsim_callback);
}else if( cli_strcmp(z,"status")==0 ){
oputf("faultsim.iId: %d\n", faultsim_state.iId);
oputf("faultsim.iErr: %d\n", faultsim_state.iErr);
oputf("faultsim.iCnt: %d\n", faultsim_state.iCnt);
+ oputf("faultsim.nHit: %d\n", faultsim_state.nHit);
oputf("faultsim.iInterval: %d\n", faultsim_state.iInterval);
oputf("faultsim.eVerbose: %d\n", faultsim_state.eVerbose);
+ oputf("faultsim.nRepeat: %d\n", faultsim_state.nRepeat);
+ oputf("faultsim.nSkip: %d\n", faultsim_state.nSkip);
}else if( cli_strcmp(z,"-v")==0 ){
if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++;
}else if( cli_strcmp(z,"-q")==0 ){
@@ -11142,6 +11155,10 @@ static int do_meta_command(char *zLine, ShellState *p){
faultsim_state.iErr = atoi(azArg[++kk]);
}else if( cli_strcmp(z,"-interval")==0 && kk+1<nArg ){
faultsim_state.iInterval = atoi(azArg[++kk]);
+ }else if( cli_strcmp(z,"-repeat")==0 && kk+1<nArg ){
+ faultsim_state.nRepeat = atoi(azArg[++kk]);
+ }else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){
+ faultsim_state.nSkip = atoi(azArg[++kk]);
}else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){
bShowHelp = 1;
}else{
@@ -11165,6 +11182,8 @@ static int do_meta_command(char *zLine, ShellState *p){
" --errcode N When triggered, return N as error code\n"
" --id ID Trigger only for the ID specified\n"
" --interval N Trigger only after every N-th call\n"
+ " --repeat N Turn off after N hits. 0 means never\n"
+ " --skip N Skip the first N encounters\n"
);
}
break;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 0d33f9ee2..aa8bfc4b7 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -4856,7 +4856,7 @@ void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
void sqlite3ExprDeleteGeneric(sqlite3*,void*);
-void sqlite3ExprDeferredDelete(Parse*, Expr*);
+int sqlite3ExprDeferredDelete(Parse*, Expr*);
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
@@ -5267,7 +5267,9 @@ void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
void sqlite3Error(sqlite3*,int);
void sqlite3ErrorClear(sqlite3*);
void sqlite3SystemError(sqlite3*,int);
+#if !defined(SQLITE_OMIT_BLOB_LITERAL)
void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
+#endif
u8 sqlite3HexToInt(int h);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
diff --git a/src/test_bestindex.c b/src/test_bestindex.c
index 6b6b41395..0e1e86a81 100644
--- a/src/test_bestindex.c
+++ b/src/test_bestindex.c
@@ -215,6 +215,9 @@ static int tclConnect(
rc = SQLITE_ERROR;
}else{
rc = sqlite3_declare_vtab(db, Tcl_GetStringResult(interp));
+ if( rc!=SQLITE_OK ){
+ *pzErr = sqlite3_mprintf("declare_vtab: %s", sqlite3_errmsg(db));
+ }
}
if( rc!=SQLITE_OK ){
diff --git a/src/vdbe.c b/src/vdbe.c
index f06a71da4..6bfcb0ee1 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -4336,23 +4336,23 @@ case OP_OpenWrite:
if( pDb->pSchema->file_format < p->minWriteFileFormat ){
p->minWriteFileFormat = pDb->pSchema->file_format;
}
+ if( pOp->p5 & OPFLAG_P2ISREG ){
+ assert( p2>0 );
+ assert( p2<=(u32)(p->nMem+1 - p->nCursor) );
+ pIn2 = &aMem[p2];
+ assert( memIsValid(pIn2) );
+ assert( (pIn2->flags & MEM_Int)!=0 );
+ sqlite3VdbeMemIntegerify(pIn2);
+ p2 = (int)pIn2->u.i;
+ /* The p2 value always comes from a prior OP_CreateBtree opcode and
+ ** that opcode will always set the p2 value to 2 or more or else fail.
+ ** If there were a failure, the prepared statement would have halted
+ ** before reaching this instruction. */
+ assert( p2>=2 );
+ }
}else{
wrFlag = 0;
- }
- if( pOp->p5 & OPFLAG_P2ISREG ){
- assert( p2>0 );
- assert( p2<=(u32)(p->nMem+1 - p->nCursor) );
- assert( pOp->opcode==OP_OpenWrite );
- pIn2 = &aMem[p2];
- assert( memIsValid(pIn2) );
- assert( (pIn2->flags & MEM_Int)!=0 );
- sqlite3VdbeMemIntegerify(pIn2);
- p2 = (int)pIn2->u.i;
- /* The p2 value always comes from a prior OP_CreateBtree opcode and
- ** that opcode will always set the p2 value to 2 or more or else fail.
- ** If there were a failure, the prepared statement would have halted
- ** before reaching this instruction. */
- assert( p2>=2 );
+ assert( (pOp->p5 & OPFLAG_P2ISREG)==0 );
}
if( pOp->p4type==P4_KEYINFO ){
pKeyInfo = pOp->p4.pKeyInfo;
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index e5c830343..e4c174e3f 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -3355,9 +3355,9 @@ int sqlite3VdbeHalt(Vdbe *p){
/* Check for immediate foreign key violations. */
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
- sqlite3VdbeCheckFk(p, 0);
+ (void)sqlite3VdbeCheckFk(p, 0);
}
-
+
/* If the auto-commit flag is set and this is the only active writer
** VM, then we do either a commit or rollback of the current transaction.
**
diff --git a/src/vtab.c b/src/vtab.c
index 61dafab71..1036eed44 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -831,7 +831,10 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
for(i=0; aKeyword[i]; i++){
int tokenType = 0;
do{ z += sqlite3GetToken(z, &tokenType); }while( tokenType==TK_SPACE );
- if( tokenType!=aKeyword[i] ) return SQLITE_MISUSE_BKPT;
+ if( tokenType!=aKeyword[i] ){
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error");
+ return SQLITE_ERROR;
+ }
}
sqlite3_mutex_enter(db->mutex);
diff --git a/src/where.c b/src/where.c
index 13a362dcc..07c5b9cf9 100644
--- a/src/where.c
+++ b/src/where.c
@@ -3170,7 +3170,7 @@ static int whereLoopAddBtreeIndex(
|| (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
){
if( iCol==XN_ROWID || pProbe->uniqNotNull
- || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ)
+ || (pProbe->nKeyCol==1 && pProbe->onError && (eOp & WO_EQ))
){
pNew->wsFlags |= WHERE_ONEROW;
}else{