aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2020-05-06 15:07:25 +0000
committerdan <dan@noemail.net>2020-05-06 15:07:25 +0000
commit293e9f5d6cd1ae9a91de09e85d1a03d777a71f3d (patch)
treea27e3f82f9385be9187e6a01bb5894afb26abbb3 /src
parent58021b237ae7e84069aaa564c0b6834a23296aed (diff)
parentfde259250327c28c75e201406f1b85f6f1ef7670 (diff)
downloadsqlite-293e9f5d6cd1ae9a91de09e85d1a03d777a71f3d.tar.gz
sqlite-293e9f5d6cd1ae9a91de09e85d1a03d777a71f3d.zip
Merge latest trunk changes into this branch.
FossilOrigin-Name: a3727dba10b476f414f0a049b35f2a5c169a408eccefa6833821560684e07f8b
Diffstat (limited to 'src')
-rw-r--r--src/analyze.c2
-rw-r--r--src/btree.c2
-rw-r--r--src/delete.c1
-rw-r--r--src/main.c139
-rw-r--r--src/sqlite.h.in1
-rw-r--r--src/vdbe.c13
6 files changed, 84 insertions, 74 deletions
diff --git a/src/analyze.c b/src/analyze.c
index 53bd62a82..b2f030df0 100644
--- a/src/analyze.c
+++ b/src/analyze.c
@@ -768,7 +768,7 @@ static void statPush(
}
}else
#endif
- if( p->nLimit && p->nRow>p->nLimit*(p->nSkipAhead+1) ){
+ if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
p->nSkipAhead++;
sqlite3_result_int(context, p->current.anDLt[0]>0);
}
diff --git a/src/btree.c b/src/btree.c
index 3b8d0529c..e80add6eb 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -7167,7 +7167,7 @@ static int editPage(
assert( nCell>=0 );
if( iOld<iNew ){
int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
- if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
+ if( NEVER(nShift>nCell) ) return SQLITE_CORRUPT_BKPT;
memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
nCell -= nShift;
}
diff --git a/src/delete.c b/src/delete.c
index 60efc9d56..141efa594 100644
--- a/src/delete.c
+++ b/src/delete.c
@@ -858,6 +858,7 @@ void sqlite3GenerateRowIndexDelete(
&iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
+ sqlite3VdbeChangeP5(v, 1); /* Cause IdxDelete to error if no entry found */
sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel);
pPrior = pIdx;
}
diff --git a/src/main.c b/src/main.c
index e386bb384..e96f5e113 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,15 +25,78 @@
#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
# include "sqliteicu.h"
#endif
+
+/*
+** This is an extension initializer that is a no-op and always
+** succeeds, except that it fails if the fault-simulation is set
+** to 500.
+*/
+static int sqlite3TestExtInit(sqlite3 *db){
+ (void)db;
+ return sqlite3FaultSim(500);
+}
+
+
+/*
+** Forward declarations of external module initializer functions
+** for modules that need them.
+*/
+#ifdef SQLITE_ENABLE_FTS1
+int sqlite3Fts1Init(sqlite3*);
+#endif
+#ifdef SQLITE_ENABLE_FTS2
+int sqlite3Fts2Init(sqlite3*);
+#endif
+#ifdef SQLITE_ENABLE_FTS5
+int sqlite3Fts5Init(sqlite3*);
+#endif
#ifdef SQLITE_ENABLE_JSON1
int sqlite3Json1Init(sqlite3*);
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
int sqlite3StmtVtabInit(sqlite3*);
#endif
+
+/*
+** An array of pointers to extension initializer functions for
+** built-in extensions.
+*/
+static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = {
+#ifdef SQLITE_ENABLE_FTS1
+ sqlite3Fts1Init,
+#endif
+#ifdef SQLITE_ENABLE_FTS2
+ sqlite3Fts2Init,
+#endif
+#ifdef SQLITE_ENABLE_FTS3
+ sqlite3Fts3Init,
+#endif
#ifdef SQLITE_ENABLE_FTS5
-int sqlite3Fts5Init(sqlite3*);
+ sqlite3Fts5Init,
+#endif
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
+ sqlite3IcuInit,
#endif
+#ifdef SQLITE_ENABLE_RTREE
+ sqlite3RtreeInit,
+#endif
+#ifdef SQLITE_ENABLE_DBPAGE_VTAB
+ sqlite3DbpageRegister,
+#endif
+#ifdef SQLITE_ENABLE_DBSTAT_VTAB
+ sqlite3DbstatRegister,
+#endif
+ sqlite3TestExtInit,
+#ifdef SQLITE_ENABLE_JSON1
+ sqlite3Json1Init,
+#endif
+#ifdef SQLITE_ENABLE_STMTVTAB
+ sqlite3StmtVtabInit,
+#endif
+#ifdef SQLITE_ENABLE_BYTECODE_VTAB
+ sqlite3VdbeBytecodeVtabInit,
+#endif
+};
#ifndef SQLITE_AMALGAMATION
/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
@@ -3004,6 +3067,7 @@ static int openDatabase(
int isThreadsafe; /* True for threadsafe connections */
char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
+ int i; /* Loop counter */
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
@@ -3244,14 +3308,11 @@ static int openDatabase(
sqlite3RegisterPerConnectionBuiltinFunctions(db);
rc = sqlite3_errcode(db);
-#ifdef SQLITE_ENABLE_FTS5
- /* Register any built-in FTS5 module before loading the automatic
- ** extensions. This allows automatic extensions to register FTS5
- ** tokenizers and auxiliary functions. */
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3Fts5Init(db);
+
+ /* Load compiled-in extensions */
+ for(i=0; rc==SQLITE_OK && i<ArraySize(sqlite3BuiltinExtensions); i++){
+ rc = sqlite3BuiltinExtensions[i](db);
}
-#endif
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
@@ -3264,68 +3325,6 @@ static int openDatabase(
}
}
-#ifdef SQLITE_ENABLE_FTS1
- if( !db->mallocFailed ){
- extern int sqlite3Fts1Init(sqlite3*);
- rc = sqlite3Fts1Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_FTS2
- if( !db->mallocFailed && rc==SQLITE_OK ){
- extern int sqlite3Fts2Init(sqlite3*);
- rc = sqlite3Fts2Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3Fts3Init(db);
- }
-#endif
-
-#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3IcuInit(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_RTREE
- if( !db->mallocFailed && rc==SQLITE_OK){
- rc = sqlite3RtreeInit(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_DBPAGE_VTAB
- if( !db->mallocFailed && rc==SQLITE_OK){
- rc = sqlite3DbpageRegister(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_DBSTAT_VTAB
- if( !db->mallocFailed && rc==SQLITE_OK){
- rc = sqlite3DbstatRegister(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_JSON1
- if( !db->mallocFailed && rc==SQLITE_OK){
- rc = sqlite3Json1Init(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_STMTVTAB
- if( !db->mallocFailed && rc==SQLITE_OK){
- rc = sqlite3StmtVtabInit(db);
- }
-#endif
-
-#ifdef SQLITE_ENABLE_BYTECODE_VTAB
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3VdbeBytecodeVtabInit(db);
- }
-#endif
-
#ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS
/* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time
** option gives access to internal functions by default.
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 5c082623c..aa0ac9b0f 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -516,6 +516,7 @@ int sqlite3_exec(
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
+#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
diff --git a/src/vdbe.c b/src/vdbe.c
index 69055d916..ce96439d1 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -5652,12 +5652,19 @@ case OP_SorterInsert: { /* in2 */
break;
}
-/* Opcode: IdxDelete P1 P2 P3 * *
+/* Opcode: IdxDelete P1 P2 P3 * P5
** Synopsis: key=r[P2@P3]
**
** The content of P3 registers starting at register P2 form
** an unpacked index key. This opcode removes that entry from the
** index opened by cursor P1.
+**
+** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
+** if no matching index entry is found. This happens when running
+** an UPDATE or DELETE statement and the index entry to be updated
+** or deleted is not found. For some uses of IdxDelete
+** (example: the EXCEPT operator) it does not matter that no matching
+** entry is found. For those cases, P5 is zero.
*/
case OP_IdxDelete: {
VdbeCursor *pC;
@@ -5674,7 +5681,6 @@ case OP_IdxDelete: {
sqlite3VdbeIncrWriteCounter(p, pC);
pCrsr = pC->uc.pCursor;
assert( pCrsr!=0 );
- assert( pOp->p5==0 );
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.default_rc = 0;
@@ -5684,6 +5690,9 @@ case OP_IdxDelete: {
if( res==0 ){
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
if( rc ) goto abort_due_to_error;
+ }else if( pOp->p5 ){
+ rc = SQLITE_CORRUPT_INDEX;
+ goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;