aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2023-01-21 12:18:28 +0000
committerstephan <stephan@noemail.net>2023-01-21 12:18:28 +0000
commitcdcb84ef00da4a9b367e6536149634f633c41c71 (patch)
tree45826b1e478212df2dab3e0dacc8305a4f364c0a /src
parenta7c498599f917607542bcd7003c445723aba9127 (diff)
parent3fdb05e883ce0a6fc610474eaa37d79fd7ac67e1 (diff)
downloadsqlite-cdcb84ef00da4a9b367e6536149634f633c41c71.tar.gz
sqlite-cdcb84ef00da4a9b367e6536149634f633c41c71.zip
Merge trunk into wasi-patches branch.
FossilOrigin-Name: 6fc20d75d49310aedbc3351a4a5f1aa9ef5b4100501c7bfbe556aca2be2e44d7
Diffstat (limited to 'src')
-rw-r--r--src/attach.c29
-rw-r--r--src/json.c11
-rw-r--r--src/prepare.c7
-rw-r--r--src/resolve.c1
-rw-r--r--src/select.c13
-rw-r--r--src/shell.c.in43
-rw-r--r--src/sqlite.h.in15
-rw-r--r--src/sqliteInt.h4
-rw-r--r--src/tclsqlite.c3
-rw-r--r--src/test1.c46
-rw-r--r--src/test_bestindex.c6
-rw-r--r--src/util.c20
-rw-r--r--src/vdbe.c2
-rw-r--r--src/vdbeaux.c3
-rw-r--r--src/where.c11
15 files changed, 172 insertions, 42 deletions
diff --git a/src/attach.c b/src/attach.c
index 1732be27b..4a6a25bf0 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -85,7 +85,7 @@ static void attachFunc(
char *zErr = 0;
unsigned int flags;
Db *aNew; /* New array of Db pointers */
- Db *pNew; /* Db object for the newly attached database */
+ Db *pNew = 0; /* Db object for the newly attached database */
char *zErrDyn = 0;
sqlite3_vfs *pVfs;
@@ -105,13 +105,26 @@ static void attachFunc(
/* This is not a real ATTACH. Instead, this routine is being called
** from sqlite3_deserialize() to close database db->init.iDb and
** reopen it as a MemDB */
+ Btree *pNewBt = 0;
pVfs = sqlite3_vfs_find("memdb");
if( pVfs==0 ) return;
- pNew = &db->aDb[db->init.iDb];
- if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
- pNew->pBt = 0;
- pNew->pSchema = 0;
- rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+ rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB);
+ if( rc==SQLITE_OK ){
+ Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt);
+ if( pNewSchema ){
+ /* Both the Btree and the new Schema were allocated successfully.
+ ** Close the old db and update the aDb[] slot with the new memdb
+ ** values. */
+ pNew = &db->aDb[db->init.iDb];
+ if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt);
+ pNew->pBt = pNewBt;
+ pNew->pSchema = pNewSchema;
+ }else{
+ sqlite3BtreeClose(pNewBt);
+ rc = SQLITE_NOMEM;
+ }
+ }
+ if( rc ) goto attach_error;
}else{
/* This is a real ATTACH
**
@@ -224,7 +237,7 @@ static void attachFunc(
}
#endif
if( rc ){
- if( !REOPEN_AS_MEMDB(db) ){
+ if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pBt ){
@@ -341,6 +354,8 @@ static void codeAttach(
sqlite3* db = pParse->db;
int regArgs;
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end;
+
if( pParse->nErr ) goto attach_end;
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
diff --git a/src/json.c b/src/json.c
index 3636d3665..67448421b 100644
--- a/src/json.c
+++ b/src/json.c
@@ -2473,6 +2473,13 @@ static int jsonEachBestIndex(
idxMask |= iMask;
}
}
+ if( pIdxInfo->nOrderBy>0
+ && pIdxInfo->aOrderBy[0].iColumn<0
+ && pIdxInfo->aOrderBy[0].desc==0
+ ){
+ pIdxInfo->orderByConsumed = 1;
+ }
+
if( (unusableMask & ~idxMask)!=0 ){
/* If there are any unusable constraints on JSON or ROOT, then reject
** this entire plan */
@@ -2668,10 +2675,10 @@ void sqlite3RegisterJsonFunctions(void){
#endif
WAGGREGATE(json_group_array, 1, 0, 0,
jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
- SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS),
+ SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
WAGGREGATE(json_group_object, 2, 0, 0,
jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
- SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)
+ SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC)
};
sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
#endif
diff --git a/src/prepare.c b/src/prepare.c
index 760738740..b2613e2c1 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -306,7 +306,12 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){
#else
encoding = SQLITE_UTF8;
#endif
- sqlite3SetTextEncoding(db, encoding);
+ if( db->nVdbeActive>0 && encoding!=ENC(db) ){
+ rc = SQLITE_LOCKED;
+ goto initone_error_out;
+ }else{
+ sqlite3SetTextEncoding(db, encoding);
+ }
}else{
/* If opening an attached database, the encoding much match ENC(db) */
if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){
diff --git a/src/resolve.c b/src/resolve.c
index 1c3a9d909..0d196ac37 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -506,6 +506,7 @@ static int lookupName(
if( pParse->bReturning ){
eNewExprOp = TK_REGISTER;
pExpr->op2 = TK_COLUMN;
+ pExpr->iColumn = iCol;
pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable +
sqlite3TableColumnToStorage(pTab, iCol) + 1;
}else{
diff --git a/src/select.c b/src/select.c
index 2288858ea..d27bed026 100644
--- a/src/select.c
+++ b/src/select.c
@@ -2211,7 +2211,7 @@ int sqlite3ColumnsFromExprList(
*pnCol = nCol;
*paCol = aCol;
- for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
+ for(i=0, pCol=aCol; i<nCol && !pParse->nErr; i++, pCol++){
struct ExprList_item *pX = &pEList->a[i];
struct ExprList_item *pCollide;
/* Get an appropriate name for the column
@@ -2261,7 +2261,10 @@ int sqlite3ColumnsFromExprList(
if( zName[j]==':' ) nName = j;
}
zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
- if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
+ sqlite3ProgressCheck(pParse);
+ if( cnt>3 ){
+ sqlite3_randomness(sizeof(cnt), &cnt);
+ }
}
pCol->zCnName = zName;
pCol->hName = sqlite3StrIHash(zName);
@@ -2274,14 +2277,14 @@ int sqlite3ColumnsFromExprList(
}
}
sqlite3HashClear(&ht);
- if( db->mallocFailed ){
+ if( pParse->nErr ){
for(j=0; j<i; j++){
sqlite3DbFree(db, aCol[j].zCnName);
}
sqlite3DbFree(db, aCol);
*paCol = 0;
*pnCol = 0;
- return SQLITE_NOMEM_BKPT;
+ return pParse->rc;
}
return SQLITE_OK;
}
@@ -2313,7 +2316,7 @@ void sqlite3SubqueryColumnTypes(
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
- assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
+ assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 );
assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB );
if( db->mallocFailed ) return;
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
diff --git a/src/shell.c.in b/src/shell.c.in
index 2c2bd557e..70774938a 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -481,6 +481,18 @@ static char mainPrompt[PROMPT_LEN_MAX];
/* Continuation prompt. default: " ...> " */
static char continuePrompt[PROMPT_LEN_MAX];
+/* This is variant of the standard-library strncpy() routine with the
+** one change that the destination string is always zero-terminated, even
+** if there is no zero-terminator in the first n-1 characters of the source
+** string.
+*/
+static char *shell_strncpy(char *dest, const char *src, size_t n){
+ size_t i;
+ for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i];
+ dest[i] = 0;
+ return dest;
+}
+
/*
** Optionally disable dynamic continuation prompt.
** Unless disabled, the continuation prompt shows open SQL lexemes if any,
@@ -548,18 +560,18 @@ static char *dynamicContinuePrompt(void){
if( ndp > ncp-3 ) return continuePrompt;
strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
- strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
+ shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
PROMPT_LEN_MAX-4);
}else{
if( dynPrompt.inParenLevel>9 ){
- strncpy(dynPrompt.dynamicPrompt, "(..", 4);
+ shell_strncpy(dynPrompt.dynamicPrompt, "(..", 4);
}else if( dynPrompt.inParenLevel<0 ){
- strncpy(dynPrompt.dynamicPrompt, ")x!", 4);
+ shell_strncpy(dynPrompt.dynamicPrompt, ")x!", 4);
}else{
- strncpy(dynPrompt.dynamicPrompt, "(x.", 4);
+ shell_strncpy(dynPrompt.dynamicPrompt, "(x.", 4);
dynPrompt.dynamicPrompt[2] = (char)('0'+dynPrompt.inParenLevel);
}
- strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, PROMPT_LEN_MAX-4);
+ shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, PROMPT_LEN_MAX-4);
}
}
return dynPrompt.dynamicPrompt;
@@ -5974,7 +5986,7 @@ static void tryToCloneSchema(
char *zErrMsg = 0;
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
- " WHERE %s", zWhere);
+ " WHERE %s ORDER BY rowid ASC", zWhere);
shell_check_oom(zQuery);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
@@ -5987,12 +5999,14 @@ static void tryToCloneSchema(
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
if( zName==0 || zSql==0 ) continue;
- printf("%s... ", zName); fflush(stdout);
- sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
- if( zErrMsg ){
- utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
- sqlite3_free(zErrMsg);
- zErrMsg = 0;
+ if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){
+ printf("%s... ", zName); fflush(stdout);
+ sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
+ if( zErrMsg ){
+ utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
+ sqlite3_free(zErrMsg);
+ zErrMsg = 0;
+ }
}
if( xForEach ){
xForEach(p, newDb, (const char*)zName);
@@ -6016,6 +6030,7 @@ static void tryToCloneSchema(
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
if( zName==0 || zSql==0 ) continue;
+ if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ) continue;
printf("%s... ", zName); fflush(stdout);
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
if( zErrMsg ){
@@ -9631,10 +9646,10 @@ static int do_meta_command(char *zLine, ShellState *p){
if( c=='p' && cli_strncmp(azArg[0], "prompt", n)==0 ){
if( nArg >= 2) {
- strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
+ shell_strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
}
if( nArg >= 3) {
- strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
+ shell_strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
}
}else
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index bf1477ef2..2ee27898d 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -3366,7 +3366,7 @@ int sqlite3_trace_v2(
**
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
-** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
+** [sqlite3_step()] and [sqlite3_prepare()] and similar for
** database connection D. An example use for this
** interface is to keep a GUI updated during a large query.
**
@@ -3391,6 +3391,13 @@ int sqlite3_trace_v2(
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
+** The progress handler callback would originally only be invoked from the
+** bytecode engine. It still might be invoked during [sqlite3_prepare()]
+** and similar because those routines might force a reparse of the schema
+** which involves running the bytecode engine. However, beginning with
+** SQLite version 3.41.0, the progress handler callback might also be
+** invoked directly from [sqlite3_prepare()] while analyzing and generating
+** code for complex queries.
*/
void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
@@ -7157,10 +7164,10 @@ struct sqlite3_module {
** when the omit flag is true there is no guarantee that the constraint will
** not be checked again using byte code.)^
**
-** ^The idxNum and idxPtr values are recorded and passed into the
+** ^The idxNum and idxStr values are recorded and passed into the
** [xFilter] method.
-** ^[sqlite3_free()] is used to free idxPtr if and only if
-** needToFreeIdxPtr is true.
+** ^[sqlite3_free()] is used to free idxStr if and only if
+** needToFreeIdxStr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 09e817406..3da5f13d5 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3754,6 +3754,9 @@ struct Parse {
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
u32 newmask; /* Mask of new.* columns referenced */
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */
+#endif
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
u8 bReturning; /* Coding a RETURNING trigger */
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
@@ -4631,6 +4634,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
#endif
void sqlite3SetString(char **, sqlite3*, const char*);
+void sqlite3ProgressCheck(Parse*);
void sqlite3ErrorMsg(Parse*, const char*, ...);
int sqlite3ErrorToParser(sqlite3*,int);
void sqlite3Dequote(char*);
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 4e25a6501..c455c29f1 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -3054,6 +3054,9 @@ deserialize_error:
if( pDb->zProgress ){
Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
}
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ sqlite3_progress_handler(pDb->db, 0, 0, 0);
+#endif
}else if( objc==4 ){
char *zProgress;
int len;
diff --git a/src/test1.c b/src/test1.c
index dda77a90a..b1f0baafc 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -4137,6 +4137,14 @@ static int SQLITE_TCLAPI test_bind_value_from_select(
return TCL_OK;
}
+#ifdef _WIN32
+ struct iovec {
+ void *iov_base;
+ size_t iov_len;
+ };
+#else
+# include <sys/uio.h>
+#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
@@ -4149,6 +4157,7 @@ static int SQLITE_TCLAPI test_bind_value_from_select(
** -int64
** -double
** -text
+** -blob
**
** Each call clears static data. Called with no options does nothing
** but clear static data.
@@ -4188,6 +4197,11 @@ static int SQLITE_TCLAPI test_carray_bind(
sqlite3_free(((char**)aStaticData)[i]);
}
}
+ if( eStaticType==4 ){
+ for(i=0; i<nStaticData; i++){
+ sqlite3_free(((struct iovec*)aStaticData)[i].iov_base);
+ }
+ }
sqlite3_free(aStaticData);
aStaticData = 0;
nStaticData = 0;
@@ -4217,6 +4231,9 @@ static int SQLITE_TCLAPI test_carray_bind(
if( strcmp(z, "-text")==0 ){
eType = 3; /* CARRAY_TEXT */
}else
+ if( strcmp(z, "-blob")==0 ){
+ eType = 4; /* CARRAY_BLOB */
+ }else
if( strcmp(z, "--")==0 ){
break;
}else
@@ -4230,6 +4247,11 @@ static int SQLITE_TCLAPI test_carray_bind(
(char*)0);
return TCL_ERROR;
}
+ if( eType==4 && !isStatic && !isTransient ){
+ Tcl_AppendResult(interp, "blob data must be either -static or -transient",
+ (char*)0);
+ return TCL_ERROR;
+ }
if( isStatic && isTransient ){
Tcl_AppendResult(interp, "cannot be both -static and -transient",
(char*)0);
@@ -4244,7 +4266,7 @@ static int SQLITE_TCLAPI test_carray_bind(
if( Tcl_GetIntFromObj(interp, objv[i], &idx) ) return TCL_ERROR;
i++;
nData = objc - i;
- switch( eType + 4*(nData<=0) ){
+ switch( eType + 5*(nData<=0) ){
case 0: { /* INT32 */
int *a = sqlite3_malloc( sizeof(int)*nData );
if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; }
@@ -4297,7 +4319,24 @@ static int SQLITE_TCLAPI test_carray_bind(
aData = a;
break;
}
- case 4: { /* nData==0 */
+ case 4: { /* BLOB */
+ struct iovec *a = sqlite3_malloc( sizeof(struct iovec)*nData );
+ if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; }
+ for(j=0; j<nData; j++){
+ int n = 0;
+ unsigned char *v = Tcl_GetByteArrayFromObj(objv[i+i], &n);
+ a[j].iov_len = n;
+ a[j].iov_base = sqlite3_malloc64( n );
+ if( a[j].iov_base==0 ){
+ a[j].iov_len = 0;
+ }else{
+ memcpy(a[j].iov_base, v, n);
+ }
+ }
+ aData = a;
+ break;
+ }
+ case 5: { /* nData==0 */
aData = "";
xDel = SQLITE_STATIC;
isTransient = 0;
@@ -4315,6 +4354,9 @@ static int SQLITE_TCLAPI test_carray_bind(
if( eType==3 ){
for(i=0; i<nData; i++) sqlite3_free(((char**)aData)[i]);
}
+ if( eType==4 ){
+ for(i=0; i<nData; i++) sqlite3_free(((struct iovec*)aData)[i].iov_base);
+ }
sqlite3_free(aData);
}
carray_bind_done:
diff --git a/src/test_bestindex.c b/src/test_bestindex.c
index 65f063e50..f6e0678ce 100644
--- a/src/test_bestindex.c
+++ b/src/test_bestindex.c
@@ -766,11 +766,11 @@ static int tclFindFunction(
if( Tcl_GetIntFromObj(interp, pObj, &iRet) ){
rc = SQLITE_ERROR;
}else if( iRet>0 ){
- int nName = strlen(zName);
- int nByte = nName + 1 + sizeof(TestFindFunction);
+ sqlite3_int64 nName = strlen(zName);
+ sqlite3_int64 nByte = nName + 1 + sizeof(TestFindFunction);
TestFindFunction *pNew = 0;
- pNew = (TestFindFunction*)sqlite3_malloc(nByte);
+ pNew = (TestFindFunction*)sqlite3_malloc64(nByte);
if( pNew==0 ){
iRet = 0;
}else{
diff --git a/src/util.c b/src/util.c
index 23c6b1a66..632d317e3 100644
--- a/src/util.c
+++ b/src/util.c
@@ -176,6 +176,26 @@ void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
}
/*
+** Check for interrupts and invoke progress callback.
+*/
+void sqlite3ProgressCheck(Parse *p){
+ sqlite3 *db = p->db;
+ if( AtomicLoad(&db->u1.isInterrupted) ){
+ p->nErr++;
+ p->rc = SQLITE_INTERRUPT;
+ }
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+ if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){
+ if( db->xProgress(db->pProgressArg) ){
+ p->nErr++;
+ p->rc = SQLITE_INTERRUPT;
+ }
+ p->nProgressSteps = 0;
+ }
+#endif
+}
+
+/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
**
** This function should be used to report any error that occurs while
diff --git a/src/vdbe.c b/src/vdbe.c
index 92dc1e1ed..db6086233 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2194,7 +2194,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
- testcase( flags3==pIn3->flags );
+ assert( flags3==pIn3->flags || CORRUPT_DB );
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index ca9e5112a..d04d8f1e1 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -574,6 +574,9 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
int i;
for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1;
#endif
+ if( nNewSize>=100 && (nNewSize/100)>(p->nLabelAlloc/100) ){
+ sqlite3ProgressCheck(p);
+ }
p->nLabelAlloc = nNewSize;
p->aLabel[j] = v->nOp;
}
diff --git a/src/where.c b/src/where.c
index 890c3bf52..205f24762 100644
--- a/src/where.c
+++ b/src/where.c
@@ -2698,6 +2698,7 @@ static void whereLoopOutputAdjust(
if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
}
if( j<0 ){
+ sqlite3ProgressCheck(pWC->pWInfo->pParse);
if( pLoop->maskSelf==pTerm->prereqAll ){
/* If there are extra terms in the WHERE clause not used by an index
** that depend only on the table being scanned, and that will tend to
@@ -2865,7 +2866,10 @@ static int whereLoopAddBtreeIndex(
WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
pNew = pBuilder->pNew;
- if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
+ assert( db->mallocFailed==0 || pParse->nErr>0 );
+ if( pParse->nErr ){
+ return pParse->rc;
+ }
WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n",
pProbe->pTable->zName,pProbe->zName,
pNew->u.btree.nEq, pNew->nSkip, pNew->rRun));
@@ -3181,6 +3185,9 @@ static int whereLoopAddBtreeIndex(
&& (pNew->u.btree.nEq<pProbe->nKeyCol ||
pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY)
){
+ if( pNew->u.btree.nEq>3 ){
+ sqlite3ProgressCheck(pParse);
+ }
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
}
pNew->nOut = saved_nOut;
@@ -4340,8 +4347,6 @@ static int whereLoopAddOr(
if( rc==SQLITE_OK ){
rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
}
- assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0
- || rc==SQLITE_NOMEM );
testcase( rc==SQLITE_NOMEM && sCur.n>0 );
testcase( rc==SQLITE_DONE );
if( sCur.n==0 ){