aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/alter.c7
-rw-r--r--src/date.c2
-rw-r--r--src/expr.c2
-rw-r--r--src/func.c2
-rw-r--r--src/json.c4
-rw-r--r--src/main.c8
-rw-r--r--src/parse.y4
-rw-r--r--src/pcache1.c12
-rw-r--r--src/printf.c4
-rw-r--r--src/select.c7
-rw-r--r--src/shell.c.in37
-rw-r--r--src/sqlite.h.in4
-rw-r--r--src/tclsqlite.c21
-rw-r--r--src/tokenize.c6
-rw-r--r--src/util.c2
-rw-r--r--src/vacuum.c2
-rw-r--r--src/vdbe.c2
-rw-r--r--src/vdbeblob.c9
-rw-r--r--src/vdbesort.c4
19 files changed, 95 insertions, 44 deletions
diff --git a/src/alter.c b/src/alter.c
index 819257166..f3108cbf9 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -1136,6 +1136,7 @@ static int renameParseSql(
int bTemp /* True if SQL is from temp schema */
){
int rc;
+ u64 flags;
sqlite3ParseObjectInit(p, db);
if( zSql==0 ){
@@ -1154,7 +1155,11 @@ static int renameParseSql(
p->eParseMode = PARSE_MODE_RENAME;
p->db = db;
p->nQueryLoop = 1;
+ flags = db->flags;
+ testcase( (db->flags & SQLITE_Comments)==0 && strstr(zSql," /* ")!=0 );
+ db->flags |= SQLITE_Comments;
rc = sqlite3RunParser(p, zSql);
+ db->flags = flags;
if( db->mallocFailed ) rc = SQLITE_NOMEM;
if( rc==SQLITE_OK
&& NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0)
@@ -2050,7 +2055,7 @@ static void renameTableTest(
u64 flags = db->flags;
if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL);
rc = renameParseSql(&sParse, zDb, db, zInput, bTemp);
- db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL));
+ db->flags = flags;
if( rc==SQLITE_OK ){
if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){
NameContext sNC;
diff --git a/src/date.c b/src/date.c
index de2736637..1b4f10fb4 100644
--- a/src/date.c
+++ b/src/date.c
@@ -1357,7 +1357,7 @@ static int daysAfterMonday(DateTime *pDate){
** In other words, return the day of the week according
** to this code:
**
-** 0=Sunday, 1=Monday, 2=Tues, ..., 6=Saturday
+** 0=Sunday, 1=Monday, 2=Tuesday, ..., 6=Saturday
*/
static int daysAfterSunday(DateTime *pDate){
assert( pDate->validJD );
diff --git a/src/expr.c b/src/expr.c
index f6b5729b4..a3c41a1f5 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -4672,7 +4672,7 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
/*
-** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This
+** Expression pExpr is guaranteed to be a TK_COLUMN or equivalent. This
** function checks the Parse.pIdxPartExpr list to see if this column
** can be replaced with a constant value. If so, it generates code to
** put the constant value in a register (ideally, but not necessarily,
diff --git a/src/func.c b/src/func.c
index d8c812759..9e2839336 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1919,7 +1919,7 @@ static void kahanBabuskaNeumaierInit(
** that it returns NULL if it sums over no inputs. TOTAL returns
** 0.0 in that case. In addition, TOTAL always returns a float where
** SUM might return an integer if it never encounters a floating point
-** value. TOTAL never fails, but SUM might through an exception if
+** value. TOTAL never fails, but SUM might throw an exception if
** it overflows an integer.
*/
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
diff --git a/src/json.c b/src/json.c
index 97bf25b2d..5360831af 100644
--- a/src/json.c
+++ b/src/json.c
@@ -419,7 +419,7 @@ static int jsonCacheInsert(
** most-recently used entry if it isn't so already.
**
** The JsonParse object returned still belongs to the Cache and might
-** be deleted at any moment. If the caller whants the JsonParse to
+** be deleted at any moment. If the caller wants the JsonParse to
** linger, it needs to increment the nPJRef reference counter.
*/
static JsonParse *jsonCacheSearch(
@@ -3464,7 +3464,7 @@ rebuild_from_cache:
** JSON functions were suppose to work. From the beginning, blob was
** reserved for expansion and a blob value should have raised an error.
** But it did not, due to a bug. And many applications came to depend
- ** upon this buggy behavior, espeically when using the CLI and reading
+ ** upon this buggy behavior, especially when using the CLI and reading
** JSON text using readfile(), which returns a blob. For this reason
** we will continue to support the bug moving forward.
** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d
diff --git a/src/main.c b/src/main.c
index 4d981d0ce..ba2faf0b7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -303,6 +303,14 @@ int sqlite3_initialize(void){
if( rc==SQLITE_OK ){
sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage,
sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage);
+#ifdef SQLITE_EXTRA_INIT_MUTEXED
+ {
+ int SQLITE_EXTRA_INIT_MUTEXED(const char*);
+ rc = SQLITE_EXTRA_INIT_MUTEXED(0);
+ }
+#endif
+ }
+ if( rc==SQLITE_OK ){
sqlite3MemoryBarrier();
sqlite3GlobalConfig.isInit = 1;
#ifdef SQLITE_EXTRA_INIT
diff --git a/src/parse.y b/src/parse.y
index e6aff2e0e..a5691cad4 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -323,7 +323,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
//
%token_class id ID|INDEXED.
-// And "ids" is an identifer-or-string.
+// And "ids" is an identifier-or-string.
//
%token_class ids ID|STRING.
@@ -1219,7 +1219,7 @@ expr(A) ::= idj(X) LP STAR RP. {
** The purpose of this function is to generate an Expr node from the first syntax
** into a TK_FUNCTION node that looks like it came from the second syntax.
**
- ** Only functions that have the SQLITE_SELFORDER1 perperty are allowed to do this
+ ** Only functions that have the SQLITE_SELFORDER1 property are allowed to do this
** transformation. Because DISTINCT is not allowed in the ordered-set aggregate
** syntax, an error is raised if DISTINCT is used.
*/
diff --git a/src/pcache1.c b/src/pcache1.c
index 88a7b3a0b..39607328f 100644
--- a/src/pcache1.c
+++ b/src/pcache1.c
@@ -232,10 +232,6 @@ static SQLITE_WSD struct PCacheGlobal {
sqlite3_mutex *mutex; /* Mutex for accessing the following: */
PgFreeslot *pFree; /* Free page blocks */
int nFreeSlot; /* Number of unused pcache slots */
- /* The following value requires a mutex to change. We skip the mutex on
- ** reading because (1) most platforms read a 32-bit integer atomically and
- ** (2) even if an incorrect value is read, no great harm is done since this
- ** is really just an optimization. */
int bUnderPressure; /* True if low on PAGECACHE memory */
} pcache1_g;
@@ -283,7 +279,7 @@ void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
pcache1.pStart = pBuf;
pcache1.pFree = 0;
- pcache1.bUnderPressure = 0;
+ AtomicStore(&pcache1.bUnderPressure,0);
while( n-- ){
p = (PgFreeslot*)pBuf;
p->pNext = pcache1.pFree;
@@ -351,7 +347,7 @@ static void *pcache1Alloc(int nByte){
if( p ){
pcache1.pFree = pcache1.pFree->pNext;
pcache1.nFreeSlot--;
- pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
+ AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot<pcache1.nReserve);
assert( pcache1.nFreeSlot>=0 );
sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
@@ -390,7 +386,7 @@ static void pcache1Free(void *p){
pSlot->pNext = pcache1.pFree;
pcache1.pFree = pSlot;
pcache1.nFreeSlot++;
- pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
+ AtomicStore(&pcache1.bUnderPressure,pcache1.nFreeSlot<pcache1.nReserve);
assert( pcache1.nFreeSlot<=pcache1.nSlot );
sqlite3_mutex_leave(pcache1.mutex);
}else{
@@ -521,7 +517,7 @@ void sqlite3PageFree(void *p){
*/
static int pcache1UnderMemoryPressure(PCache1 *pCache){
if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
- return pcache1.bUnderPressure;
+ return AtomicLoad(&pcache1.bUnderPressure);
}else{
return sqlite3HeapNearlyFull();
}
diff --git a/src/printf.c b/src/printf.c
index ae9e9010b..166c11194 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -800,7 +800,7 @@ void sqlite3_str_vappendf(
for(k=0; k<i; k++){
if( escarg[k]=='\\' ){
nBack++;
- }else if( escarg[k]<=0x1f ){
+ }else if( ((u8*)escarg)[k]<=0x1f ){
nCtrl++;
}
}
@@ -838,7 +838,7 @@ void sqlite3_str_vappendf(
bufpt[j++] = ch;
}else if( ch=='\\' ){
bufpt[j++] = '\\';
- }else if( ch<=0x1f ){
+ }else if( ((unsigned char)ch)<=0x1f ){
bufpt[j-1] = '\\';
bufpt[j++] = 'u';
bufpt[j++] = '0';
diff --git a/src/select.c b/src/select.c
index e7db19533..904290223 100644
--- a/src/select.c
+++ b/src/select.c
@@ -7201,6 +7201,7 @@ static void agginfoFree(sqlite3 *db, void *pArg){
** * There is no WHERE or GROUP BY or HAVING clauses on the subqueries
** * The outer query is a simple count(*) with no WHERE clause or other
** extraneous syntax.
+** * None of the subqueries are DISTINCT (forumpost/a860f5fb2e 2025-03-10)
**
** Return TRUE if the optimization is undertaken.
*/
@@ -7233,7 +7234,11 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
if( pSub->pWhere ) return 0; /* No WHERE clause */
if( pSub->pLimit ) return 0; /* No LIMIT clause */
- if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
+ if( pSub->selFlags & (SF_Aggregate|SF_Distinct) ){
+ testcase( pSub->selFlags & SF_Aggregate );
+ testcase( pSub->selFlags & SF_Distinct );
+ return 0; /* Not an aggregate nor DISTINCT */
+ }
assert( pSub->pHaving==0 ); /* Due to the previous */
pSub = pSub->pPrior; /* Repeat over compound */
}while( pSub );
diff --git a/src/shell.c.in b/src/shell.c.in
index 72a5cee40..93d73e6ac 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -218,6 +218,8 @@ typedef unsigned char u8;
#define IsSpace(X) isspace((unsigned char)X)
#define IsDigit(X) isdigit((unsigned char)X)
#define ToLower(X) (char)tolower((unsigned char)X)
+#define IsAlnum(X) isalnum((unsigned char)X)
+#define IsAlpha(X) isalpha((unsigned char)X)
#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
@@ -1127,9 +1129,9 @@ static void appendText(ShellText *p, const char *zAppend, char quote){
static char quoteChar(const char *zName){
int i;
if( zName==0 ) return '"';
- if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
+ if( !IsAlpha(zName[0]) && zName[0]!='_' ) return '"';
for(i=0; zName[i]; i++){
- if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
+ if( !IsAlnum(zName[i]) && zName[i]!='_' ) return '"';
}
return sqlite3_keyword_check(zName, i) ? '"' : 0;
}
@@ -2739,6 +2741,8 @@ static int shell_callback(
char cEnd = 0;
char c;
int nLine = 0;
+ int isIndex;
+ int isWhere = 0;
assert( nArg==1 );
if( azArg[0]==0 ) break;
if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
@@ -2747,6 +2751,8 @@ static int shell_callback(
sqlite3_fprintf(p->out, "%s;\n", azArg[0]);
break;
}
+ isIndex = sqlite3_strlike("CREATE INDEX%", azArg[0], 0)==0
+ || sqlite3_strlike("CREATE UNIQUE INDEX%", azArg[0], 0)==0;
z = sqlite3_mprintf("%s", azArg[0]);
shell_check_oom(z);
j = 0;
@@ -2776,14 +2782,26 @@ static int shell_callback(
nParen++;
}else if( c==')' ){
nParen--;
- if( nLine>0 && nParen==0 && j>0 ){
+ if( nLine>0 && nParen==0 && j>0 && !isWhere ){
printSchemaLineN(p->out, z, j, "\n");
j = 0;
}
+ }else if( (c=='w' || c=='W')
+ && nParen==0 && isIndex
+ && sqlite3_strnicmp("WHERE",&z[i],5)==0
+ && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
+ isWhere = 1;
+ }else if( isWhere && (c=='A' || c=='a')
+ && nParen==0
+ && sqlite3_strnicmp("AND",&z[i],3)==0
+ && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
+ printSchemaLineN(p->out, z, j, "\n ");
+ j = 0;
}
z[j++] = c;
if( nParen==1 && cEnd==0
&& (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
+ && !isWhere
){
if( c=='\n' ) j--;
printSchemaLineN(p->out, z, j, "\n ");
@@ -3987,11 +4005,11 @@ static char *translateForDisplayAndDup(
if( n>=mxWidth && bWordWrap ){
/* Perhaps try to back up to a better place to break the line */
for(k=i; k>i/2; k--){
- if( isspace(z[k-1]) ) break;
+ if( IsSpace(z[k-1]) ) break;
}
if( k<=i/2 ){
for(k=i; k>i/2; k--){
- if( isalnum(z[k-1])!=isalnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
+ if( IsAlnum(z[k-1])!=IsAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
}
}
if( k<=i/2 ){
@@ -5925,7 +5943,7 @@ static void linenoise_completion(
#endif
if( nLine>(i64)sizeof(zBuf)-30 ) return;
if( zLine[0]=='.' || zLine[0]=='#') return;
- for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
+ for(i=nLine-1; i>=0 && (IsAlnum(zLine[i]) || zLine[i]=='_'); i--){}
if( i==nLine-1 ) return;
iStart = i+1;
memcpy(zBuf, zLine, iStart);
@@ -8165,6 +8183,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);
+ sqlite3_fprintf(pState->out, ".dbconfig defensive off\n");
sqlite3_recover_run(p);
if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
const char *zErr = sqlite3_recover_errmsg(p);
@@ -12256,7 +12275,7 @@ static int line_is_command_terminator(char *zLine){
** out of the build if compiling with SQLITE_OMIT_COMPLETE.
*/
#ifdef SQLITE_OMIT_COMPLETE
-# error the CLI application is imcompatable with SQLITE_OMIT_COMPLETE.
+# error the CLI application is incompatible with SQLITE_OMIT_COMPLETE.
#endif
/*
@@ -12435,7 +12454,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
if(!z || !*z){
return 0;
}
- while(*z && isspace(*z)) ++z;
+ while(*z && IsSpace(*z)) ++z;
zBegin = z;
for(; *z && '\n'!=*z; ++nZ, ++z){}
if(nZ>0 && '\r'==zBegin[nZ-1]){
@@ -13456,6 +13475,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
** the database filename.
*/
for(i=0; i<nCmd; i++){
+ echo_group_input(&data, azCmd[i]);
if( azCmd[i][0]=='.' ){
rc = do_meta_command(azCmd[i], &data);
if( rc ){
@@ -13464,7 +13484,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
}
}else{
open_db(&data, 0);
- echo_group_input(&data, azCmd[i]);
rc = shell_exec(&data, azCmd[i], &zErrMsg);
if( zErrMsg || rc ){
if( zErrMsg!=0 ){
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 2bd51d27f..71338031c 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -5175,7 +5175,7 @@ const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]),
** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
@@ -7071,6 +7071,8 @@ int sqlite3_autovacuum_pages(
**
** ^The second argument is a pointer to the function to invoke when a
** row is updated, inserted or deleted in a rowid table.
+** ^The update hook is disabled by invoking sqlite3_update_hook()
+** with a NULL pointer as the second parameter.
** ^The first argument to the callback is a copy of the third argument
** to sqlite3_update_hook().
** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE],
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 824e8c4d3..c619ffca4 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -1232,6 +1232,7 @@ static int auth_callback(
}
#endif /* SQLITE_OMIT_AUTHORIZATION */
+#if 0
/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
@@ -1276,6 +1277,7 @@ static char *local_getline(char *zPrompt, FILE *in){
zLine = realloc( zLine, n+1 );
return zLine;
}
+#endif
/*
@@ -2057,7 +2059,7 @@ static int SQLITE_TCLAPI DbObjCmd(
** (4) Name of the database (ex: "main", "temp")
** (5) Name of trigger that is doing the access
**
- ** The callback should return on of the following strings: SQLITE_OK,
+ ** The callback should return one of the following strings: SQLITE_OK,
** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error.
**
** If this method is invoked with no arguments, the current authorization
@@ -2520,9 +2522,10 @@ static int SQLITE_TCLAPI DbObjCmd(
char *zLine; /* A single line of input from the file */
char **azCol; /* zLine[] broken up into columns */
const char *zCommit; /* How to commit changes */
- FILE *in; /* The input file */
+ Tcl_Channel in; /* The input file */
int lineno = 0; /* Line number of input file */
char zLineNum[80]; /* Line number print buffer */
+ Tcl_DString str;
Tcl_Obj *pResult; /* interp result */
const char *zSep;
@@ -2601,23 +2604,24 @@ static int SQLITE_TCLAPI DbObjCmd(
sqlite3_finalize(pStmt);
return TCL_ERROR;
}
- in = fopen(zFile, "rb");
+ in = Tcl_OpenFileChannel(interp, zFile, "rb", 0666);
if( in==0 ){
- Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0);
sqlite3_finalize(pStmt);
return TCL_ERROR;
}
azCol = malloc( sizeof(azCol[0])*(nCol+1) );
if( azCol==0 ) {
Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
- fclose(in);
+ Tcl_Close(interp, in);
return TCL_ERROR;
}
+ Tcl_DStringInit(&str);
(void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
zCommit = "COMMIT";
- while( (zLine = local_getline(0, in))!=0 ){
+ while( Tcl_Gets(in, &str)>=0 ) {
char *z;
lineno++;
+ zLine = Tcl_DStringValue(&str);
azCol[0] = zLine;
for(i=0, z=zLine; *z; z++){
if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
@@ -2655,15 +2659,16 @@ static int SQLITE_TCLAPI DbObjCmd(
}
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
- free(zLine);
+ Tcl_DStringSetLength(&str, 0);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
zCommit = "ROLLBACK";
break;
}
}
+ Tcl_DStringFree(&str);
free(azCol);
- fclose(in);
+ Tcl_Close(interp, in);
sqlite3_finalize(pStmt);
(void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
diff --git a/src/tokenize.c b/src/tokenize.c
index fe300ca52..e4d9f5371 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -692,7 +692,11 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){
assert( n==6 );
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
#endif /* SQLITE_OMIT_WINDOWFUNC */
- }else if( tokenType==TK_COMMENT && (db->flags & SQLITE_Comments)!=0 ){
+ }else if( tokenType==TK_COMMENT
+ && (db->init.busy || (db->flags & SQLITE_Comments)!=0)
+ ){
+ /* Ignore SQL comments if either (1) we are reparsing the schema or
+ ** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */
zSql += n;
continue;
}else if( tokenType!=TK_QNUMBER ){
diff --git a/src/util.c b/src/util.c
index 703ef0a23..8e4fd516e 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1639,7 +1639,7 @@ int sqlite3MulInt64(i64 *pA, i64 iB){
}
/*
-** Compute the absolute value of a 32-bit signed integer, of possible. Or
+** Compute the absolute value of a 32-bit signed integer, if possible. Or
** if the integer has a value of -2147483648, return +2147483647
*/
int sqlite3AbsInt32(int x){
diff --git a/src/vacuum.c b/src/vacuum.c
index e203f68c6..ae3af86b7 100644
--- a/src/vacuum.c
+++ b/src/vacuum.c
@@ -195,7 +195,7 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_mTrace = db->mTrace;
- db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_Comments;
db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
db->flags &= ~(u64)(SQLITE_ForeignKeys | SQLITE_ReverseOrder
| SQLITE_Defensive | SQLITE_CountRows);
diff --git a/src/vdbe.c b/src/vdbe.c
index b78a0aabf..ed5687f25 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -6056,7 +6056,7 @@ case OP_RowData: {
/* The OP_RowData opcodes always follow OP_NotExists or
** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions
** that might invalidate the cursor.
- ** If this where not the case, on of the following assert()s
+ ** If this were not the case, one of the following assert()s
** would fail. Should this ever change (because of changes in the code
** generator) then the fix would be to insert a call to
** sqlite3VdbeCursorMoveto().
diff --git a/src/vdbeblob.c b/src/vdbeblob.c
index 79698d0af..42edcf7de 100644
--- a/src/vdbeblob.c
+++ b/src/vdbeblob.c
@@ -133,6 +133,7 @@ int sqlite3_blob_open(
char *zErr = 0;
Table *pTab;
Incrblob *pBlob = 0;
+ int iDb;
Parse sParse;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -178,7 +179,10 @@ int sqlite3_blob_open(
sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
}
#endif
- if( !pTab ){
+ if( pTab==0
+ || ((iDb = sqlite3SchemaToIndex(db, pTab->pSchema))==1 &&
+ sqlite3OpenTempDatabase(&sParse))
+ ){
if( sParse.zErrMsg ){
sqlite3DbFree(db, zErr);
zErr = sParse.zErrMsg;
@@ -189,7 +193,7 @@ int sqlite3_blob_open(
goto blob_open_out;
}
pBlob->pTab = pTab;
- pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
+ pBlob->zDb = db->aDb[iDb].zDbSName;
/* Now search pTab for the exact column. */
iCol = sqlite3ColumnIndex(pTab, zColumn);
@@ -273,7 +277,6 @@ int sqlite3_blob_open(
{OP_Halt, 0, 0, 0}, /* 5 */
};
Vdbe *v = (Vdbe *)pBlob->pStmt;
- int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
VdbeOp *aOp;
sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag,
diff --git a/src/vdbesort.c b/src/vdbesort.c
index 5774537b8..c9da88f6e 100644
--- a/src/vdbesort.c
+++ b/src/vdbesort.c
@@ -1431,6 +1431,10 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
p->u.pNext = 0;
for(i=0; aSlot[i]; i++){
p = vdbeSorterMerge(pTask, p, aSlot[i]);
+ /* ,--Each aSlot[] holds twice as much as the previous. So we cannot use
+ ** | up all 64 aSlots[] with only a 64-bit address space.
+ ** v */
+ assert( i<ArraySize(aSlot) );
aSlot[i] = 0;
}
aSlot[i] = p;