aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGordon Tetlow <gordon@FreeBSD.org>2020-08-05 17:13:08 +0000
committerGordon Tetlow <gordon@FreeBSD.org>2020-08-05 17:13:08 +0000
commit4f31a97afaa7e43d00695e547d90680b88305699 (patch)
tree870a8d68e73d9162ffd516e9f4e1c5d7b1645479
parentb1039a53836ab29bbc2239e5f8f95e1b972aa930 (diff)
downloadsrc-4f31a97afaa7e43d00695e547d90680b88305699.tar.gz
src-4f31a97afaa7e43d00695e547d90680b88305699.zip
Fix multiple vulnerabilities in sqlite3.
Approved by: so Security: FreeBSD-SA-20:22.sqlite Security: CVE-2020-11655 Security: CVE-2020-11656 Security: CVE-2020-13434 Security: CVE-2020-13435 Security: CVE-2020-13630 Security: CVE-2020-13631 Security: CVE-2020-13632
Notes
Notes: svn path=/releng/11.4/; revision=363922
-rw-r--r--contrib/sqlite3/Makefile.msc18
-rwxr-xr-xcontrib/sqlite3/configure22
-rw-r--r--contrib/sqlite3/configure.ac4
-rw-r--r--contrib/sqlite3/shell.c858
-rw-r--r--contrib/sqlite3/sqlite3.c18248
-rw-r--r--contrib/sqlite3/sqlite3.h777
-rw-r--r--contrib/sqlite3/sqlite3ext.h25
-rwxr-xr-xcontrib/sqlite3/tea/configure18
-rw-r--r--contrib/sqlite3/tea/configure.ac2
-rw-r--r--contrib/sqlite3/tea/generic/tclsqlite3.c75
-rw-r--r--contrib/sqlite3/tea/win/makefile.vc49
11 files changed, 12716 insertions, 7380 deletions
diff --git a/contrib/sqlite3/Makefile.msc b/contrib/sqlite3/Makefile.msc
index 2a7042efb064..746162a00c04 100644
--- a/contrib/sqlite3/Makefile.msc
+++ b/contrib/sqlite3/Makefile.msc
@@ -196,6 +196,7 @@ OSTRACE = 0
DEBUG = 0
!ENDIF
+
# Enable use of available compiler optimizations? Normally, this should be
# non-zero. Setting this to zero, thus disabling all compiler optimizations,
# can be useful for testing.
@@ -210,6 +211,12 @@ OPTIMIZATIONS = 2
SESSION = 0
!ENDIF
+# Set this to non-0 to enable support for the rbu extension.
+#
+!IFNDEF RBU
+RBU = 0
+!ENDIF
+
# Set the source code file to be used by executables and libraries when
# they need the amalgamation.
#
@@ -282,7 +289,7 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
-OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_BYTECODE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
@@ -296,6 +303,13 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
!ENDIF
+# Should the rbu extension be enabled? If so, add compilation options
+# to enable it.
+#
+!IF $(RBU)!=0
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1
+!ENDIF
+
# These are the "extended" SQLite compilation options used when compiling for
# the Windows 10 platform.
#
@@ -978,7 +992,7 @@ Replace.exe:
sqlite3.def: Replace.exe $(LIBOBJ)
echo EXPORTS > sqlite3.def
dumpbin /all $(LIBOBJ) \
- | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
+ | .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
| sort >> sqlite3.def
$(SQLITE3EXE): shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
diff --git a/contrib/sqlite3/configure b/contrib/sqlite3/configure
index e4755326f3f8..38baeb97e8fe 100755
--- a/contrib/sqlite3/configure
+++ b/contrib/sqlite3/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.30.1.
+# Generated by GNU Autoconf 2.69 for sqlite 3.32.2.
#
# Report bugs to <http://www.sqlite.org>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
-PACKAGE_VERSION='3.30.1'
-PACKAGE_STRING='sqlite 3.30.1'
+PACKAGE_VERSION='3.32.2'
+PACKAGE_STRING='sqlite 3.32.2'
PACKAGE_BUGREPORT='http://www.sqlite.org'
PACKAGE_URL=''
@@ -1341,7 +1341,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures sqlite 3.30.1 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.32.2 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1412,7 +1412,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sqlite 3.30.1:";;
+ short | recursive ) echo "Configuration of sqlite 3.32.2:";;
esac
cat <<\_ACEOF
@@ -1537,7 +1537,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sqlite configure 3.30.1
+sqlite configure 3.32.2
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1952,7 +1952,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by sqlite $as_me 3.30.1, which was
+It was created by sqlite $as_me 3.32.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2818,7 +2818,7 @@ fi
# Define the identity of the package.
PACKAGE='sqlite'
- VERSION='3.30.1'
+ VERSION='3.32.2'
cat >>confdefs.h <<_ACEOF
@@ -13653,7 +13653,7 @@ else
fi
if test x"$enable_rtree" = "xyes"; then
- BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY"
fi
#-----------------------------------------------------------------------
@@ -14438,7 +14438,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sqlite $as_me 3.30.1, which was
+This file was extended by sqlite $as_me 3.32.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14495,7 +14495,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-sqlite config.status 3.30.1
+sqlite config.status 3.32.2
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/contrib/sqlite3/configure.ac b/contrib/sqlite3/configure.ac
index 26f96a6e48a7..ca5cc611c55a 100644
--- a/contrib/sqlite3/configure.ac
+++ b/contrib/sqlite3/configure.ac
@@ -10,7 +10,7 @@
#
AC_PREREQ(2.61)
-AC_INIT(sqlite, 3.30.1, http://www.sqlite.org)
+AC_INIT(sqlite, 3.32.2, http://www.sqlite.org)
AC_CONFIG_SRCDIR([sqlite3.c])
AC_CONFIG_AUX_DIR([.])
@@ -161,7 +161,7 @@ AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
[--enable-rtree], [include rtree support [default=yes]])],
[], [enable_rtree=yes])
if test x"$enable_rtree" = "xyes"; then
- BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY"
fi
#-----------------------------------------------------------------------
diff --git a/contrib/sqlite3/shell.c b/contrib/sqlite3/shell.c
index 053180cc560c..974f57af79a2 100644
--- a/contrib/sqlite3/shell.c
+++ b/contrib/sqlite3/shell.c
@@ -36,6 +36,14 @@
#endif
/*
+** Determine if we are dealing with WinRT, which provides only a subset of
+** the full Win32 API.
+*/
+#if !defined(SQLITE_OS_WINRT)
+# define SQLITE_OS_WINRT 0
+#endif
+
+/*
** Warning pragmas copied from msvc.h in the core.
*/
#if defined(_MSC_VER)
@@ -147,22 +155,26 @@ typedef unsigned char u8;
#if defined(_WIN32) || defined(WIN32)
-# include <io.h>
-# include <fcntl.h>
-# define isatty(h) _isatty(h)
-# ifndef access
-# define access(f,m) _access((f),(m))
-# endif
-# ifndef unlink
-# define unlink _unlink
-# endif
-# ifndef strdup
-# define strdup _strdup
+# if SQLITE_OS_WINRT
+# define SQLITE_OMIT_POPEN 1
+# else
+# include <io.h>
+# include <fcntl.h>
+# define isatty(h) _isatty(h)
+# ifndef access
+# define access(f,m) _access((f),(m))
+# endif
+# ifndef unlink
+# define unlink _unlink
+# endif
+# ifndef strdup
+# define strdup _strdup
+# endif
+# undef popen
+# define popen _popen
+# undef pclose
+# define pclose _pclose
# endif
-# undef popen
-# define popen _popen
-# undef pclose
-# define pclose _pclose
#else
/* Make sure isatty() has a prototype. */
extern int isatty(int);
@@ -191,6 +203,9 @@ typedef unsigned char u8;
#define ToLower(X) (char)tolower((unsigned char)X)
#if defined(_WIN32) || defined(WIN32)
+#if SQLITE_OS_WINRT
+#include <intrin.h>
+#endif
#include <windows.h>
/* string conversion routines only needed on Win32 */
@@ -206,7 +221,7 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
** rendering quoted strings that contain \n characters). The following
** routines take care of that.
*/
-#if defined(_WIN32) || defined(WIN32)
+#if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
static void setBinaryMode(FILE *file, int isOutput){
if( isOutput ) fflush(file);
_setmode(_fileno(file), _O_BINARY);
@@ -310,6 +325,7 @@ static int hasTimer(void){
if( getProcessTimesAddr ){
return 1;
} else {
+#if !SQLITE_OS_WINRT
/* GetProcessTimes() isn't supported in WIN95 and some other Windows
** versions. See if the version we are running on has it, and if it
** does, save off a pointer to it and the current process handle.
@@ -326,6 +342,7 @@ static int hasTimer(void){
FreeLibrary(hinstLib);
}
}
+#endif
}
return 0;
}
@@ -415,6 +432,15 @@ static sqlite3 *globalDb = 0;
*/
static volatile int seenInterrupt = 0;
+#ifdef SQLITE_DEBUG
+/*
+** Out-of-memory simulator variables
+*/
+static unsigned int oomCounter = 0; /* Simulate OOM when equals 1 */
+static unsigned int oomRepeat = 0; /* Number of OOMs in a row */
+static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */
+#endif /* SQLITE_DEBUG */
+
/*
** This is the name of our program. It is set in main(), used
** in a number of other places, mostly for error messages.
@@ -466,6 +492,49 @@ static void shell_out_of_memory(void){
exit(1);
}
+#ifdef SQLITE_DEBUG
+/* This routine is called when a simulated OOM occurs. It is broken
+** out as a separate routine to make it easy to set a breakpoint on
+** the OOM
+*/
+void shellOomFault(void){
+ if( oomRepeat>0 ){
+ oomRepeat--;
+ }else{
+ oomCounter--;
+ }
+}
+#endif /* SQLITE_DEBUG */
+
+#ifdef SQLITE_DEBUG
+/* This routine is a replacement malloc() that is used to simulate
+** Out-Of-Memory (OOM) errors for testing purposes.
+*/
+static void *oomMalloc(int nByte){
+ if( oomCounter ){
+ if( oomCounter==1 ){
+ shellOomFault();
+ return 0;
+ }else{
+ oomCounter--;
+ }
+ }
+ return defaultMalloc(nByte);
+}
+#endif /* SQLITE_DEBUG */
+
+#ifdef SQLITE_DEBUG
+/* Register the OOM simulator. This must occur before any memory
+** allocations */
+static void registerOomSimulator(void){
+ sqlite3_mem_methods mem;
+ sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem);
+ defaultMalloc = mem.xMalloc;
+ mem.xMalloc = oomMalloc;
+ sqlite3_config(SQLITE_CONFIG_MALLOC, &mem);
+}
+#endif
+
/*
** Write I/O traces to the following stream.
*/
@@ -2007,19 +2076,23 @@ int sqlite3_shathree_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "sha3", 1, SQLITE_UTF8, 0,
- sha3Func, 0, 0);
+ rc = sqlite3_create_function(db, "sha3", 1,
+ SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
+ 0, sha3Func, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3", 2, SQLITE_UTF8, 0,
- sha3Func, 0, 0);
+ rc = sqlite3_create_function(db, "sha3", 2,
+ SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
+ 0, sha3Func, 0, 0);
}
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8, 0,
- sha3QueryFunc, 0, 0);
+ rc = sqlite3_create_function(db, "sha3_query", 1,
+ SQLITE_UTF8 | SQLITE_DIRECTONLY,
+ 0, sha3QueryFunc, 0, 0);
}
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sha3_query", 2, SQLITE_UTF8, 0,
- sha3QueryFunc, 0, 0);
+ rc = sqlite3_create_function(db, "sha3_query", 2,
+ SQLITE_UTF8 | SQLITE_DIRECTONLY,
+ 0, sha3QueryFunc, 0, 0);
}
return rc;
}
@@ -2422,6 +2495,7 @@ static int writeFile(
if( mtime>=0 ){
#if defined(_WIN32)
+#if !SQLITE_OS_WINRT
/* Windows */
FILETIME lastAccess;
FILETIME lastWrite;
@@ -2452,6 +2526,7 @@ static int writeFile(
}else{
return 1;
}
+#endif
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
/* Recent unix */
struct timespec times[2];
@@ -2613,6 +2688,7 @@ static int fsdirConnect(
pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
+ sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
}
*ppVtab = (sqlite3_vtab*)pNew;
return rc;
@@ -3006,10 +3082,12 @@ int sqlite3_fileio_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
+ rc = sqlite3_create_function(db, "readfile", 1,
+ SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
readfileFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0,
+ rc = sqlite3_create_function(db, "writefile", -1,
+ SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
writefileFunc, 0, 0);
}
if( rc==SQLITE_OK ){
@@ -3144,6 +3222,7 @@ static int completionConnect(
#define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */
#define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */
+ sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x("
" candidate TEXT,"
@@ -4205,6 +4284,101 @@ int sqlite3MemTraceDeactivate(void){
}
/************************* End ../ext/misc/memtrace.c ********************/
+/************************* Begin ../ext/misc/uint.c ******************/
+/*
+** 2020-04-14
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This SQLite extension implements the UINT collating sequence.
+**
+** UINT works like BINARY for text, except that embedded strings
+** of digits compare in numeric order.
+**
+** * Leading zeros are handled properly, in the sense that
+** they do not mess of the maginitude comparison of embedded
+** strings of digits. "x00123y" is equal to "x123y".
+**
+** * Only unsigned integers are recognized. Plus and minus
+** signs are ignored. Decimal points and exponential notation
+** are ignored.
+**
+** * Embedded integers can be of arbitrary length. Comparison
+** is *not* limited integers that can be expressed as a
+** 64-bit machine integer.
+*/
+/* #include "sqlite3ext.h" */
+SQLITE_EXTENSION_INIT1
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+/*
+** Compare text in lexicographic order, except strings of digits
+** compare in numeric order.
+*/
+static int uintCollFunc(
+ void *notUsed,
+ int nKey1, const void *pKey1,
+ int nKey2, const void *pKey2
+){
+ const unsigned char *zA = (const unsigned char*)pKey1;
+ const unsigned char *zB = (const unsigned char*)pKey2;
+ int i=0, j=0, x;
+ (void)notUsed;
+ while( i<nKey1 && j<nKey2 ){
+ x = zA[i] - zB[j];
+ if( isdigit(zA[i]) ){
+ int k;
+ if( !isdigit(zB[j]) ) return x;
+ while( i<nKey1 && zA[i]=='0' ){ i++; }
+ while( j<nKey2 && zB[j]=='0' ){ j++; }
+ k = 0;
+ while( i+k<nKey1 && isdigit(zA[i+k])
+ && j+k<nKey2 && isdigit(zB[j+k]) ){
+ k++;
+ }
+ if( i+k<nKey1 && isdigit(zA[i+k]) ){
+ return +1;
+ }else if( j+k<nKey2 && isdigit(zB[j+k]) ){
+ return -1;
+ }else{
+ x = memcmp(zA+i, zB+j, k);
+ if( x ) return x;
+ i += k;
+ j += k;
+ }
+ }else if( x ){
+ return x;
+ }else{
+ i++;
+ j++;
+ }
+ }
+ return (nKey1 - i) - (nKey2 - j);
+}
+
+#ifdef _WIN32
+
+#endif
+int sqlite3_uint_init(
+ sqlite3 *db,
+ char **pzErrMsg,
+ const sqlite3_api_routines *pApi
+){
+ SQLITE_EXTENSION_INIT2(pApi);
+ (void)pzErrMsg; /* Unused parameter */
+ return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
+}
+
+/************************* End ../ext/misc/uint.c ********************/
#ifdef SQLITE_HAVE_ZLIB
/************************* Begin ../ext/misc/zipfile.c ******************/
/*
@@ -4578,6 +4752,7 @@ static int zipfileConnect(
zipfileDequote(pNew->zFile);
}
}
+ sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
*ppVtab = (sqlite3_vtab*)pNew;
return rc;
}
@@ -5190,25 +5365,25 @@ static int zipfileDeflate(
u8 **ppOut, int *pnOut, /* Output */
char **pzErr /* OUT: Error message */
){
- sqlite3_int64 nAlloc = compressBound(nIn);
- u8 *aOut;
int rc = SQLITE_OK;
+ sqlite3_int64 nAlloc;
+ z_stream str;
+ u8 *aOut;
+
+ memset(&str, 0, sizeof(str));
+ str.next_in = (Bytef*)aIn;
+ str.avail_in = nIn;
+ deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
+ nAlloc = deflateBound(&str, nIn);
aOut = (u8*)sqlite3_malloc64(nAlloc);
if( aOut==0 ){
rc = SQLITE_NOMEM;
}else{
int res;
- z_stream str;
- memset(&str, 0, sizeof(str));
- str.next_in = (Bytef*)aIn;
- str.avail_in = nIn;
str.next_out = aOut;
str.avail_out = nAlloc;
-
- deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
res = deflate(&str, Z_FINISH);
-
if( res==Z_STREAM_END ){
*ppOut = aOut;
*pnOut = (int)str.total_out;
@@ -5517,10 +5692,10 @@ static int zipfileBestIndex(
idx = i;
}
}
+ pIdxInfo->estimatedCost = 1000.0;
if( idx>=0 ){
pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
pIdxInfo->aConstraintUsage[idx].omit = 1;
- pIdxInfo->estimatedCost = 1000.0;
pIdxInfo->idxNum = 1;
}else if( unusable ){
return SQLITE_CONSTRAINT;
@@ -5642,8 +5817,8 @@ static int zipfileGetMode(
** identical, ignoring any trailing '/' character in either path. */
static int zipfileComparePath(const char *zA, const char *zB, int nB){
int nA = (int)strlen(zA);
- if( zA[nA-1]=='/' ) nA--;
- if( zB[nB-1]=='/' ) nB--;
+ if( nA>0 && zA[nA-1]=='/' ) nA--;
+ if( nB>0 && zB[nB-1]=='/' ) nB--;
if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
return 1;
}
@@ -5653,6 +5828,10 @@ static int zipfileBegin(sqlite3_vtab *pVtab){
int rc = SQLITE_OK;
assert( pTab->pWriteFd==0 );
+ if( pTab->zFile==0 || pTab->zFile[0]==0 ){
+ pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
+ return SQLITE_ERROR;
+ }
/* Open a write fd on the file. Also load the entire central directory
** structure into memory. During the transaction any new file data is
@@ -5827,6 +6006,7 @@ static int zipfileUpdate(
if( rc==SQLITE_OK ){
zPath = (const char*)sqlite3_value_text(apVal[2]);
+ if( zPath==0 ) zPath = "";
nPath = (int)strlen(zPath);
mTime = zipfileGetTime(apVal[4]);
}
@@ -5836,11 +6016,15 @@ static int zipfileUpdate(
** '/'. This appears to be required for compatibility with info-zip
** (the unzip command on unix). It does not create directories
** otherwise. */
- if( zPath[nPath-1]!='/' ){
+ if( nPath<=0 || zPath[nPath-1]!='/' ){
zFree = sqlite3_mprintf("%s/", zPath);
- if( zFree==0 ){ rc = SQLITE_NOMEM; }
zPath = (const char*)zFree;
- nPath++;
+ if( zFree==0 ){
+ rc = SQLITE_NOMEM;
+ nPath = 0;
+ }else{
+ nPath = (int)strlen(zPath);
+ }
}
}
@@ -6233,19 +6417,19 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
** at the end of the path. Or, if this is not a directory and the path
** ends in '/' it is an error. */
if( bIsDir==0 ){
- if( zName[nName-1]=='/' ){
+ if( nName>0 && zName[nName-1]=='/' ){
zErr = sqlite3_mprintf("non-directory name must not end with /");
rc = SQLITE_ERROR;
goto zipfile_step_out;
}
}else{
- if( zName[nName-1]!='/' ){
+ if( nName==0 || zName[nName-1]!='/' ){
zName = zFree = sqlite3_mprintf("%s/", zName);
- nName++;
if( zName==0 ){
rc = SQLITE_NOMEM;
goto zipfile_step_out;
}
+ nName = (int)strlen(zName);
}else{
while( nName>1 && zName[nName-2]=='/' ) nName--;
}
@@ -6407,6 +6591,7 @@ int sqlite3_zipfile_init(
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#include <zlib.h>
+#include <assert.h>
/*
** Implementation of the "sqlar_compress(X)" SQL function.
@@ -6501,10 +6686,12 @@ int sqlite3_sqlar_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0,
+ rc = sqlite3_create_function(db, "sqlar_compress", 1,
+ SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
sqlarCompressFunc, 0, 0);
if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0,
+ rc = sqlite3_create_function(db, "sqlar_uncompress", 2,
+ SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
sqlarUncompressFunc, 0, 0);
}
return rc;
@@ -6525,8 +6712,8 @@ int sqlite3_sqlar_init(
**
*************************************************************************
*/
-
-
+#if !defined(SQLITEEXPERT_H)
+#define SQLITEEXPERT_H 1
/* #include "sqlite3.h" */
typedef struct sqlite3expert sqlite3expert;
@@ -6680,7 +6867,7 @@ const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport);
*/
void sqlite3_expert_destroy(sqlite3expert*);
-
+#endif /* !defined(SQLITEEXPERT_H) */
/************************* End ../ext/expert/sqlite3expert.h ********************/
/************************* Begin ../ext/expert/sqlite3expert.c ******************/
@@ -7814,14 +8001,19 @@ int idxFindIndexes(
/* int iParent = sqlite3_column_int(pExplain, 1); */
/* int iNotUsed = sqlite3_column_int(pExplain, 2); */
const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
- int nDetail = STRLEN(zDetail);
+ int nDetail;
int i;
+ if( !zDetail ) continue;
+ nDetail = STRLEN(zDetail);
+
for(i=0; i<nDetail; i++){
const char *zIdx = 0;
- if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
+ if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
zIdx = &zDetail[i+13];
- }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
+ }else if( i+22<nDetail
+ && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0
+ ){
zIdx = &zDetail[i+22];
}
if( zIdx ){
@@ -8636,7 +8828,7 @@ void sqlite3_expert_destroy(sqlite3expert *p){
}
}
-#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
/************************* End ../ext/expert/sqlite3expert.c ********************/
@@ -9566,6 +9758,7 @@ struct ShellState {
int outCount; /* Revert to stdout when reaching zero */
int cnt; /* Number of records displayed so far */
int lineno; /* Line number of last line read from in */
+ int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
FILE *in; /* Read commands from this stream */
FILE *out; /* Write results here */
FILE *traceOut; /* Output for sqlite3_trace() */
@@ -9581,6 +9774,7 @@ struct ShellState {
unsigned mxProgress; /* Maximum progress callbacks before failing */
unsigned flgProgress; /* Flags for the progress callback */
unsigned shellFlgs; /* Various flags */
+ unsigned priorShFlgs; /* Saved copy of flags */
sqlite3_int64 szMax; /* --maxsize argument to .open */
char *zDestTable; /* Name of destination table when MODE_Insert */
char *zTempFile; /* Temporary file that might need deleting */
@@ -9881,11 +10075,13 @@ edit_func_end:
*/
static void outputModePush(ShellState *p){
p->modePrior = p->mode;
+ p->priorShFlgs = p->shellFlgs;
memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
}
static void outputModePop(ShellState *p){
p->mode = p->modePrior;
+ p->shellFlgs = p->priorShFlgs;
memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
}
@@ -10400,19 +10596,22 @@ static int shell_callback(
const int *colWidth;
int showHdr;
char *rowSep;
+ int nWidth;
if( p->cMode==MODE_Column ){
colWidth = p->colWidth;
+ nWidth = ArraySize(p->colWidth);
showHdr = p->showHeader;
rowSep = p->rowSeparator;
}else{
colWidth = aExplainWidths;
+ nWidth = ArraySize(aExplainWidths);
showHdr = 1;
rowSep = SEP_Row;
}
if( p->cnt++==0 ){
for(i=0; i<nArg; i++){
int w, n;
- if( i<ArraySize(p->colWidth) ){
+ if( i<nWidth ){
w = colWidth[i];
}else{
w = 0;
@@ -10847,8 +11046,7 @@ static void set_table_name(ShellState *p, const char *zName){
*/
static int run_table_dump_query(
ShellState *p, /* Query context */
- const char *zSelect, /* SELECT statement to extract content */
- const char *zFirstRow /* Print before first row, if not NULL */
+ const char *zSelect /* SELECT statement to extract content */
){
sqlite3_stmt *pSelect;
int rc;
@@ -10865,10 +11063,6 @@ static int run_table_dump_query(
rc = sqlite3_step(pSelect);
nResult = sqlite3_column_count(pSelect);
while( rc==SQLITE_ROW ){
- if( zFirstRow ){
- utf8_printf(p->out, "%s", zFirstRow);
- zFirstRow = 0;
- }
z = (const char*)sqlite3_column_text(pSelect, 0);
utf8_printf(p->out, "%s", z);
for(i=1; i<nResult; i++){
@@ -11302,6 +11496,9 @@ static void restore_debug_trace_modes(void){
/* Create the TEMP table used to store parameter bindings */
static void bind_table_init(ShellState *p){
int wrSchema = 0;
+ int defensiveMode = 0;
+ sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode);
+ sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
sqlite3_exec(p->db,
@@ -11311,6 +11508,7 @@ static void bind_table_init(ShellState *p){
") WITHOUT ROWID;",
0, 0, 0);
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
+ sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0);
}
/*
@@ -11321,9 +11519,9 @@ static void bind_table_init(ShellState *p){
** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value)
** WITHOUT ROWID;
**
-** No bindings occur if this table does not exist. The special character '$'
-** is included in the table name to help prevent collisions with actual tables.
-** The table must be in the TEMP schema.
+** No bindings occur if this table does not exist. The name of the table
+** begins with "sqlite_" so that it will not collide with ordinary application
+** tables. The table must be in the TEMP schema.
*/
static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
int nVar;
@@ -11627,6 +11825,7 @@ static int shell_exec(
const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
int iEqpId = sqlite3_column_int(pExplain, 0);
int iParentId = sqlite3_column_int(pExplain, 1);
+ if( zEQPLine==0 ) zEQPLine = "";
if( zEQPLine[0]=='-' ) eqp_render(pArg);
eqp_append(pArg, iEqpId, iParentId, zEQPLine);
}
@@ -12037,11 +12236,12 @@ static const char *(azHelp[]) = {
".databases List names and files of attached databases",
".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
".dbinfo ?DB? Show status information about the database",
- ".dump ?TABLE? ... Render all database content as SQL",
+ ".dump ?TABLE? Render database content as SQL",
" Options:",
" --preserve-rowids Include ROWID values in the output",
" --newlines Allow unescaped newline characters in output",
" TABLE is a LIKE pattern for the tables to dump",
+ " Additional LIKE patterns can be given in subsequent arguments",
".echo on|off Turn command echo on or off",
".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
" Other Modes:",
@@ -12051,17 +12251,29 @@ static const char *(azHelp[]) = {
#endif
" trigger Like \"full\" but also show trigger bytecode",
".excel Display the output of next command in spreadsheet",
+ " --bom Put a UTF8 byte-order mark on intermediate file",
".exit ?CODE? Exit this program with return-code CODE",
".expert EXPERIMENTAL. Suggest indexes for queries",
-/* Because explain mode comes on automatically now, the ".explain" mode
-** is removed from the help screen. It is still supported for legacy, however */
-/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off",*/
+ ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
".filectrl CMD ... Run various sqlite3_file_control() operations",
- " Run \".filectrl\" with no arguments for details",
+ " --schema SCHEMA Use SCHEMA instead of \"main\"",
+ " --help Show CMD details",
".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
".headers on|off Turn display of headers on or off",
".help ?-all? ?PATTERN? Show help text for PATTERN",
".import FILE TABLE Import data from FILE into TABLE",
+ " Options:",
+ " --ascii Use \\037 and \\036 as column and row separators",
+ " --csv Use , and \\n as column and row separators",
+ " --skip N Skip the first N rows of input",
+ " -v \"Verbose\" - increase auxiliary output",
+ " Notes:",
+ " * If TABLE does not exist, it is created. The first row of input",
+ " determines the column names.",
+ " * If neither --csv or --ascii are used, the input mode is derived",
+ " from the \".mode\" output mode",
+ " * If FILE begins with \"|\" then it is a command that generates the",
+ " input text.",
#ifndef SQLITE_OMIT_TEST_CONTROL
".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
#endif
@@ -12092,11 +12304,14 @@ static const char *(azHelp[]) = {
" tabs Tab-separated values",
" tcl TCL list elements",
".nullvalue STRING Use STRING in place of NULL values",
- ".once (-e|-x|FILE) Output for the next SQL command only to FILE",
+ ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
" If FILE begins with '|' then open as a pipe",
- " Other options:",
- " -e Invoke system text editor",
- " -x Open in a spreadsheet",
+ " --bom Put a UTF8 byte-order mark at the beginning",
+ " -e Send output to the system text editor",
+ " -x Send output as CSV to a spreadsheet (same as \".excel\")",
+#ifdef SQLITE_DEBUG
+ ".oom [--repeat M] [N] Simulate an OOM error on the N-th allocation",
+#endif
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
" Options:",
" --append Use appendvfs to append database to the end of FILE",
@@ -12106,10 +12321,15 @@ static const char *(azHelp[]) = {
" --maxsize N Maximum size for --hexdb or --deserialized database",
#endif
" --new Initialize FILE to an empty database",
+ " --nofollow Do not follow symbolic links",
" --readonly Open FILE readonly",
" --zip FILE is a ZIP archive",
".output ?FILE? Send output to FILE or stdout if FILE is omitted",
- " If FILE begins with '|' then open it as a pipe.",
+ " If FILE begins with '|' then open it as a pipe.",
+ " Options:",
+ " --bom Prefix output with a UTF8 byte-order mark",
+ " -e Send output to the system text editor",
+ " -x Send output as CSV to a spreadsheet",
".parameter CMD ... Manage SQL parameter bindings",
" clear Erase all bindings",
" init Initialize the TEMP table that holds bindings",
@@ -12229,6 +12449,7 @@ static int showHelp(FILE *out, const char *zPattern){
|| zPattern[0]=='0'
|| strcmp(zPattern,"-a")==0
|| strcmp(zPattern,"-all")==0
+ || strcmp(zPattern,"--all")==0
){
/* Show all commands, but only one line per command */
if( zPattern==0 ) zPattern = "";
@@ -12670,7 +12891,7 @@ static void open_db(ShellState *p, int openFlags){
switch( p->openMode ){
case SHELL_OPEN_APPENDVFS: {
sqlite3_open_v2(p->zDbFilename, &p->db,
- SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
break;
}
case SHELL_OPEN_HEXDB:
@@ -12683,12 +12904,14 @@ static void open_db(ShellState *p, int openFlags){
break;
}
case SHELL_OPEN_READONLY: {
- sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0);
+ sqlite3_open_v2(p->zDbFilename, &p->db,
+ SQLITE_OPEN_READONLY|p->openFlags, 0);
break;
}
case SHELL_OPEN_UNSPEC:
case SHELL_OPEN_NORMAL: {
- sqlite3_open(p->zDbFilename, &p->db);
+ sqlite3_open_v2(p->zDbFilename, &p->db,
+ SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
break;
}
}
@@ -12708,6 +12931,7 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_fileio_init(p->db, 0, 0);
sqlite3_shathree_init(p->db, 0, 0);
sqlite3_completion_init(p->db, 0, 0);
+ sqlite3_uint_init(p->db, 0, 0);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
sqlite3_dbdata_init(p->db, 0, 0);
#endif
@@ -13044,6 +13268,8 @@ struct ImportCtx {
int n; /* Number of bytes in z */
int nAlloc; /* Space allocated for z[] */
int nLine; /* Current line number */
+ int nRow; /* Number of rows imported */
+ int nErr; /* Number of errors encountered */
int bNotFirst; /* True if one or more bytes already read */
int cTerm; /* Character that terminated the most recent field */
int cColSep; /* The column separator character. (Usually ",") */
@@ -13425,11 +13651,15 @@ static void output_reset(ShellState *p){
zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
if( system(zCmd) ){
utf8_printf(stderr, "Failed: [%s]\n", zCmd);
+ }else{
+ /* Give the start/open/xdg-open command some time to get
+ ** going before we continue, and potential delete the
+ ** p->zTempFile data file out from under it */
+ sqlite3_sleep(2000);
}
sqlite3_free(zCmd);
outputModePop(p);
p->doXdgOpen = 0;
- sqlite3_sleep(100);
}
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
}
@@ -13462,7 +13692,7 @@ static unsigned int get4byteInt(unsigned char *a){
}
/*
-** Implementation of the ".info" command.
+** Implementation of the ".dbinfo" command.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
@@ -13505,12 +13735,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
-1, &pStmt, 0);
if( rc ){
- if( !sqlite3_compileoption_used("ENABLE_DBPAGE_VTAB") ){
- utf8_printf(stderr, "the \".dbinfo\" command requires the "
- "-DSQLITE_ENABLE_DBPAGE_VTAB compile-time options\n");
- }else{
- utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
- }
+ utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
return 1;
}
@@ -13719,9 +13944,21 @@ static void newTempFile(ShellState *p, const char *zSuffix){
sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
}
if( p->zTempFile==0 ){
+ /* If p->db is an in-memory database then the TEMPFILENAME file-control
+ ** will not work and we will need to fallback to guessing */
+ char *zTemp;
sqlite3_uint64 r;
sqlite3_randomness(sizeof(r), &r);
- p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix);
+ zTemp = getenv("TEMP");
+ if( zTemp==0 ) zTemp = getenv("TMP");
+ if( zTemp==0 ){
+#ifdef _WIN32
+ zTemp = "\\tmp";
+#else
+ zTemp = "/tmp";
+#endif
+ }
+ p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
}else{
p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
}
@@ -15699,20 +15936,22 @@ static int do_meta_command(char *zLine, ShellState *p){
const char *zName;
int op;
} aDbConfig[] = {
+ { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
+ { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
+ { "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
+ { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
+ { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
+ { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
- { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
- { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
{ "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
- { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
+ { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
+ { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA },
{ "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
- { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
- { "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
- { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
};
int ii, v;
open_db(p, 0);
@@ -15722,7 +15961,7 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
}
sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
- utf8_printf(p->out, "%18s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
+ utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
if( nArg>1 ) break;
}
if( nArg>1 && ii==ArraySize(aDbConfig) ){
@@ -15743,7 +15982,8 @@ static int do_meta_command(char *zLine, ShellState *p){
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
- const char *zLike = 0;
+ char *zLike = 0;
+ char *zSql;
int i;
int savedShowHeader = p->showHeader;
int savedShellFlags = p->shellFlgs;
@@ -15771,12 +16011,10 @@ static int do_meta_command(char *zLine, ShellState *p){
goto meta_command_exit;
}
}else if( zLike ){
- raw_printf(stderr, "Usage: .dump ?--preserve-rowids? "
- "?--newlines? ?LIKE-PATTERN?\n");
- rc = 1;
- goto meta_command_exit;
+ zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
+ zLike, azArg[i]);
}else{
- zLike = azArg[i];
+ zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
}
}
@@ -15794,35 +16032,25 @@ static int do_meta_command(char *zLine, ShellState *p){
** corrupt. */
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
p->nErr = 0;
- if( zLike==0 ){
- run_schema_dump_query(p,
- "SELECT name, type, sql FROM sqlite_master "
- "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
- );
- run_schema_dump_query(p,
- "SELECT name, type, sql FROM sqlite_master "
- "WHERE name=='sqlite_sequence'"
- );
- run_table_dump_query(p,
- "SELECT sql FROM sqlite_master "
- "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
- );
- }else{
- char *zSql;
- zSql = sqlite3_mprintf(
- "SELECT name, type, sql FROM sqlite_master "
- "WHERE tbl_name LIKE %Q AND type=='table'"
- " AND sql NOT NULL", zLike);
- run_schema_dump_query(p,zSql);
- sqlite3_free(zSql);
- zSql = sqlite3_mprintf(
- "SELECT sql FROM sqlite_master "
- "WHERE sql NOT NULL"
- " AND type IN ('index','trigger','view')"
- " AND tbl_name LIKE %Q", zLike);
- run_table_dump_query(p, zSql, 0);
- sqlite3_free(zSql);
- }
+ if( zLike==0 ) zLike = sqlite3_mprintf("true");
+ zSql = sqlite3_mprintf(
+ "SELECT name, type, sql FROM sqlite_master "
+ "WHERE (%s) AND type=='table'"
+ " AND sql NOT NULL"
+ " ORDER BY tbl_name='sqlite_sequence', rowid",
+ zLike
+ );
+ run_schema_dump_query(p,zSql);
+ sqlite3_free(zSql);
+ zSql = sqlite3_mprintf(
+ "SELECT sql FROM sqlite_master "
+ "WHERE (%s) AND sql NOT NULL"
+ " AND type IN ('index','trigger','view')",
+ zLike
+ );
+ run_table_dump_query(p, zSql);
+ sqlite3_free(zSql);
+ sqlite3_free(zLike);
if( p->writableSchema ){
raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
p->writableSchema = 0;
@@ -15925,6 +16153,7 @@ static int do_meta_command(char *zLine, ShellState *p){
{ "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" },
{ "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
{ "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" },
+ { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" },
};
int filectrl = -1;
int iCtrl = -1;
@@ -15932,10 +16161,21 @@ static int do_meta_command(char *zLine, ShellState *p){
int isOk = 0; /* 0: usage 1: %lld 2: no-result */
int n2, i;
const char *zCmd = 0;
+ const char *zSchema = 0;
open_db(p, 0);
zCmd = nArg>=2 ? azArg[1] : "help";
+ if( zCmd[0]=='-'
+ && (strcmp(zCmd,"--schema")==0 || strcmp(zCmd,"-schema")==0)
+ && nArg>=4
+ ){
+ zSchema = azArg[2];
+ for(i=3; i<nArg; i++) azArg[i-2] = azArg[i];
+ nArg -= 2;
+ zCmd = azArg[1];
+ }
+
/* The argument can optionally begin with "-" or "--" */
if( zCmd[0]=='-' && zCmd[1] ){
zCmd++;
@@ -15977,7 +16217,7 @@ static int do_meta_command(char *zLine, ShellState *p){
case SQLITE_FCNTL_SIZE_LIMIT: {
if( nArg!=2 && nArg!=3 ) break;
iRes = nArg==3 ? integerValue(azArg[2]) : -1;
- sqlite3_file_control(p->db, 0, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
+ sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
isOk = 1;
break;
}
@@ -15986,7 +16226,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int x;
if( nArg!=3 ) break;
x = (int)integerValue(azArg[2]);
- sqlite3_file_control(p->db, 0, filectrl, &x);
+ sqlite3_file_control(p->db, zSchema, filectrl, &x);
isOk = 2;
break;
}
@@ -15995,7 +16235,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int x;
if( nArg!=2 && nArg!=3 ) break;
x = nArg==3 ? booleanValue(azArg[2]) : -1;
- sqlite3_file_control(p->db, 0, filectrl, &x);
+ sqlite3_file_control(p->db, zSchema, filectrl, &x);
iRes = x;
isOk = 1;
break;
@@ -16003,7 +16243,7 @@ static int do_meta_command(char *zLine, ShellState *p){
case SQLITE_FCNTL_HAS_MOVED: {
int x;
if( nArg!=2 ) break;
- sqlite3_file_control(p->db, 0, filectrl, &x);
+ sqlite3_file_control(p->db, zSchema, filectrl, &x);
iRes = x;
isOk = 1;
break;
@@ -16011,7 +16251,7 @@ static int do_meta_command(char *zLine, ShellState *p){
case SQLITE_FCNTL_TEMPFILENAME: {
char *z = 0;
if( nArg!=2 ) break;
- sqlite3_file_control(p->db, 0, filectrl, &z);
+ sqlite3_file_control(p->db, zSchema, filectrl, &z);
if( z ){
utf8_printf(p->out, "%s\n", z);
sqlite3_free(z);
@@ -16019,6 +16259,18 @@ static int do_meta_command(char *zLine, ShellState *p){
isOk = 2;
break;
}
+ case SQLITE_FCNTL_RESERVE_BYTES: {
+ int x;
+ if( nArg>=3 ){
+ x = atoi(azArg[2]);
+ sqlite3_file_control(p->db, zSchema, filectrl, &x);
+ }
+ x = -1;
+ sqlite3_file_control(p->db, zSchema, filectrl, &x);
+ utf8_printf(p->out,"%d\n", x);
+ isOk = 2;
+ break;
+ }
}
}
if( isOk==0 && iCtrl>=0 ){
@@ -16102,8 +16354,8 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
- char *zTable; /* Insert data into this table */
- char *zFile; /* Name of file to extra content from */
+ char *zTable = 0; /* Insert data into this table */
+ char *zFile = 0; /* Name of file to extra content from */
sqlite3_stmt *pStmt = NULL; /* A statement */
int nCol; /* Number of columns in the table */
int nByte; /* Number of bytes in an SQL string */
@@ -16114,51 +16366,108 @@ static int do_meta_command(char *zLine, ShellState *p){
ImportCtx sCtx; /* Reader context */
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
+ int eVerbose = 0; /* Larger for more console output */
+ int nSkip = 0; /* Initial lines to skip */
+ int useOutputMode = 1; /* Use output mode to determine separators */
- if( nArg!=3 ){
- raw_printf(stderr, "Usage: .import FILE TABLE\n");
- goto meta_command_exit;
- }
- zFile = azArg[1];
- zTable = azArg[2];
- seenInterrupt = 0;
memset(&sCtx, 0, sizeof(sCtx));
- open_db(p, 0);
- nSep = strlen30(p->colSeparator);
- if( nSep==0 ){
- raw_printf(stderr,
- "Error: non-null column separator required for import\n");
- return 1;
+ if( p->mode==MODE_Ascii ){
+ xRead = ascii_read_one_field;
+ }else{
+ xRead = csv_read_one_field;
}
- if( nSep>1 ){
- raw_printf(stderr, "Error: multi-character column separators not allowed"
- " for import\n");
- return 1;
+ for(i=1; i<nArg; i++){
+ char *z = azArg[i];
+ if( z[0]=='-' && z[1]=='-' ) z++;
+ if( z[0]!='-' ){
+ if( zFile==0 ){
+ zFile = z;
+ }else if( zTable==0 ){
+ zTable = z;
+ }else{
+ utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
+ showHelp(p->out, "import");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }else if( strcmp(z,"-v")==0 ){
+ eVerbose++;
+ }else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
+ nSkip = integerValue(azArg[++i]);
+ }else if( strcmp(z,"-ascii")==0 ){
+ sCtx.cColSep = SEP_Unit[0];
+ sCtx.cRowSep = SEP_Record[0];
+ xRead = ascii_read_one_field;
+ useOutputMode = 0;
+ }else if( strcmp(z,"-csv")==0 ){
+ sCtx.cColSep = ',';
+ sCtx.cRowSep = '\n';
+ xRead = csv_read_one_field;
+ useOutputMode = 0;
+ }else{
+ utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
+ showHelp(p->out, "import");
+ rc = 1;
+ goto meta_command_exit;
+ }
}
- nSep = strlen30(p->rowSeparator);
- if( nSep==0 ){
- raw_printf(stderr, "Error: non-null row separator required for import\n");
- return 1;
+ if( zTable==0 ){
+ utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
+ zFile==0 ? "FILE" : "TABLE");
+ showHelp(p->out, "import");
+ rc = 1;
+ goto meta_command_exit;
}
- if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
- /* When importing CSV (only), if the row separator is set to the
- ** default output row separator, change it to the default input
- ** row separator. This avoids having to maintain different input
- ** and output row separators. */
- sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
+ seenInterrupt = 0;
+ open_db(p, 0);
+ if( useOutputMode ){
+ /* If neither the --csv or --ascii options are specified, then set
+ ** the column and row separator characters from the output mode. */
+ nSep = strlen30(p->colSeparator);
+ if( nSep==0 ){
+ raw_printf(stderr,
+ "Error: non-null column separator required for import\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ if( nSep>1 ){
+ raw_printf(stderr,
+ "Error: multi-character column separators not allowed"
+ " for import\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
nSep = strlen30(p->rowSeparator);
- }
- if( nSep>1 ){
- raw_printf(stderr, "Error: multi-character row separators not allowed"
- " for import\n");
- return 1;
+ if( nSep==0 ){
+ raw_printf(stderr,
+ "Error: non-null row separator required for import\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
+ /* When importing CSV (only), if the row separator is set to the
+ ** default output row separator, change it to the default input
+ ** row separator. This avoids having to maintain different input
+ ** and output row separators. */
+ sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
+ nSep = strlen30(p->rowSeparator);
+ }
+ if( nSep>1 ){
+ raw_printf(stderr, "Error: multi-character row separators not allowed"
+ " for import\n");
+ rc = 1;
+ goto meta_command_exit;
+ }
+ sCtx.cColSep = p->colSeparator[0];
+ sCtx.cRowSep = p->rowSeparator[0];
}
sCtx.zFile = zFile;
sCtx.nLine = 1;
if( sCtx.zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
raw_printf(stderr, "Error: pipes are not supported in this OS\n");
- return 1;
+ rc = 1;
+ goto meta_command_exit;
#else
sCtx.in = popen(sCtx.zFile+1, "r");
sCtx.zFile = "<pipe>";
@@ -16168,17 +16477,26 @@ static int do_meta_command(char *zLine, ShellState *p){
sCtx.in = fopen(sCtx.zFile, "rb");
xCloser = fclose;
}
- if( p->mode==MODE_Ascii ){
- xRead = ascii_read_one_field;
- }else{
- xRead = csv_read_one_field;
- }
if( sCtx.in==0 ){
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
- return 1;
+ rc = 1;
+ goto meta_command_exit;
+ }
+ if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
+ char zSep[2];
+ zSep[1] = 0;
+ zSep[0] = sCtx.cColSep;
+ utf8_printf(p->out, "Column separator ");
+ output_c_string(p->out, zSep);
+ utf8_printf(p->out, ", row separator ");
+ zSep[0] = sCtx.cRowSep;
+ output_c_string(p->out, zSep);
+ utf8_printf(p->out, "\n");
+ }
+ while( (nSkip--)>0 ){
+ while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
+ sCtx.nLine++;
}
- sCtx.cColSep = p->colSeparator[0];
- sCtx.cRowSep = p->rowSeparator[0];
zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
if( zSql==0 ){
xCloser(sCtx.in);
@@ -16200,9 +16518,13 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(sCtx.z);
xCloser(sCtx.in);
utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
- return 1;
+ rc = 1;
+ goto meta_command_exit;
}
zCreate = sqlite3_mprintf("%z\n)", zCreate);
+ if( eVerbose>=1 ){
+ utf8_printf(p->out, "%s\n", zCreate);
+ }
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
if( rc ){
@@ -16210,7 +16532,8 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_errmsg(p->db));
sqlite3_free(sCtx.z);
xCloser(sCtx.in);
- return 1;
+ rc = 1;
+ goto meta_command_exit;
}
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
}
@@ -16219,7 +16542,8 @@ static int do_meta_command(char *zLine, ShellState *p){
if (pStmt) sqlite3_finalize(pStmt);
utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
xCloser(sCtx.in);
- return 1;
+ rc = 1;
+ goto meta_command_exit;
}
nCol = sqlite3_column_count(pStmt);
sqlite3_finalize(pStmt);
@@ -16238,13 +16562,17 @@ static int do_meta_command(char *zLine, ShellState *p){
}
zSql[j++] = ')';
zSql[j] = 0;
+ if( eVerbose>=2 ){
+ utf8_printf(p->out, "Insert using: %s\n", zSql);
+ }
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
if (pStmt) sqlite3_finalize(pStmt);
xCloser(sCtx.in);
- return 1;
+ rc = 1;
+ goto meta_command_exit;
}
needCommit = sqlite3_get_autocommit(p->db);
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
@@ -16287,6 +16615,9 @@ static int do_meta_command(char *zLine, ShellState *p){
if( rc!=SQLITE_OK ){
utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
startLine, sqlite3_errmsg(p->db));
+ sCtx.nErr++;
+ }else{
+ sCtx.nRow++;
}
}
}while( sCtx.cTerm!=EOF );
@@ -16295,6 +16626,11 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(sCtx.z);
sqlite3_finalize(pStmt);
if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
+ if( eVerbose>0 ){
+ utf8_printf(p->out,
+ "Added %d rows with %d errors using %d lines of input\n",
+ sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
+ }
}else
#ifndef SQLITE_UNTESTABLE
@@ -16303,10 +16639,19 @@ static int do_meta_command(char *zLine, ShellState *p){
char *zCollist = 0;
sqlite3_stmt *pStmt;
int tnum = 0;
+ int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
+ int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
int i;
if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
" .imposter off\n");
+ /* Also allowed, but not documented:
+ **
+ ** .imposter TABLE IMPOSTER
+ **
+ ** where TABLE is a WITHOUT ROWID table. In that case, the
+ ** imposter is another WITHOUT ROWID table with the columns in
+ ** storage order. */
rc = 1;
goto meta_command_exit;
}
@@ -16315,19 +16660,22 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
goto meta_command_exit;
}
- zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
- " WHERE name='%q' AND type='index'", azArg[1]);
+ zSql = sqlite3_mprintf(
+ "SELECT rootpage, 0 FROM sqlite_master"
+ " WHERE name='%q' AND type='index'"
+ "UNION ALL "
+ "SELECT rootpage, 1 FROM sqlite_master"
+ " WHERE name='%q' AND type='table'"
+ " AND sql LIKE '%%without%%rowid%%'",
+ azArg[1], azArg[1]
+ );
sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( sqlite3_step(pStmt)==SQLITE_ROW ){
tnum = sqlite3_column_int(pStmt, 0);
+ isWO = sqlite3_column_int(pStmt, 1);
}
sqlite3_finalize(pStmt);
- if( tnum==0 ){
- utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
- rc = 1;
- goto meta_command_exit;
- }
zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
@@ -16344,6 +16692,9 @@ static int do_meta_command(char *zLine, ShellState *p){
zCol = zLabel;
}
}
+ if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){
+ lenPK = (int)strlen(zCollist);
+ }
if( zCollist==0 ){
zCollist = sqlite3_mprintf("\"%w\"", zCol);
}else{
@@ -16351,9 +16702,16 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}
sqlite3_finalize(pStmt);
+ if( i==0 || tnum==0 ){
+ utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
+ rc = 1;
+ sqlite3_free(zCollist);
+ goto meta_command_exit;
+ }
+ if( lenPK==0 ) lenPK = 100000;
zSql = sqlite3_mprintf(
- "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
- azArg[2], zCollist, zCollist);
+ "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
+ azArg[2], zCollist, lenPK, zCollist);
sqlite3_free(zCollist);
rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
if( rc==SQLITE_OK ){
@@ -16364,7 +16722,8 @@ static int do_meta_command(char *zLine, ShellState *p){
}else{
utf8_printf(stdout, "%s;\n", zSql);
raw_printf(stdout,
- "WARNING: writing to an imposter table will corrupt the index!\n"
+ "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n",
+ azArg[1], isWO ? "table" : "index"
);
}
}else{
@@ -16550,6 +16909,34 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}else
+#ifdef SQLITE_DEBUG
+ if( c=='o' && strcmp(azArg[0],"oom")==0 ){
+ int i;
+ for(i=1; i<nArg; i++){
+ const char *z = azArg[i];
+ if( z[0]=='-' && z[1]=='-' ) z++;
+ if( strcmp(z,"-repeat")==0 ){
+ if( i==nArg-1 ){
+ raw_printf(p->out, "missing argument on \"%s\"\n", azArg[i]);
+ rc = 1;
+ }else{
+ oomRepeat = (int)integerValue(azArg[++i]);
+ }
+ }else if( IsDigit(z[0]) ){
+ oomCounter = (int)integerValue(azArg[i]);
+ }else{
+ raw_printf(p->out, "unknown argument: \"%s\"\n", azArg[i]);
+ raw_printf(p->out, "Usage: .oom [--repeat N] [M]\n");
+ rc = 1;
+ }
+ }
+ if( rc==0 ){
+ raw_printf(p->out, "oomCounter = %d\n", oomCounter);
+ raw_printf(p->out, "oomRepeat = %d\n", oomRepeat);
+ }
+ }else
+#endif /* SQLITE_DEBUG */
+
if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
char *zNewFilename; /* Name of the database file to open */
int iName = 1; /* Index in azArg[] of the filename */
@@ -16562,6 +16949,7 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = 0;
p->openMode = SHELL_OPEN_UNSPEC;
+ p->openFlags = 0;
p->szMax = 0;
/* Check for command-line arguments */
for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
@@ -16576,6 +16964,8 @@ static int do_meta_command(char *zLine, ShellState *p){
p->openMode = SHELL_OPEN_APPENDVFS;
}else if( optionMatch(z, "readonly") ){
p->openMode = SHELL_OPEN_READONLY;
+ }else if( optionMatch(z, "nofollow") ){
+ p->openFlags |= SQLITE_OPEN_NOFOLLOW;
#ifdef SQLITE_ENABLE_DESERIALIZE
}else if( optionMatch(z, "deserialize") ){
p->openMode = SHELL_OPEN_DESERIALIZE;
@@ -16614,42 +17004,66 @@ static int do_meta_command(char *zLine, ShellState *p){
&& (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
){
- const char *zFile = nArg>=2 ? azArg[1] : "stdout";
+ const char *zFile = 0;
int bTxtMode = 0;
- if( azArg[0][0]=='e' ){
- /* Transform the ".excel" command into ".once -x" */
- nArg = 2;
- azArg[0] = "once";
- zFile = azArg[1] = "-x";
- n = 4;
- }
- if( nArg>2 ){
- utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]);
- rc = 1;
- goto meta_command_exit;
+ int i;
+ int eMode = 0;
+ int bBOM = 0;
+ int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
+
+ if( c=='e' ){
+ eMode = 'x';
+ bOnce = 2;
+ }else if( strncmp(azArg[0],"once",n)==0 ){
+ bOnce = 1;
}
- if( n>1 && strncmp(azArg[0], "once", n)==0 ){
- if( nArg<2 ){
- raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n");
+ for(i=1; i<nArg; i++){
+ char *z = azArg[i];
+ if( z[0]=='-' ){
+ if( z[1]=='-' ) z++;
+ if( strcmp(z,"-bom")==0 ){
+ bBOM = 1;
+ }else if( c!='e' && strcmp(z,"-x")==0 ){
+ eMode = 'x'; /* spreadsheet */
+ }else if( c!='e' && strcmp(z,"-e")==0 ){
+ eMode = 'e'; /* text editor */
+ }else{
+ utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n",
+ azArg[i]);
+ showHelp(p->out, azArg[0]);
+ rc = 1;
+ goto meta_command_exit;
+ }
+ }else if( zFile==0 ){
+ zFile = z;
+ }else{
+ utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n",
+ azArg[i]);
+ showHelp(p->out, azArg[0]);
rc = 1;
goto meta_command_exit;
}
+ }
+ if( zFile==0 ) zFile = "stdout";
+ if( bOnce ){
p->outCount = 2;
}else{
p->outCount = 0;
}
output_reset(p);
- if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
#ifndef SQLITE_NOHAVE_SYSTEM
- if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
+ if( eMode=='e' || eMode=='x' ){
p->doXdgOpen = 1;
outputModePush(p);
- if( zFile[1]=='x' ){
+ if( eMode=='x' ){
+ /* spreadsheet mode. Output as CSV. */
newTempFile(p, "csv");
+ ShellClearFlag(p, SHFLG_Echo);
p->mode = MODE_Csv;
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
}else{
+ /* text editor mode */
newTempFile(p, "txt");
bTxtMode = 1;
}
@@ -16668,6 +17082,7 @@ static int do_meta_command(char *zLine, ShellState *p){
p->out = stdout;
rc = 1;
}else{
+ if( bBOM ) fprintf(p->out,"\357\273\277");
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
#endif
@@ -16680,6 +17095,7 @@ static int do_meta_command(char *zLine, ShellState *p){
p->out = stdout;
rc = 1;
} else {
+ if( bBOM ) fprintf(p->out,"\357\273\277");
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
}
@@ -17732,7 +18148,7 @@ static int do_meta_command(char *zLine, ShellState *p){
{ "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
/*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
{ "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
- { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
+ { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" },
{ "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
@@ -17743,7 +18159,6 @@ static int do_meta_command(char *zLine, ShellState *p){
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
{ "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
- { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE"},
};
int testctrl = -1;
int iCtrl = -1;
@@ -17796,7 +18211,6 @@ static int do_meta_command(char *zLine, ShellState *p){
/* sqlite3_test_control(int, db, int) */
case SQLITE_TESTCTRL_OPTIMIZATIONS:
- case SQLITE_TESTCTRL_RESERVE:
if( nArg==3 ){
int opt = (int)strtol(azArg[2], 0, 0);
rc2 = sqlite3_test_control(testctrl, p->db, opt);
@@ -17848,7 +18262,6 @@ static int do_meta_command(char *zLine, ShellState *p){
/* sqlite3_test_control(int, int) */
case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS:
- case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
if( nArg==3 ){
int opt = booleanValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
@@ -17866,6 +18279,12 @@ static int do_meta_command(char *zLine, ShellState *p){
}
break;
+ /* sqlite3_test_control(sqlite3*) */
+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
+ rc2 = sqlite3_test_control(testctrl, p->db);
+ isOk = 3;
+ break;
+
case SQLITE_TESTCTRL_IMPOSTER:
if( nArg==5 ){
rc2 = sqlite3_test_control(testctrl, p->db,
@@ -18496,6 +18915,7 @@ static const char zOptions[] =
" -multiplex enable the multiplexor VFS\n"
#endif
" -newline SEP set output row separator. Default: '\\n'\n"
+ " -nofollow refuse to open symbolic links to database files\n"
" -nullvalue TEXT set text string for NULL values. Default ''\n"
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
" -quote set output mode to 'quote'\n"
@@ -18562,14 +18982,18 @@ static void main_init(ShellState *data) {
*/
#ifdef _WIN32
static void printBold(const char *zText){
+#if !SQLITE_OS_WINRT
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
SetConsoleTextAttribute(out,
FOREGROUND_RED|FOREGROUND_INTENSITY
);
+#endif
printf("%s", zText);
+#if !SQLITE_OS_WINRT
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
+#endif
}
#else
static void printBold(const char *zText){
@@ -18624,6 +19048,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
stdin_is_interactive = isatty(0);
stdout_is_console = isatty(1);
+#ifdef SQLITE_DEBUG
+ registerOomSimulator();
+#endif
+
#if !defined(_WIN32_WCE)
if( getenv("SQLITE_DEBUG_BREAK") ){
if( isatty(0) && isatty(2) ){
@@ -18633,7 +19061,11 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
fgetc(stdin);
}else{
#if defined(_WIN32) || defined(WIN32)
+#if SQLITE_OS_WINRT
+ __debugbreak();
+#else
DebugBreak();
+#endif
#elif defined(SIGTRAP)
raise(SIGTRAP);
#endif
@@ -18806,6 +19238,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-readonly")==0 ){
data.openMode = SHELL_OPEN_READONLY;
+ }else if( strcmp(z,"-nofollow")==0 ){
+ data.openFlags = SQLITE_OPEN_NOFOLLOW;
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
}else if( strncmp(z, "-A",2)==0 ){
/* All remaining command-line arguments are passed to the ".archive"
@@ -18909,6 +19343,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
}else if( strcmp(z,"-readonly")==0 ){
data.openMode = SHELL_OPEN_READONLY;
+ }else if( strcmp(z,"-nofollow")==0 ){
+ data.openFlags |= SQLITE_OPEN_NOFOLLOW;
}else if( strcmp(z,"-ascii")==0 ){
data.mode = MODE_Ascii;
sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
diff --git a/contrib/sqlite3/sqlite3.c b/contrib/sqlite3/sqlite3.c
index 8fd740b30015..bbcac6b4ceb5 100644
--- a/contrib/sqlite3/sqlite3.c
+++ b/contrib/sqlite3/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.30.1. By combining all the individual C code files into this
+** version 3.32.2. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -218,6 +218,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
"ENABLE_BATCH_ATOMIC_WRITE",
#endif
+#if SQLITE_ENABLE_BYTECODE_VTAB
+ "ENABLE_BYTECODE_VTAB",
+#endif
#if SQLITE_ENABLE_CEROD
"ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
#endif
@@ -380,9 +383,6 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_FTS5_NO_WITHOUT_ROWID
"FTS5_NO_WITHOUT_ROWID",
#endif
-#if SQLITE_HAS_CODEC
- "HAS_CODEC",
-#endif
#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
"HAVE_ISNAN",
#endif
@@ -539,9 +539,6 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_OMIT_BLOB_LITERAL
"OMIT_BLOB_LITERAL",
#endif
-#if SQLITE_OMIT_BTREECOUNT
- "OMIT_BTREECOUNT",
-#endif
#if SQLITE_OMIT_CAST
"OMIT_CAST",
#endif
@@ -1165,9 +1162,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.30.1"
-#define SQLITE_VERSION_NUMBER 3030001
-#define SQLITE_SOURCE_ID "2019-10-10 20:19:45 18db032d058f1436ce3dea84081f4ee5a0f2259ad97301d43c426bc7f3df1b0b"
+#define SQLITE_VERSION "3.32.2"
+#define SQLITE_VERSION_NUMBER 3032002
+#define SQLITE_SOURCE_ID "2020-06-04 12:58:43 ec02243ea6ce33b090870ae55ab8aa2534b54d216d45c4aa2fdbb00e86861e8c"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1341,26 +1338,22 @@ typedef sqlite_uint64 sqlite3_uint64;
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
-** ^If the database connection is associated with unfinalized prepared
-** statements or unfinished sqlite3_backup objects then sqlite3_close()
-** will leave the database connection open and return [SQLITE_BUSY].
-** ^If sqlite3_close_v2() is called with unfinalized prepared statements
-** and/or unfinished sqlite3_backups, then the database connection becomes
-** an unusable "zombie" which will automatically be deallocated when the
-** last prepared statement is finalized or the last sqlite3_backup is
-** finished. The sqlite3_close_v2() interface is intended for use with
-** host languages that are garbage collected, and where the order in which
-** destructors are called is arbitrary.
-**
-** Applications should [sqlite3_finalize | finalize] all [prepared statements],
-** [sqlite3_blob_close | close] all [BLOB handles], and
+** Ideally, applications should [sqlite3_finalize | finalize] all
+** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
-** with the [sqlite3] object prior to attempting to close the object. ^If
-** sqlite3_close_v2() is called on a [database connection] that still has
-** outstanding [prepared statements], [BLOB handles], and/or
-** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation
-** of resources is deferred until all [prepared statements], [BLOB handles],
-** and [sqlite3_backup] objects are also destroyed.
+** with the [sqlite3] object prior to attempting to close the object.
+** ^If the database connection is associated with unfinalized prepared
+** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
+** sqlite3_close() will leave the database connection open and return
+** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
+** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
+** it returns [SQLITE_OK] regardless, but instead of deallocating the database
+** connection immediately, it marks the database connection as an unusable
+** "zombie" and makes arrangements to automatically deallocate the database
+** connection after all prepared statements are finalized, all BLOB handles
+** are closed, and all backups have finished. The sqlite3_close_v2() interface
+** is intended for use with host languages that are garbage collected, and
+** where the order in which destructors are called is arbitrary.
**
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
@@ -1549,17 +1542,21 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
+#define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
+#define SQLITE_BUSY_TIMEOUT (SQLITE_BUSY | (3<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
+#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))
@@ -1577,11 +1574,13 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8))
+#define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8))
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8))
+#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8))
/*
** CAPI3REF: Flags For File Open Operations
@@ -1610,6 +1609,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
+#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
/* Reserved: 0x00F00000 */
@@ -2021,16 +2021,16 @@ struct sqlite3_io_methods {
** ^The [SQLITE_FCNTL_BUSYHANDLER]
** file-control may be invoked by SQLite on the database file handle
** shortly after it is opened in order to provide a custom VFS with access
-** to the connections busy-handler callback. The argument is of type (void **)
+** to the connection's busy-handler callback. The argument is of type (void**)
** - an array of two (void *) values. The first (void *) actually points
-** to a function of type (int (*)(void *)). In order to invoke the connections
+** to a function of type (int (*)(void *)). In order to invoke the connection's
** busy-handler, this function should be invoked with the second (void *) in
** the array as the only argument. If it returns non-zero, then the operation
** should be retried. If it returns zero, the custom VFS should abandon the
** current operation.
**
** <li>[[SQLITE_FCNTL_TEMPFILENAME]]
-** ^Application can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
+** ^Applications can invoke the [SQLITE_FCNTL_TEMPFILENAME] file-control
** to have SQLite generate a
** temporary filename using the same algorithm that is followed to generate
** temporary filenames for TEMP tables and other internal uses. The
@@ -2125,10 +2125,12 @@ struct sqlite3_io_methods {
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
**
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
-** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
-** a file lock using the xLock or xShmLock methods of the VFS to wait
-** for up to M milliseconds before failing, where M is the single
-** unsigned integer parameter.
+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode is used to configure a VFS
+** to block for up to M milliseconds before failing when attempting to
+** obtain a file lock using the xLock or xShmLock methods of the VFS.
+** The parameter is a pointer to a 32-bit signed integer that contains
+** the value that M is to be set to. Before returning, the 32-bit signed
+** integer is overwritten with the previous value of M.
**
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
@@ -2143,12 +2145,23 @@ struct sqlite3_io_methods {
** not provide a mechanism to detect changes to MAIN only. Also, the
** [sqlite3_total_changes()] interface responds to internal changes only and
** omits changes made by other database connections. The
-** [PRAGMA data_version] command provide a mechanism to detect changes to
+** [PRAGMA data_version] command provides a mechanism to detect changes to
** a single attached database that occur due to other database connections,
** but omits changes implemented by the database connection on which it is
** called. This file control is the only mechanism to detect changes that
** happen either internally or externally and that are associated with
** a particular attached database.
+**
+** <li>[[SQLITE_FCNTL_CKPT_START]]
+** The [SQLITE_FCNTL_CKPT_START] opcode is invoked from within a checkpoint
+** in wal mode before the client starts to copy pages from the wal
+** file to the database file.
+**
+** <li>[[SQLITE_FCNTL_CKPT_DONE]]
+** The [SQLITE_FCNTL_CKPT_DONE] opcode is invoked from within a checkpoint
+** in wal mode after the client has finished copying pages from the wal
+** file to the database file, but before the *-shm file is updated to
+** record the fact that the pages have been checkpointed.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -2186,6 +2199,9 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
#define SQLITE_FCNTL_DATA_VERSION 35
#define SQLITE_FCNTL_SIZE_LIMIT 36
+#define SQLITE_FCNTL_CKPT_DONE 37
+#define SQLITE_FCNTL_RESERVE_BYTES 38
+#define SQLITE_FCNTL_CKPT_START 39
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -2231,10 +2247,10 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
** may be appended to the sqlite3_vfs object and the iVersion value
** may increase again in future versions of SQLite.
-** Note that the structure
-** of the sqlite3_vfs object changes in the transition from
+** Note that due to an oversight, the structure
+** of the sqlite3_vfs object changed in the transition from
** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
-** and yet the iVersion field was not modified.
+** and yet the iVersion field was not increased.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS. mxPathname is the maximum length of
@@ -2325,7 +2341,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** for exclusive access.
**
** ^At least szOsFile bytes of memory are allocated by SQLite
-** to hold the [sqlite3_file] structure passed as the third
+** to hold the [sqlite3_file] structure passed as the third
** argument to xOpen. The xOpen method does not have to
** allocate the structure; it should just fill it in. Note that
** the xOpen method must set the sqlite3_file.pMethods to either
@@ -2662,7 +2678,7 @@ SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
** that causes the corresponding memory allocation to fail.
**
** The xInit method initializes the memory allocator. For example,
-** it might allocate any require mutexes or initialize internal data
+** it might allocate any required mutexes or initialize internal data
** structures. The xShutdown method is invoked (indirectly) by
** [sqlite3_shutdown()] and should deallocate any resources acquired
** by xInit. The pAppData pointer is used as the only parameter to
@@ -2784,6 +2800,7 @@ struct sqlite3_mem_methods {
** memory allocation statistics. ^(When memory allocation statistics are
** disabled, the following SQLite interfaces become non-operational:
** <ul>
+** <li> [sqlite3_hard_heap_limit64()]
** <li> [sqlite3_memory_used()]
** <li> [sqlite3_memory_highwater()]
** <li> [sqlite3_soft_heap_limit64()]
@@ -2802,7 +2819,7 @@ struct sqlite3_mem_methods {
** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a memory pool
** that SQLite can use for the database page cache with the default page
** cache implementation.
-** This configuration option is a no-op if an application-define page
+** This configuration option is a no-op if an application-defined page
** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2].
** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
** 8-byte aligned memory (pMem), the size of each page cache line (sz),
@@ -3287,7 +3304,7 @@ struct sqlite3_mem_methods {
** [[SQLITE_DBCONFIG_DQS_DML]]
** <dt>SQLITE_DBCONFIG_DQS_DML</td>
** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
-** the legacy [double-quoted string literal] misfeature for DML statement
+** the legacy [double-quoted string literal] misfeature for DML statements
** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
** default value of this setting is determined by the [-DSQLITE_DQS]
** compile-time option.
@@ -3301,6 +3318,49 @@ struct sqlite3_mem_methods {
** default value of this setting is determined by the [-DSQLITE_DQS]
** compile-time option.
** </dd>
+**
+** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
+** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
+** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
+** assume that database schemas (the contents of the [sqlite_master] tables)
+** are untainted by malicious content.
+** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
+** takes additional defensive steps to protect the application from harm
+** including:
+** <ul>
+** <li> Prohibit the use of SQL functions inside triggers, views,
+** CHECK constraints, DEFAULT clauses, expression indexes,
+** partial indexes, or generated columns
+** unless those functions are tagged with [SQLITE_INNOCUOUS].
+** <li> Prohibit the use of virtual tables inside of triggers or views
+** unless those virtual tables are tagged with [SQLITE_VTAB_INNOCUOUS].
+** </ul>
+** This setting defaults to "on" for legacy compatibility, however
+** all applications are advised to turn it off if possible. This setting
+** can also be controlled using the [PRAGMA trusted_schema] statement.
+** </dd>
+**
+** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]]
+** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td>
+** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates
+** the legacy file format flag. When activated, this flag causes all newly
+** created database file to have a schema format version number (the 4-byte
+** integer found at offset 44 into the database header) of 1. This in turn
+** means that the resulting database file will be readable and writable by
+** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting,
+** newly created databases are generally not understandable by SQLite versions
+** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there
+** is now scarcely any need to generated database files that are compatible
+** all the way back to version 3.0.0, and so this setting is of little
+** practical use, but is provided so that SQLite can continue to claim the
+** ability to generate new database files that are compatible with version
+** 3.0.0.
+** <p>Note that when the SQLITE_DBCONFIG_LEGACY_FILE_FORMAT setting is on,
+** the [VACUUM] command will fail with an obscure error when attempting to
+** process a table with generated columns and a descending index. This is
+** not considered a bug since SQLite versions 3.3.0 and earlier do not support
+** either generated columns or decending indexes.
+** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -3319,7 +3379,9 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */
-#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */
+#define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -3525,7 +3587,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
** ^The sqlite3_interrupt(D) call is in effect until all currently running
** SQL statements on [database connection] D complete. ^Any new SQL statements
** that are started after the sqlite3_interrupt() call and before the
-** running statements reaches zero are interrupted as if they had been
+** running statement count reaches zero are interrupted as if they had been
** running prior to the sqlite3_interrupt() call. ^New SQL statements
** that are started after the running statement count reaches zero are
** not effected by the sqlite3_interrupt().
@@ -3693,9 +3755,9 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
** Cindy | 21
** </pre></blockquote>
**
-** There are two column (M==2) and three rows (N==3). Thus the
+** There are two columns (M==2) and three rows (N==3). Thus the
** result table has 8 entries. Suppose the result table is stored
-** in an array names azResult. Then azResult holds this content:
+** in an array named azResult. Then azResult holds this content:
**
** <blockquote><pre>
** azResult&#91;0] = "Name";
@@ -3788,7 +3850,7 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
**
** The SQLite core uses these three routines for all of its own
** internal memory allocation needs. "Core" in the previous sentence
-** does not include operating-system specific VFS implementation. The
+** does not include operating-system specific [VFS] implementation. The
** Windows VFS uses native malloc() and free() for some operations.
**
** ^The sqlite3_malloc() routine returns a pointer to a block
@@ -3849,19 +3911,6 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
** option is used.
**
-** In SQLite version 3.5.0 and 3.5.1, it was possible to define
-** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
-** implementation of these routines to be omitted. That capability
-** is no longer provided. Only built-in memory allocators can be used.
-**
-** Prior to SQLite version 3.7.10, the Windows OS interface layer called
-** the system malloc() and free() directly when converting
-** filenames between the UTF-8 encoding used by SQLite
-** and whatever filename encoding is used by the particular Windows
-** installation. Memory allocation errors were detected, but
-** they were reported back as [SQLITE_CANTOPEN] or
-** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
-**
** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
** must be either NULL or else pointers obtained from a prior
** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
@@ -3910,7 +3959,7 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** SQLite contains a high-quality pseudo-random number generator (PRNG) used to
** select random [ROWID | ROWIDs] when inserting new records into a table that
** already uses the largest possible [ROWID]. The PRNG is also used for
-** the build-in random() and randomblob() SQL functions. This interface allows
+** the built-in random() and randomblob() SQL functions. This interface allows
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
@@ -4284,10 +4333,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** The sqlite3_open_v2() interface works like sqlite3_open()
** except that it accepts two additional parameters for additional control
** over the new database connection. ^(The flags parameter to
-** sqlite3_open_v2() can take one of
-** the following three values, optionally combined with the
-** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE],
-** [SQLITE_OPEN_PRIVATECACHE], and/or [SQLITE_OPEN_URI] flags:)^
+** sqlite3_open_v2() must include, at a minimum, one of the following
+** three flag combinations:)^
**
** <dl>
** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
@@ -4305,23 +4352,51 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** sqlite3_open() and sqlite3_open16().</dd>)^
** </dl>
**
+** In addition to the required flags, the following optional flags are
+** also supported:
+**
+** <dl>
+** ^(<dt>[SQLITE_OPEN_URI]</dt>
+** <dd>The filename can be interpreted as a URI if this flag is set.</dd>)^
+**
+** ^(<dt>[SQLITE_OPEN_MEMORY]</dt>
+** <dd>The database will be opened as an in-memory database. The database
+** is named by the "filename" argument for the purposes of cache-sharing,
+** if shared cache mode is enabled, but the "filename" is otherwise ignored.
+** </dd>)^
+**
+** ^(<dt>[SQLITE_OPEN_NOMUTEX]</dt>
+** <dd>The new database connection will use the "multi-thread"
+** [threading mode].)^ This means that separate threads are allowed
+** to use SQLite at the same time, as long as each thread is using
+** a different [database connection].
+**
+** ^(<dt>[SQLITE_OPEN_FULLMUTEX]</dt>
+** <dd>The new database connection will use the "serialized"
+** [threading mode].)^ This means the multiple threads can safely
+** attempt to use the same database connection at the same time.
+** (Mutexes will block any actual concurrency, but in this mode
+** there is no harm in trying.)
+**
+** ^(<dt>[SQLITE_OPEN_SHAREDCACHE]</dt>
+** <dd>The database is opened [shared cache] enabled, overriding
+** the default shared cache setting provided by
+** [sqlite3_enable_shared_cache()].)^
+**
+** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
+** <dd>The database is opened [shared cache] disabled, overriding
+** the default shared cache setting provided by
+** [sqlite3_enable_shared_cache()].)^
+**
+** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
+** <dd>The database filename is not allowed to be a symbolic link</dd>
+** </dl>)^
+**
** If the 3rd parameter to sqlite3_open_v2() is not one of the
-** combinations shown above optionally combined with other
+** required combinations shown above optionally combined with other
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
** then the behavior is undefined.
**
-** ^If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection
-** opens in the multi-thread [threading mode] as long as the single-thread
-** mode has not been set at compile-time or start-time. ^If the
-** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens
-** in the serialized [threading mode] unless single-thread was
-** previously selected at compile-time or start-time.
-** ^The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be
-** eligible to use [shared cache mode], regardless of whether or not shared
-** cache is enabled using [sqlite3_enable_shared_cache()]. ^The
-** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not
-** participate in [shared cache mode] even if it is enabled.
-**
** ^The fourth parameter to sqlite3_open_v2() is the name of the
** [sqlite3_vfs] object that defines the operating system interface that
** the new database connection should use. ^If the fourth parameter is
@@ -4501,17 +4576,27 @@ SQLITE_API int sqlite3_open_v2(
/*
** CAPI3REF: Obtain Values For URI Parameters
**
-** These are utility routines, useful to VFS implementations, that check
-** to see if a database file was a URI that contained a specific query
+** These are utility routines, useful to [VFS|custom VFS implementations],
+** that check if a database file was a URI that contained a specific query
** parameter, and if so obtains the value of that query parameter.
**
-** If F is the database filename pointer passed into the xOpen() method of
-** a VFS implementation when the flags parameter to xOpen() has one or
-** more of the [SQLITE_OPEN_URI] or [SQLITE_OPEN_MAIN_DB] bits set and
-** P is the name of the query parameter, then
+** The first parameter to these interfaces (hereafter referred to
+** as F) must be one of:
+** <ul>
+** <li> A database filename pointer created by the SQLite core and
+** passed into the xOpen() method of a VFS implemention, or
+** <li> A filename obtained from [sqlite3_db_filename()], or
+** <li> A new filename constructed using [sqlite3_create_filename()].
+** </ul>
+** If the F parameter is not one of the above, then the behavior is
+** undefined and probably undesirable. Older versions of SQLite were
+** more tolerant of invalid F parameters than newer versions.
+**
+** If F is a suitable filename (as described in the previous paragraph)
+** and if P is the name of the query parameter, then
** sqlite3_uri_parameter(F,P) returns the value of the P
** parameter if it exists or a NULL pointer if P does not appear as a
-** query parameter on F. If P is a query parameter of F
+** query parameter on F. If P is a query parameter of F and it
** has no explicit value, then sqlite3_uri_parameter(F,P) returns
** a pointer to an empty string.
**
@@ -4523,26 +4608,145 @@ SQLITE_API int sqlite3_open_v2(
** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of
** query parameter P is one of "no", "false", or "off" in any case or
** if the value begins with a numeric zero. If P is not a query
-** parameter on F or if the value of P is does not match any of the
+** parameter on F or if the value of P does not match any of the
** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0).
**
** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
** 64-bit signed integer and returns that integer, or D if P does not
** exist. If the value of P is something other than an integer, then
** zero is returned.
+**
+** The sqlite3_uri_key(F,N) returns a pointer to the name (not
+** the value) of the N-th query parameter for filename F, or a NULL
+** pointer if N is less than zero or greater than the number of query
+** parameters minus 1. The N value is zero-based so N should be 0 to obtain
+** the name of the first query parameter, 1 for the second parameter, and
+** so forth.
**
** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and
-** is not a database file pathname pointer that SQLite passed into the xOpen
-** VFS method, then the behavior of this routine is undefined and probably
-** undesirable.
+** is not a database file pathname pointer that the SQLite core passed
+** into the xOpen VFS method, then the behavior of this routine is undefined
+** and probably undesirable.
+**
+** Beginning with SQLite [version 3.31.0] ([dateof:3.31.0]) the input F
+** parameter can also be the name of a rollback journal file or WAL file
+** in addition to the main database file. Prior to version 3.31.0, these
+** routines would only work if F was the name of the main database file.
+** When the F parameter is the name of the rollback journal or WAL file,
+** it has access to all the same query parameters as were found on the
+** main database file.
**
** See the [URI filename] documentation for additional information.
*/
SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N);
+/*
+** CAPI3REF: Translate filenames
+**
+** These routines are available to [VFS|custom VFS implementations] for
+** translating filenames between the main database file, the journal file,
+** and the WAL file.
+**
+** If F is the name of an sqlite database file, journal file, or WAL file
+** passed by the SQLite core into the VFS, then sqlite3_filename_database(F)
+** returns the name of the corresponding database file.
+**
+** If F is the name of an sqlite database file, journal file, or WAL file
+** passed by the SQLite core into the VFS, or if F is a database filename
+** obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F)
+** returns the name of the corresponding rollback journal file.
+**
+** If F is the name of an sqlite database file, journal file, or WAL file
+** that was passed by the SQLite core into the VFS, or if F is a database
+** filename obtained from [sqlite3_db_filename()], then
+** sqlite3_filename_wal(F) returns the name of the corresponding
+** WAL file.
+**
+** In all of the above, if F is not the name of a database, journal or WAL
+** filename passed into the VFS from the SQLite core and F is not the
+** return value from [sqlite3_db_filename()], then the result is
+** undefined and is likely a memory access violation.
+*/
+SQLITE_API const char *sqlite3_filename_database(const char*);
+SQLITE_API const char *sqlite3_filename_journal(const char*);
+SQLITE_API const char *sqlite3_filename_wal(const char*);
+
+/*
+** CAPI3REF: Database File Corresponding To A Journal
+**
+** ^If X is the name of a rollback or WAL-mode journal file that is
+** passed into the xOpen method of [sqlite3_vfs], then
+** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file]
+** object that represents the main database file.
+**
+** This routine is intended for use in custom [VFS] implementations
+** only. It is not a general-purpose interface.
+** The argument sqlite3_file_object(X) must be a filename pointer that
+** has been passed into [sqlite3_vfs].xOpen method where the
+** flags parameter to xOpen contains one of the bits
+** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use
+** of this routine results in undefined and probably undesirable
+** behavior.
+*/
+SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
+
+/*
+** CAPI3REF: Create and Destroy VFS Filenames
+**
+** These interfces are provided for use by [VFS shim] implementations and
+** are not useful outside of that context.
+**
+** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of
+** database filename D with corresponding journal file J and WAL file W and
+** with N URI parameters key/values pairs in the array P. The result from
+** sqlite3_create_filename(D,J,W,N,P) is a pointer to a database filename that
+** is safe to pass to routines like:
+** <ul>
+** <li> [sqlite3_uri_parameter()],
+** <li> [sqlite3_uri_boolean()],
+** <li> [sqlite3_uri_int64()],
+** <li> [sqlite3_uri_key()],
+** <li> [sqlite3_filename_database()],
+** <li> [sqlite3_filename_journal()], or
+** <li> [sqlite3_filename_wal()].
+** </ul>
+** If a memory allocation error occurs, sqlite3_create_filename() might
+** return a NULL pointer. The memory obtained from sqlite3_create_filename(X)
+** must be released by a corresponding call to sqlite3_free_filename(Y).
+**
+** The P parameter in sqlite3_create_filename(D,J,W,N,P) should be an array
+** of 2*N pointers to strings. Each pair of pointers in this array corresponds
+** to a key and value for a query parameter. The P parameter may be a NULL
+** pointer if N is zero. None of the 2*N pointers in the P array may be
+** NULL pointers and key pointers should not be empty strings.
+** None of the D, J, or W parameters to sqlite3_create_filename(D,J,W,N,P) may
+** be NULL pointers, though they can be empty strings.
+**
+** The sqlite3_free_filename(Y) routine releases a memory allocation
+** previously obtained from sqlite3_create_filename(). Invoking
+** sqlite3_free_filename(Y) where Y is a NULL pointer is a harmless no-op.
+**
+** If the Y parameter to sqlite3_free_filename(Y) is anything other
+** than a NULL pointer or a pointer previously acquired from
+** sqlite3_create_filename(), then bad things such as heap
+** corruption or segfaults may occur. The value Y should be
+** used again after sqlite3_free_filename(Y) has been called. This means
+** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y,
+** then the corresponding [sqlite3_module.xClose() method should also be
+** invoked prior to calling sqlite3_free_filename(Y).
+*/
+SQLITE_API char *sqlite3_create_filename(
+ const char *zDatabase,
+ const char *zJournal,
+ const char *zWal,
+ int nParam,
+ const char **azParam
+);
+SQLITE_API void sqlite3_free_filename(char*);
/*
** CAPI3REF: Error Codes And Messages
@@ -4860,12 +5064,12 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** </li>
**
** <li>
-** ^If the specific value bound to [parameter | host parameter] in the
+** ^If the specific value bound to a [parameter | host parameter] in the
** WHERE clause might influence the choice of query plan for a statement,
** then the statement will be automatically recompiled, as if there had been
-** a schema change, on the first [sqlite3_step()] call following any change
+** a schema change, on the first [sqlite3_step()] call following any change
** to the [sqlite3_bind_text | bindings] of that [parameter].
-** ^The specific value of WHERE-clause [parameter] might influence the
+** ^The specific value of a WHERE-clause [parameter] might influence the
** choice of query plan if the parameter is the left-hand side of a [LIKE]
** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
@@ -5125,12 +5329,30 @@ typedef struct sqlite3_context sqlite3_context;
** [sqlite3_bind_parameter_index()] API if desired. ^The index
** for "?NNN" parameters is the value of NNN.
** ^The NNN value must be between 1 and the [sqlite3_limit()]
-** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
+** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 32766).
**
** ^The third argument is the value to bind to the parameter.
** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16()
** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter
** is ignored and the end result is the same as sqlite3_bind_null().
+** ^If the third parameter to sqlite3_bind_text() is not NULL, then
+** it should be a pointer to well-formed UTF8 text.
+** ^If the third parameter to sqlite3_bind_text16() is not NULL, then
+** it should be a pointer to well-formed UTF16 text.
+** ^If the third parameter to sqlite3_bind_text64() is not NULL, then
+** it should be a pointer to a well-formed unicode string that is
+** either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16
+** otherwise.
+**
+** [[byte-order determination rules]] ^The byte-order of
+** UTF16 input text is determined by the byte-order mark (BOM, U+FEFF)
+** found in first character, which is removed, or in the absence of a BOM
+** the byte order is the native byte order of the host
+** machine for sqlite3_bind_text16() or the byte order specified in
+** the 6th parameter for sqlite3_bind_text64().)^
+** ^If UTF16 input text contains invalid unicode
+** characters, then SQLite might change those invalid characters
+** into the unicode replacement character: U+FFFD.
**
** ^(In those routines that have a fourth argument, its value is the
** number of bytes in the parameter. To be clear: the value is the
@@ -5144,7 +5366,7 @@ typedef struct sqlite3_context sqlite3_context;
** or sqlite3_bind_text16() or sqlite3_bind_text64() then
** that parameter must be the byte offset
** where the NUL terminator would occur assuming the string were NUL
-** terminated. If any NUL characters occur at byte offsets less than
+** terminated. If any NUL characters occurs at byte offsets less than
** the value of the fourth parameter then the resulting string value will
** contain embedded NULs. The result of expressions involving strings
** with embedded NULs is undefined.
@@ -5374,7 +5596,7 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
**
** ^If the Nth column returned by the statement is an expression or
** subquery and is not a column value, then all of these functions return
-** NULL. ^These routine might also return NULL if a memory allocation error
+** NULL. ^These routines might also return NULL if a memory allocation error
** occurs. ^Otherwise, they return the name of the attached database, table,
** or column that query result column was extracted from.
**
@@ -5384,10 +5606,6 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
** ^These APIs are only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol.
**
-** If two or more threads call one or more of these routines against the same
-** prepared statement and column at the same time then the results are
-** undefined.
-**
** If two or more threads call one or more
** [sqlite3_column_database_name | column metadata interfaces]
** for the same [prepared statement] and result column
@@ -5524,7 +5742,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*);
** ^The sqlite3_data_count(P) interface returns the number of columns in the
** current row of the result set of [prepared statement] P.
** ^If prepared statement P does not have results ready to return
-** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
+** (via calls to the [sqlite3_column_int | sqlite3_column()] family of
** interfaces) then sqlite3_data_count(P) returns 0.
** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
@@ -5848,8 +6066,6 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
** KEYWORDS: {function creation routines}
-** KEYWORDS: {application-defined SQL function}
-** KEYWORDS: {application-defined SQL functions}
** METHOD: sqlite3
**
** ^These functions (collectively known as "function creation routines")
@@ -5905,9 +6121,20 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
** flag, which if present prevents the function from being invoked from
-** within VIEWs or TRIGGERs. For security reasons, the [SQLITE_DIRECTONLY]
-** flag is recommended for any application-defined SQL function that has
-** side-effects.
+** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions,
+** index expressions, or the WHERE clause of partial indexes.
+**
+** <span style="background-color:#ffff90;">
+** For best security, the [SQLITE_DIRECTONLY] flag is recommended for
+** all application-defined SQL functions that do not need to be
+** used inside of triggers, view, CHECK constraints, or other elements of
+** the database schema. This flags is especially recommended for SQL
+** functions that have side effects or reveal internal application state.
+** Without this flag, an attacker might be able to modify the schema of
+** a database file to include invocations of the function with parameters
+** chosen by the attacker, which the application will then execute when
+** the database file is opened and read.
+** </span>
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
@@ -6026,18 +6253,53 @@ SQLITE_API int sqlite3_create_window_function(
** to [sqlite3_create_function()], [sqlite3_create_function16()], or
** [sqlite3_create_function_v2()].
**
-** The SQLITE_DETERMINISTIC flag means that the new function will always
-** maps the same inputs into the same output. The abs() function is
-** deterministic, for example, but randomblob() is not.
-**
+** <dl>
+** [[SQLITE_DETERMINISTIC]] <dt>SQLITE_DETERMINISTIC</dt><dd>
+** The SQLITE_DETERMINISTIC flag means that the new function always gives
+** the same output when the input parameters are the same.
+** The [abs|abs() function] is deterministic, for example, but
+** [randomblob|randomblob()] is not. Functions must
+** be deterministic in order to be used in certain contexts such as
+** with the WHERE clause of [partial indexes] or in [generated columns].
+** SQLite might also optimize deterministic functions by factoring them
+** out of inner loops.
+** </dd>
+**
+** [[SQLITE_DIRECTONLY]] <dt>SQLITE_DIRECTONLY</dt><dd>
** The SQLITE_DIRECTONLY flag means that the function may only be invoked
-** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is
-** a security feature which is recommended for all
-** [application-defined SQL functions] that have side-effects. This flag
-** prevents an attacker from adding triggers and views to a schema then
-** tricking a high-privilege application into causing unintended side-effects
-** while performing ordinary queries.
+** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in
+** schema structures such as [CHECK constraints], [DEFAULT clauses],
+** [expression indexes], [partial indexes], or [generated columns].
+** The SQLITE_DIRECTONLY flags is a security feature which is recommended
+** for all [application-defined SQL functions], and especially for functions
+** that have side-effects or that could potentially leak sensitive
+** information.
+** </dd>
+**
+** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd>
+** The SQLITE_INNOCUOUS flag means that the function is unlikely
+** to cause problems even if misused. An innocuous function should have
+** no side effects and should not depend on any values other than its
+** input parameters. The [abs|abs() function] is an example of an
+** innocuous function.
+** The [load_extension() SQL function] is not innocuous because of its
+** side effects.
+** <p> SQLITE_INNOCUOUS is similar to SQLITE_DETERMINISTIC, but is not
+** exactly the same. The [random|random() function] is an example of a
+** function that is innocuous but not deterministic.
+** <p>Some heightened security settings
+** ([SQLITE_DBCONFIG_TRUSTED_SCHEMA] and [PRAGMA trusted_schema=OFF])
+** disable the use of SQL functions inside views and triggers and in
+** schema structures such as [CHECK constraints], [DEFAULT clauses],
+** [expression indexes], [partial indexes], and [generated columns] unless
+** the function is tagged with SQLITE_INNOCUOUS. Most built-in functions
+** are innocuous. Developers are advised to avoid using the
+** SQLITE_INNOCUOUS flag for application-defined functions unless the
+** function has been carefully audited and found to be free of potentially
+** security-adverse side-effects and information-leaks.
+** </dd>
**
+** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd>
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
** Specifying this flag makes no difference for scalar or aggregate user
@@ -6045,10 +6307,13 @@ SQLITE_API int sqlite3_create_window_function(
** function, then any sub-types belonging to arguments passed to the window
** function may be discarded before the window function is called (i.e.
** sqlite3_value_subtype() will always return 0).
+** </dd>
+** </dl>
*/
#define SQLITE_DETERMINISTIC 0x000000800
#define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000
+#define SQLITE_INNOCUOUS 0x000200000
/*
** CAPI3REF: Deprecated Functions
@@ -6107,8 +6372,8 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
**
** These routines extract type, size, and content information from
** [protected sqlite3_value] objects. Protected sqlite3_value objects
-** are used to pass parameter information into implementation of
-** [application-defined SQL functions] and [virtual tables].
+** are used to pass parameter information into the functions that
+** implement [application-defined SQL functions] and [virtual tables].
**
** These routines work only with [protected sqlite3_value] objects.
** Any attempt to use these routines on an [unprotected sqlite3_value]
@@ -6165,7 +6430,7 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** ^The sqlite3_value_frombind(X) interface returns non-zero if the
** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
** interfaces. ^If X comes from an SQL literal value, or a table column,
-** and expression, then sqlite3_value_frombind(X) returns zero.
+** or an expression, then sqlite3_value_frombind(X) returns zero.
**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
@@ -6251,8 +6516,8 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
** routine to allocate memory for storing their state.
**
** ^The first time the sqlite3_aggregate_context(C,N) routine is called
-** for a particular aggregate function, SQLite
-** allocates N of memory, zeroes out that memory, and returns a pointer
+** for a particular aggregate function, SQLite allocates
+** N bytes of memory, zeroes out that memory, and returns a pointer
** to the new memory. ^On second and subsequent calls to
** sqlite3_aggregate_context() for the same aggregate function instance,
** the same buffer is returned. Sqlite3_aggregate_context() is normally
@@ -6269,7 +6534,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
**
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
** determined by the N parameter on first successful call. Changing the
-** value of N in subsequent call to sqlite3_aggregate_context() within
+** value of N in any subsequent call to sqlite3_aggregate_context() within
** the same aggregate function instance will not resize the memory
** allocation.)^ Within the xFinal callback, it is customary to set
** N=0 in calls to sqlite3_aggregate_context(C,N) so that no
@@ -6426,8 +6691,9 @@ typedef void (*sqlite3_destructor_type)(void*);
** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16()
** as the text of an error message. ^SQLite interprets the error
** message string from sqlite3_result_error() as UTF-8. ^SQLite
-** interprets the string from sqlite3_result_error16() as UTF-16 in native
-** byte order. ^If the third parameter to sqlite3_result_error()
+** interprets the string from sqlite3_result_error16() as UTF-16 using
+** the same [byte-order determination rules] as [sqlite3_bind_text16()].
+** ^If the third parameter to sqlite3_result_error()
** or sqlite3_result_error16() is negative then SQLite takes as the error
** message all text up through the first zero character.
** ^If the third parameter to sqlite3_result_error() or
@@ -6495,6 +6761,25 @@ typedef void (*sqlite3_destructor_type)(void*);
** then SQLite makes a copy of the result into space obtained
** from [sqlite3_malloc()] before it returns.
**
+** ^For the sqlite3_result_text16(), sqlite3_result_text16le(), and
+** sqlite3_result_text16be() routines, and for sqlite3_result_text64()
+** when the encoding is not UTF8, if the input UTF16 begins with a
+** byte-order mark (BOM, U+FEFF) then the BOM is removed from the
+** string and the rest of the string is interpreted according to the
+** byte-order specified by the BOM. ^The byte-order specified by
+** the BOM at the beginning of the text overrides the byte-order
+** specified by the interface procedure. ^So, for example, if
+** sqlite3_result_text16le() is invoked with text that begins
+** with bytes 0xfe, 0xff (a big-endian byte-order mark) then the
+** first two bytes of input are skipped and the remaining input
+** is interpreted as UTF16BE text.
+**
+** ^For UTF16 input text to the sqlite3_result_text16(),
+** sqlite3_result_text16be(), sqlite3_result_text16le(), and
+** sqlite3_result_text64() routines, if the text contains invalid
+** UTF16 characters, the invalid characters might be converted
+** into the unicode replacement character, U+FFFD.
+**
** ^The sqlite3_result_value() interface sets the result of
** the application-defined function to be a copy of the
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
@@ -6580,7 +6865,7 @@ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
** <li> [SQLITE_UTF16_ALIGNED].
** </ul>)^
** ^The eTextRep argument determines the encoding of strings passed
-** to the collating function callback, xCallback.
+** to the collating function callback, xCompare.
** ^The [SQLITE_UTF16] and [SQLITE_UTF16_ALIGNED] values for eTextRep
** force strings to be UTF16 with native byte order.
** ^The [SQLITE_UTF16_ALIGNED] value for eTextRep forces strings to begin
@@ -6589,18 +6874,19 @@ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
** ^The fourth argument, pArg, is an application data pointer that is passed
** through as the first argument to the collating function callback.
**
-** ^The fifth argument, xCallback, is a pointer to the collating function.
+** ^The fifth argument, xCompare, is a pointer to the collating function.
** ^Multiple collating functions can be registered using the same name but
** with different eTextRep parameters and SQLite will use whichever
** function requires the least amount of data transformation.
-** ^If the xCallback argument is NULL then the collating function is
+** ^If the xCompare argument is NULL then the collating function is
** deleted. ^When all collating functions having the same name are deleted,
** that collation is no longer usable.
**
** ^The collating function callback is invoked with a copy of the pArg
** application data pointer and with two strings in the encoding specified
-** by the eTextRep argument. The collating function must return an
-** integer that is negative, zero, or positive
+** by the eTextRep argument. The two integer parameters to the collating
+** function callback are the length of the two strings, in bytes. The collating
+** function must return an integer that is negative, zero, or positive
** if the first string is less than, equal to, or greater than the second,
** respectively. A collating function must always return the same answer
** given the same inputs. If two or more collating functions are registered
@@ -6617,7 +6903,7 @@ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
** </ol>
**
** If a collating function fails any of the above constraints and that
-** collating function is registered and used, then the behavior of SQLite
+** collating function is registered and used, then the behavior of SQLite
** is undefined.
**
** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation()
@@ -6699,51 +6985,6 @@ SQLITE_API int sqlite3_collation_needed16(
void(*)(void*,sqlite3*,int eTextRep,const void*)
);
-#ifdef SQLITE_HAS_CODEC
-/*
-** Specify the key for an encrypted database. This routine should be
-** called right after sqlite3_open().
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_key(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The key */
-);
-SQLITE_API int sqlite3_key_v2(
- sqlite3 *db, /* Database to be rekeyed */
- const char *zDbName, /* Name of the database */
- const void *pKey, int nKey /* The key */
-);
-
-/*
-** Change the key on an open database. If the current database is not
-** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
-** database is decrypted.
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-SQLITE_API int sqlite3_rekey(
- sqlite3 *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The new key */
-);
-SQLITE_API int sqlite3_rekey_v2(
- sqlite3 *db, /* Database to be rekeyed */
- const char *zDbName, /* Name of the database */
- const void *pKey, int nKey /* The new key */
-);
-
-/*
-** Specify the activation key for a SEE database. Unless
-** activated, none of the SEE routines will work.
-*/
-SQLITE_API void sqlite3_activate_see(
- const char *zPassPhrase /* Activation phrase */
-);
-#endif
-
#ifdef SQLITE_ENABLE_CEROD
/*
** Specify the activation key for a CEROD database. Unless
@@ -6944,16 +7185,31 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
** CAPI3REF: Return The Filename For A Database Connection
** METHOD: sqlite3
**
-** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
-** associated with database N of connection D. ^The main database file
-** has the name "main". If there is no attached database N on the database
+** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename
+** associated with database N of connection D.
+** ^If there is no attached database N on the database
** connection D, or if database N is a temporary or in-memory database, then
** this function will return either a NULL pointer or an empty string.
**
+** ^The string value returned by this routine is owned and managed by
+** the database connection. ^The value will be valid until the database N
+** is [DETACH]-ed or until the database connection closes.
+**
** ^The filename returned by this function is the output of the
** xFullPathname method of the [VFS]. ^In other words, the filename
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
+**
+** If the filename pointer returned by this routine is not NULL, then it
+** can be used as the filename input parameter to these routines:
+** <ul>
+** <li> [sqlite3_uri_parameter()]
+** <li> [sqlite3_uri_boolean()]
+** <li> [sqlite3_uri_int64()]
+** <li> [sqlite3_filename_database()]
+** <li> [sqlite3_filename_journal()]
+** <li> [sqlite3_filename_wal()]
+** </ul>
*/
SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
@@ -7103,15 +7359,19 @@ SQLITE_API void *sqlite3_update_hook(
**
** ^(The cache sharing mode set by this interface effects all subsequent
** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
-** Existing database connections continue use the sharing mode
+** Existing database connections continue to use the sharing mode
** that was in effect at the time they were opened.)^
**
** ^(This routine returns [SQLITE_OK] if shared cache was enabled or disabled
** successfully. An [error code] is returned otherwise.)^
**
-** ^Shared cache is disabled by default. But this might change in
-** future releases of SQLite. Applications that care about shared
-** cache setting should set it explicitly.
+** ^Shared cache is disabled by default. It is recommended that it stay
+** that way. In other words, do not use this routine. This interface
+** continues to be provided for historical compatibility, but its use is
+** discouraged. Any use of shared cache is discouraged. If shared cache
+** must be used, it is recommended that shared cache only be enabled for
+** individual database connections using the [sqlite3_open_v2()] interface
+** with the [SQLITE_OPEN_SHAREDCACHE] flag.
**
** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
** and will always return SQLITE_MISUSE. On those systems,
@@ -7158,6 +7418,9 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
**
+** These interfaces impose limits on the amount of heap memory that will be
+** by all database connections within a single process.
+**
** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the
** soft limit on the amount of heap memory that may be allocated by SQLite.
** ^SQLite strives to keep heap memory utilization below the soft heap
@@ -7168,20 +7431,41 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** an [SQLITE_NOMEM] error. In other words, the soft heap limit
** is advisory only.
**
-** ^The return value from sqlite3_soft_heap_limit64() is the size of
-** the soft heap limit prior to the call, or negative in the case of an
-** error. ^If the argument N is negative
-** then no change is made to the soft heap limit. Hence, the current
-** size of the soft heap limit can be determined by invoking
-** sqlite3_soft_heap_limit64() with a negative argument.
+** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of
+** N bytes on the amount of memory that will be allocated. ^The
+** sqlite3_hard_heap_limit64(N) interface is similar to
+** sqlite3_soft_heap_limit64(N) except that memory allocations will fail
+** when the hard heap limit is reached.
**
-** ^If the argument N is zero then the soft heap limit is disabled.
-**
-** ^(The soft heap limit is not enforced in the current implementation
+** ^The return value from both sqlite3_soft_heap_limit64() and
+** sqlite3_hard_heap_limit64() is the size of
+** the heap limit prior to the call, or negative in the case of an
+** error. ^If the argument N is negative
+** then no change is made to the heap limit. Hence, the current
+** size of heap limits can be determined by invoking
+** sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1).
+**
+** ^Setting the heap limits to zero disables the heap limiter mechanism.
+**
+** ^The soft heap limit may not be greater than the hard heap limit.
+** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N)
+** is invoked with a value of N that is greater than the hard heap limit,
+** the the soft heap limit is set to the value of the hard heap limit.
+** ^The soft heap limit is automatically enabled whenever the hard heap
+** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and
+** the soft heap limit is outside the range of 1..N, then the soft heap
+** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the
+** hard heap limit is enabled makes the soft heap limit equal to the
+** hard heap limit.
+**
+** The memory allocation limits can also be adjusted using
+** [PRAGMA soft_heap_limit] and [PRAGMA hard_heap_limit].
+**
+** ^(The heap limits are not enforced in the current implementation
** if one or more of following conditions are true:
**
** <ul>
-** <li> The soft heap limit is set to zero.
+** <li> The limit value is set to zero.
** <li> Memory accounting is disabled using a combination of the
** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and
** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option.
@@ -7192,21 +7476,11 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** from the heap.
** </ul>)^
**
-** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]),
-** the soft heap limit is enforced
-** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
-** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
-** the soft heap limit is enforced on every memory allocation. Without
-** [SQLITE_ENABLE_MEMORY_MANAGEMENT], the soft heap limit is only enforced
-** when memory is allocated by the page cache. Testing suggests that because
-** the page cache is the predominate memory user in SQLite, most
-** applications will achieve adequate soft heap limit enforcement without
-** the use of [SQLITE_ENABLE_MEMORY_MANAGEMENT].
-**
-** The circumstances under which SQLite will enforce the soft heap limit may
+** The circumstances under which SQLite will enforce the heap limits may
** changes in future releases of SQLite.
*/
SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N);
/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -7230,7 +7504,7 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
** interface returns SQLITE_OK and fills in the non-NULL pointers in
** the final five arguments with appropriate values if the specified
** column exists. ^The sqlite3_table_column_metadata() interface returns
-** SQLITE_ERROR and if the specified column does not exist.
+** SQLITE_ERROR if the specified column does not exist.
** ^If the column-name parameter to sqlite3_table_column_metadata() is a
** NULL pointer, then this routine simply checks for the existence of the
** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
@@ -7372,7 +7646,7 @@ SQLITE_API int sqlite3_load_extension(
** to enable or disable only the C-API.)^
**
** <b>Security warning:</b> It is recommended that extension loading
-** be disabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
+** be enabled using the [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method
** rather than this interface, so the [load_extension()] SQL function
** remains disabled. This will prevent SQL injections from giving attackers
** access to extension loading capabilities.
@@ -7459,7 +7733,7 @@ typedef struct sqlite3_module sqlite3_module;
** KEYWORDS: sqlite3_module {virtual table module}
**
** This structure, sometimes called a "virtual table module",
-** defines the implementation of a [virtual tables].
+** defines the implementation of a [virtual table].
** This structure consists mostly of methods for the module.
**
** ^A virtual table module is created by filling in a persistent
@@ -7556,7 +7830,13 @@ struct sqlite3_module {
** the right-hand side of the corresponding aConstraint[] is evaluated
** and becomes the argvIndex-th entry in argv. ^(If aConstraintUsage[].omit
** is true, then the constraint is assumed to be fully handled by the
-** virtual table and is not checked again by SQLite.)^
+** virtual table and might not be checked again by the byte code.)^ ^(The
+** aConstraintUsage[].omit flag is an optimization hint. When the omit flag
+** is left in its default setting of false, the constraint will always be
+** checked separately in byte code. If the omit flag is change to true, then
+** the constraint may or may not be checked in byte code. In other words,
+** 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
** [xFilter] method.
@@ -7596,7 +7876,7 @@ struct sqlite3_module {
** If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting
** to read or write the estimatedRows field are undefined (but are likely
-** to included crashing the application). The estimatedRows field should
+** to include crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
** value greater than or equal to 3008002. Similarly, the idxFlags field
** was added for [version 3.9.0] ([dateof:3.9.0]).
@@ -7648,7 +7928,7 @@ struct sqlite3_index_info {
/*
** CAPI3REF: Virtual Table Constraint Operator Codes
**
-** These macros defined the allowed values for the
+** These macros define the allowed values for the
** [sqlite3_index_info].aConstraint[].op field. Each value represents
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
@@ -8258,7 +8538,7 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
** The only difference is that the public sqlite3_XXX functions enumerated
** above silently ignore any invocations that pass a NULL pointer instead
** of a valid mutex handle. The implementations of the methods defined
-** by this structure are not required to handle this case, the results
+** by this structure are not required to handle this case. The results
** of passing a NULL pointer instead of a valid mutex handle are undefined
** (i.e. it is acceptable to provide an implementation that segfaults if
** it is passed a NULL pointer).
@@ -8447,7 +8727,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_PENDING_BYTE 11
#define SQLITE_TESTCTRL_ASSERT 12
#define SQLITE_TESTCTRL_ALWAYS 13
-#define SQLITE_TESTCTRL_RESERVE 14
+#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
@@ -8731,7 +9011,7 @@ SQLITE_API int sqlite3_status64(
**
** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(<dt>SQLITE_STATUS_PAGECACHE_SIZE</dt>
** <dd>This parameter records the largest memory allocation request
-** handed to [pagecache memory allocator]. Only the value returned in the
+** handed to the [pagecache memory allocator]. Only the value returned in the
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
@@ -8807,7 +9087,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** checked out.</dd>)^
**
** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(<dt>SQLITE_DBSTATUS_LOOKASIDE_HIT</dt>
-** <dd>This parameter returns the number malloc attempts that were
+** <dd>This parameter returns the number of malloc attempts that were
** satisfied using lookaside memory. Only the high-water value is meaningful;
** the current value is always zero.)^
**
@@ -8889,7 +9169,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
** cache overflowing. Transactions are more efficient if they are written
** to disk all at once. When pages spill mid-transaction, that introduces
** additional overhead. This parameter can be used help identify
-** inefficiencies that can be resolve by increasing the cache size.
+** inefficiencies that can be resolved by increasing the cache size.
** </dd>
**
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
@@ -8978,7 +9258,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
**
** [[SQLITE_STMTSTATUS_REPREPARE]] <dt>SQLITE_STMTSTATUS_REPREPARE</dt>
** <dd>^This is the number of times that the prepare statement has been
-** automatically regenerated due to schema changes or change to
+** automatically regenerated due to schema changes or changes to
** [bound parameters] that might affect the query plan.
**
** [[SQLITE_STMTSTATUS_RUN]] <dt>SQLITE_STMTSTATUS_RUN</dt>
@@ -9149,7 +9429,7 @@ struct sqlite3_pcache_page {
**
** ^(SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite
** will only use a createFlag of 2 after a prior call with a createFlag of 1
-** failed.)^ In between the to xFetch() calls, SQLite may
+** failed.)^ In between the xFetch() calls, SQLite may
** attempt to unpin one or more cache pages by spilling the content of
** pinned pages to disk and synching the operating system disk cache.
**
@@ -9467,7 +9747,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
** the first argument to register for a callback that will be invoked
** when the blocking connections current transaction is concluded. ^The
** callback is invoked from within the [sqlite3_step] or [sqlite3_close]
-** call that concludes the blocking connections transaction.
+** call that concludes the blocking connection's transaction.
**
** ^(If sqlite3_unlock_notify() is called in a multi-threaded application,
** there is a chance that the blocking connection will have already
@@ -9505,7 +9785,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
** an unlock-notify callback is a pointer to an array of void* pointers,
** and the second is the number of entries in the array.
**
-** When a blocking connections transaction is concluded, there may be
+** When a blocking connection's transaction is concluded, there may be
** more than one blocked connection that has registered for an unlock-notify
** callback. ^If two or more such blocked connections have specified the
** same callback function, then instead of invoking the callback function
@@ -9853,14 +10133,20 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
** If this interface is invoked outside the context of an xConnect or
** xCreate virtual table method then the behavior is undefined.
**
-** At present, there is only one option that may be configured using
-** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
-** may be added in the future.
+** In the call sqlite3_vtab_config(D,C,...) the D parameter is the
+** [database connection] in which the virtual table is being created and
+** which is passed in as the first argument to the [xConnect] or [xCreate]
+** method that is invoking sqlite3_vtab_config(). The C parameter is one
+** of the [virtual table configuration options]. The presence and meaning
+** of parameters after C depend on which [virtual table configuration option]
+** is used.
*/
SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
+** KEYWORDS: {virtual table configuration options}
+** KEYWORDS: {virtual table configuration option}
**
** These macros define the various options to the
** [sqlite3_vtab_config()] interface that [virtual table] implementations
@@ -9868,7 +10154,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
**
** <dl>
** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]]
-** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT
+** <dt>SQLITE_VTAB_CONSTRAINT_SUPPORT</dt>
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported,
** where X is an integer. If X is zero, then the [virtual table] whose
@@ -9897,9 +10183,31 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** return SQLITE_OK. Or, if this is not possible, it may return
** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT
** constraint handling.
+** </dd>
+**
+** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt>
+** <dd>Calls of the form
+** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the
+** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
+** prohibits that virtual table from being used from within triggers and
+** views.
+** </dd>
+**
+** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt>
+** <dd>Calls of the form
+** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the
+** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
+** identify that virtual table as being safe to use from within triggers
+** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the
+** virtual table can do no serious harm even if it is controlled by a
+** malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS
+** flag unless absolutely necessary.
+** </dd>
** </dl>
*/
#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
+#define SQLITE_VTAB_INNOCUOUS 2
+#define SQLITE_VTAB_DIRECTONLY 3
/*
** CAPI3REF: Determine The Virtual Table Conflict Policy
@@ -9979,15 +10287,15 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
-** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
+** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be
** set to the total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
-** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
+** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be set
** to the total number of rows examined by all iterations of the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
-** <dd>^The "double" variable pointed to by the T parameter will be set to the
+** <dd>^The "double" variable pointed to by the V parameter will be set to the
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop. If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
@@ -9995,17 +10303,17 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
-** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** <dd>^The "const char *" variable pointed to by the V parameter will be set
** to a zero-terminated UTF-8 string containing the name of the index or table
** used for the X-th loop.
**
** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
-** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** <dd>^The "const char *" variable pointed to by the V parameter will be set
** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
** description for the X-th loop.
**
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
-** <dd>^The "int" variable pointed to by the T parameter will be set to the
+** <dd>^The "int" variable pointed to by the V parameter will be set to the
** "select-id" for the X-th loop. The select-id identifies which query or
** subquery the loop is part of. The main query has a select-id of zero.
** The select-id is the same value as is output in the first column
@@ -10860,7 +11168,7 @@ SQLITE_API int sqlite3session_attach(
** The second argument (xFilter) is the "filter callback". For changes to rows
** in tables that are not attached to the Session object, the filter is called
** to determine whether changes to the table's rows should be tracked or not.
-** If xFilter returns 0, changes is not tracked. Note that once a table is
+** If xFilter returns 0, changes are not tracked. Note that once a table is
** attached, xFilter will not be called again.
*/
SQLITE_API void sqlite3session_table_filter(
@@ -11034,7 +11342,7 @@ SQLITE_API int sqlite3session_changeset(
** It an error if database zFrom does not exist or does not contain the
** required compatible table.
**
-** If the operation successful, SQLITE_OK is returned. Otherwise, an SQLite
+** If the operation is successful, SQLITE_OK is returned. Otherwise, an SQLite
** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg
** may be set to point to a buffer containing an English language error
** message. It is the responsibility of the caller to free this buffer using
@@ -11171,7 +11479,7 @@ SQLITE_API int sqlite3changeset_start_v2(
** CAPI3REF: Advance A Changeset Iterator
** METHOD: sqlite3_changeset_iter
**
-** This function may only be used with iterators created by function
+** This function may only be used with iterators created by the function
** [sqlite3changeset_start()]. If it is called on an iterator passed to
** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE
** is returned and the call has no effect.
@@ -11587,8 +11895,8 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);
** case, this function fails with SQLITE_SCHEMA. If the input changeset
** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
** returned. Or, if an out-of-memory condition occurs during processing, this
-** function returns SQLITE_NOMEM. In all cases, if an error occurs the
-** final contents of the changegroup is undefined.
+** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
+** of the final contents of the changegroup is undefined.
**
** If no error occurs, SQLITE_OK is returned.
*/
@@ -11763,7 +12071,7 @@ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** It is safe to execute SQL statements, including those that write to the
** table that the callback related to, from within the xConflict callback.
-** This can be used to further customize the applications conflict
+** This can be used to further customize the application's conflict
** resolution strategy.
**
** All changes made by these functions are enclosed in a savepoint transaction.
@@ -12073,7 +12381,7 @@ SQLITE_API int sqlite3rebaser_configure(
**
** Argument pIn must point to a buffer containing a changeset nIn bytes
** in size. This function allocates and populates a buffer with a copy
-** of the changeset rebased rebased according to the configuration of the
+** of the changeset rebased according to the configuration of the
** rebaser object passed as the first argument. If successful, (*ppOut)
** is set to point to the new buffer containing the rebased changeset and
** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
@@ -12481,7 +12789,7 @@ struct Fts5PhraseIter {
**
** xSetAuxdata(pFts5, pAux, xDelete)
**
-** Save the pointer passed as the second argument as the extension functions
+** Save the pointer passed as the second argument as the extension function's
** "auxiliary data". The pointer may then be retrieved by the current or any
** future invocation of the same fts5 extension function made as part of
** the same MATCH query using the xGetAuxdata() API.
@@ -12723,8 +13031,8 @@ struct Fts5ExtensionApi {
**
** There are several ways to approach this in FTS5:
**
-** <ol><li> By mapping all synonyms to a single token. In this case, the
-** In the above example, this means that the tokenizer returns the
+** <ol><li> By mapping all synonyms to a single token. In this case, using
+** the above example, this means that the tokenizer returns the
** same token for inputs "first" and "1st". Say that token is in
** fact "first", so that when the user inserts the document "I won
** 1st place" entries are added to the index for tokens "i", "won",
@@ -13045,9 +13353,12 @@ struct fts5_api {
/*
** The maximum value of a ?nnn wildcard that the parser will accept.
+** If the value exceeds 32767 then extra space is required for the Expr
+** structure. But otherwise, we believe that the number can be as large
+** as a signed 32-bit integer can hold.
*/
#ifndef SQLITE_MAX_VARIABLE_NUMBER
-# define SQLITE_MAX_VARIABLE_NUMBER 999
+# define SQLITE_MAX_VARIABLE_NUMBER 32766
#endif
/* Maximum page size. The upper bound on this value is 65536. This a limit
@@ -13137,6 +13448,21 @@ struct fts5_api {
#endif
/*
+** WAL mode depends on atomic aligned 32-bit loads and stores in a few
+** places. The following macros try to make this explicit.
+*/
+#ifndef __has_feature
+# define __has_feature(x) 0 /* compatibility with non-clang compilers */
+#endif
+#if GCC_VERSION>=4007000 || __has_feature(c_atomic)
+# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
+# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
+#else
+# define AtomicLoad(PTR) (*(PTR))
+# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
+#endif
+
+/*
** Include standard header files as necessary
*/
#ifdef HAVE_STDINT_H
@@ -13397,6 +13723,26 @@ SQLITE_PRIVATE void sqlite3Coverage(int);
#endif
/*
+** The harmless(X) macro indicates that expression X is usually false
+** but can be true without causing any problems, but we don't know of
+** any way to cause X to be true.
+**
+** In debugging and testing builds, this macro will abort if X is ever
+** true. In this way, developers are alerted to a possible test case
+** that causes X to be true. If a harmless macro ever fails, that is
+** an opportunity to change the macro into a testcase() and add a new
+** test case to the test suite.
+**
+** For normal production builds, harmless(X) is a no-op, since it does
+** not matter whether expression X is true or false.
+*/
+#ifdef SQLITE_DEBUG
+# define harmless(X) assert(!(X));
+#else
+# define harmless(X)
+#endif
+
+/*
** Some conditionals are optimizations only. In other words, if the
** conditionals are replaced with a constant 1 (true) or 0 (false) then
** the correct answer is still obtained, though perhaps not as quickly.
@@ -13673,90 +14019,92 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_GROUPS 92
#define TK_OTHERS 93
#define TK_TIES 94
-#define TK_REINDEX 95
-#define TK_RENAME 96
-#define TK_CTIME_KW 97
-#define TK_ANY 98
-#define TK_BITAND 99
-#define TK_BITOR 100
-#define TK_LSHIFT 101
-#define TK_RSHIFT 102
-#define TK_PLUS 103
-#define TK_MINUS 104
-#define TK_STAR 105
-#define TK_SLASH 106
-#define TK_REM 107
-#define TK_CONCAT 108
-#define TK_COLLATE 109
-#define TK_BITNOT 110
-#define TK_ON 111
-#define TK_INDEXED 112
-#define TK_STRING 113
-#define TK_JOIN_KW 114
-#define TK_CONSTRAINT 115
-#define TK_DEFAULT 116
-#define TK_NULL 117
-#define TK_PRIMARY 118
-#define TK_UNIQUE 119
-#define TK_CHECK 120
-#define TK_REFERENCES 121
-#define TK_AUTOINCR 122
-#define TK_INSERT 123
-#define TK_DELETE 124
-#define TK_UPDATE 125
-#define TK_SET 126
-#define TK_DEFERRABLE 127
-#define TK_FOREIGN 128
-#define TK_DROP 129
-#define TK_UNION 130
-#define TK_ALL 131
-#define TK_EXCEPT 132
-#define TK_INTERSECT 133
-#define TK_SELECT 134
-#define TK_VALUES 135
-#define TK_DISTINCT 136
-#define TK_DOT 137
-#define TK_FROM 138
-#define TK_JOIN 139
-#define TK_USING 140
-#define TK_ORDER 141
-#define TK_GROUP 142
-#define TK_HAVING 143
-#define TK_LIMIT 144
-#define TK_WHERE 145
-#define TK_INTO 146
-#define TK_NOTHING 147
-#define TK_FLOAT 148
-#define TK_BLOB 149
-#define TK_INTEGER 150
-#define TK_VARIABLE 151
-#define TK_CASE 152
-#define TK_WHEN 153
-#define TK_THEN 154
-#define TK_ELSE 155
-#define TK_INDEX 156
-#define TK_ALTER 157
-#define TK_ADD 158
-#define TK_WINDOW 159
-#define TK_OVER 160
-#define TK_FILTER 161
-#define TK_COLUMN 162
-#define TK_AGG_FUNCTION 163
-#define TK_AGG_COLUMN 164
-#define TK_TRUEFALSE 165
-#define TK_ISNOT 166
-#define TK_FUNCTION 167
-#define TK_UMINUS 168
-#define TK_UPLUS 169
-#define TK_TRUTH 170
-#define TK_REGISTER 171
-#define TK_VECTOR 172
-#define TK_SELECT_COLUMN 173
-#define TK_IF_NULL_ROW 174
-#define TK_ASTERISK 175
-#define TK_SPAN 176
-#define TK_SPACE 177
-#define TK_ILLEGAL 178
+#define TK_GENERATED 95
+#define TK_ALWAYS 96
+#define TK_REINDEX 97
+#define TK_RENAME 98
+#define TK_CTIME_KW 99
+#define TK_ANY 100
+#define TK_BITAND 101
+#define TK_BITOR 102
+#define TK_LSHIFT 103
+#define TK_RSHIFT 104
+#define TK_PLUS 105
+#define TK_MINUS 106
+#define TK_STAR 107
+#define TK_SLASH 108
+#define TK_REM 109
+#define TK_CONCAT 110
+#define TK_COLLATE 111
+#define TK_BITNOT 112
+#define TK_ON 113
+#define TK_INDEXED 114
+#define TK_STRING 115
+#define TK_JOIN_KW 116
+#define TK_CONSTRAINT 117
+#define TK_DEFAULT 118
+#define TK_NULL 119
+#define TK_PRIMARY 120
+#define TK_UNIQUE 121
+#define TK_CHECK 122
+#define TK_REFERENCES 123
+#define TK_AUTOINCR 124
+#define TK_INSERT 125
+#define TK_DELETE 126
+#define TK_UPDATE 127
+#define TK_SET 128
+#define TK_DEFERRABLE 129
+#define TK_FOREIGN 130
+#define TK_DROP 131
+#define TK_UNION 132
+#define TK_ALL 133
+#define TK_EXCEPT 134
+#define TK_INTERSECT 135
+#define TK_SELECT 136
+#define TK_VALUES 137
+#define TK_DISTINCT 138
+#define TK_DOT 139
+#define TK_FROM 140
+#define TK_JOIN 141
+#define TK_USING 142
+#define TK_ORDER 143
+#define TK_GROUP 144
+#define TK_HAVING 145
+#define TK_LIMIT 146
+#define TK_WHERE 147
+#define TK_INTO 148
+#define TK_NOTHING 149
+#define TK_FLOAT 150
+#define TK_BLOB 151
+#define TK_INTEGER 152
+#define TK_VARIABLE 153
+#define TK_CASE 154
+#define TK_WHEN 155
+#define TK_THEN 156
+#define TK_ELSE 157
+#define TK_INDEX 158
+#define TK_ALTER 159
+#define TK_ADD 160
+#define TK_WINDOW 161
+#define TK_OVER 162
+#define TK_FILTER 163
+#define TK_COLUMN 164
+#define TK_AGG_FUNCTION 165
+#define TK_AGG_COLUMN 166
+#define TK_TRUEFALSE 167
+#define TK_ISNOT 168
+#define TK_FUNCTION 169
+#define TK_UMINUS 170
+#define TK_UPLUS 171
+#define TK_TRUTH 172
+#define TK_REGISTER 173
+#define TK_VECTOR 174
+#define TK_SELECT_COLUMN 175
+#define TK_IF_NULL_ROW 176
+#define TK_ASTERISK 177
+#define TK_SPAN 178
+#define TK_SPACE 179
+#define TK_ILLEGAL 180
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -14191,7 +14539,6 @@ struct BusyHandler {
int (*xBusyHandler)(void *,int); /* The busy callback */
void *pBusyArg; /* First arg to busy callback */
int nBusy; /* Incremented with each busy call */
- u8 bExtraFileArg; /* Include sqlite3_file as callback arg */
};
/*
@@ -14354,6 +14701,7 @@ typedef struct With With;
** A bit in a Bitmask
*/
#define MASKBIT(n) (((Bitmask)1)<<(n))
+#define MASKBIT64(n) (((u64)1)<<(n))
#define MASKBIT32(n) (((unsigned int)1)<<(n))
#define ALLBITS ((Bitmask)-1)
@@ -14448,7 +14796,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*);
+SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree*);
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
@@ -14680,6 +15028,8 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
+SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*);
+SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*);
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
#endif
@@ -14688,7 +15038,7 @@ SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);
-SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
+SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,int*aRoot,int nRoot,int,int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*);
@@ -14708,9 +15058,7 @@ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
-#ifndef SQLITE_OMIT_BTREECOUNT
-SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
-#endif
+SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
#ifdef SQLITE_TEST
SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
@@ -14966,30 +15314,30 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_SeekLE 23 /* jump, synopsis: key=r[P3@P4] */
#define OP_SeekGE 24 /* jump, synopsis: key=r[P3@P4] */
#define OP_SeekGT 25 /* jump, synopsis: key=r[P3@P4] */
-#define OP_IfNoHope 26 /* jump, synopsis: key=r[P3@P4] */
-#define OP_NoConflict 27 /* jump, synopsis: key=r[P3@P4] */
-#define OP_NotFound 28 /* jump, synopsis: key=r[P3@P4] */
-#define OP_Found 29 /* jump, synopsis: key=r[P3@P4] */
-#define OP_SeekRowid 30 /* jump, synopsis: intkey=r[P3] */
-#define OP_NotExists 31 /* jump, synopsis: intkey=r[P3] */
-#define OP_Last 32 /* jump */
-#define OP_IfSmaller 33 /* jump */
-#define OP_SorterSort 34 /* jump */
-#define OP_Sort 35 /* jump */
-#define OP_Rewind 36 /* jump */
-#define OP_IdxLE 37 /* jump, synopsis: key=r[P3@P4] */
-#define OP_IdxGT 38 /* jump, synopsis: key=r[P3@P4] */
-#define OP_IdxLT 39 /* jump, synopsis: key=r[P3@P4] */
-#define OP_IdxGE 40 /* jump, synopsis: key=r[P3@P4] */
-#define OP_RowSetRead 41 /* jump, synopsis: r[P3]=rowset(P1) */
-#define OP_RowSetTest 42 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_IfNotOpen 26 /* jump, synopsis: if( !csr[P1] ) goto P2 */
+#define OP_IfNoHope 27 /* jump, synopsis: key=r[P3@P4] */
+#define OP_NoConflict 28 /* jump, synopsis: key=r[P3@P4] */
+#define OP_NotFound 29 /* jump, synopsis: key=r[P3@P4] */
+#define OP_Found 30 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekRowid 31 /* jump, synopsis: intkey=r[P3] */
+#define OP_NotExists 32 /* jump, synopsis: intkey=r[P3] */
+#define OP_Last 33 /* jump */
+#define OP_IfSmaller 34 /* jump */
+#define OP_SorterSort 35 /* jump */
+#define OP_Sort 36 /* jump */
+#define OP_Rewind 37 /* jump */
+#define OP_IdxLE 38 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxGT 39 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxLT 40 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxGE 41 /* jump, synopsis: key=r[P3@P4] */
+#define OP_RowSetRead 42 /* jump, synopsis: r[P3]=rowset(P1) */
#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_Program 45 /* jump */
-#define OP_FkIfZero 46 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_IfPos 47 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IfNotZero 48 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
-#define OP_DecrJumpZero 49 /* jump, synopsis: if (--r[P1])==0 goto P2 */
+#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 46 /* jump */
+#define OP_FkIfZero 47 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_IfPos 48 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero 49 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
@@ -14999,83 +15347,83 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
#define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
#define OP_ElseNotEq 58 /* jump, same as TK_ESCAPE */
-#define OP_IncrVacuum 59 /* jump */
-#define OP_VNext 60 /* jump */
-#define OP_Init 61 /* jump, synopsis: Start at P2 */
-#define OP_PureFunc0 62
-#define OP_Function0 63 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_PureFunc 64
-#define OP_Function 65 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_Return 66
-#define OP_EndCoroutine 67
-#define OP_HaltIfNull 68 /* synopsis: if r[P3]=null halt */
-#define OP_Halt 69
-#define OP_Integer 70 /* synopsis: r[P2]=P1 */
-#define OP_Int64 71 /* synopsis: r[P2]=P4 */
-#define OP_String 72 /* synopsis: r[P2]='P4' (len=P1) */
-#define OP_Null 73 /* synopsis: r[P2..P3]=NULL */
-#define OP_SoftNull 74 /* synopsis: r[P1]=NULL */
-#define OP_Blob 75 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 76 /* synopsis: r[P2]=parameter(P1,P4) */
-#define OP_Move 77 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_Copy 78 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
-#define OP_SCopy 79 /* synopsis: r[P2]=r[P1] */
-#define OP_IntCopy 80 /* synopsis: r[P2]=r[P1] */
-#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */
-#define OP_CollSeq 82
-#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */
-#define OP_RealAffinity 84
-#define OP_Cast 85 /* synopsis: affinity(r[P1]) */
-#define OP_Permutation 86
-#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */
-#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
-#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */
-#define OP_Column 90 /* synopsis: r[P3]=PX */
-#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */
-#define OP_MakeRecord 92 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_Count 93 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 94
-#define OP_SetCookie 95
-#define OP_ReopenIdx 96 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenRead 97 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 98 /* synopsis: root=P2 iDb=P3 */
-#define OP_BitAnd 99 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 100 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 101 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
-#define OP_ShiftRight 102 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
-#define OP_Add 103 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 104 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 105 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 106 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 107 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 108 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_OpenDup 109
-#define OP_BitNot 110 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
-#define OP_OpenAutoindex 111 /* synopsis: nColumn=P2 */
-#define OP_OpenEphemeral 112 /* synopsis: nColumn=P2 */
-#define OP_String8 113 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_SorterOpen 114
-#define OP_SequenceTest 115 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
-#define OP_OpenPseudo 116 /* synopsis: P3 columns in r[P2] */
-#define OP_Close 117
-#define OP_ColumnsUsed 118
-#define OP_SeekHit 119 /* synopsis: seekHit=P2 */
-#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */
-#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */
-#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */
-#define OP_Delete 123
-#define OP_ResetCount 124
-#define OP_SorterCompare 125 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData 126 /* synopsis: r[P2]=data */
-#define OP_RowData 127 /* synopsis: r[P2]=data */
-#define OP_Rowid 128 /* synopsis: r[P2]=rowid */
-#define OP_NullRow 129
-#define OP_SeekEnd 130
+#define OP_DecrJumpZero 59 /* jump, synopsis: if (--r[P1])==0 goto P2 */
+#define OP_IncrVacuum 60 /* jump */
+#define OP_VNext 61 /* jump */
+#define OP_Init 62 /* jump, synopsis: Start at P2 */
+#define OP_PureFunc 63 /* synopsis: r[P3]=func(r[P2@NP]) */
+#define OP_Function 64 /* synopsis: r[P3]=func(r[P2@NP]) */
+#define OP_Return 65
+#define OP_EndCoroutine 66
+#define OP_HaltIfNull 67 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 68
+#define OP_Integer 69 /* synopsis: r[P2]=P1 */
+#define OP_Int64 70 /* synopsis: r[P2]=P4 */
+#define OP_String 71 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 72 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 73 /* synopsis: r[P1]=NULL */
+#define OP_Blob 74 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 75 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 76 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 77 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 78 /* synopsis: r[P2]=r[P1] */
+#define OP_IntCopy 79 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 80 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 81
+#define OP_AddImm 82 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_RealAffinity 83
+#define OP_Cast 84 /* synopsis: affinity(r[P1]) */
+#define OP_Permutation 85
+#define OP_Compare 86 /* synopsis: r[P1@P3] <-> r[P2@P3] */
+#define OP_IsTrue 87 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
+#define OP_Offset 88 /* synopsis: r[P3] = sqlite_offset(P1) */
+#define OP_Column 89 /* synopsis: r[P3]=PX */
+#define OP_Affinity 90 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 91 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 92 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 93
+#define OP_SetCookie 94
+#define OP_ReopenIdx 95 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenRead 96 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 97 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenDup 98
+#define OP_OpenAutoindex 99 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 100 /* synopsis: nColumn=P2 */
+#define OP_BitAnd 101 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 102 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 103 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight 104 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add 105 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 106 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 107 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 108 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 109 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 110 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_SorterOpen 111
+#define OP_BitNot 112 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
+#define OP_SequenceTest 113 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
+#define OP_OpenPseudo 114 /* synopsis: P3 columns in r[P2] */
+#define OP_String8 115 /* same as TK_STRING, synopsis: r[P2]='P4' */
+#define OP_Close 116
+#define OP_ColumnsUsed 117
+#define OP_SeekHit 118 /* synopsis: seekHit=P2 */
+#define OP_Sequence 119 /* synopsis: r[P2]=cursor[P1].ctr++ */
+#define OP_NewRowid 120 /* synopsis: r[P2]=rowid */
+#define OP_Insert 121 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_Delete 122
+#define OP_ResetCount 123
+#define OP_SorterCompare 124 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 125 /* synopsis: r[P2]=data */
+#define OP_RowData 126 /* synopsis: r[P2]=data */
+#define OP_Rowid 127 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 128
+#define OP_SeekEnd 129
+#define OP_IdxInsert 130 /* synopsis: key=r[P2] */
#define OP_SorterInsert 131 /* synopsis: key=r[P2] */
-#define OP_IdxInsert 132 /* synopsis: key=r[P2] */
-#define OP_IdxDelete 133 /* synopsis: key=r[P2@P3] */
-#define OP_DeferredSeek 134 /* synopsis: Move P3 to P1.rowid if needed */
-#define OP_IdxRowid 135 /* synopsis: r[P2]=rowid */
+#define OP_IdxDelete 132 /* synopsis: key=r[P2@P3] */
+#define OP_DeferredSeek 133 /* synopsis: Move P3 to P1.rowid if needed */
+#define OP_IdxRowid 134 /* synopsis: r[P2]=rowid */
+#define OP_FinishSeek 135
#define OP_Destroy 136
#define OP_Clear 137
#define OP_ResetSorter 138
@@ -15088,9 +15436,9 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_DropTrigger 145
#define OP_IntegrityCk 146
#define OP_RowSetAdd 147 /* synopsis: rowset(P1)=r[P2] */
-#define OP_Real 148 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_Param 149
-#define OP_FkCounter 150 /* synopsis: fkctr[P1]+=P2 */
+#define OP_Param 148
+#define OP_FkCounter 149 /* synopsis: fkctr[P1]+=P2 */
+#define OP_Real 150 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
#define OP_MemMax 151 /* synopsis: r[P1]=max(r[P1],r[P2]) */
#define OP_OffsetLimit 152 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
#define OP_AggInverse 153 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
@@ -15099,20 +15447,23 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_AggValue 156 /* synopsis: r[P3]=value N=P2 */
#define OP_AggFinal 157 /* synopsis: accum=r[P1] N=P2 */
#define OP_Expire 158
-#define OP_TableLock 159 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 160
-#define OP_VCreate 161
-#define OP_VDestroy 162
-#define OP_VOpen 163
-#define OP_VColumn 164 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VRename 165
-#define OP_Pagecount 166
-#define OP_MaxPgcnt 167
-#define OP_Trace 168
-#define OP_CursorHint 169
-#define OP_Noop 170
-#define OP_Explain 171
-#define OP_Abortable 172
+#define OP_CursorLock 159
+#define OP_CursorUnlock 160
+#define OP_TableLock 161 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 162
+#define OP_VCreate 163
+#define OP_VDestroy 164
+#define OP_VOpen 165
+#define OP_VColumn 166 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VRename 167
+#define OP_Pagecount 168
+#define OP_MaxPgcnt 169
+#define OP_Trace 170
+#define OP_CursorHint 171
+#define OP_ReleaseReg 172 /* synopsis: release r[P1@P2] mask P3 */
+#define OP_Noop 173
+#define OP_Explain 174
+#define OP_Abortable 175
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
@@ -15128,25 +15479,26 @@ typedef struct VdbeOpList VdbeOpList;
/* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
/* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x01, 0x09, 0x09,\
-/* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
-/* 32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
-/* 40 */ 0x01, 0x23, 0x0b, 0x26, 0x26, 0x01, 0x01, 0x03,\
+/* 24 */ 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09, 0x09,\
+/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
+/* 40 */ 0x01, 0x01, 0x23, 0x26, 0x26, 0x0b, 0x01, 0x01,\
/* 48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
-/* 56 */ 0x0b, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,\
-/* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\
-/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
-/* 80 */ 0x10, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\
-/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
-/* 96 */ 0x00, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26, 0x26,\
-/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12, 0x00,\
-/* 112 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 128 */ 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\
+/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00,\
+/* 64 */ 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10,\
+/* 72 */ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10,\
+/* 80 */ 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x12,\
+/* 88 */ 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26, 0x26,\
+/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\
+/* 112 */ 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,\
+/* 120 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+/* 128 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
/* 136 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
-/* 144 */ 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00, 0x04,\
+/* 144 */ 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x10, 0x04,\
/* 152 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
-/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00,}
+/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 168 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+}
/* The sqlite3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode. The smaller the maximum
@@ -15154,7 +15506,7 @@ typedef struct VdbeOpList VdbeOpList;
** generated this include file strives to group all JUMP opcodes
** together near the beginning of the list.
*/
-#define SQLITE_MX_JUMP_OPCODE 61 /* Maximum JUMP opcode */
+#define SQLITE_MX_JUMP_OPCODE 62 /* Maximum JUMP opcode */
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -15170,6 +15522,7 @@ typedef struct VdbeOpList VdbeOpList;
** for a description of what each of these routines does.
*/
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*);
+SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe*);
SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
@@ -15180,6 +15533,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
+SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int);
SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int);
#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
@@ -15219,8 +15573,14 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
+SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe*, int addr);
SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int);
+#else
+# define sqlite3VdbeReleaseRegisters(P,A,N,M,F)
+#endif
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
@@ -15269,11 +15629,13 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
-#ifndef SQLITE_OMIT_TRIGGER
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
-#endif
+SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*);
SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*);
+#ifdef SQLITE_ENABLE_BYTECODE_VTAB
+SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3*);
+#endif
/* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on
** each VDBE opcode.
@@ -15510,9 +15872,6 @@ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
/* Functions used to configure a Pager object. */
SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
-#ifdef SQLITE_HAS_CODEC
-SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*);
-#endif
SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int);
@@ -15562,14 +15921,22 @@ SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
# ifdef SQLITE_ENABLE_SNAPSHOT
-SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
-SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
+SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager*, sqlite3_snapshot **ppSnapshot);
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager*, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
#endif
+#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_ENABLE_SETLK_TIMEOUT)
+SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager*, int);
+SQLITE_PRIVATE void sqlite3PagerWalDb(Pager*, sqlite3*);
+#else
+# define sqlite3PagerWalWriteLock(y,z) SQLITE_OK
+# define sqlite3PagerWalDb(x,y)
+#endif
+
#ifdef SQLITE_DIRECT_OVERFLOW_READ
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif
@@ -15585,7 +15952,7 @@ SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*);
SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
#endif
SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
-SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
+SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager*, int);
SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*);
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*);
@@ -15595,21 +15962,12 @@ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*);
SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
-SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager);
-#else
-# define sqlite3PagerResetLockTimeout(X)
-#endif
/* Functions used to truncate the database file. */
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
-#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
-SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
-#endif
-
/* Functions to support testing and debugging. */
#if !defined(NDEBUG) || defined(SQLITE_TEST)
SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*);
@@ -16277,7 +16635,6 @@ struct Schema {
*/
#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
#define DB_UnresetViews 0x0002 /* Some views have defined column names */
-#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */
#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */
/*
@@ -16305,15 +16662,47 @@ struct Schema {
** is shared by multiple database connections. Therefore, while parsing
** schema information, the Lookaside.bEnabled flag is cleared so that
** lookaside allocations are not used to construct the schema objects.
+**
+** New lookaside allocations are only allowed if bDisable==0. When
+** bDisable is greater than zero, sz is set to zero which effectively
+** disables lookaside without adding a new test for the bDisable flag
+** in a performance-critical path. sz should be set by to szTrue whenever
+** bDisable changes back to zero.
+**
+** Lookaside buffers are initially held on the pInit list. As they are
+** used and freed, they are added back to the pFree list. New allocations
+** come off of pFree first, then pInit as a fallback. This dual-list
+** allows use to compute a high-water mark - the maximum number of allocations
+** outstanding at any point in the past - by subtracting the number of
+** allocations on the pInit list from the total number of allocations.
+**
+** Enhancement on 2019-12-12: Two-size-lookaside
+** The default lookaside configuration is 100 slots of 1200 bytes each.
+** The larger slot sizes are important for performance, but they waste
+** a lot of space, as most lookaside allocations are less than 128 bytes.
+** The two-size-lookaside enhancement breaks up the lookaside allocation
+** into two pools: One of 128-byte slots and the other of the default size
+** (1200-byte) slots. Allocations are filled from the small-pool first,
+** failing over to the full-size pool if that does not work. Thus more
+** lookaside slots are available while also using less memory.
+** This enhancement can be omitted by compiling with
+** SQLITE_OMIT_TWOSIZE_LOOKASIDE.
*/
struct Lookaside {
u32 bDisable; /* Only operate the lookaside when zero */
u16 sz; /* Size of each buffer in bytes */
+ u16 szTrue; /* True value of sz, even if disabled */
u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
u32 nSlot; /* Number of lookaside slots allocated */
u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
LookasideSlot *pInit; /* List of buffers not previously used */
LookasideSlot *pFree; /* List of available buffers */
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ LookasideSlot *pSmallInit; /* List of small buffers not prediously used */
+ LookasideSlot *pSmallFree; /* List of available small buffers */
+ void *pMiddle; /* First byte past end of full-size buffers and
+ ** the first byte of LOOKASIDE_SMALL buffers */
+#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
void *pStart; /* First byte of available memory space */
void *pEnd; /* First byte past end of available space */
};
@@ -16321,6 +16710,17 @@ struct LookasideSlot {
LookasideSlot *pNext; /* Next buffer in the list of free buffers */
};
+#define DisableLookaside db->lookaside.bDisable++;db->lookaside.sz=0
+#define EnableLookaside db->lookaside.bDisable--;\
+ db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue
+
+/* Size of the smaller allocations in two-size lookside */
+#ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+# define LOOKASIDE_SMALL 0
+#else
+# define LOOKASIDE_SMALL 128
+#endif
+
/*
** A hash table for built-in function definitions. (Application-defined
** functions use a regular table table from hash.h.)
@@ -16392,7 +16792,7 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
struct sqlite3 {
sqlite3_vfs *pVfs; /* OS Interface */
struct Vdbe *pVdbe; /* List of active virtual machines */
- CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
+ CollSeq *pDfltColl; /* BINARY collseq for the database encoding */
sqlite3_mutex *mutex; /* Connection mutex */
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
@@ -16495,6 +16895,7 @@ struct sqlite3 {
BusyHandler busyHandler; /* Busy callback */
Db aDbStatic[2]; /* Static space for the 2 default backends */
Savepoint *pSavepoint; /* List of active savepoints */
+ int nAnalysisLimit; /* Number of index rows to ANALYZE */
int busyTimeout; /* Busy handler timeout, in msec */
int nSavepoint; /* Number of non-transaction savepoints */
int nStatement; /* Number of nested statement-transactions */
@@ -16530,6 +16931,13 @@ struct sqlite3 {
#define ENC(db) ((db)->enc)
/*
+** A u64 constant where the lower 32 bits are all zeros. Only the
+** upper 32 bits are included in the argument. Necessary because some
+** C-compilers still do not accept LL integer literals.
+*/
+#define HI(X) ((u64)(X)<<32)
+
+/*
** Possible values for the sqlite3.flags.
**
** Value constraints (enforced via assert()):
@@ -16544,9 +16952,8 @@ struct sqlite3 {
#define SQLITE_CkptFullFSync 0x00000010 /* Use full fsync for checkpoint */
#define SQLITE_CacheSpill 0x00000020 /* OK to spill pager cache */
#define SQLITE_ShortColNames 0x00000040 /* Show short columns names */
-#define SQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
- /* DELETE, or UPDATE and return */
- /* the count using a callback. */
+#define SQLITE_TrustedSchema 0x00000080 /* Allow unsafe functions and
+ ** vtabs in the schema definition */
#define SQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
/* result set is empty */
#define SQLITE_IgnoreChecks 0x00000200 /* Do not enforce check constraints */
@@ -16572,9 +16979,11 @@ struct sqlite3 {
#define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/
#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
+#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
+ /* DELETE, or UPDATE and return */
+ /* the count using a callback. */
/* Flags used only if debugging */
-#define HI(X) ((u64)(X)<<32)
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -16592,6 +17001,8 @@ struct sqlite3 {
#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
#define DBFLAG_VacuumInto 0x0008 /* Currently running VACUUM INTO */
#define DBFLAG_SchemaKnownOk 0x0010 /* Schema is known to be valid */
+#define DBFLAG_InternalFunc 0x0020 /* Allow use of internal functions */
+#define DBFLAG_EncodingFixed 0x0040 /* No longer possible to change enc. */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -16699,6 +17110,7 @@ struct FuncDestructor {
** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG
** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API
** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API
+** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS
** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API
*/
#define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
@@ -16709,18 +17121,29 @@ struct FuncDestructor {
#define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */
#define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */
#define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */
-#define SQLITE_FUNC_COALESCE 0x0200 /* Built-in coalesce() or ifnull() */
+/* 0x0200 -- available for reuse */
#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
-#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
+#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
+#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
+#define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */
+
+/* Identifier numbers for each in-line function */
+#define INLINEFUNC_coalesce 0
+#define INLINEFUNC_implies_nonnull_row 1
+#define INLINEFUNC_expr_implies_expr 2
+#define INLINEFUNC_expr_compare 3
+#define INLINEFUNC_affinity 4
+#define INLINEFUNC_iif 5
+#define INLINEFUNC_unlikely 99 /* Default case */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -16736,6 +17159,22 @@ struct FuncDestructor {
** VFUNCTION(zName, nArg, iArg, bNC, xFunc)
** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag.
**
+** SFUNCTION(zName, nArg, iArg, bNC, xFunc)
+** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
+** adds the SQLITE_DIRECTONLY flag.
+**
+** INLINE_FUNC(zName, nArg, iFuncId, mFlags)
+** zName is the name of a function that is implemented by in-line
+** byte code rather than by the usual callbacks. The iFuncId
+** parameter determines the function id. The mFlags parameter is
+** optional SQLITE_FUNC_ flags for this function.
+**
+** TEST_FUNC(zName, nArg, iFuncId, mFlags)
+** zName is the name of a test-only function implemented by in-line
+** byte code rather than by the usual callbacks. The iFuncId
+** parameter determines the function id. The mFlags parameter is
+** optional SQLITE_FUNC_ flags for this function.
+**
** DFUNCTION(zName, nArg, iArg, bNC, xFunc)
** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag and
** adds the SQLITE_FUNC_SLOCHNG flag. Used for date & time functions
@@ -16775,6 +17214,16 @@ struct FuncDestructor {
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
+ {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
+#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
+ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
+ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
+#define TEST_FUNC(zName, nArg, iArg, mFlags) \
+ {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
+ SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
+ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
0, 0, xFunc, 0, 0, 0, #zName, {0} }
@@ -16790,12 +17239,6 @@ struct FuncDestructor {
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
(void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
-#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue) \
- {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
-#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
- {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
- SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
@@ -16841,26 +17284,46 @@ struct Module {
};
/*
-** information about each column of an SQL table is held in an instance
-** of this structure.
+** Information about each column of an SQL table is held in an instance
+** of the Column structure, in the Table.aCol[] array.
+**
+** Definitions:
+**
+** "table column index" This is the index of the column in the
+** Table.aCol[] array, and also the index of
+** the column in the original CREATE TABLE stmt.
+**
+** "storage column index" This is the index of the column in the
+** record BLOB generated by the OP_MakeRecord
+** opcode. The storage column index is less than
+** or equal to the table column index. It is
+** equal if and only if there are no VIRTUAL
+** columns to the left.
*/
struct Column {
char *zName; /* Name of this column, \000, then the type */
- Expr *pDflt; /* Default value of this column */
+ Expr *pDflt; /* Default value or GENERATED ALWAYS AS value */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* An OE_ code for handling a NOT NULL constraint */
char affinity; /* One of the SQLITE_AFF_... values */
u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */
- u8 colFlags; /* Boolean properties. See COLFLAG_ defines below */
+ u8 hName; /* Column name hash for faster lookup */
+ u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */
};
/* Allowed values for Column.colFlags:
*/
-#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
-#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
-#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */
-#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */
+#define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */
+#define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */
+#define COLFLAG_HASTYPE 0x0004 /* Type name follows column name */
+#define COLFLAG_UNIQUE 0x0008 /* Column def contains "UNIQUE" or "PK" */
#define COLFLAG_SORTERREF 0x0010 /* Use sorter-refs with this column */
+#define COLFLAG_VIRTUAL 0x0020 /* GENERATED ALWAYS AS ... VIRTUAL */
+#define COLFLAG_STORED 0x0040 /* GENERATED ALWAYS AS ... STORED */
+#define COLFLAG_NOTAVAIL 0x0080 /* STORED column not yet calculated */
+#define COLFLAG_BUSY 0x0100 /* Blocks recursion on GENERATED columns */
+#define COLFLAG_GENERATED 0x0060 /* Combo: _STORED, _VIRTUAL */
+#define COLFLAG_NOINSERT 0x0062 /* Combo: _HIDDEN, _STORED, _VIRTUAL */
/*
** A "Collating Sequence" is defined by an instance of the following
@@ -16978,10 +17441,17 @@ struct VTable {
sqlite3_vtab *pVtab; /* Pointer to vtab instance */
int nRef; /* Number of pointers to this structure */
u8 bConstraint; /* True if constraints are supported */
+ u8 eVtabRisk; /* Riskiness of allowing hacker access */
int iSavepoint; /* Depth of the SAVEPOINT stack */
VTable *pNext; /* Next in linked list (see above) */
};
+/* Allowed values for VTable.eVtabRisk
+*/
+#define SQLITE_VTABRISK_Low 0
+#define SQLITE_VTABRISK_Normal 1
+#define SQLITE_VTABRISK_High 2
+
/*
** The schema for each SQL table and view is represented in memory
** by an instance of the following structure.
@@ -17000,6 +17470,7 @@ struct Table {
u32 tabFlags; /* Mask of TF_* values */
i16 iPKey; /* If not negative, use aCol[iPKey] as the rowid */
i16 nCol; /* Number of columns in this table */
+ i16 nNVCol; /* Number of columns that are not VIRTUAL */
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
LogEst szTabRow; /* Estimated size of each table row in bytes */
#ifdef SQLITE_ENABLE_COSTMULT
@@ -17026,20 +17497,28 @@ struct Table {
** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
** vtab1(a HIDDEN, b);". Since "b" is a non-hidden column but "a" is hidden,
** the TF_OOOHidden attribute would apply in this case. Such tables require
-** special handling during INSERT processing.
+** special handling during INSERT processing. The "OOO" means "Out Of Order".
+**
+** Constraints:
+**
+** TF_HasVirtual == COLFLAG_Virtual
+** TF_HasStored == COLFLAG_Stored
*/
#define TF_Readonly 0x0001 /* Read-only system table */
#define TF_Ephemeral 0x0002 /* An ephemeral table */
#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */
#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */
#define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */
-#define TF_WithoutRowid 0x0020 /* No rowid. PRIMARY KEY is the key */
-#define TF_NoVisibleRowid 0x0040 /* No user-visible "rowid" column */
-#define TF_OOOHidden 0x0080 /* Out-of-Order hidden columns */
+#define TF_HasVirtual 0x0020 /* Has one or more VIRTUAL columns */
+#define TF_HasStored 0x0040 /* Has one or more STORED columns */
+#define TF_HasGenerated 0x0060 /* Combo: HasVirtual + HasStored */
+#define TF_WithoutRowid 0x0080 /* No rowid. PRIMARY KEY is the key */
#define TF_StatsUsed 0x0100 /* Query planner decisions affected by
** Index.aiRowLogEst[] values */
-#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
-#define TF_Shadow 0x0400 /* True for a shadow table */
+#define TF_NoVisibleRowid 0x0200 /* No user-visible "rowid" column */
+#define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */
+#define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */
+#define TF_Shadow 0x1000 /* True for a shadow table */
/*
** Test to see whether or not a table is a virtual table. This is
@@ -17048,8 +17527,11 @@ struct Table {
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
# define IsVirtual(X) ((X)->nModuleArg)
+# define ExprIsVtab(X) \
+ ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg)
#else
# define IsVirtual(X) 0
+# define ExprIsVtab(X) 0
#endif
/*
@@ -17290,6 +17772,7 @@ struct Index {
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
+ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */
#ifdef SQLITE_ENABLE_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -17360,7 +17843,7 @@ struct Token {
** code for a SELECT that contains aggregate functions.
**
** If Expr.op==TK_AGG_COLUMN or TK_AGG_FUNCTION then Expr.pAggInfo is a
-** pointer to this structure. The Expr.iColumn field is the index in
+** pointer to this structure. The Expr.iAgg field is the index in
** AggInfo.aCol[] or AggInfo.aFunc[] of information needed to generate
** code for that node.
**
@@ -17406,10 +17889,10 @@ struct AggInfo {
** it uses less memory in the Expr object, which is a big memory user
** in systems with lots of prepared statements. And few applications
** need more than about 10 or 20 variables. But some extreme users want
-** to have prepared statements with over 32767 variables, and for them
+** to have prepared statements with over 32766 variables, and for them
** the option is available (at compile-time).
*/
-#if SQLITE_MAX_VARIABLE_NUMBER<=32767
+#if SQLITE_MAX_VARIABLE_NUMBER<32767
typedef i16 ynVar;
#else
typedef int ynVar;
@@ -17481,6 +17964,13 @@ typedef int ynVar;
struct Expr {
u8 op; /* Operation performed by this node */
char affExpr; /* affinity, or RAISE type */
+ u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
+ ** TK_COLUMN: the value of p5 for OP_Column
+ ** TK_AGG_FUNCTION: nesting depth
+ ** TK_FUNCTION: NC_SelfRef flag if needs OP_PureFunc */
+#ifdef SQLITE_DEBUG
+ u8 vvaFlags; /* Verification flags. */
+#endif
u32 flags; /* Various flags. EP_* See below */
union {
char *zToken; /* Token value. Zero terminated and dequoted */
@@ -17519,9 +18009,6 @@ struct Expr {
** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
- u8 op2; /* TK_REGISTER/TK_TRUTH: original value of Expr.op
- ** TK_COLUMN: the value of p5 for OP_Column
- ** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
union {
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL
@@ -17550,7 +18037,7 @@ struct Expr {
#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */
- /* 0x000200 Available for reuse */
+#define EP_Commuted 0x000200 /* Comparison operator has been commuted */
#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Skip 0x001000 /* Operator does not contribute to affinity */
@@ -17558,7 +18045,7 @@ struct Expr {
#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
#define EP_Win 0x008000 /* Contains window functions */
#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */
-#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
+ /* 0x020000 // available for reuse */
#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
@@ -17571,7 +18058,8 @@ struct Expr {
#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
-#define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */
+#define EP_FromDDL 0x40000000 /* Originates from sqlite_master */
+ /* 0x80000000 // Available */
/*
** The EP_Propagate mask is a set of properties that automatically propagate
@@ -17590,14 +18078,24 @@ struct Expr {
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
+
+/* Flags for use with Expr.vvaFlags
+*/
+#define EP_NoReduce 0x01 /* Cannot EXPRDUP_REDUCE this Expr */
+#define EP_Immutable 0x02 /* Do not change this Expr node */
+
/* The ExprSetVVAProperty() macro is used for Verification, Validation,
** and Accreditation only. It works like ExprSetProperty() during VVA
** processes but is a no-op for delivery.
*/
#ifdef SQLITE_DEBUG
-# define ExprSetVVAProperty(E,P) (E)->flags|=(P)
+# define ExprSetVVAProperty(E,P) (E)->vvaFlags|=(P)
+# define ExprHasVVAProperty(E,P) (((E)->vvaFlags&(P))!=0)
+# define ExprClearVVAProperties(E) (E)->vvaFlags = 0
#else
# define ExprSetVVAProperty(E,P)
+# define ExprHasVVAProperty(E,P) 0
+# define ExprClearVVAProperties(E)
#endif
/*
@@ -17635,23 +18133,28 @@ struct Expr {
** also be used as the argument to a function, in which case the a.zName
** field is not used.
**
-** By default the Expr.zSpan field holds a human-readable description of
-** the expression that is used in the generation of error messages and
-** column labels. In this case, Expr.zSpan is typically the text of a
-** column expression as it exists in a SELECT statement. However, if
-** the bSpanIsTab flag is set, then zSpan is overloaded to mean the name
-** of the result column in the form: DATABASE.TABLE.COLUMN. This later
-** form is used for name resolution with nested FROM clauses.
+** In order to try to keep memory usage down, the Expr.a.zEName field
+** is used for multiple purposes:
+**
+** eEName Usage
+** ---------- -------------------------
+** ENAME_NAME (1) the AS of result set column
+** (2) COLUMN= of an UPDATE
+**
+** ENAME_TAB DB.TABLE.NAME used to resolve names
+** of subqueries
+**
+** ENAME_SPAN Text of the original result set
+** expression.
*/
struct ExprList {
int nExpr; /* Number of expressions on the list */
struct ExprList_item { /* For each expression in the list */
Expr *pExpr; /* The parse tree for this expression */
- char *zName; /* Token associated with this expression */
- char *zSpan; /* Original text of the expression */
+ char *zEName; /* Token associated with this expression */
u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */
+ unsigned eEName :2; /* Meaning of zEName */
unsigned done :1; /* A flag to indicate when processing is finished */
- unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */
unsigned reusable :1; /* Constant expression is reusable */
unsigned bSorterRef :1; /* Defer evaluation until after sorting */
unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
@@ -17666,6 +18169,13 @@ struct ExprList {
};
/*
+** Allowed values for Expr.a.eEName
+*/
+#define ENAME_NAME 0 /* The AS clause of a result set */
+#define ENAME_SPAN 1 /* Complete text of the result set expression */
+#define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */
+
+/*
** An instance of this structure can hold a simple list of identifiers,
** such as the list "a,b,c" in the following statements:
**
@@ -17728,6 +18238,7 @@ struct SrcList {
unsigned isCorrelated :1; /* True if sub-query is correlated */
unsigned viaCoroutine :1; /* Implemented as a co-routine */
unsigned isRecursive :1; /* True for recursive reference in WITH */
+ unsigned fromDDL :1; /* Comes from sqlite_master */
} fg;
int iCursor; /* The VDBE cursor number used to access this table */
Expr *pOn; /* The ON clause of a join */
@@ -17831,21 +18342,24 @@ struct NameContext {
** NC_HasWin == EP_Win
**
*/
-#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
-#define NC_PartIdx 0x0002 /* True if resolving a partial index WHERE */
-#define NC_IsCheck 0x0004 /* True if resolving names in a CHECK constraint */
-#define NC_InAggFunc 0x0008 /* True if analyzing arguments to an agg func */
-#define NC_HasAgg 0x0010 /* One or more aggregate functions seen */
-#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
-#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */
-#define NC_UEList 0x0080 /* True if uNC.pEList is used */
-#define NC_UAggInfo 0x0100 /* True if uNC.pAggInfo is used */
-#define NC_UUpsert 0x0200 /* True if uNC.pUpsert is used */
-#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
-#define NC_Complex 0x2000 /* True if a function or subquery seen */
-#define NC_AllowWin 0x4000 /* Window functions are allowed here */
-#define NC_HasWin 0x8000 /* One or more window functions seen */
-#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */
+#define NC_AllowAgg 0x00001 /* Aggregate functions are allowed here */
+#define NC_PartIdx 0x00002 /* True if resolving a partial index WHERE */
+#define NC_IsCheck 0x00004 /* True if resolving a CHECK constraint */
+#define NC_GenCol 0x00008 /* True for a GENERATED ALWAYS AS clause */
+#define NC_HasAgg 0x00010 /* One or more aggregate functions seen */
+#define NC_IdxExpr 0x00020 /* True if resolving columns of CREATE INDEX */
+#define NC_SelfRef 0x0002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */
+#define NC_VarSelect 0x00040 /* A correlated subquery has been seen */
+#define NC_UEList 0x00080 /* True if uNC.pEList is used */
+#define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */
+#define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */
+#define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */
+#define NC_Complex 0x02000 /* True if a function or subquery seen */
+#define NC_AllowWin 0x04000 /* Window functions are allowed here */
+#define NC_HasWin 0x08000 /* One or more window functions seen */
+#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */
+#define NC_InAggFunc 0x20000 /* True if analyzing arguments to an agg func */
+#define NC_FromDDL 0x40000 /* SQL text comes from sqlite_master */
/*
** An instance of the following object describes a single ON CONFLICT
@@ -17895,13 +18409,13 @@ struct Upsert {
** sequences for the ORDER BY clause.
*/
struct Select {
- ExprList *pEList; /* The fields of the result */
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
LogEst nSelectRow; /* Estimated number of result rows */
u32 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
u32 selId; /* Unique identifier number for this SELECT */
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
+ ExprList *pEList; /* The fields of the result */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
ExprList *pGroupBy; /* The GROUP BY clause */
@@ -17926,26 +18440,28 @@ struct Select {
** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX
** SF_FixedLimit == WHERE_USE_LIMIT
*/
-#define SF_Distinct 0x00001 /* Output should be DISTINCT */
-#define SF_All 0x00002 /* Includes the ALL keyword */
-#define SF_Resolved 0x00004 /* Identifiers have been resolved */
-#define SF_Aggregate 0x00008 /* Contains agg functions or a GROUP BY */
-#define SF_HasAgg 0x00010 /* Contains aggregate functions */
-#define SF_UsesEphemeral 0x00020 /* Uses the OpenEphemeral opcode */
-#define SF_Expanded 0x00040 /* sqlite3SelectExpand() called on this */
-#define SF_HasTypeInfo 0x00080 /* FROM subqueries have Table metadata */
-#define SF_Compound 0x00100 /* Part of a compound query */
-#define SF_Values 0x00200 /* Synthesized from VALUES clause */
-#define SF_MultiValue 0x00400 /* Single VALUES term with multiple rows */
-#define SF_NestedFrom 0x00800 /* Part of a parenthesized FROM clause */
-#define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */
-#define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */
-#define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */
-#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */
-#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
-#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
-#define SF_ComplexResult 0x40000 /* Result contains subquery or function */
-#define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */
+#define SF_Distinct 0x0000001 /* Output should be DISTINCT */
+#define SF_All 0x0000002 /* Includes the ALL keyword */
+#define SF_Resolved 0x0000004 /* Identifiers have been resolved */
+#define SF_Aggregate 0x0000008 /* Contains agg functions or a GROUP BY */
+#define SF_HasAgg 0x0000010 /* Contains aggregate functions */
+#define SF_UsesEphemeral 0x0000020 /* Uses the OpenEphemeral opcode */
+#define SF_Expanded 0x0000040 /* sqlite3SelectExpand() called on this */
+#define SF_HasTypeInfo 0x0000080 /* FROM subqueries have Table metadata */
+#define SF_Compound 0x0000100 /* Part of a compound query */
+#define SF_Values 0x0000200 /* Synthesized from VALUES clause */
+#define SF_MultiValue 0x0000400 /* Single VALUES term with multiple rows */
+#define SF_NestedFrom 0x0000800 /* Part of a parenthesized FROM clause */
+#define SF_MinMaxAgg 0x0001000 /* Aggregate containing min() or max() */
+#define SF_Recursive 0x0002000 /* The recursive part of a recursive CTE */
+#define SF_FixedLimit 0x0004000 /* nSelectRow set by a constant LIMIT */
+#define SF_MaybeConvert 0x0008000 /* Need convertCompoundSelectToSubquery() */
+#define SF_Converted 0x0010000 /* By convertCompoundSelectToSubquery() */
+#define SF_IncludeHidden 0x0020000 /* Include hidden columns in output */
+#define SF_ComplexResult 0x0040000 /* Result contains subquery or function */
+#define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */
+#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */
+#define SF_View 0x0200000 /* SELECT statement is a view */
/*
** The results of a SELECT can be distributed in several ways, as defined
@@ -18225,8 +18741,8 @@ struct Parse {
#define PARSE_MODE_NORMAL 0
#define PARSE_MODE_DECLARE_VTAB 1
-#define PARSE_MODE_RENAME_COLUMN 2
-#define PARSE_MODE_RENAME_TABLE 3
+#define PARSE_MODE_RENAME 2
+#define PARSE_MODE_UNMAP 3
/*
** Sizes and pointers of various parts of the Parse object.
@@ -18248,7 +18764,7 @@ struct Parse {
#if defined(SQLITE_OMIT_ALTERTABLE)
#define IN_RENAME_OBJECT 0
#else
- #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME_COLUMN)
+ #define IN_RENAME_OBJECT (pParse->eParseMode>=PARSE_MODE_RENAME)
#endif
#if defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_OMIT_ALTERTABLE)
@@ -18399,7 +18915,7 @@ typedef struct DbFixer DbFixer;
struct DbFixer {
Parse *pParse; /* The parsing context. Error messages written here */
Schema *pSchema; /* Fix items to this schema */
- int bVarOnly; /* Check for variable references only */
+ u8 bTemp; /* True for TEMP schema entries */
const char *zDb; /* Make sure all objects are contained in this database */
const char *zType; /* Type of the container - used for error messages */
const Token *pName; /* Name of the container - used for error messages */
@@ -18504,7 +19020,6 @@ struct Sqlite3Config {
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
- int bInternalFunctions; /* Internal SQL functions are visible */
int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
@@ -18537,7 +19052,7 @@ struct Walker {
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
int walkerDepth; /* Number of subqueries */
- u8 eCode; /* A small processing code */
+ u16 eCode; /* A small processing code */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
int n; /* A counter */
@@ -18553,6 +19068,8 @@ struct Walker {
struct WindowRewrite *pRewrite; /* Window rewrite context */
struct WhereConst *pConst; /* WHERE clause constants */
struct RenameCtx *pRename; /* RENAME COLUMN context */
+ struct Table *pTab; /* Table of generated column */
+ struct SrcList_item *pSrcItem; /* A single FROM clause item */
} u;
};
@@ -18565,6 +19082,9 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
+SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*);
+SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*);
+
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
#endif
@@ -18666,7 +19186,7 @@ SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*,
SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*);
SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin);
SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*, int);
-SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Window*);
+SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Select*);
SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*);
SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
@@ -18709,13 +19229,16 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3NomemError(int);
SQLITE_PRIVATE int sqlite3IoerrnomemError(int);
-SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
-# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
#else
# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
+#endif
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_CORRUPT_PGNO)
+SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
+# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P))
+#else
# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__)
#endif
@@ -18932,6 +19455,7 @@ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
+SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
@@ -18960,7 +19484,14 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int);
SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
-SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index*, i16);
+SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index*, i16);
+#ifdef SQLITE_OMIT_GENERATED_COLUMNS
+# define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */
+# define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */
+#else
+SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table*, i16);
+SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table*, i16);
+#endif
SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
#if SQLITE_ENABLE_HIDDEN_COLUMNS
SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*);
@@ -18973,14 +19504,11 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
+SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
-#ifdef SQLITE_HAS_CODEC
-SQLITE_PRIVATE int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
-#else
-# define sqlite3CodecQueryParameters(A,B,C) 0
-#endif
+#define sqlite3CodecQueryParameters(A,B,C) 0
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
#ifdef SQLITE_UNTESTABLE
@@ -19030,6 +19558,9 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
# define sqlite3AutoincrementEnd(X)
#endif
SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*);
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns(Parse*, int, Table*);
+#endif
SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
@@ -19052,6 +19583,7 @@ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,u32,Expr*);
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
+SQLITE_PRIVATE void sqlite3SelectReset(Parse*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
@@ -19074,17 +19606,20 @@ SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*);
#define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */
#define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */
#define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */
+SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo*);
SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int);
+#endif
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
-SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8);
#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
@@ -19126,6 +19661,7 @@ SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int);
SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*);
SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
+SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*);
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*);
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
@@ -19221,6 +19757,7 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Tab
#endif
SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
+SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int);
SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -19235,6 +19772,7 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int)
# define sqlite3AuthContextPush(a,b,c)
# define sqlite3AuthContextPop(a) ((void)(a))
#endif
+SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName);
SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*);
SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
@@ -19283,6 +19821,8 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
*/
#define getVarint32(A,B) \
(u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B)))
+#define getVarint32NR(A,B) \
+ B=(u32)*(A);if(B>=0x80)sqlite3GetVarint32((A),(u32*)&(B))
#define putVarint32(A,B) \
(u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\
sqlite3PutVarint((A),(B)))
@@ -19292,10 +19832,10 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int);
-SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
+SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
+SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table*,int);
-SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
+SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr);
SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
@@ -19318,9 +19858,10 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*);
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
-SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
-SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
+SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8);
+SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr);
+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr);
+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
@@ -19381,7 +19922,14 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
-SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
+SQLITE_PRIVATE int sqlite3MatchEName(
+ const struct ExprList_item*,
+ const char*,
+ const char*,
+ const char*
+);
+SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr*);
+SQLITE_PRIVATE u8 sqlite3StrIHash(const char*);
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*);
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
@@ -19397,7 +19945,7 @@ SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
-SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
+SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *);
SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB);
@@ -19519,6 +20067,14 @@ SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
);
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
+SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
+SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
+#else
+# define sqlite3ShadowTableName(A,B) 0
+# define sqlite3IsShadowTableOf(A,B,C) 0
+#endif
SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
@@ -19540,7 +20096,8 @@ SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*);
#endif
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
-SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
+SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse*,const Expr*);
+SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, const Expr*, const Expr*);
SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
SQLITE_PRIVATE const char *sqlite3JournalModename(int);
#ifndef SQLITE_OMIT_WAL
@@ -19846,7 +20403,6 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.
*/
-#ifdef SQLITE_ASCII
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */
@@ -19884,7 +20440,6 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, /* f0..f7 ........ */
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40 /* f8..ff ........ */
};
-#endif
/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
** compatibility for legacy applications, the URI filename capability is
@@ -19896,16 +20451,9 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
** disabled. The default value may be changed by compiling with the
** SQLITE_USE_URI symbol defined.
-**
-** URI filenames are enabled by default if SQLITE_HAS_CODEC is
-** enabled.
*/
#ifndef SQLITE_USE_URI
-# ifdef SQLITE_HAS_CODEC
-# define SQLITE_USE_URI 1
-# else
-# define SQLITE_USE_URI 0
-# endif
+# define SQLITE_USE_URI 0
#endif
/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
@@ -19949,9 +20497,18 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE)
** or at run-time for an individual database connection using
** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE);
+**
+** With the two-size-lookaside enhancement, less lookaside is required.
+** The default configuration of 1200,40 actually provides 30 1200-byte slots
+** and 93 128-byte slots, which is more lookaside than is available
+** using the older 1200,100 configuration without two-size-lookaside.
*/
#ifndef SQLITE_DEFAULT_LOOKASIDE
-# define SQLITE_DEFAULT_LOOKASIDE 1200,100
+# ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+# define SQLITE_DEFAULT_LOOKASIDE 1200,100 /* 120KB of memory */
+# else
+# define SQLITE_DEFAULT_LOOKASIDE 1200,40 /* 48KB of memory */
+# endif
#endif
@@ -20017,7 +20574,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
- 0, /* bInternalFunctions */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
0, /* iPrngSeed */
@@ -20127,7 +20683,8 @@ SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY";
** "explain" P4 display logic is enabled.
*/
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
- || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
+ || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) \
+ || defined(SQLITE_ENABLE_BYTECODE_VTAB)
# define VDBE_DISPLAY_P4 1
#else
# define VDBE_DISPLAY_P4 0
@@ -20382,7 +20939,8 @@ struct sqlite3_value {
** True if Mem X is a NULL-nochng type.
*/
#define MemNullNochng(X) \
- ((X)->flags==(MEM_Null|MEM_Zero) && (X)->n==0 && (X)->u.nZero==0)
+ (((X)->flags&MEM_TypeMask)==(MEM_Null|MEM_Zero) \
+ && (X)->n==0 && (X)->u.nZero==0)
/*
** Return true if a memory cell is not marked as invalid. This macro
@@ -20513,9 +21071,9 @@ struct Vdbe {
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
+ u8 doingRerun; /* True if rerunning after an auto-reprepare */
bft expired:2; /* 1: recompile VM immediately 2: when convenient */
bft explain:2; /* True if EXPLAIN present on SQL command */
- bft doingRerun:1; /* True if rerunning after an auto-reprepare */
bft changeCntOn:1; /* True to update the change-counter */
bft runOnlyOnce:1; /* Automatically expire on reset */
bft usesStmtJournal:1; /* True if uses a statement journal */
@@ -20578,6 +21136,7 @@ struct PreUpdate {
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
+SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
@@ -20590,7 +21149,14 @@ int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
-#ifndef SQLITE_OMIT_EXPLAIN
+#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
+SQLITE_PRIVATE int sqlite3VdbeNextOpcode(Vdbe*,Mem*,int,int*,int*,Op**);
+SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3*,Op*);
+#endif
+#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS)
+SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(sqlite3*,const Op*,const char*);
+#endif
+#if !defined(SQLITE_OMIT_EXPLAIN)
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
#endif
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
@@ -20624,14 +21190,15 @@ SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull);
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
-SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
+SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
#endif
-#ifndef SQLITE_OMIT_EXPLAIN
+#if !defined(SQLITE_OMIT_EXPLAIN) || defined(SQLITE_ENABLE_BYTECODE_VTAB)
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
#endif
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
@@ -20690,7 +21257,7 @@ SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*);
-SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
+SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr);
#endif
#ifndef SQLITE_OMIT_UTF16
SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
@@ -20882,6 +21449,10 @@ static u32 countLookasideSlots(LookasideSlot *p){
SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
u32 nInit = countLookasideSlots(db->lookaside.pInit);
u32 nFree = countLookasideSlots(db->lookaside.pFree);
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ nInit += countLookasideSlots(db->lookaside.pSmallInit);
+ nFree += countLookasideSlots(db->lookaside.pSmallFree);
+#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
return db->lookaside.nSlot - (nInit+nFree);
}
@@ -20914,6 +21485,15 @@ SQLITE_API int sqlite3_db_status(
db->lookaside.pInit = db->lookaside.pFree;
db->lookaside.pFree = 0;
}
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ p = db->lookaside.pSmallFree;
+ if( p ){
+ while( p->pNext ) p = p->pNext;
+ p->pNext = db->lookaside.pSmallInit;
+ db->lookaside.pSmallInit = db->lookaside.pSmallFree;
+ db->lookaside.pSmallFree = 0;
+ }
+#endif
}
break;
}
@@ -21698,12 +22278,12 @@ static const struct {
double rLimit; /* Maximum NNN value for this transform */
double rXform; /* Constant used for this transform */
} aXformType[] = {
- { 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) },
- { 0, 6, "minute", 7737817680.0, 86400000.0/(24.0*60.0) },
- { 0, 4, "hour", 128963628.0, 86400000.0/24.0 },
- { 0, 3, "day", 5373485.0, 86400000.0 },
- { 1, 5, "month", 176546.0, 30.0*86400000.0 },
- { 2, 4, "year", 14713.0, 365.0*86400000.0 },
+ { 0, 6, "second", 464269060800.0, 1000.0 },
+ { 0, 6, "minute", 7737817680.0, 60000.0 },
+ { 0, 4, "hour", 128963628.0, 3600000.0 },
+ { 0, 3, "day", 5373485.0, 86400000.0 },
+ { 1, 5, "month", 176546.0, 2592000000.0 },
+ { 2, 4, "year", 14713.0, 31536000000.0 },
};
/*
@@ -21765,7 +22345,7 @@ static int parseModifier(
r = p->s*1000.0 + 210866760000000.0;
if( r>=0.0 && r<464269060800000.0 ){
clearYMD_HMS_TZ(p);
- p->iJD = (sqlite3_int64)r;
+ p->iJD = (sqlite3_int64)(r + 0.5);
p->validJD = 1;
p->rawS = 0;
rc = 0;
@@ -22544,7 +23124,7 @@ SQLITE_PRIVATE int sqlite3OsOpen(
** down into the VFS layer. Some SQLITE_OPEN_ flags (for example,
** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
** reaching the VFS. */
- rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x87f7f, pFlagsOut);
+ rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut);
assert( rc==SQLITE_OK || pFile->pMethods==0 );
return rc;
}
@@ -25263,6 +25843,7 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){
GLOBAL(int, mutexIsInit) = 1;
#endif
+ sqlite3MemoryBarrier();
return rc;
}
@@ -26062,7 +26643,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
+** counters for x86 and x86_64 class CPUs.
*/
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
@@ -26073,8 +26654,9 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
** processor and returns that value. This can be used for high-res
** profiling.
*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
+#if !defined(__STRICT_ANSI__) && \
+ (defined(__GNUC__) || defined(_MSC_VER)) && \
+ (defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(__GNUC__)
@@ -26095,7 +26677,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
#endif
-#elif (defined(__GNUC__) && defined(__x86_64__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long val;
@@ -26103,7 +26685,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
return val;
}
-#elif (defined(__GNUC__) && defined(__ppc__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long long retval;
@@ -26120,14 +26702,13 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
#else
- #error Need implementation of sqlite3Hwtime() for your platform.
-
/*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
+ ** asm() is needed for hardware timing support. Without asm(),
+ ** disable the sqlite3Hwtime() routine.
+ **
+ ** sqlite3Hwtime() is only used for some obscure debugging
+ ** and analysis configurations, not in any deliverable, so this
+ ** should not be a great loss.
*/
SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
@@ -26712,18 +27293,26 @@ SQLITE_API int sqlite3_release_memory(int n){
}
/*
+** Default value of the hard heap limit. 0 means "no limit".
+*/
+#ifndef SQLITE_MAX_MEMORY
+# define SQLITE_MAX_MEMORY 0
+#endif
+
+/*
** State information local to the memory allocation subsystem.
*/
static SQLITE_WSD struct Mem0Global {
sqlite3_mutex *mutex; /* Mutex to serialize access */
sqlite3_int64 alarmThreshold; /* The soft heap limit */
+ sqlite3_int64 hardLimit; /* The hard upper bound on memory */
/*
** True if heap is nearly "full" where "full" is defined by the
** sqlite3_soft_heap_limit() setting.
*/
int nearlyFull;
-} mem0 = { 0, 0, 0 };
+} mem0 = { 0, SQLITE_MAX_MEMORY, SQLITE_MAX_MEMORY, 0 };
#define mem0 GLOBAL(struct Mem0Global, mem0)
@@ -26753,8 +27342,15 @@ SQLITE_API int sqlite3_memory_alarm(
#endif
/*
-** Set the soft heap-size limit for the library. Passing a zero or
-** negative value indicates no limit.
+** Set the soft heap-size limit for the library. An argument of
+** zero disables the limit. A negative argument is a no-op used to
+** obtain the return value.
+**
+** The return value is the value of the heap limit just before this
+** interface was called.
+**
+** If the hard heap limit is enabled, then the soft heap limit cannot
+** be disabled nor raised above the hard heap limit.
*/
SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
@@ -26770,9 +27366,12 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_mutex_leave(mem0.mutex);
return priorLimit;
}
+ if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){
+ n = mem0.hardLimit;
+ }
mem0.alarmThreshold = n;
nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
- mem0.nearlyFull = (n>0 && n<=nUsed);
+ AtomicStore(&mem0.nearlyFull, n>0 && n<=nUsed);
sqlite3_mutex_leave(mem0.mutex);
excess = sqlite3_memory_used() - n;
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
@@ -26784,6 +27383,37 @@ SQLITE_API void sqlite3_soft_heap_limit(int n){
}
/*
+** Set the hard heap-size limit for the library. An argument of zero
+** disables the hard heap limit. A negative argument is a no-op used
+** to obtain the return value without affecting the hard heap limit.
+**
+** The return value is the value of the hard heap limit just prior to
+** calling this interface.
+**
+** Setting the hard heap limit will also activate the soft heap limit
+** and constrain the soft heap limit to be no more than the hard heap
+** limit.
+*/
+SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){
+ sqlite3_int64 priorLimit;
+#ifndef SQLITE_OMIT_AUTOINIT
+ int rc = sqlite3_initialize();
+ if( rc ) return -1;
+#endif
+ sqlite3_mutex_enter(mem0.mutex);
+ priorLimit = mem0.hardLimit;
+ if( n>=0 ){
+ mem0.hardLimit = n;
+ if( n<mem0.alarmThreshold || mem0.alarmThreshold==0 ){
+ mem0.alarmThreshold = n;
+ }
+ }
+ sqlite3_mutex_leave(mem0.mutex);
+ return priorLimit;
+}
+
+
+/*
** Initialize the memory allocation subsystem.
*/
SQLITE_PRIVATE int sqlite3MallocInit(void){
@@ -26809,7 +27439,7 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){
** sqlite3_soft_heap_limit().
*/
SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){
- return mem0.nearlyFull;
+ return AtomicLoad(&mem0.nearlyFull);
}
/*
@@ -26869,21 +27499,21 @@ static void mallocWithAlarm(int n, void **pp){
** following xRoundup() call. */
nFull = sqlite3GlobalConfig.m.xRoundup(n);
-#ifdef SQLITE_MAX_MEMORY
- if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nFull>SQLITE_MAX_MEMORY ){
- *pp = 0;
- return;
- }
-#endif
-
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n);
if( mem0.alarmThreshold>0 ){
sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
if( nUsed >= mem0.alarmThreshold - nFull ){
- mem0.nearlyFull = 1;
+ AtomicStore(&mem0.nearlyFull, 1);
sqlite3MallocAlarm(nFull);
+ if( mem0.hardLimit ){
+ nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+ if( nUsed >= mem0.hardLimit - nFull ){
+ *pp = 0;
+ return;
+ }
+ }
}else{
- mem0.nearlyFull = 0;
+ AtomicStore(&mem0.nearlyFull, 0);
}
}
p = sqlite3GlobalConfig.m.xMalloc(nFull);
@@ -26962,10 +27592,17 @@ SQLITE_PRIVATE int sqlite3MallocSize(void *p){
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return sqlite3GlobalConfig.m.xSize(p);
}
+static int lookasideMallocSize(sqlite3 *db, void *p){
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ return p<db->lookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL;
+#else
+ return db->lookaside.szTrue;
+#endif
+}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( p!=0 );
- if( db==0 || !isLookaside(db,p) ){
#ifdef SQLITE_DEBUG
+ if( db==0 || !isLookaside(db,p) ){
if( db==0 ){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
@@ -26973,12 +27610,23 @@ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
}
+ }
#endif
- return sqlite3GlobalConfig.m.xSize(p);
- }else{
- assert( sqlite3_mutex_held(db->mutex) );
- return db->lookaside.sz;
+ if( db ){
+ if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){
+ assert( sqlite3_mutex_held(db->mutex) );
+ return LOOKASIDE_SMALL;
+ }
+#endif
+ if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
+ assert( sqlite3_mutex_held(db->mutex) );
+ return db->lookaside.szTrue;
+ }
+ }
}
+ return sqlite3GlobalConfig.m.xSize(p);
}
SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
@@ -27025,15 +27673,27 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
measureAllocationSize(db, p);
return;
}
- if( isLookaside(db, p) ){
- LookasideSlot *pBuf = (LookasideSlot*)p;
+ if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){
+ LookasideSlot *pBuf = (LookasideSlot*)p;
#ifdef SQLITE_DEBUG
- /* Trash all content in the buffer being freed */
- memset(p, 0xaa, db->lookaside.sz);
+ memset(p, 0xaa, LOOKASIDE_SMALL); /* Trash freed content */
#endif
- pBuf->pNext = db->lookaside.pFree;
- db->lookaside.pFree = pBuf;
- return;
+ pBuf->pNext = db->lookaside.pSmallFree;
+ db->lookaside.pSmallFree = pBuf;
+ return;
+ }
+#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
+ if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
+ LookasideSlot *pBuf = (LookasideSlot*)p;
+#ifdef SQLITE_DEBUG
+ memset(p, 0xaa, db->lookaside.szTrue); /* Trash freed content */
+#endif
+ pBuf->pNext = db->lookaside.pFree;
+ db->lookaside.pFree = pBuf;
+ return;
+ }
}
}
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
@@ -27082,10 +27742,12 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
sqlite3MallocAlarm(nDiff);
}
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
if( pNew==0 && mem0.alarmThreshold>0 ){
sqlite3MallocAlarm((int)nBytes);
pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
}
+#endif
if( pNew ){
nNew = sqlite3MallocSize(pNew);
sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
@@ -27189,23 +27851,37 @@ SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
assert( db!=0 );
assert( sqlite3_mutex_held(db->mutex) );
assert( db->pnBytesFreed==0 );
- if( db->lookaside.bDisable==0 ){
- assert( db->mallocFailed==0 );
- if( n>db->lookaside.sz ){
- db->lookaside.anStat[1]++;
- }else if( (pBuf = db->lookaside.pFree)!=0 ){
- db->lookaside.pFree = pBuf->pNext;
+ if( n>db->lookaside.sz ){
+ if( !db->lookaside.bDisable ){
+ db->lookaside.anStat[1]++;
+ }else if( db->mallocFailed ){
+ return 0;
+ }
+ return dbMallocRawFinish(db, n);
+ }
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ if( n<=LOOKASIDE_SMALL ){
+ if( (pBuf = db->lookaside.pSmallFree)!=0 ){
+ db->lookaside.pSmallFree = pBuf->pNext;
db->lookaside.anStat[0]++;
return (void*)pBuf;
- }else if( (pBuf = db->lookaside.pInit)!=0 ){
- db->lookaside.pInit = pBuf->pNext;
+ }else if( (pBuf = db->lookaside.pSmallInit)!=0 ){
+ db->lookaside.pSmallInit = pBuf->pNext;
db->lookaside.anStat[0]++;
return (void*)pBuf;
- }else{
- db->lookaside.anStat[2]++;
}
- }else if( db->mallocFailed ){
- return 0;
+ }
+#endif
+ if( (pBuf = db->lookaside.pFree)!=0 ){
+ db->lookaside.pFree = pBuf->pNext;
+ db->lookaside.anStat[0]++;
+ return (void*)pBuf;
+ }else if( (pBuf = db->lookaside.pInit)!=0 ){
+ db->lookaside.pInit = pBuf->pNext;
+ db->lookaside.anStat[0]++;
+ return (void*)pBuf;
+ }else{
+ db->lookaside.anStat[2]++;
}
#else
assert( db!=0 );
@@ -27229,7 +27905,16 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
assert( db!=0 );
if( p==0 ) return sqlite3DbMallocRawNN(db, n);
assert( sqlite3_mutex_held(db->mutex) );
- if( isLookaside(db,p) && n<=db->lookaside.sz ) return p;
+ if( ((uptr)p)<(uptr)db->lookaside.pEnd ){
+#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
+ if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){
+ if( n<=LOOKASIDE_SMALL ) return p;
+ }else
+#endif
+ if( ((uptr)p)>=(uptr)db->lookaside.pStart ){
+ if( n<=db->lookaside.szTrue ) return p;
+ }
+ }
return dbReallocFinish(db, p, n);
}
static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
@@ -27240,14 +27925,14 @@ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){
if( isLookaside(db, p) ){
pNew = sqlite3DbMallocRawNN(db, n);
if( pNew ){
- memcpy(pNew, p, db->lookaside.sz);
+ memcpy(pNew, p, lookasideMallocSize(db, p));
sqlite3DbFree(db, p);
}
}else{
assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- pNew = sqlite3_realloc64(p, n);
+ pNew = sqlite3Realloc(p, n);
if( !pNew ){
sqlite3OomFault(db);
}
@@ -27337,9 +28022,9 @@ SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
if( db->mallocFailed==0 && db->bBenignMalloc==0 ){
db->mallocFailed = 1;
if( db->nVdbeExec>0 ){
- db->u1.isInterrupted = 1;
+ AtomicStore(&db->u1.isInterrupted, 1);
}
- db->lookaside.bDisable++;
+ DisableLookaside;
if( db->pParse ){
db->pParse->rc = SQLITE_NOMEM_BKPT;
}
@@ -27356,9 +28041,9 @@ SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){
SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){
if( db->mallocFailed && db->nVdbeExec==0 ){
db->mallocFailed = 0;
- db->u1.isInterrupted = 0;
+ AtomicStore(&db->u1.isInterrupted, 0);
assert( db->lookaside.bDisable>0 );
- db->lookaside.bDisable--;
+ EnableLookaside;
}
}
@@ -27595,6 +28280,13 @@ static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
/*
+** Hard limit on the precision of floating-point conversions.
+*/
+#ifndef SQLITE_PRINTF_PRECISION_LIMIT
+# define SQLITE_FP_PRECISION_LIMIT 100000000
+#endif
+
+/*
** Render a string given by "fmt" into the StrAccum object.
*/
SQLITE_API void sqlite3_str_vappendf(
@@ -27794,6 +28486,8 @@ SQLITE_API void sqlite3_str_vappendf(
** xtype The class of the conversion.
** infop Pointer to the appropriate info struct.
*/
+ assert( width>=0 );
+ assert( precision>=(-1) );
switch( xtype ){
case etPOINTER:
flag_long = sizeof(char*)==sizeof(i64) ? 2 :
@@ -27915,6 +28609,11 @@ SQLITE_API void sqlite3_str_vappendf(
length = 0;
#else
if( precision<0 ) precision = 6; /* Set default precision */
+#ifdef SQLITE_FP_PRECISION_LIMIT
+ if( precision>SQLITE_FP_PRECISION_LIMIT ){
+ precision = SQLITE_FP_PRECISION_LIMIT;
+ }
+#endif
if( realvalue<0.0 ){
realvalue = -realvalue;
prefix = '-';
@@ -28197,7 +28896,7 @@ SQLITE_API void sqlite3_str_vappendf(
}
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
- /* For %q, %Q, and %w, the precision is the number of byte (or
+ /* For %q, %Q, and %w, the precision is the number of bytes (or
** characters if the ! flags is present) to use from the input.
** Because of the extra quoting characters inserted, the number
** of output characters may be larger than the precision.
@@ -28324,7 +29023,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
if( p->db ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
- zNew = sqlite3_realloc64(zOld, p->nAlloc);
+ zNew = sqlite3Realloc(zOld, p->nAlloc);
}
if( zNew ){
assert( p->zText!=0 || p->nChar==0 );
@@ -28666,7 +29365,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
va_list ap;
StrAccum acc;
- char zBuf[500];
+ char zBuf[SQLITE_PRINT_BUF_SIZE*10];
sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
va_start(ap,zFormat);
sqlite3_str_vappendf(&acc, zFormat, ap);
@@ -28766,7 +29465,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
va_start(ap, zFormat);
sqlite3_str_vappendf(&acc, zFormat, ap);
va_end(ap);
- assert( acc.nChar>0 );
+ assert( acc.nChar>0 || acc.accError );
sqlite3_str_append(&acc, "\n", 1);
}
sqlite3StrAccumFinish(&acc);
@@ -28806,7 +29505,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
char cSep = '(';
int j;
for(j=0; j<pCte->pCols->nExpr; j++){
- sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
+ sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName);
cSep = ',';
}
sqlite3_str_appendf(&x, ")");
@@ -28831,15 +29530,15 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
StrAccum x;
char zLine[100];
sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
- sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
+ sqlite3_str_appendf(&x, "{%d:*}", pItem->iCursor);
if( pItem->zDatabase ){
sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
}else if( pItem->zName ){
sqlite3_str_appendf(&x, " %s", pItem->zName);
}
if( pItem->pTab ){
- sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
- pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
+ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
+ pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
}
if( pItem->zAlias ){
sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
@@ -28847,6 +29546,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
if( pItem->fg.jointype & JT_LEFT ){
sqlite3_str_appendf(&x, " LEFT-JOIN");
}
+ if( pItem->fg.fromDDL ){
+ sqlite3_str_appendf(&x, " DDL");
+ }
sqlite3StrAccumFinish(&x);
sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
if( pItem->pSelect ){
@@ -29095,22 +29797,28 @@ SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin,
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
const char *zBinOp = 0; /* Binary operator */
const char *zUniOp = 0; /* Unary operator */
- char zFlgs[60];
+ char zFlgs[200];
pView = sqlite3TreeViewPush(pView, moreToFollow);
if( pExpr==0 ){
sqlite3TreeViewLine(pView, "nil");
sqlite3TreeViewPop(pView);
return;
}
- if( pExpr->flags || pExpr->affExpr ){
+ if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
+ StrAccum x;
+ sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
+ sqlite3_str_appendf(&x, " fg.af=%x.%c",
+ pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
if( ExprHasProperty(pExpr, EP_FromJoin) ){
- sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c iRJT=%d",
- pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n',
- pExpr->iRightJoinTable);
- }else{
- sqlite3_snprintf(sizeof(zFlgs),zFlgs," fg.af=%x.%c",
- pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
+ sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
+ }
+ if( ExprHasProperty(pExpr, EP_FromDDL) ){
+ sqlite3_str_appendf(&x, " DDL");
+ }
+ if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
+ sqlite3_str_appendf(&x, " IMMUTABLE");
}
+ sqlite3StrAccumFinish(&x);
}else{
zFlgs[0] = 0;
}
@@ -29123,10 +29831,18 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
case TK_COLUMN: {
if( pExpr->iTable<0 ){
/* This only happens when coding check constraints */
- sqlite3TreeViewLine(pView, "COLUMN(%d)%s", pExpr->iColumn, zFlgs);
+ char zOp2[16];
+ if( pExpr->op2 ){
+ sqlite3_snprintf(sizeof(zOp2),zOp2," op2=0x%02x",pExpr->op2);
+ }else{
+ zOp2[0] = 0;
+ }
+ sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s",
+ pExpr->iColumn, zFlgs, zOp2);
}else{
- sqlite3TreeViewLine(pView, "{%d:%d}%s",
- pExpr->iTable, pExpr->iColumn, zFlgs);
+ sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s",
+ pExpr->iTable, pExpr->iColumn,
+ pExpr->y.pTab, zFlgs);
}
if( ExprHasProperty(pExpr, EP_FixedCol) ){
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
@@ -29208,6 +29924,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
case TK_RSHIFT: zBinOp = "RSHIFT"; break;
case TK_CONCAT: zBinOp = "CONCAT"; break;
case TK_DOT: zBinOp = "DOT"; break;
+ case TK_LIMIT: zBinOp = "LIMIT"; break;
case TK_UMINUS: zUniOp = "UMINUS"; break;
case TK_UPLUS: zUniOp = "UPLUS"; break;
@@ -29258,14 +29975,26 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
}else{
pFarg = pExpr->x.pList;
#ifndef SQLITE_OMIT_WINDOWFUNC
- pWin = pExpr->y.pWin;
+ pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0;
#else
pWin = 0;
#endif
}
if( pExpr->op==TK_AGG_FUNCTION ){
- sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s",
- pExpr->op2, pExpr->u.zToken, zFlgs);
+ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s iAgg=%d agg=%p",
+ pExpr->op2, pExpr->u.zToken, zFlgs,
+ pExpr->iAgg, pExpr->pAggInfo);
+ }else if( pExpr->op2!=0 ){
+ const char *zOp2;
+ char zBuf[8];
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2);
+ zOp2 = zBuf;
+ if( pExpr->op2==NC_IsCheck ) zOp2 = "NC_IsCheck";
+ if( pExpr->op2==NC_IdxExpr ) zOp2 = "NC_IdxExpr";
+ if( pExpr->op2==NC_PartIdx ) zOp2 = "NC_PartIdx";
+ if( pExpr->op2==NC_GenCol ) zOp2 = "NC_GenCol";
+ sqlite3TreeViewLine(pView, "FUNCTION %Q%s op2=%s",
+ pExpr->u.zToken, zFlgs, zOp2);
}else{
sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs);
}
@@ -29361,7 +30090,9 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
break;
}
case TK_VECTOR: {
- sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR");
+ char *z = sqlite3_mprintf("VECTOR%s",zFlgs);
+ sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z);
+ sqlite3_free(z);
break;
}
case TK_SELECT_COLUMN: {
@@ -29407,8 +30138,9 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nExpr; i++){
int j = pList->a[i].u.x.iOrderByCol;
- char *zName = pList->a[i].zName;
+ char *zName = pList->a[i].zEName;
int moreToFollow = i<pList->nExpr - 1;
+ if( pList->a[i].eEName!=ENAME_NAME ) zName = 0;
if( j || zName ){
sqlite3TreeViewPush(pView, moreToFollow);
moreToFollow = 0;
@@ -29965,26 +30697,6 @@ static const unsigned char sqlite3Utf8Trans1[] = {
} \
}
-#define READ_UTF16LE(zIn, TERM, c){ \
- c = (*zIn++); \
- c += ((*zIn++)<<8); \
- if( c>=0xD800 && c<0xE000 && TERM ){ \
- int c2 = (*zIn++); \
- c2 += ((*zIn++)<<8); \
- c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
- } \
-}
-
-#define READ_UTF16BE(zIn, TERM, c){ \
- c = ((*zIn++)<<8); \
- c += (*zIn++); \
- if( c>=0xD800 && c<0xE000 && TERM ){ \
- int c2 = ((*zIn++)<<8); \
- c2 += (*zIn++); \
- c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
- } \
-}
-
/*
** Translate a single UTF-8 character. Return the unicode value.
**
@@ -30075,9 +30787,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
{
- char zBuf[100];
- sqlite3VdbeMemPrettyPrint(pMem, zBuf);
- fprintf(stderr, "INPUT: %s\n", zBuf);
+ StrAccum acc;
+ char zBuf[1000];
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ sqlite3VdbeMemPrettyPrint(pMem, &acc);
+ fprintf(stderr, "INPUT: %s\n", sqlite3StrAccumFinish(&acc));
}
#endif
@@ -30159,13 +30873,59 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
if( pMem->enc==SQLITE_UTF16LE ){
/* UTF-16 Little-endian -> UTF-8 */
while( zIn<zTerm ){
- READ_UTF16LE(zIn, zIn<zTerm, c);
+ c = *(zIn++);
+ c += (*(zIn++))<<8;
+ if( c>=0xd800 && c<0xe000 ){
+#ifdef SQLITE_REPLACE_INVALID_UTF
+ if( c>=0xdc00 || zIn>=zTerm ){
+ c = 0xfffd;
+ }else{
+ int c2 = *(zIn++);
+ c2 += (*(zIn++))<<8;
+ if( c2<0xdc00 || c2>=0xe000 ){
+ zIn -= 2;
+ c = 0xfffd;
+ }else{
+ c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
+ }
+ }
+#else
+ if( zIn<zTerm ){
+ int c2 = (*zIn++);
+ c2 += ((*zIn++)<<8);
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
+ }
+#endif
+ }
WRITE_UTF8(z, c);
}
}else{
/* UTF-16 Big-endian -> UTF-8 */
while( zIn<zTerm ){
- READ_UTF16BE(zIn, zIn<zTerm, c);
+ c = (*(zIn++))<<8;
+ c += *(zIn++);
+ if( c>=0xd800 && c<0xe000 ){
+#ifdef SQLITE_REPLACE_INVALID_UTF
+ if( c>=0xdc00 || zIn>=zTerm ){
+ c = 0xfffd;
+ }else{
+ int c2 = (*(zIn++))<<8;
+ c2 += *(zIn++);
+ if( c2<0xdc00 || c2>=0xe000 ){
+ zIn -= 2;
+ c = 0xfffd;
+ }else{
+ c = ((c&0x3ff)<<10) + (c2&0x3ff) + 0x10000;
+ }
+ }
+#else
+ if( zIn<zTerm ){
+ int c2 = ((*zIn++)<<8);
+ c2 += (*zIn++);
+ c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10);
+ }
+#endif
+ }
WRITE_UTF8(z, c);
}
}
@@ -30185,9 +30945,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desired
translate_out:
#if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
{
- char zBuf[100];
- sqlite3VdbeMemPrettyPrint(pMem, zBuf);
- fprintf(stderr, "OUTPUT: %s\n", zBuf);
+ StrAccum acc;
+ char zBuf[1000];
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ sqlite3VdbeMemPrettyPrint(pMem, &acc);
+ fprintf(stderr, "OUTPUT: %s\n", sqlite3StrAccumFinish(&acc));
}
#endif
return SQLITE_OK;
@@ -30322,18 +31084,15 @@ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){
unsigned char const *z = zIn;
int n = 0;
- if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
- while( n<nChar ){
- READ_UTF16BE(z, 1, c);
- n++;
- }
- }else{
- while( n<nChar ){
- READ_UTF16LE(z, 1, c);
- n++;
- }
+ if( SQLITE_UTF16NATIVE==SQLITE_UTF16LE ) z++;
+ while( n<nChar ){
+ c = z[0];
+ z += 2;
+ if( c>=0xd8 && c<0xdc && z[0]>=0xdc && z[0]<0xe0 ) z += 2;
+ n++;
}
- return (int)(z-(unsigned char const *)zIn);
+ return (int)(z-(unsigned char const *)zIn)
+ - (SQLITE_UTF16NATIVE==SQLITE_UTF16LE);
}
#if defined(SQLITE_TEST)
@@ -30363,30 +31122,6 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
assert( c==t );
assert( (z-zBuf)==n );
}
- for(i=0; i<0x00110000; i++){
- if( i>=0xD800 && i<0xE000 ) continue;
- z = zBuf;
- WRITE_UTF16LE(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- READ_UTF16LE(z, 1, c);
- assert( c==i );
- assert( (z-zBuf)==n );
- }
- for(i=0; i<0x00110000; i++){
- if( i>=0xD800 && i<0xE000 ) continue;
- z = zBuf;
- WRITE_UTF16BE(z, i);
- n = (int)(z-zBuf);
- assert( n>0 && n<=4 );
- z[0] = 0;
- z = zBuf;
- READ_UTF16BE(z, 1, c);
- assert( c==i );
- assert( (z-zBuf)==n );
- }
}
#endif /* SQLITE_TEST */
#endif /* SQLITE_OMIT_UTF16 */
@@ -30412,7 +31147,9 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
*/
/* #include "sqliteInt.h" */
/* #include <stdarg.h> */
+#ifndef SQLITE_OMIT_FLOATING_POINT
#include <math.h>
+#endif
/*
** Routine needed to support the testcase() macro.
@@ -30587,6 +31324,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
sqlite3DbFree(db, pParse->zErrMsg);
pParse->zErrMsg = zMsg;
pParse->rc = SQLITE_ERROR;
+ pParse->pWith = 0;
}
}
@@ -30710,6 +31448,19 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
}
/*
+** Compute an 8-bit hash on a string that is insensitive to case differences
+*/
+SQLITE_PRIVATE u8 sqlite3StrIHash(const char *z){
+ u8 h = 0;
+ if( z==0 ) return 0;
+ while( z[0] ){
+ h += UpperToLower[(unsigned char)z[0]];
+ z++;
+ }
+ return h;
+}
+
+/*
** Compute 10 to the E-th power. Examples: E==1 results in 10.
** E==2 results in 100. E==50 results in 1.0e50.
**
@@ -30777,10 +31528,13 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){
** returns FALSE but it still converts the prefix and writes the result
** into *pResult.
*/
+#if defined(_MSC_VER)
+#pragma warning(disable : 4756)
+#endif
SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
#ifndef SQLITE_OMIT_FLOATING_POINT
int incr;
- const char *zEnd = z + length;
+ const char *zEnd;
/* sign * significand * (10 ^ (esign * exponent)) */
int sign = 1; /* sign of significand */
i64 s = 0; /* significand */
@@ -30794,12 +31548,15 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
*pResult = 0.0; /* Default return value, in case of an error */
+ if( length==0 ) return 0;
if( enc==SQLITE_UTF8 ){
incr = 1;
+ zEnd = z + length;
}else{
int i;
incr = 2;
+ length &= ~1;
assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 );
testcase( enc==SQLITE_UTF16LE );
testcase( enc==SQLITE_UTF16BE );
@@ -30964,6 +31721,9 @@ do_atof_calc:
return !sqlite3Atoi64(z, pResult, length, enc);
#endif /* SQLITE_OMIT_FLOATING_POINT */
}
+#if defined(_MSC_VER)
+#pragma warning(default : 4756)
+#endif
/*
** Compare the 19-character string zNum against the text representation
@@ -31639,7 +32399,7 @@ SQLITE_PRIVATE u8 sqlite3HexToInt(int h){
return (u8)(h & 0xf);
}
-#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
+#if !defined(SQLITE_OMIT_BLOB_LITERAL)
/*
** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
** value. Return a pointer to its binary value. Space to hold the
@@ -31660,7 +32420,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
}
return zBlob;
}
-#endif /* !SQLITE_OMIT_BLOB_LITERAL || SQLITE_HAS_CODEC */
+#endif /* !SQLITE_OMIT_BLOB_LITERAL */
/*
** Log an error that is an API call on a connection pointer that should
@@ -32334,30 +33094,30 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 23 */ "SeekLE" OpHelp("key=r[P3@P4]"),
/* 24 */ "SeekGE" OpHelp("key=r[P3@P4]"),
/* 25 */ "SeekGT" OpHelp("key=r[P3@P4]"),
- /* 26 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
- /* 27 */ "NoConflict" OpHelp("key=r[P3@P4]"),
- /* 28 */ "NotFound" OpHelp("key=r[P3@P4]"),
- /* 29 */ "Found" OpHelp("key=r[P3@P4]"),
- /* 30 */ "SeekRowid" OpHelp("intkey=r[P3]"),
- /* 31 */ "NotExists" OpHelp("intkey=r[P3]"),
- /* 32 */ "Last" OpHelp(""),
- /* 33 */ "IfSmaller" OpHelp(""),
- /* 34 */ "SorterSort" OpHelp(""),
- /* 35 */ "Sort" OpHelp(""),
- /* 36 */ "Rewind" OpHelp(""),
- /* 37 */ "IdxLE" OpHelp("key=r[P3@P4]"),
- /* 38 */ "IdxGT" OpHelp("key=r[P3@P4]"),
- /* 39 */ "IdxLT" OpHelp("key=r[P3@P4]"),
- /* 40 */ "IdxGE" OpHelp("key=r[P3@P4]"),
- /* 41 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
- /* 42 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 26 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"),
+ /* 27 */ "IfNoHope" OpHelp("key=r[P3@P4]"),
+ /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 30 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"),
+ /* 32 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 33 */ "Last" OpHelp(""),
+ /* 34 */ "IfSmaller" OpHelp(""),
+ /* 35 */ "SorterSort" OpHelp(""),
+ /* 36 */ "Sort" OpHelp(""),
+ /* 37 */ "Rewind" OpHelp(""),
+ /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"),
+ /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"),
+ /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
/* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
/* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
- /* 45 */ "Program" OpHelp(""),
- /* 46 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 47 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
- /* 48 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
- /* 49 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
+ /* 45 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 46 */ "Program" OpHelp(""),
+ /* 47 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 48 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 49 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
/* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
/* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
/* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
@@ -32367,83 +33127,83 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
/* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
/* 58 */ "ElseNotEq" OpHelp(""),
- /* 59 */ "IncrVacuum" OpHelp(""),
- /* 60 */ "VNext" OpHelp(""),
- /* 61 */ "Init" OpHelp("Start at P2"),
- /* 62 */ "PureFunc0" OpHelp(""),
- /* 63 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 64 */ "PureFunc" OpHelp(""),
- /* 65 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 66 */ "Return" OpHelp(""),
- /* 67 */ "EndCoroutine" OpHelp(""),
- /* 68 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
- /* 69 */ "Halt" OpHelp(""),
- /* 70 */ "Integer" OpHelp("r[P2]=P1"),
- /* 71 */ "Int64" OpHelp("r[P2]=P4"),
- /* 72 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
- /* 73 */ "Null" OpHelp("r[P2..P3]=NULL"),
- /* 74 */ "SoftNull" OpHelp("r[P1]=NULL"),
- /* 75 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 76 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
- /* 77 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 78 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
- /* 79 */ "SCopy" OpHelp("r[P2]=r[P1]"),
- /* 80 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
- /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"),
- /* 82 */ "CollSeq" OpHelp(""),
- /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
- /* 84 */ "RealAffinity" OpHelp(""),
- /* 85 */ "Cast" OpHelp("affinity(r[P1])"),
- /* 86 */ "Permutation" OpHelp(""),
- /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
- /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
- /* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
- /* 90 */ "Column" OpHelp("r[P3]=PX"),
- /* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
- /* 92 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 93 */ "Count" OpHelp("r[P2]=count()"),
- /* 94 */ "ReadCookie" OpHelp(""),
- /* 95 */ "SetCookie" OpHelp(""),
- /* 96 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 97 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 98 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 99 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 100 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 101 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
- /* 102 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
- /* 103 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 104 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 105 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 106 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 107 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 108 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 109 */ "OpenDup" OpHelp(""),
- /* 110 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
- /* 111 */ "OpenAutoindex" OpHelp("nColumn=P2"),
- /* 112 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 113 */ "String8" OpHelp("r[P2]='P4'"),
- /* 114 */ "SorterOpen" OpHelp(""),
- /* 115 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
- /* 116 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
- /* 117 */ "Close" OpHelp(""),
- /* 118 */ "ColumnsUsed" OpHelp(""),
- /* 119 */ "SeekHit" OpHelp("seekHit=P2"),
- /* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
- /* 121 */ "NewRowid" OpHelp("r[P2]=rowid"),
- /* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
- /* 123 */ "Delete" OpHelp(""),
- /* 124 */ "ResetCount" OpHelp(""),
- /* 125 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
- /* 126 */ "SorterData" OpHelp("r[P2]=data"),
- /* 127 */ "RowData" OpHelp("r[P2]=data"),
- /* 128 */ "Rowid" OpHelp("r[P2]=rowid"),
- /* 129 */ "NullRow" OpHelp(""),
- /* 130 */ "SeekEnd" OpHelp(""),
+ /* 59 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
+ /* 60 */ "IncrVacuum" OpHelp(""),
+ /* 61 */ "VNext" OpHelp(""),
+ /* 62 */ "Init" OpHelp("Start at P2"),
+ /* 63 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
+ /* 64 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
+ /* 65 */ "Return" OpHelp(""),
+ /* 66 */ "EndCoroutine" OpHelp(""),
+ /* 67 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 68 */ "Halt" OpHelp(""),
+ /* 69 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 70 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 71 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 72 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 73 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 74 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 75 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 76 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 77 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 78 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 79 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
+ /* 80 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 81 */ "CollSeq" OpHelp(""),
+ /* 82 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 83 */ "RealAffinity" OpHelp(""),
+ /* 84 */ "Cast" OpHelp("affinity(r[P1])"),
+ /* 85 */ "Permutation" OpHelp(""),
+ /* 86 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
+ /* 87 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
+ /* 88 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
+ /* 89 */ "Column" OpHelp("r[P3]=PX"),
+ /* 90 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 91 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 92 */ "Count" OpHelp("r[P2]=count()"),
+ /* 93 */ "ReadCookie" OpHelp(""),
+ /* 94 */ "SetCookie" OpHelp(""),
+ /* 95 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
+ /* 96 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 97 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 98 */ "OpenDup" OpHelp(""),
+ /* 99 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 100 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 101 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 102 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 103 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
+ /* 104 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
+ /* 105 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 106 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 107 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 108 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 109 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 110 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 111 */ "SorterOpen" OpHelp(""),
+ /* 112 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
+ /* 113 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+ /* 114 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 115 */ "String8" OpHelp("r[P2]='P4'"),
+ /* 116 */ "Close" OpHelp(""),
+ /* 117 */ "ColumnsUsed" OpHelp(""),
+ /* 118 */ "SeekHit" OpHelp("seekHit=P2"),
+ /* 119 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
+ /* 120 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 121 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 122 */ "Delete" OpHelp(""),
+ /* 123 */ "ResetCount" OpHelp(""),
+ /* 124 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 125 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 126 */ "RowData" OpHelp("r[P2]=data"),
+ /* 127 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 128 */ "NullRow" OpHelp(""),
+ /* 129 */ "SeekEnd" OpHelp(""),
+ /* 130 */ "IdxInsert" OpHelp("key=r[P2]"),
/* 131 */ "SorterInsert" OpHelp("key=r[P2]"),
- /* 132 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 133 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
- /* 134 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
- /* 135 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 132 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 133 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
+ /* 134 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 135 */ "FinishSeek" OpHelp(""),
/* 136 */ "Destroy" OpHelp(""),
/* 137 */ "Clear" OpHelp(""),
/* 138 */ "ResetSorter" OpHelp(""),
@@ -32456,9 +33216,9 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 145 */ "DropTrigger" OpHelp(""),
/* 146 */ "IntegrityCk" OpHelp(""),
/* 147 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
- /* 148 */ "Real" OpHelp("r[P2]=P4"),
- /* 149 */ "Param" OpHelp(""),
- /* 150 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 148 */ "Param" OpHelp(""),
+ /* 149 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 150 */ "Real" OpHelp("r[P2]=P4"),
/* 151 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
/* 152 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
/* 153 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
@@ -32467,20 +33227,23 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 156 */ "AggValue" OpHelp("r[P3]=value N=P2"),
/* 157 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
/* 158 */ "Expire" OpHelp(""),
- /* 159 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 160 */ "VBegin" OpHelp(""),
- /* 161 */ "VCreate" OpHelp(""),
- /* 162 */ "VDestroy" OpHelp(""),
- /* 163 */ "VOpen" OpHelp(""),
- /* 164 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 165 */ "VRename" OpHelp(""),
- /* 166 */ "Pagecount" OpHelp(""),
- /* 167 */ "MaxPgcnt" OpHelp(""),
- /* 168 */ "Trace" OpHelp(""),
- /* 169 */ "CursorHint" OpHelp(""),
- /* 170 */ "Noop" OpHelp(""),
- /* 171 */ "Explain" OpHelp(""),
- /* 172 */ "Abortable" OpHelp(""),
+ /* 159 */ "CursorLock" OpHelp(""),
+ /* 160 */ "CursorUnlock" OpHelp(""),
+ /* 161 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 162 */ "VBegin" OpHelp(""),
+ /* 163 */ "VCreate" OpHelp(""),
+ /* 164 */ "VDestroy" OpHelp(""),
+ /* 165 */ "VOpen" OpHelp(""),
+ /* 166 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 167 */ "VRename" OpHelp(""),
+ /* 168 */ "Pagecount" OpHelp(""),
+ /* 169 */ "MaxPgcnt" OpHelp(""),
+ /* 170 */ "Trace" OpHelp(""),
+ /* 171 */ "CursorHint" OpHelp(""),
+ /* 172 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
+ /* 173 */ "Noop" OpHelp(""),
+ /* 174 */ "Explain" OpHelp(""),
+ /* 175 */ "Abortable" OpHelp(""),
};
return azName[i];
}
@@ -32844,7 +33607,7 @@ static pid_t randomnessPid = 0;
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
+** counters for x86 and x86_64 class CPUs.
*/
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
@@ -32855,8 +33618,9 @@ static pid_t randomnessPid = 0;
** processor and returns that value. This can be used for high-res
** profiling.
*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
+#if !defined(__STRICT_ANSI__) && \
+ (defined(__GNUC__) || defined(_MSC_VER)) && \
+ (defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(__GNUC__)
@@ -32877,7 +33641,7 @@ static pid_t randomnessPid = 0;
#endif
-#elif (defined(__GNUC__) && defined(__x86_64__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long val;
@@ -32885,7 +33649,7 @@ static pid_t randomnessPid = 0;
return val;
}
-#elif (defined(__GNUC__) && defined(__ppc__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long long retval;
@@ -32902,14 +33666,13 @@ static pid_t randomnessPid = 0;
#else
- #error Need implementation of sqlite3Hwtime() for your platform.
-
/*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
+ ** asm() is needed for hardware timing support. Without asm(),
+ ** disable the sqlite3Hwtime() routine.
+ **
+ ** sqlite3Hwtime() is only used for some obscure debugging
+ ** and analysis configurations, not in any deliverable, so this
+ ** should not be a great loss.
*/
SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
@@ -33377,7 +34140,7 @@ static int robust_open(const char *z, int f, mode_t m){
sqlite3_log(SQLITE_WARNING,
"attempt to open \"%s\" as file descriptor %d", z, fd);
fd = -1;
- if( osOpen("/dev/null", f, m)<0 ) break;
+ if( osOpen("/dev/null", O_RDONLY, m)<0 ) break;
}
if( fd>=0 ){
if( m!=0 ){
@@ -34253,8 +35016,9 @@ static int osSetPosixAdvisoryLock(
struct flock *pLock, /* The description of the lock */
unixFile *pFile /* Structure holding timeout value */
){
+ int tm = pFile->iBusyTimeout;
int rc = osFcntl(h,F_SETLK,pLock);
- while( rc<0 && pFile->iBusyTimeout>0 ){
+ while( rc<0 && tm>0 ){
/* On systems that support some kind of blocking file lock with a timeout,
** make appropriate changes here to invoke that blocking file lock. On
** generic posix, however, there is no such API. So we simply try the
@@ -34262,7 +35026,7 @@ static int osSetPosixAdvisoryLock(
** the lock is obtained. */
usleep(1000);
rc = osFcntl(h,F_SETLK,pLock);
- pFile->iBusyTimeout--;
+ tm--;
}
return rc;
}
@@ -36683,7 +37447,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
case SQLITE_FCNTL_LOCK_TIMEOUT: {
+ int iOld = pFile->iBusyTimeout;
pFile->iBusyTimeout = *(int*)pArg;
+ *(int*)pArg = iOld;
return SQLITE_OK;
}
#endif
@@ -37002,13 +37768,20 @@ static int unixShmSystemLock(
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
if( pShmNode->hShm>=0 ){
+ int res;
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
f.l_len = n;
- rc = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
- rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
+ res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile);
+ if( res==-1 ){
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY);
+#else
+ rc = SQLITE_BUSY;
+#endif
+ }
}
/* Update the global lock state and do debug tracing */
@@ -37264,10 +38037,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
if( pInode->bProcessLock==0 ){
if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT,(sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW,
+ (sStat.st_mode&0777));
}
if( pShmNode->hShm<0 ){
- pShmNode->hShm = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+ pShmNode->hShm = robust_open(zShm, O_RDONLY|O_NOFOLLOW,
+ (sStat.st_mode&0777));
if( pShmNode->hShm<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
goto shm_open_err;
@@ -37503,6 +38278,25 @@ static int unixShmLock(
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
+ /* Check that, if this to be a blocking lock, no locks that occur later
+ ** in the following list than the lock being obtained are already held:
+ **
+ ** 1. Checkpointer lock (ofst==1).
+ ** 2. Write lock (ofst==0).
+ ** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
+ **
+ ** In other words, if this is a blocking lock, none of the locks that
+ ** occur later in the above list than the lock being obtained may be
+ ** held. */
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || (
+ (ofst!=2) /* not RECOVER */
+ && (ofst!=1 || (p->exclMask|p->sharedMask)==0)
+ && (ofst!=0 || (p->exclMask|p->sharedMask)<3)
+ && (ofst<3 || (p->exclMask|p->sharedMask)<(1<<ofst))
+ ));
+#endif
+
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
sqlite3_mutex_enter(pShmNode->pShmMutex);
@@ -38617,7 +39411,7 @@ static int unixOpen(
unixFile *p = (unixFile *)pFile;
int fd = -1; /* File descriptor returned by open() */
int openFlags = 0; /* Flags to pass to open() */
- int eType = flags&0xFFFFFF00; /* Type of file to open */
+ int eType = flags&0x0FFF00; /* Type of file to open */
int noLock; /* True to omit locking primitives */
int rc = SQLITE_OK; /* Function Return Code */
int ctrlFlags = 0; /* UNIXFILE_* flags */
@@ -38727,7 +39521,7 @@ static int unixOpen(
if( isReadWrite ) openFlags |= O_RDWR;
if( isCreate ) openFlags |= O_CREAT;
if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW);
- openFlags |= (O_LARGEFILE|O_BINARY);
+ openFlags |= (O_LARGEFILE|O_BINARY|O_NOFOLLOW);
if( fd<0 ){
mode_t openMode; /* Permissions to create file with */
@@ -38945,7 +39739,8 @@ static int unixAccess(
if( flags==SQLITE_ACCESS_EXISTS ){
struct stat buf;
- *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
+ *pResOut = 0==osStat(zPath, &buf) &&
+ (!S_ISREG(buf.st_mode) || buf.st_size>0);
}else{
*pResOut = osAccess(zPath, W_OK|R_OK)==0;
}
@@ -38999,7 +39794,7 @@ static int unixFullPathname(
#else
int rc = SQLITE_OK;
int nByte;
- int nLink = 1; /* Number of symbolic links followed so far */
+ int nLink = 0; /* Number of symbolic links followed so far */
const char *zIn = zPath; /* Input path for each iteration of loop */
char *zDel = 0;
@@ -39028,10 +39823,11 @@ static int unixFullPathname(
}
if( bLink ){
+ nLink++;
if( zDel==0 ){
zDel = sqlite3_malloc(nOut);
if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
- }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
+ }else if( nLink>=SQLITE_MAX_SYMLINKS ){
rc = SQLITE_CANTOPEN_BKPT;
}
@@ -39067,6 +39863,7 @@ static int unixFullPathname(
}while( rc==SQLITE_OK );
sqlite3_free(zDel);
+ if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
return rc;
#endif /* HAVE_READLINK && HAVE_LSTAT */
}
@@ -39552,7 +40349,7 @@ static int proxyCreateUnixFile(
int fd = -1;
unixFile *pNew;
int rc = SQLITE_OK;
- int openFlags = O_RDWR | O_CREAT;
+ int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW;
sqlite3_vfs dummyVfs;
int terrno = 0;
UnixUnusedFd *pUnused = NULL;
@@ -39582,7 +40379,7 @@ static int proxyCreateUnixFile(
}
}
if( fd<0 ){
- openFlags = O_RDONLY;
+ openFlags = O_RDONLY | O_NOFOLLOW;
fd = robust_open(path, openFlags, 0);
terrno = errno;
}
@@ -39708,7 +40505,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){
goto end_breaklock;
}
/* write it out to the temporary break file */
- fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL), 0);
+ fd = robust_open(tPath, (O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW), 0);
if( fd<0 ){
sqlite3_snprintf(sizeof(errmsg), errmsg, "create failed (%d)", errno);
goto end_breaklock;
@@ -40666,7 +41463,7 @@ SQLITE_API int sqlite3_os_end(void){
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
+** counters for x86 and x86_64 class CPUs.
*/
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
@@ -40677,8 +41474,9 @@ SQLITE_API int sqlite3_os_end(void){
** processor and returns that value. This can be used for high-res
** profiling.
*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
+#if !defined(__STRICT_ANSI__) && \
+ (defined(__GNUC__) || defined(_MSC_VER)) && \
+ (defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(__GNUC__)
@@ -40699,7 +41497,7 @@ SQLITE_API int sqlite3_os_end(void){
#endif
-#elif (defined(__GNUC__) && defined(__x86_64__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long val;
@@ -40707,7 +41505,7 @@ SQLITE_API int sqlite3_os_end(void){
return val;
}
-#elif (defined(__GNUC__) && defined(__ppc__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long long retval;
@@ -40724,14 +41522,13 @@ SQLITE_API int sqlite3_os_end(void){
#else
- #error Need implementation of sqlite3Hwtime() for your platform.
-
/*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
+ ** asm() is needed for hardware timing support. Without asm(),
+ ** disable the sqlite3Hwtime() routine.
+ **
+ ** sqlite3Hwtime() is only used for some obscure debugging
+ ** and analysis configurations, not in any deliverable, so this
+ ** should not be a great loss.
*/
SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
@@ -44290,6 +45087,7 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
/* Forward references to VFS helper methods used for temporary files */
static int winGetTempname(sqlite3_vfs *, char **);
static int winIsDir(const void *);
+static BOOL winIsLongPathPrefix(const char *);
static BOOL winIsDriveLetterAndColon(const char *);
/*
@@ -46059,7 +46857,9 @@ static int winOpen(
if( isReadonly ){
pFile->ctrlFlags |= WINFILE_RDONLY;
}
- if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
+ if( (flags & SQLITE_OPEN_MAIN_DB)
+ && sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE)
+ ){
pFile->ctrlFlags |= WINFILE_PSOW;
}
pFile->lastErrno = NO_ERROR;
@@ -46270,6 +47070,17 @@ static int winAccess(
}
/*
+** Returns non-zero if the specified path name starts with the "long path"
+** prefix.
+*/
+static BOOL winIsLongPathPrefix(
+ const char *zPathname
+){
+ return ( zPathname[0]=='\\' && zPathname[1]=='\\'
+ && zPathname[2]=='?' && zPathname[3]=='\\' );
+}
+
+/*
** Returns non-zero if the specified path name starts with a drive letter
** followed by a colon character.
*/
@@ -46333,10 +47144,11 @@ static int winFullPathname(
char *zOut;
#endif
- /* If this path name begins with "/X:", where "X" is any alphabetic
- ** character, discard the initial "/" from the pathname.
+ /* If this path name begins with "/X:" or "\\?\", where "X" is any
+ ** alphabetic character, discard the initial "/" from the pathname.
*/
- if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
+ if( zRelative[0]=='/' && (winIsDriveLetterAndColon(zRelative+1)
+ || winIsLongPathPrefix(zRelative+1)) ){
zRelative++;
}
@@ -47092,7 +47904,7 @@ static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){
}
newSz *= 2;
if( newSz>p->szMax ) newSz = p->szMax;
- pNew = sqlite3_realloc64(p->aData, newSz);
+ pNew = sqlite3Realloc(p->aData, newSz);
if( pNew==0 ) return SQLITE_NOMEM;
p->aData = pNew;
p->szAlloc = newSz;
@@ -47539,10 +48351,11 @@ SQLITE_PRIVATE int sqlite3MemdbInit(void){
sqlite3_vfs *pLower = sqlite3_vfs_find(0);
int sz = pLower->szOsFile;
memdb_vfs.pAppData = pLower;
- /* In all known configurations of SQLite, the size of a default
- ** sqlite3_file is greater than the size of a memdb sqlite3_file.
- ** Should that ever change, remove the following NEVER() */
- if( NEVER(sz<sizeof(MemFile)) ) sz = sizeof(MemFile);
+ /* The following conditional can only be true when compiled for
+ ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave
+ ** it in, to be safe, but it is marked as NO_TEST since there
+ ** is no way to reach it under most builds. */
+ if( sz<sizeof(MemFile) ) sz = sizeof(MemFile); /*NO_TEST*/
memdb_vfs.szOsFile = sz;
return sqlite3_vfs_register(&memdb_vfs, 0);
}
@@ -49299,13 +50112,15 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
}
#else
pPg = pcache1Alloc(pCache->szAlloc);
- p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
#endif
if( benignMalloc ){ sqlite3EndBenignMalloc(); }
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
pcache1EnterMutex(pCache->pGroup);
#endif
if( pPg==0 ) return 0;
+#ifndef SQLITE_PCACHE_SEPARATE_HEADER
+ p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
+#endif
p->page.pBuf = pPg;
p->page.pExtra = &p[1];
p->isBulkLocal = 0;
@@ -50306,7 +51121,7 @@ SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){
/*
** Allocate a new RowSetEntry object that is associated with the
** given RowSet. Return a pointer to the new and completely uninitialized
-** objected.
+** object.
**
** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
** routine returns NULL.
@@ -50582,7 +51397,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
if( p ){
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
- /* Only sort the current set of entiries if they need it */
+ /* Only sort the current set of entries if they need it */
p = rowSetEntrySort(p);
}
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
@@ -50804,6 +51619,11 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
/* Return the sqlite3_file object for the WAL file */
SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal);
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock);
+SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db);
+#endif
+
#endif /* ifndef SQLITE_OMIT_WAL */
#endif /* SQLITE_WAL_H */
@@ -51195,20 +52015,6 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
#define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1)
/*
-** A macro used for invoking the codec if there is one
-*/
-#ifdef SQLITE_HAS_CODEC
-# define CODEC1(P,D,N,X,E) \
- if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
-# define CODEC2(P,D,N,X,E,O) \
- if( P->xCodec==0 ){ O=(char*)D; }else \
- if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
-#else
-# define CODEC1(P,D,N,X,E) /* NO-OP */
-# define CODEC2(P,D,N,X,E,O) O=(char*)D
-#endif
-
-/*
** The maximum allowed sector size. 64KiB. If the xSectorsize() method
** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
** This could conceivably cause corruption following a power failure on
@@ -51493,12 +52299,6 @@ struct Pager {
#endif
void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
-#ifdef SQLITE_HAS_CODEC
- void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
- void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
- void (*xCodecFree)(void*); /* Destructor for the codec */
- void *pCodec; /* First argument to xCodec... methods */
-#endif
char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */
PCache *pPCache; /* Pointer to page cache object */
#ifndef SQLITE_OMIT_WAL
@@ -51625,9 +52425,6 @@ static const unsigned char aJournalMagic[] = {
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
if( pPager->fd->pMethods==0 ) return 0;
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
-#ifdef SQLITE_HAS_CODEC
- if( pPager->xCodec!=0 ) return 0;
-#endif
#ifndef SQLITE_OMIT_WAL
if( pPager->pWal ){
u32 iRead = 0;
@@ -51861,11 +52658,7 @@ static void setGetterMethod(Pager *pPager){
if( pPager->errCode ){
pPager->xGet = getPageError;
#if SQLITE_MAX_MMAP_SIZE>0
- }else if( USEFETCH(pPager)
-#ifdef SQLITE_HAS_CODEC
- && pPager->xCodec==0
-#endif
- ){
+ }else if( USEFETCH(pPager) ){
pPager->xGet = getPageMMap;
#endif /* SQLITE_MAX_MMAP_SIZE>0 */
}else{
@@ -51960,6 +52753,7 @@ static int pagerUnlockDb(Pager *pPager, int eLock){
}
IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
}
+ pPager->changeCountDone = pPager->tempFile; /* ticket fb3b3024ea238d5c */
return rc;
}
@@ -52147,6 +52941,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
len = 0;
}
zMaster[len] = '\0';
+ zMaster[len+1] = '\0';
return SQLITE_OK;
}
@@ -52680,7 +53475,6 @@ static void pager_unlock(Pager *pPager){
** code is cleared and the cache reset in the block below.
*/
assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
- pPager->changeCountDone = 0;
pPager->eState = PAGER_OPEN;
}
@@ -52944,7 +53738,6 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
&& (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
){
rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
- pPager->changeCountDone = 0;
}
pPager->eState = PAGER_READER;
pPager->setMaster = 0;
@@ -53014,35 +53807,6 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){
}
/*
-** Report the current page size and number of reserved bytes back
-** to the codec.
-*/
-#ifdef SQLITE_HAS_CODEC
-static void pagerReportSize(Pager *pPager){
- if( pPager->xCodecSizeChng ){
- pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
- (int)pPager->nReserve);
- }
-}
-#else
-# define pagerReportSize(X) /* No-op if we do not support a codec */
-#endif
-
-#ifdef SQLITE_HAS_CODEC
-/*
-** Make sure the number of reserved bits is the same in the destination
-** pager as it is in the source. This comes up when a VACUUM changes the
-** number of reserved bits to the "optimal" amount.
-*/
-SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
- if( pDest->nReserve!=pSrc->nReserve ){
- pDest->nReserve = pSrc->nReserve;
- pagerReportSize(pDest);
- }
-}
-#endif
-
-/*
** Read a single page from either the journal file (if isMainJrnl==1) or
** from the sub-journal (if isMainJrnl==0) and playback that page.
** The page begins at offset *pOffset into the file. The *pOffset
@@ -53093,11 +53857,6 @@ static int pager_playback_one_page(
char *aData; /* Temporary storage for the page */
sqlite3_file *jfd; /* The file descriptor for the journal file */
int isSynced; /* True if journal page is synced */
-#ifdef SQLITE_HAS_CODEC
- /* The jrnlEnc flag is true if Journal pages should be passed through
- ** the codec. It is false for pure in-memory journals. */
- const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
-#endif
assert( (isMainJrnl&~1)==0 ); /* isMainJrnl is 0 or 1 */
assert( (isSavepnt&~1)==0 ); /* isSavepnt is 0 or 1 */
@@ -53160,7 +53919,6 @@ static int pager_playback_one_page(
*/
if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
pPager->nReserve = ((u8*)aData)[20];
- pagerReportSize(pPager);
}
/* If the pager is in CACHEMOD state, then there must be a copy of this
@@ -53228,26 +53986,12 @@ static int pager_playback_one_page(
** is if the data was just read from an in-memory sub-journal. In that
** case it must be encrypted here before it is copied into the database
** file. */
-#ifdef SQLITE_HAS_CODEC
- if( !jrnlEnc ){
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
- rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
- }else
-#endif
rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
if( pPager->pBackup ){
-#ifdef SQLITE_HAS_CODEC
- if( jrnlEnc ){
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
- sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData);
- }else
-#endif
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
}
}else if( !isMainJrnl && pPg==0 ){
@@ -53298,11 +54042,6 @@ static int pager_playback_one_page(
if( pgno==1 ){
memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
}
-
- /* Decode the page just read from disk */
-#if SQLITE_HAS_CODEC
- if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); }
-#endif
sqlite3PcacheRelease(pPg);
}
return rc;
@@ -53383,15 +54122,16 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
if( rc!=SQLITE_OK ) goto delmaster_out;
nMasterPtr = pVfs->mxPathname+1;
- zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
+ zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 2);
if( !zMasterJournal ){
rc = SQLITE_NOMEM_BKPT;
goto delmaster_out;
}
- zMasterPtr = &zMasterJournal[nMasterJournal+1];
+ zMasterPtr = &zMasterJournal[nMasterJournal+2];
rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
if( rc!=SQLITE_OK ) goto delmaster_out;
zMasterJournal[nMasterJournal] = 0;
+ zMasterJournal[nMasterJournal+1] = 0;
zJournal = zMasterJournal;
while( (zJournal-zMasterJournal)<nMasterJournal ){
@@ -53404,9 +54144,12 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
/* One of the journals pointed to by the master journal exists.
** Open it and check if it points at the master journal. If
** so, return without deleting the master journal file.
+ ** NB: zJournal is really a MAIN_JOURNAL. But call it a
+ ** MASTER_JOURNAL here so that the VFS will not send the zJournal
+ ** name into sqlite3_database_file_object().
*/
int c;
- int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
+ int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
if( rc!=SQLITE_OK ){
goto delmaster_out;
@@ -53861,8 +54604,6 @@ static int readDbPage(PgHdr *pPg){
memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
}
}
- CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT);
-
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
@@ -54606,7 +55347,6 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
if( nReserve<0 ) nReserve = pPager->nReserve;
assert( nReserve>=0 && nReserve<1000 );
pPager->nReserve = (i16)nReserve;
- pagerReportSize(pPager);
pagerFixMaplimit(pPager);
}
return rc;
@@ -55002,11 +55742,6 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
sqlite3OsClose(pPager->fd);
sqlite3PageFree(pTmp);
sqlite3PcacheClose(pPager->pPCache);
-
-#ifdef SQLITE_HAS_CODEC
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
-#endif
-
assert( !pPager->aSavepoint && !pPager->pInJournal );
assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
@@ -55257,8 +55992,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
if( pList->pgno==1 ) pager_write_changecounter(pList);
- /* Encode the database */
- CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData);
+ pData = pList->pData;
/* Write out the page data. */
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
@@ -55347,12 +56081,6 @@ static int subjournalPage(PgHdr *pPg){
void *pData = pPg->pData;
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
-
-#if SQLITE_HAS_CODEC
- if( !pPager->subjInMemory ){
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
- }else
-#endif
pData2 = pData;
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
@@ -55548,7 +56276,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */
u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */
const char *zUri = 0; /* URI args to copy */
- int nUri = 0; /* Number of bytes of URI args at *zUri */
+ int nUriByte = 1; /* Number of bytes of URI args at *zUri */
+ int nUri = 0; /* Number of URI parameters */
/* Figure out how much space is required for each journal file-handle
** (there are two of them, the main journal and the sub-journal). */
@@ -55582,14 +56311,24 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_OK_SYMLINK ){
+ if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){
+ rc = SQLITE_CANTOPEN_SYMLINK;
+ }else{
+ rc = SQLITE_OK;
+ }
+ }
+ }
nPathname = sqlite3Strlen30(zPathname);
z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
while( *z ){
- z += sqlite3Strlen30(z)+1;
- z += sqlite3Strlen30(z)+1;
+ z += strlen(z)+1;
+ z += strlen(z)+1;
+ nUri++;
}
- nUri = (int)(&z[1] - zUri);
- assert( nUri>=0 );
+ nUriByte = (int)(&z[1] - zUri);
+ assert( nUriByte>=1 );
if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
/* This branch is taken when the journal path required by
** the database being opened will be more than pVfs->mxPathname
@@ -55614,50 +56353,111 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
** Database file handle (pVfs->szOsFile bytes)
** Sub-journal file handle (journalFileSize bytes)
** Main journal file handle (journalFileSize bytes)
+ ** Ptr back to the Pager (sizeof(Pager*) bytes)
+ ** \0\0\0\0 database prefix (4 bytes)
** Database file name (nPathname+1 bytes)
- ** Journal file name (nPathname+8+1 bytes)
+ ** URI query parameters (nUriByte bytes)
+ ** Journal filename (nPathname+8+1 bytes)
+ ** WAL filename (nPathname+4+1 bytes)
+ ** \0\0\0 terminator (3 bytes)
+ **
+ ** Some 3rd-party software, over which we have no control, depends on
+ ** the specific order of the filenames and the \0 separators between them
+ ** so that it can (for example) find the database filename given the WAL
+ ** filename without using the sqlite3_filename_database() API. This is a
+ ** misuse of SQLite and a bug in the 3rd-party software, but the 3rd-party
+ ** software is in widespread use, so we try to avoid changing the filename
+ ** order and formatting if possible. In particular, the details of the
+ ** filename format expected by 3rd-party software should be as follows:
+ **
+ ** - Main Database Path
+ ** - \0
+ ** - Multiple URI components consisting of:
+ ** - Key
+ ** - \0
+ ** - Value
+ ** - \0
+ ** - \0
+ ** - Journal Path
+ ** - \0
+ ** - WAL Path (zWALName)
+ ** - \0
+ **
+ ** The sqlite3_create_filename() interface and the databaseFilename() utility
+ ** that is used by sqlite3_filename_database() and kin also depend on the
+ ** specific formatting and order of the various filenames, so if the format
+ ** changes here, be sure to change it there as well.
*/
pPtr = (u8 *)sqlite3MallocZero(
- ROUND8(sizeof(*pPager)) + /* Pager structure */
- ROUND8(pcacheSize) + /* PCache object */
- ROUND8(pVfs->szOsFile) + /* The main db file */
- journalFileSize * 2 + /* The two journal files */
- nPathname + 1 + nUri + /* zFilename */
- nPathname + 8 + 2 /* zJournal */
+ ROUND8(sizeof(*pPager)) + /* Pager structure */
+ ROUND8(pcacheSize) + /* PCache object */
+ ROUND8(pVfs->szOsFile) + /* The main db file */
+ journalFileSize * 2 + /* The two journal files */
+ sizeof(pPager) + /* Space to hold a pointer */
+ 4 + /* Database prefix */
+ nPathname + 1 + /* database filename */
+ nUriByte + /* query parameters */
+ nPathname + 8 + 1 + /* Journal filename */
#ifndef SQLITE_OMIT_WAL
- + nPathname + 4 + 2 /* zWal */
+ nPathname + 4 + 1 + /* WAL filename */
#endif
+ 3 /* Terminator */
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
return SQLITE_NOMEM_BKPT;
}
- pPager = (Pager*)(pPtr);
- pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
- pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
- pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
- pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize);
- pPager->zFilename = (char*)(pPtr += journalFileSize);
+ pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager));
+ pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize);
+ pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile);
+ pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
+ pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize;
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
+ memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager);
+
+ /* Fill in the Pager.zFilename and pPager.zQueryParam fields */
+ pPtr += 4; /* Skip zero prefix */
+ pPager->zFilename = (char*)pPtr;
+ if( nPathname>0 ){
+ memcpy(pPtr, zPathname, nPathname); pPtr += nPathname + 1;
+ if( zUri ){
+ memcpy(pPtr, zUri, nUriByte); pPtr += nUriByte;
+ }else{
+ pPtr++;
+ }
+ }
+
+
+ /* Fill in Pager.zJournal */
+ if( nPathname>0 ){
+ pPager->zJournal = (char*)pPtr;
+ memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
+ memcpy(pPtr, "-journal",8); pPtr += 8 + 1;
+#ifdef SQLITE_ENABLE_8_3_NAMES
+ sqlite3FileSuffix3(zFilename,pPager->zJournal);
+ pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1);
+#endif
+ }else{
+ pPager->zJournal = 0;
+ }
- /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
- if( zPathname ){
- assert( nPathname>0 );
- pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri);
- memcpy(pPager->zFilename, zPathname, nPathname);
- if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
- memcpy(pPager->zJournal, zPathname, nPathname);
- memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
- sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
- pPager->zWal = &pPager->zJournal[nPathname+8+1];
- memcpy(pPager->zWal, zPathname, nPathname);
- memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
- sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
+ /* Fill in Pager.zWal */
+ if( nPathname>0 ){
+ pPager->zWal = (char*)pPtr;
+ memcpy(pPtr, zPathname, nPathname); pPtr += nPathname;
+ memcpy(pPtr, "-wal", 4); pPtr += 4 + 1;
+#ifdef SQLITE_ENABLE_8_3_NAMES
+ sqlite3FileSuffix3(zFilename, pPager->zWal);
+ pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1);
#endif
- sqlite3DbFree(0, zPathname);
+ }else{
+ pPager->zWal = 0;
}
+#endif
+
+ if( nPathname ) sqlite3DbFree(0, zPathname);
pPager->pVfs = pVfs;
pPager->vfsFlags = vfsFlags;
@@ -55706,9 +56506,9 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
}
#endif
}
- pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
+ pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0);
if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
- || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
+ || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){
vfsFlags |= SQLITE_OPEN_READONLY;
goto act_like_temp_file;
}
@@ -55815,6 +56615,19 @@ act_like_temp_file:
return SQLITE_OK;
}
+/*
+** Return the sqlite3_file for the main database given the name
+** of the corresonding WAL or Journal name as passed into
+** xOpen.
+*/
+SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){
+ Pager *pPager;
+ while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
+ zName--;
+ }
+ pPager = *(Pager**)(zName - 4 - sizeof(Pager*));
+ return pPager->fd;
+}
/*
@@ -56370,9 +57183,6 @@ static int getPageMMap(
);
assert( USEFETCH(pPager) );
-#ifdef SQLITE_HAS_CODEC
- assert( pPager->xCodec==0 );
-#endif
/* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
** allows the compiler optimizer to reuse the results of the "pgno>1"
@@ -56503,7 +57313,6 @@ SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
assert( pPg->pgno==1 );
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
pPager = pPg->pPager;
- sqlite3PagerResetLockTimeout(pPager);
sqlite3PcacheRelease(pPg);
pagerUnlockIfUnused(pPager);
}
@@ -56701,7 +57510,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
assert( pPager->journalHdr<=pPager->journalOff );
- CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
+ pData2 = pPg->pData;
cksum = pager_cksum(pPager, (u8*)pData2);
/* Even if an IO or diskfull error occurs while journalling the
@@ -57066,7 +57875,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
if( DIRECT_MODE ){
const void *zBuf;
assert( pPager->dbFileSize>0 );
- CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf);
+ zBuf = pPgHdr->pData;
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
pPager->aStat[PAGER_STAT_WRITE]++;
@@ -57399,6 +58208,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
** But if (due to a coding error elsewhere in the system) it does get
** called, just return the same error code without doing anything. */
if( NEVER(pPager->errCode) ) return pPager->errCode;
+ pPager->iDataVersion++;
assert( pPager->eState==PAGER_WRITER_LOCKED
|| pPager->eState==PAGER_WRITER_FINISHED
@@ -57427,7 +58237,6 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
}
PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
- pPager->iDataVersion++;
rc = pager_end_transaction(pPager, pPager->setMaster, 1);
return pager_error(pPager, rc);
}
@@ -57771,9 +58580,13 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
** behavior. But when the Btree needs to know the filename for matching to
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
** participate in shared-cache.
+**
+** The return value to this routine is always safe to use with
+** sqlite3_uri_parameter() and sqlite3_filename_database() and friends.
*/
-SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
- return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
+SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){
+ static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename;
}
/*
@@ -57792,16 +58605,6 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
return pPager->fd;
}
-#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
-/*
-** Reset the lock timeout for pager.
-*/
-SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){
- int x = 0;
- sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
-}
-#endif
-
/*
** Return the file handle for the journal file (if it exists).
** This will be either the rollback journal or the WAL file.
@@ -57821,54 +58624,6 @@ SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
return pPager->zJournal;
}
-#ifdef SQLITE_HAS_CODEC
-/*
-** Set or retrieve the codec for this pager
-*/
-SQLITE_PRIVATE void sqlite3PagerSetCodec(
- Pager *pPager,
- void *(*xCodec)(void*,void*,Pgno,int),
- void (*xCodecSizeChng)(void*,int,int),
- void (*xCodecFree)(void*),
- void *pCodec
-){
- if( pPager->xCodecFree ){
- pPager->xCodecFree(pPager->pCodec);
- }else{
- pager_reset(pPager);
- }
- pPager->xCodec = pPager->memDb ? 0 : xCodec;
- pPager->xCodecSizeChng = xCodecSizeChng;
- pPager->xCodecFree = xCodecFree;
- pPager->pCodec = pCodec;
- setGetterMethod(pPager);
- pagerReportSize(pPager);
-}
-SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
- return pPager->pCodec;
-}
-
-/*
-** This function is called by the wal module when writing page content
-** into the log file.
-**
-** This function returns a pointer to a buffer containing the encrypted
-** page content. If a malloc fails, this function may return NULL.
-*/
-SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
- void *aData = 0;
- CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
- return aData;
-}
-
-/*
-** Return the current pager state
-*/
-SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
- return pPager->eState;
-}
-#endif /* SQLITE_HAS_CODEC */
-
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Move the page pPg to location pgno in the file.
@@ -58263,7 +59018,6 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint(
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
- sqlite3PagerResetLockTimeout(pPager);
}
return rc;
}
@@ -58428,6 +59182,32 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
return rc;
}
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+/*
+** If pager pPager is a wal-mode database not in exclusive locking mode,
+** invoke the sqlite3WalWriteLock() function on the associated Wal object
+** with the same db and bLock parameters as were passed to this function.
+** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
+*/
+SQLITE_PRIVATE int sqlite3PagerWalWriteLock(Pager *pPager, int bLock){
+ int rc = SQLITE_OK;
+ if( pagerUseWal(pPager) && pPager->exclusiveMode==0 ){
+ rc = sqlite3WalWriteLock(pPager->pWal, bLock);
+ }
+ return rc;
+}
+
+/*
+** Set the database handle used by the wal layer to determine if
+** blocking locks are required.
+*/
+SQLITE_PRIVATE void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){
+ if( pagerUseWal(pPager) ){
+ sqlite3WalDb(pPager->pWal, db);
+ }
+}
+#endif
+
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** If this is a WAL database, obtain a snapshot handle for the snapshot
@@ -58446,7 +59226,10 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppS
** read transaction is opened, attempt to read from the snapshot it
** identifies. If this is not a WAL database, return an error.
*/
-SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){
+SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(
+ Pager *pPager,
+ sqlite3_snapshot *pSnapshot
+){
int rc = SQLITE_OK;
if( pPager->pWal ){
sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot);
@@ -58783,18 +59566,6 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0;
#endif
/*
-** WAL mode depends on atomic aligned 32-bit loads and stores in a few
-** places. The following macros try to make this explicit.
-*/
-#if GCC_VESRION>=5004000
-# define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED)
-# define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED)
-#else
-# define AtomicLoad(PTR) (*(PTR))
-# define AtomicStore(PTR,VAL) (*(PTR) = (VAL))
-#endif
-
-/*
** The maximum (and only) versions of the wal and wal-index formats
** that may be interpreted by this version of SQLite.
**
@@ -59003,6 +59774,9 @@ struct Wal {
#ifdef SQLITE_ENABLE_SNAPSHOT
WalIndexHdr *pSnapshot; /* Start transaction here if not NULL */
#endif
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ sqlite3 *db;
+#endif
};
/*
@@ -59101,7 +59875,7 @@ static SQLITE_NOINLINE int walIndexPageRealloc(
if( pWal->nWiData<=iPage ){
sqlite3_int64 nByte = sizeof(u32*)*(iPage+1);
volatile u32 **apNew;
- apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
+ apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM_BKPT;
@@ -59222,6 +59996,10 @@ static void walChecksumBytes(
aOut[1] = s2;
}
+/*
+** If there is the possibility of concurrent access to the SHM file
+** from multiple threads and/or processes, then do a memory barrier.
+*/
static void walShmBarrier(Wal *pWal){
if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
sqlite3OsShmBarrier(pWal->pDbFd);
@@ -59229,11 +60007,24 @@ static void walShmBarrier(Wal *pWal){
}
/*
+** Add the SQLITE_NO_TSAN as part of the return-type of a function
+** definition as a hint that the function contains constructs that
+** might give false-positive TSAN warnings.
+**
+** See tag-20200519-1.
+*/
+#if defined(__clang__) && !defined(SQLITE_NO_TSAN)
+# define SQLITE_NO_TSAN __attribute__((no_sanitize_thread))
+#else
+# define SQLITE_NO_TSAN
+#endif
+
+/*
** Write the header information in pWal->hdr into the wal-index.
**
** The checksum on pWal->hdr is updated before it is written.
*/
-static void walIndexWriteHdr(Wal *pWal){
+static SQLITE_NO_TSAN void walIndexWriteHdr(Wal *pWal){
volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
const int nCksum = offsetof(WalIndexHdr, aCksum);
@@ -59241,6 +60032,7 @@ static void walIndexWriteHdr(Wal *pWal){
pWal->hdr.isInit = 1;
pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
+ /* Possible TSAN false-positive. See tag-20200519-1 */
memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
walShmBarrier(pWal);
memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr));
@@ -59376,7 +60168,7 @@ static int walLockShared(Wal *pWal, int lockIdx){
SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
walLockName(lockIdx), rc ? "failed" : "ok"));
- VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
+ VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
return rc;
}
static void walUnlockShared(Wal *pWal, int lockIdx){
@@ -59392,7 +60184,7 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){
SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
walLockName(lockIdx), n, rc ? "failed" : "ok"));
- VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
+ VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); )
return rc;
}
static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
@@ -60212,6 +61004,89 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
return rc;
}
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+/*
+** Attempt to enable blocking locks. Blocking locks are enabled only if (a)
+** they are supported by the VFS, and (b) the database handle is configured
+** with a busy-timeout. Return 1 if blocking locks are successfully enabled,
+** or 0 otherwise.
+*/
+static int walEnableBlocking(Wal *pWal){
+ int res = 0;
+ if( pWal->db ){
+ int tmout = pWal->db->busyTimeout;
+ if( tmout ){
+ int rc;
+ rc = sqlite3OsFileControl(
+ pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout
+ );
+ res = (rc==SQLITE_OK);
+ }
+ }
+ return res;
+}
+
+/*
+** Disable blocking locks.
+*/
+static void walDisableBlocking(Wal *pWal){
+ int tmout = 0;
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout);
+}
+
+/*
+** If parameter bLock is true, attempt to enable blocking locks, take
+** the WRITER lock, and then disable blocking locks. If blocking locks
+** cannot be enabled, no attempt to obtain the WRITER lock is made. Return
+** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not
+** an error if blocking locks can not be enabled.
+**
+** If the bLock parameter is false and the WRITER lock is held, release it.
+*/
+SQLITE_PRIVATE int sqlite3WalWriteLock(Wal *pWal, int bLock){
+ int rc = SQLITE_OK;
+ assert( pWal->readLock<0 || bLock==0 );
+ if( bLock ){
+ assert( pWal->db );
+ if( walEnableBlocking(pWal) ){
+ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
+ if( rc==SQLITE_OK ){
+ pWal->writeLock = 1;
+ }
+ walDisableBlocking(pWal);
+ }
+ }else if( pWal->writeLock ){
+ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
+ pWal->writeLock = 0;
+ }
+ return rc;
+}
+
+/*
+** Set the database handle used to determine if blocking locks are required.
+*/
+SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){
+ pWal->db = db;
+}
+
+/*
+** Take an exclusive WRITE lock. Blocking if so configured.
+*/
+static int walLockWriter(Wal *pWal){
+ int rc;
+ walEnableBlocking(pWal);
+ rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
+ walDisableBlocking(pWal);
+ return rc;
+}
+#else
+# define walEnableBlocking(x) 0
+# define walDisableBlocking(x)
+# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1)
+# define sqlite3WalDb(pWal, db)
+#endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */
+
+
/*
** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
** n. If the attempt fails and parameter xBusy is not NULL, then it is a
@@ -60229,6 +61104,12 @@ static int walBusyLock(
do {
rc = walLockExclusive(pWal, lockIdx, n);
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ if( rc==SQLITE_BUSY_TIMEOUT ){
+ walDisableBlocking(pWal);
+ rc = SQLITE_BUSY;
+ }
+#endif
return rc;
}
@@ -60266,7 +61147,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
walIndexWriteHdr(pWal);
- pInfo->nBackfill = 0;
+ AtomicStore(&pInfo->nBackfill, 0);
pInfo->nBackfillAttempted = 0;
pInfo->aReadMark[1] = 0;
for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
@@ -60341,20 +61222,13 @@ static int walCheckpoint(
mxSafeFrame = pWal->hdr.mxFrame;
mxPage = pWal->hdr.nPage;
for(i=1; i<WAL_NREADER; i++){
- /* Thread-sanitizer reports that the following is an unsafe read,
- ** as some other thread may be in the process of updating the value
- ** of the aReadMark[] slot. The assumption here is that if that is
- ** happening, the other client may only be increasing the value,
- ** not decreasing it. So assuming either that either the "old" or
- ** "new" version of the value is read, and not some arbitrary value
- ** that would never be written by a real client, things are still
- ** safe. */
- u32 y = pInfo->aReadMark[i];
+ u32 y = AtomicLoad(pInfo->aReadMark+i);
if( mxSafeFrame>y ){
assert( y<=pWal->hdr.mxFrame );
rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
- pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
+ u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
+ AtomicStore(pInfo->aReadMark+i, iMark);
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
}else if( rc==SQLITE_BUSY ){
mxSafeFrame = y;
@@ -60372,7 +61246,7 @@ static int walCheckpoint(
}
if( pIter
- && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
+ && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK
){
u32 nBackfill = pInfo->nBackfill;
@@ -60387,6 +61261,7 @@ static int walCheckpoint(
if( rc==SQLITE_OK ){
i64 nReq = ((i64)mxPage * szPage);
i64 nSize; /* Current size of database file */
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_START, 0);
rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
if( rc==SQLITE_OK && nSize<nReq ){
sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
@@ -60398,7 +61273,7 @@ static int walCheckpoint(
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
i64 iOffset;
assert( walFramePgno(pWal, iFrame)==iDbpage );
- if( db->u1.isInterrupted ){
+ if( AtomicLoad(&db->u1.isInterrupted) ){
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
break;
}
@@ -60414,6 +61289,7 @@ static int walCheckpoint(
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
if( rc!=SQLITE_OK ) break;
}
+ sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0);
/* If work was actually accomplished... */
if( rc==SQLITE_OK ){
@@ -60426,7 +61302,7 @@ static int walCheckpoint(
}
}
if( rc==SQLITE_OK ){
- pInfo->nBackfill = mxSafeFrame;
+ AtomicStore(&pInfo->nBackfill, mxSafeFrame);
}
}
@@ -60585,7 +61461,7 @@ SQLITE_PRIVATE int sqlite3WalClose(
** If the checksum cannot be verified return non-zero. If the header
** is read successfully and the checksum verified, return zero.
*/
-static int walIndexTryHdr(Wal *pWal, int *pChanged){
+static SQLITE_NO_TSAN int walIndexTryHdr(Wal *pWal, int *pChanged){
u32 aCksum[2]; /* Checksum on the header content */
WalIndexHdr h1, h2; /* Two copies of the header content */
WalIndexHdr volatile *aHdr; /* Header in shared memory */
@@ -60598,13 +61474,19 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
** meaning it is possible that an inconsistent snapshot is read
** from the file. If this happens, return non-zero.
**
+ ** tag-20200519-1:
** There are two copies of the header at the beginning of the wal-index.
** When reading, read [0] first then [1]. Writes are in the reverse order.
** Memory barriers are used to prevent the compiler or the hardware from
- ** reordering the reads and writes.
+ ** reordering the reads and writes. TSAN and similar tools can sometimes
+ ** give false-positive warnings about these accesses because the tools do not
+ ** account for the double-read and the memory barrier. The use of mutexes
+ ** here would be problematic as the memory being accessed is potentially
+ ** shared among multiple processes and not all mutex implementions work
+ ** reliably in that environment.
*/
aHdr = walIndexHdr(pWal);
- memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
+ memcpy(&h1, (void *)&aHdr[0], sizeof(h1)); /* Possible TSAN false-positive */
walShmBarrier(pWal);
memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
@@ -60694,28 +61576,32 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
/* If the first attempt failed, it might have been due to a race
** with a writer. So get a WRITE lock and try again.
*/
- assert( badHdr==0 || pWal->writeLock==0 );
if( badHdr ){
if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
}
- }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
- pWal->writeLock = 1;
- if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
- badHdr = walIndexTryHdr(pWal, pChanged);
- if( badHdr ){
- /* If the wal-index header is still malformed even while holding
- ** a WRITE lock, it can only mean that the header is corrupted and
- ** needs to be reconstructed. So run recovery to do exactly that.
- */
- rc = walIndexRecover(pWal);
- *pChanged = 1;
+ }else{
+ int bWriteLock = pWal->writeLock;
+ if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){
+ pWal->writeLock = 1;
+ if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
+ badHdr = walIndexTryHdr(pWal, pChanged);
+ if( badHdr ){
+ /* If the wal-index header is still malformed even while holding
+ ** a WRITE lock, it can only mean that the header is corrupted and
+ ** needs to be reconstructed. So run recovery to do exactly that.
+ */
+ rc = walIndexRecover(pWal);
+ *pChanged = 1;
+ }
+ }
+ if( bWriteLock==0 ){
+ pWal->writeLock = 0;
+ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
}
}
- pWal->writeLock = 0;
- walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
}
}
@@ -61045,7 +61931,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
assert( pWal->nWiData>0 );
assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
- if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
+ if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
&& (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
#endif
@@ -61107,7 +61993,8 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
for(i=1; i<WAL_NREADER; i++){
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
- mxReadMark = AtomicStore(pInfo->aReadMark+i,mxFrame);
+ AtomicStore(pInfo->aReadMark+i,mxFrame);
+ mxReadMark = mxFrame;
mxI = i;
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
break;
@@ -61211,7 +62098,7 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
rc = SQLITE_NOMEM;
}else{
u32 i = pInfo->nBackfillAttempted;
- for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
+ for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){
WalHashLoc sLoc; /* Hash table location */
u32 pgno; /* Page number in db file */
i64 iDbOff; /* Offset of db file entry */
@@ -61266,12 +62153,35 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
int rc; /* Return code */
int cnt = 0; /* Number of TryBeginRead attempts */
-
#ifdef SQLITE_ENABLE_SNAPSHOT
int bChanged = 0;
WalIndexHdr *pSnapshot = pWal->pSnapshot;
- if( pSnapshot && memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
- bChanged = 1;
+#endif
+
+ assert( pWal->ckptLock==0 );
+
+#ifdef SQLITE_ENABLE_SNAPSHOT
+ if( pSnapshot ){
+ if( memcmp(pSnapshot, &pWal->hdr, sizeof(WalIndexHdr))!=0 ){
+ bChanged = 1;
+ }
+
+ /* It is possible that there is a checkpointer thread running
+ ** concurrent with this code. If this is the case, it may be that the
+ ** checkpointer has already determined that it will checkpoint
+ ** snapshot X, where X is later in the wal file than pSnapshot, but
+ ** has not yet set the pInfo->nBackfillAttempted variable to indicate
+ ** its intent. To avoid the race condition this leads to, ensure that
+ ** there is no checkpointer process by taking a shared CKPT lock
+ ** before checking pInfo->nBackfillAttempted. */
+ (void)walEnableBlocking(pWal);
+ rc = walLockShared(pWal, WAL_CKPT_LOCK);
+ walDisableBlocking(pWal);
+
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ pWal->ckptLock = 1;
}
#endif
@@ -61304,48 +62214,42 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
assert( pWal->readLock>0 || pWal->hdr.mxFrame==0 );
assert( pInfo->aReadMark[pWal->readLock]<=pSnapshot->mxFrame );
- /* It is possible that there is a checkpointer thread running
- ** concurrent with this code. If this is the case, it may be that the
- ** checkpointer has already determined that it will checkpoint
- ** snapshot X, where X is later in the wal file than pSnapshot, but
- ** has not yet set the pInfo->nBackfillAttempted variable to indicate
- ** its intent. To avoid the race condition this leads to, ensure that
- ** there is no checkpointer process by taking a shared CKPT lock
- ** before checking pInfo->nBackfillAttempted.
- **
- ** TODO: Does the aReadMark[] lock prevent a checkpointer from doing
- ** this already?
- */
- rc = walLockShared(pWal, WAL_CKPT_LOCK);
-
- if( rc==SQLITE_OK ){
- /* Check that the wal file has not been wrapped. Assuming that it has
- ** not, also check that no checkpointer has attempted to checkpoint any
- ** frames beyond pSnapshot->mxFrame. If either of these conditions are
- ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
- ** with *pSnapshot and set *pChanged as appropriate for opening the
- ** snapshot. */
- if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
- && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
- ){
- assert( pWal->readLock>0 );
- memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
- *pChanged = bChanged;
- }else{
- rc = SQLITE_ERROR_SNAPSHOT;
- }
-
- /* Release the shared CKPT lock obtained above. */
- walUnlockShared(pWal, WAL_CKPT_LOCK);
- pWal->minFrame = 1;
+ /* Check that the wal file has not been wrapped. Assuming that it has
+ ** not, also check that no checkpointer has attempted to checkpoint any
+ ** frames beyond pSnapshot->mxFrame. If either of these conditions are
+ ** true, return SQLITE_ERROR_SNAPSHOT. Otherwise, overwrite pWal->hdr
+ ** with *pSnapshot and set *pChanged as appropriate for opening the
+ ** snapshot. */
+ if( !memcmp(pSnapshot->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt))
+ && pSnapshot->mxFrame>=pInfo->nBackfillAttempted
+ ){
+ assert( pWal->readLock>0 );
+ memcpy(&pWal->hdr, pSnapshot, sizeof(WalIndexHdr));
+ *pChanged = bChanged;
+ }else{
+ rc = SQLITE_ERROR_SNAPSHOT;
}
+ /* A client using a non-current snapshot may not ignore any frames
+ ** from the start of the wal file. This is because, for a system
+ ** where (minFrame < iSnapshot < maxFrame), a checkpointer may
+ ** have omitted to checkpoint a frame earlier than minFrame in
+ ** the file because there exists a frame after iSnapshot that
+ ** is the same database page. */
+ pWal->minFrame = 1;
if( rc!=SQLITE_OK ){
sqlite3WalEndReadTransaction(pWal);
}
}
}
+
+ /* Release the shared CKPT lock obtained above. */
+ if( pWal->ckptLock ){
+ assert( pSnapshot );
+ walUnlockShared(pWal, WAL_CKPT_LOCK);
+ pWal->ckptLock = 0;
+ }
#endif
return rc;
}
@@ -61425,14 +62329,15 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
int iKey; /* Hash slot index */
int nCollide; /* Number of hash collisions remaining */
int rc; /* Error code */
+ u32 iH;
rc = walHashGet(pWal, iHash, &sLoc);
if( rc!=SQLITE_OK ){
return rc;
}
nCollide = HASHTABLE_NSLOT;
- for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
- u32 iH = sLoc.aHash[iKey];
+ iKey = walHash(pgno);
+ while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
u32 iFrame = iH + sLoc.iZero;
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
@@ -61441,6 +62346,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
if( (nCollide--)==0 ){
return SQLITE_CORRUPT_BKPT;
}
+ iKey = walNextHash(iKey);
}
if( iRead ) break;
}
@@ -61516,6 +62422,16 @@ SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){
SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
int rc;
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ /* If the write-lock is already held, then it was obtained before the
+ ** read-transaction was even opened, making this call a no-op.
+ ** Return early. */
+ if( pWal->writeLock ){
+ assert( !memcmp(&pWal->hdr,(void *)walIndexHdr(pWal),sizeof(WalIndexHdr)) );
+ return SQLITE_OK;
+ }
+#endif
+
/* Cannot start a write transaction without first holding a read
** transaction. */
assert( pWal->readLock>=0 );
@@ -61761,11 +62677,7 @@ static int walWriteOneFrame(
int rc; /* Result code from subfunctions */
void *pData; /* Data actually written */
u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */
-#if defined(SQLITE_HAS_CODEC)
- if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
-#else
pData = pPage->pData;
-#endif
walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
if( rc ) return rc;
@@ -61948,11 +62860,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
pWal->iReCksum = iWrite;
}
-#if defined(SQLITE_HAS_CODEC)
- if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
-#else
pData = p->pData;
-#endif
rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff);
if( rc ) return rc;
p->flags &= ~PGHDR_WAL_APPEND;
@@ -62100,45 +63008,52 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
if( pWal->readOnly ) return SQLITE_READONLY;
WALTRACE(("WAL%p: checkpoint begins\n", pWal));
+ /* Enable blocking locks, if possible. If blocking locks are successfully
+ ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */
+ sqlite3WalDb(pWal, db);
+ (void)walEnableBlocking(pWal);
+
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
- ** "checkpoint" lock on the database file. */
+ ** "checkpoint" lock on the database file.
+ ** EVIDENCE-OF: R-10421-19736 If any other process is running a
+ ** checkpoint operation at the same time, the lock cannot be obtained and
+ ** SQLITE_BUSY is returned.
+ ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
+ ** it will not be invoked in this case.
+ */
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
- if( rc ){
- /* EVIDENCE-OF: R-10421-19736 If any other process is running a
- ** checkpoint operation at the same time, the lock cannot be obtained and
- ** SQLITE_BUSY is returned.
- ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
- ** it will not be invoked in this case.
- */
- testcase( rc==SQLITE_BUSY );
- testcase( xBusy!=0 );
- return rc;
- }
- pWal->ckptLock = 1;
+ testcase( rc==SQLITE_BUSY );
+ testcase( rc!=SQLITE_OK && xBusy2!=0 );
+ if( rc==SQLITE_OK ){
+ pWal->ckptLock = 1;
- /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
- ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
- ** file.
- **
- ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
- ** immediately, and a busy-handler is configured, it is invoked and the
- ** writer lock retried until either the busy-handler returns 0 or the
- ** lock is successfully obtained.
- */
- if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
- rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
- if( rc==SQLITE_OK ){
- pWal->writeLock = 1;
- }else if( rc==SQLITE_BUSY ){
- eMode2 = SQLITE_CHECKPOINT_PASSIVE;
- xBusy2 = 0;
- rc = SQLITE_OK;
+ /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
+ ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
+ ** file.
+ **
+ ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
+ ** immediately, and a busy-handler is configured, it is invoked and the
+ ** writer lock retried until either the busy-handler returns 0 or the
+ ** lock is successfully obtained.
+ */
+ if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
+ rc = walBusyLock(pWal, xBusy2, pBusyArg, WAL_WRITE_LOCK, 1);
+ if( rc==SQLITE_OK ){
+ pWal->writeLock = 1;
+ }else if( rc==SQLITE_BUSY ){
+ eMode2 = SQLITE_CHECKPOINT_PASSIVE;
+ xBusy2 = 0;
+ rc = SQLITE_OK;
+ }
}
}
+
/* Read the wal-index header. */
if( rc==SQLITE_OK ){
+ walDisableBlocking(pWal);
rc = walIndexReadHdr(pWal, &isChanged);
+ (void)walEnableBlocking(pWal);
if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
}
@@ -62170,11 +63085,19 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
}
+ walDisableBlocking(pWal);
+ sqlite3WalDb(pWal, 0);
+
/* Release the locks. */
sqlite3WalEndWriteTransaction(pWal);
- walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
- pWal->ckptLock = 0;
+ if( pWal->ckptLock ){
+ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
+ pWal->ckptLock = 0;
+ }
WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
+#endif
return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
}
@@ -62291,7 +63214,10 @@ SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapsho
/* Try to open on pSnapshot when the next read-transaction starts
*/
-SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){
+SQLITE_PRIVATE void sqlite3WalSnapshotOpen(
+ Wal *pWal,
+ sqlite3_snapshot *pSnapshot
+){
pWal->pSnapshot = (WalIndexHdr*)pSnapshot;
}
@@ -62810,9 +63736,7 @@ struct BtShared {
#endif
u8 inTransaction; /* Transaction state */
u8 max1bytePayload; /* Maximum first byte of cell for a 1-byte payload */
-#ifdef SQLITE_HAS_CODEC
- u8 optimalReserve; /* Desired amount of reserved space per page */
-#endif
+ u8 nReserveWanted; /* Desired number of extra bytes per page */
u16 btsFlags; /* Boolean parameters. See BTS_* macros below */
u16 maxLocal; /* Maximum local payload in non-LEAFDATA tables */
u16 minLocal; /* Minimum local payload in non-LEAFDATA tables */
@@ -62935,6 +63859,7 @@ struct BtCursor {
#define BTCF_AtLast 0x08 /* Cursor is pointing ot the last entry */
#define BTCF_Incrblob 0x10 /* True if an incremental I/O handle */
#define BTCF_Multiple 0x20 /* Maybe another cursor on the same btree */
+#define BTCF_Pinned 0x40 /* Cursor is busy and cannot be moved */
/*
** Potential values for BtCursor.eState.
@@ -63078,6 +64003,7 @@ struct IntegrityCk {
int v1, v2; /* Values for up to two %d fields in zPfx */
StrAccum errMsg; /* Accumulate the error message text here */
u32 *heap; /* Min-heap used for analyzing cell coverage */
+ sqlite3 *db; /* Database connection running the check */
};
/*
@@ -64011,7 +64937,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
*/
static int btreeGetHasContent(BtShared *pBt, Pgno pgno){
Bitvec *p = pBt->pHasContent;
- return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno)));
+ return p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTestNotNull(p, pgno));
}
/*
@@ -64099,6 +65025,9 @@ static int saveCursorPosition(BtCursor *pCur){
assert( 0==pCur->pKey );
assert( cursorHoldsMutex(pCur) );
+ if( pCur->curFlags & BTCF_Pinned ){
+ return SQLITE_CONSTRAINT_PINNED;
+ }
if( pCur->eState==CURSOR_SKIPNEXT ){
pCur->eState = CURSOR_VALID;
}else{
@@ -64855,7 +65784,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
sz += sz2;
- }else if( iFree+sz>usableSize ){
+ }else if( NEVER(iFree+sz>usableSize) ){
return SQLITE_CORRUPT_PAGE(pPage);
}
@@ -65047,8 +65976,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
if( (data[hdr+2] || data[hdr+1]) && gap+2<=top ){
u8 *pSpace = pageFindSlot(pPage, nByte, &rc);
if( pSpace ){
+ int g2;
assert( pSpace+nByte<=data+pPage->pBt->usableSize );
- if( (*pIdx = (int)(pSpace-data))<=gap ){
+ *pIdx = g2 = (int)(pSpace-data);
+ if( NEVER(g2<=gap) ){
return SQLITE_CORRUPT_PAGE(pPage);
}else{
return SQLITE_OK;
@@ -65126,12 +66057,12 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
}else{
while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
if( iFreeBlk<iPtr+4 ){
- if( iFreeBlk==0 ) break;
+ if( iFreeBlk==0 ) break; /* TH3: corrupt082.100 */
return SQLITE_CORRUPT_PAGE(pPage);
}
iPtr = iFreeBlk;
}
- if( iFreeBlk>pPage->pBt->usableSize-4 ){
+ if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */
return SQLITE_CORRUPT_PAGE(pPage);
}
assert( iFreeBlk>iPtr || iFreeBlk==0 );
@@ -65146,7 +66077,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
nFrag = iFreeBlk - iEnd;
if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
- if( iEnd > pPage->pBt->usableSize ){
+ if( NEVER(iEnd > pPage->pBt->usableSize) ){
return SQLITE_CORRUPT_PAGE(pPage);
}
iSize = iEnd - iStart;
@@ -65174,7 +66105,8 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
- if( iStart<x || iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage);
+ if( iStart<x ) return SQLITE_CORRUPT_PAGE(pPage);
+ if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage);
put2byte(&data[hdr+1], iFreeBlk);
put2byte(&data[hdr+5], iEnd);
}else{
@@ -65294,7 +66226,7 @@ static int btreeComputeFreeSpace(MemPage *pPage){
nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */
if( pc>0 ){
u32 next, size;
- if( pc<iCellFirst ){
+ if( pc<top ){
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
** always be at least one cell before the first freeblock.
*/
@@ -65531,12 +66463,12 @@ static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){
** error, return ((unsigned int)-1).
*/
static Pgno btreePagecount(BtShared *pBt){
+ assert( (pBt->nPage & 0x80000000)==0 || CORRUPT_DB );
return pBt->nPage;
}
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){
assert( sqlite3BtreeHoldsMutex(p) );
- assert( ((p->pBt->nPage)&0x80000000)==0 );
- return btreePagecount(p->pBt);
+ return btreePagecount(p->pBt) & 0x7fffffff;
}
/*
@@ -65698,8 +66630,7 @@ static int btreeInvokeBusyHandler(void *pArg){
BtShared *pBt = (BtShared*)pArg;
assert( pBt->db );
assert( sqlite3_mutex_held(pBt->db->mutex) );
- return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
- sqlite3PagerFile(pBt->pPager));
+ return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
}
/*
@@ -65803,9 +66734,13 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
if( rc ){
- sqlite3_free(zFullPathname);
- sqlite3_free(p);
- return rc;
+ if( rc==SQLITE_OK_SYMLINK ){
+ rc = SQLITE_OK;
+ }else{
+ sqlite3_free(zFullPathname);
+ sqlite3_free(p);
+ return rc;
+ }
}
}
#if SQLITE_THREADSAFE
@@ -66246,19 +67181,17 @@ SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(
*/
SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){
int rc = SQLITE_OK;
+ int x;
BtShared *pBt = p->pBt;
- assert( nReserve>=-1 && nReserve<=255 );
+ assert( nReserve>=0 && nReserve<=255 );
sqlite3BtreeEnter(p);
-#if SQLITE_HAS_CODEC
- if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
-#endif
+ pBt->nReserveWanted = nReserve;
+ x = pBt->pageSize - pBt->usableSize;
+ if( nReserve<x ) nReserve = x;
if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
sqlite3BtreeLeave(p);
return SQLITE_READONLY;
}
- if( nReserve<0 ){
- nReserve = pBt->pageSize - pBt->usableSize;
- }
assert( nReserve>=0 && nReserve<=255 );
if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
((pageSize-1)&pageSize)==0 ){
@@ -66304,19 +67237,17 @@ SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
** are intentually left unused. This is the "reserved" space that is
** sometimes used by extensions.
**
-** If SQLITE_HAS_MUTEX is defined then the number returned is the
-** greater of the current reserved space and the maximum requested
-** reserve space.
+** The value returned is the larger of the current reserve size and
+** the latest reserve size requested by SQLITE_FILECTRL_RESERVE_BYTES.
+** The amount of reserve can only grow - never shrink.
*/
-SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){
- int n;
+SQLITE_PRIVATE int sqlite3BtreeGetRequestedReserve(Btree *p){
+ int n1, n2;
sqlite3BtreeEnter(p);
- n = sqlite3BtreeGetReserveNoMutex(p);
-#ifdef SQLITE_HAS_CODEC
- if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve;
-#endif
+ n1 = (int)p->pBt->nReserveWanted;
+ n2 = sqlite3BtreeGetReserveNoMutex(p);
sqlite3BtreeLeave(p);
- return n;
+ return n1>n2 ? n1 : n2;
}
@@ -66766,6 +67697,7 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){
*/
SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
BtShared *pBt = p->pBt;
+ Pager *pPager = pBt->pPager;
int rc = SQLITE_OK;
sqlite3BtreeEnter(p);
@@ -66781,7 +67713,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVers
assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 );
if( (p->db->flags & SQLITE_ResetDatabase)
- && sqlite3PagerIsreadonly(pBt->pPager)==0
+ && sqlite3PagerIsreadonly(pPager)==0
){
pBt->btsFlags &= ~BTS_READ_ONLY;
}
@@ -66829,6 +67761,18 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVers
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
if( pBt->nPage==0 ) pBt->btsFlags |= BTS_INITIALLY_EMPTY;
do {
+ sqlite3PagerWalDb(pPager, p->db);
+
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ /* If transitioning from no transaction directly to a write transaction,
+ ** block for the WRITER lock first if possible. */
+ if( pBt->pPage1==0 && wrflag ){
+ assert( pBt->inTransaction==TRANS_NONE );
+ rc = sqlite3PagerWalWriteLock(pPager, 1);
+ if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
+ }
+#endif
+
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
@@ -66842,7 +67786,7 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVers
if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){
rc = SQLITE_READONLY;
}else{
- rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db));
+ rc = sqlite3PagerBegin(pPager, wrflag>1, sqlite3TempInMemory(p->db));
if( rc==SQLITE_OK ){
rc = newDatabase(pBt);
}else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){
@@ -66855,11 +67799,15 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVers
}
if( rc!=SQLITE_OK ){
+ (void)sqlite3PagerWalWriteLock(pPager, 0);
unlockBtreeIfUnused(pBt);
}
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
btreeInvokeBusyHandler(pBt) );
- sqlite3PagerResetLockTimeout(pBt->pPager);
+ sqlite3PagerWalDb(pPager, 0);
+#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
+ if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
+#endif
if( rc==SQLITE_OK ){
if( p->inTrans==TRANS_NONE ){
@@ -66911,7 +67859,7 @@ trans_begun:
** open savepoints. If the second parameter is greater than 0 and
** the sub-journal is not already open, then it will be opened here.
*/
- rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint);
+ rc = sqlite3PagerOpenSavepoint(pPager, p->db->nSavepoint);
}
}
@@ -67765,8 +68713,9 @@ static int btreeCursor(
/* The following assert statements verify that if this is a sharable
** b-tree database, the connection is holding the required table locks,
** and that no other connection has any open cursor that conflicts with
- ** this lock. */
- assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) );
+ ** this lock. The iTable<1 term disables the check for corrupt schemas. */
+ assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1))
+ || iTable<1 );
assert( wrFlag==0 || !hasReadConflicts(p, iTable) );
/* Assert that the caller has opened the required transaction. */
@@ -67779,9 +68728,13 @@ static int btreeCursor(
allocateTempSpace(pBt);
if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
}
- if( iTable==1 && btreePagecount(pBt)==0 ){
- assert( wrFlag==0 );
- iTable = 0;
+ if( iTable<=1 ){
+ if( iTable<1 ){
+ return SQLITE_CORRUPT_BKPT;
+ }else if( btreePagecount(pBt)==0 ){
+ assert( wrFlag==0 );
+ iTable = 0;
+ }
}
/* Now that no other errors can occur, finish filling in the BtCursor
@@ -67806,6 +68759,19 @@ static int btreeCursor(
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}
+static int btreeCursorWithLock(
+ Btree *p, /* The btree */
+ int iTable, /* Root page of table to open */
+ int wrFlag, /* 1 to write. 0 read-only */
+ struct KeyInfo *pKeyInfo, /* First arg to comparison function */
+ BtCursor *pCur /* Space for new cursor */
+){
+ int rc;
+ sqlite3BtreeEnter(p);
+ rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
+ sqlite3BtreeLeave(p);
+ return rc;
+}
SQLITE_PRIVATE int sqlite3BtreeCursor(
Btree *p, /* The btree */
int iTable, /* Root page of table to open */
@@ -67813,15 +68779,11 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
struct KeyInfo *pKeyInfo, /* First arg to xCompare() */
BtCursor *pCur /* Write new cursor here */
){
- int rc;
- if( iTable<1 ){
- rc = SQLITE_CORRUPT_BKPT;
+ if( p->sharable ){
+ return btreeCursorWithLock(p, iTable, wrFlag, pKeyInfo, pCur);
}else{
- sqlite3BtreeEnter(p);
- rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
- sqlite3BtreeLeave(p);
+ return btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
}
- return rc;
}
/*
@@ -67944,6 +68906,18 @@ SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
return pCur->info.nKey;
}
+/*
+** Pin or unpin a cursor.
+*/
+SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor *pCur){
+ assert( (pCur->curFlags & BTCF_Pinned)==0 );
+ pCur->curFlags |= BTCF_Pinned;
+}
+SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){
+ assert( (pCur->curFlags & BTCF_Pinned)!=0 );
+ pCur->curFlags &= ~BTCF_Pinned;
+}
+
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
/*
** Return the offset into the database file for the start of the
@@ -69100,8 +70074,11 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
** to be invalid here. This can only occur if a second cursor modifies
** the page while cursor pCur is holding a reference to it. Which can
** only happen if the database is corrupt in such a way as to link the
- ** page into more than one b-tree structure. */
- testcase( idx>pPage->nCell );
+ ** page into more than one b-tree structure.
+ **
+ ** Update 2019-12-23: appears to long longer be possible after the
+ ** addition of anotherValidCursor() condition on balance_deeper(). */
+ harmless( idx>pPage->nCell );
if( idx>=pPage->nCell ){
if( !pPage->leaf ){
@@ -70300,7 +71277,7 @@ static int rebuildPage(
assert( i<iEnd );
j = get2byte(&aData[hdr+5]);
- if( j>(u32)usableSize ){ j = 0; }
+ if( NEVER(j>(u32)usableSize) ){ j = 0; }
memcpy(&pTmp[j], &aData[j], usableSize - j);
for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
@@ -70326,7 +71303,7 @@ static int rebuildPage(
if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
memcpy(pData, pCell, sz);
assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB );
- testcase( sz!=pPg->xCellSize(pPg,pCell) );
+ testcase( sz!=pPg->xCellSize(pPg,pCell) )
i++;
if( i>=iEnd ) break;
if( pCArray->ixNx[k]<=i ){
@@ -70518,7 +71495,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;
}
@@ -71691,6 +72668,30 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
}
/*
+** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid
+** on the same B-tree as pCur.
+**
+** This can if a database is corrupt with two or more SQL tables
+** pointing to the same b-tree. If an insert occurs on one SQL table
+** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL
+** table linked to the same b-tree. If the secondary insert causes a
+** rebalance, that can change content out from under the cursor on the
+** first SQL table, violating invariants on the first insert.
+*/
+static int anotherValidCursor(BtCursor *pCur){
+ BtCursor *pOther;
+ for(pOther=pCur->pBt->pCursor; pOther; pOther=pOther->pNext){
+ if( pOther!=pCur
+ && pOther->eState==CURSOR_VALID
+ && pOther->pPage==pCur->pPage
+ ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
** The page that pCur currently points to has just been modified in
** some way. This function figures out if this modification means the
** tree needs to be balanced, and if so calls the appropriate balancing
@@ -71717,7 +72718,7 @@ static int balance(BtCursor *pCur){
if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
break;
}else if( (iPage = pCur->iPage)==0 ){
- if( pPage->nOverflow ){
+ if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
/* The root page of the b-tree is overfull. In this case call the
** balance_deeper() function to create a new child for the root-page
** and copy the current contents of the root-page to it. The
@@ -72013,7 +73014,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( flags & BTREE_SAVEPOSITION ){
assert( pCur->curFlags & BTCF_ValidNKey );
assert( pX->nKey==pCur->info.nKey );
- assert( pCur->info.nSize!=0 );
assert( loc==0 );
}
#endif
@@ -72088,7 +73088,9 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
}
}
- assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
+ assert( pCur->eState==CURSOR_VALID
+ || (pCur->eState==CURSOR_INVALID && loc)
+ || CORRUPT_DB );
pPage = pCur->pPage;
assert( pPage->intKey || pX->nKey>=0 );
@@ -72850,7 +73852,6 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
return rc;
}
-#ifndef SQLITE_OMIT_BTREECOUNT
/*
** The first argument, pCur, is a cursor opened on some b-tree. Count the
** number of entries in the b-tree and write the result to *pnEntry.
@@ -72859,7 +73860,7 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
** Otherwise, if an error is encountered (i.e. an IO error or database
** corruption) an SQLite error code is returned.
*/
-SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
+SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
i64 nEntry = 0; /* Value to return in *pnEntry */
int rc; /* Return code */
@@ -72872,7 +73873,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
/* Unless an error occurs, the following loop runs one iteration for each
** page in the B-Tree structure (not including overflow pages).
*/
- while( rc==SQLITE_OK ){
+ while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){
int iIdx; /* Index of child node in parent */
MemPage *pPage; /* Current page of the b-tree */
@@ -72923,7 +73924,6 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
/* An error has occurred. Return an error code. */
return rc;
}
-#endif
/*
** Return the pager associated with a BTree. This routine is used for
@@ -72998,6 +73998,7 @@ static int checkRef(IntegrityCk *pCheck, Pgno iPage){
checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
return 1;
}
+ if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1;
setPageReferenced(pCheck, iPage);
return 0;
}
@@ -73441,6 +74442,7 @@ end_of_check:
** returned. If a memory allocation error occurs, NULL is returned.
*/
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
+ sqlite3 *db, /* Database connection that is running the check */
Btree *p, /* The btree to be checked */
int *aRoot, /* An array of root pages numbers for individual trees */
int nRoot, /* Number of entries in aRoot[] */
@@ -73458,6 +74460,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) );
assert( nRef>=0 );
+ sCheck.db = db;
sCheck.pBt = pBt;
sCheck.pPager = pBt->pPager;
sCheck.nPage = btreePagecount(sCheck.pBt);
@@ -73971,7 +74974,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
*/
static int setDestPgsz(sqlite3_backup *p){
int rc;
- rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0);
+ rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
return rc;
}
@@ -74094,13 +75097,6 @@ static int backupOnePage(
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
-#ifdef SQLITE_HAS_CODEC
- /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
- ** guaranteed that the shared-mutex is held by this thread, handle
- ** p->pSrc may not actually be the owner. */
- int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
- int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
-#endif
int rc = SQLITE_OK;
i64 iOff;
@@ -74117,26 +75113,6 @@ static int backupOnePage(
rc = SQLITE_READONLY;
}
-#ifdef SQLITE_HAS_CODEC
- /* Backup is not possible if the page size of the destination is changing
- ** and a codec is in use.
- */
- if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
- rc = SQLITE_READONLY;
- }
-
- /* Backup is not possible if the number of bytes of reserve space differ
- ** between source and destination. If there is a difference, try to
- ** fix the destination to agree with the source. If that is not possible,
- ** then the backup cannot proceed.
- */
- if( nSrcReserve!=nDestReserve ){
- u32 newPgsz = nSrcPgsz;
- rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
- if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
- }
-#endif
-
/* This loop runs once for each destination page spanned by the source
** page. For each iteration, variable iOff is set to the byte offset
** of the destination page.
@@ -74632,10 +75608,6 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
b.pDest = pTo;
b.iNext = 1;
-#ifdef SQLITE_HAS_CODEC
- sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
-#endif
-
/* 0x7FFFFFFF is the hard limit for the number of pages in a database
** file. By passing this as the number of pages to copy to
** sqlite3_backup_step(), we can guarantee that the copy finishes
@@ -75124,15 +76096,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){
sqlite3_context ctx;
- Mem t;
assert( pFunc!=0 );
assert( pFunc->xValue!=0 );
assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
memset(&ctx, 0, sizeof(ctx));
- memset(&t, 0, sizeof(t));
- t.flags = MEM_Null;
- t.db = pAccum->db;
sqlite3VdbeMemSetNull(pOut);
ctx.pOut = pOut;
ctx.pMem = pAccum;
@@ -75258,8 +76226,7 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
return pMem->u.i;
}else if( flags & MEM_Real ){
return doubleToInt64(pMem->u.r);
- }else if( flags & (MEM_Str|MEM_Blob) ){
- assert( pMem->z || pMem->n==0 );
+ }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){
return memIntValue(pMem);
}else{
return 0;
@@ -75416,8 +76383,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
** affinity even if that results in loss of data. This routine is
** used (for example) to implement the SQL "cast()" operator.
*/
-SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
- if( pMem->flags & MEM_Null ) return;
+SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
+ if( pMem->flags & MEM_Null ) return SQLITE_OK;
switch( aff ){
case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */
if( (pMem->flags & MEM_Blob)==0 ){
@@ -75448,9 +76415,10 @@ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
- break;
+ return sqlite3VdbeChangeEncoding(pMem, encoding);
}
}
+ return SQLITE_OK;
}
/*
@@ -75616,25 +76584,27 @@ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){
** its link to a shallow copy and by marking any current shallow
** copies of this cell as invalid.
**
-** This is used for testing and debugging only - to make sure shallow
-** copies are not misused.
+** This is used for testing and debugging only - to help ensure that shallow
+** copies (created by OP_SCopy) are not misused.
*/
SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
int i;
Mem *pX;
- for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){
+ for(i=1, pX=pVdbe->aMem+1; i<pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
- /* If pX is marked as a shallow copy of pMem, then verify that
+ u16 mFlags;
+ if( pVdbe->db->flags & SQLITE_VdbeTrace ){
+ sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n",
+ (int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem));
+ }
+ /* If pX is marked as a shallow copy of pMem, then try to verify that
** no significant changes have been made to pX since the OP_SCopy.
** A significant change would indicated a missed call to this
** function for pX. Minor changes, such as adding or removing a
** dual type, are allowed, as long as the underlying value is the
** same. */
- u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
+ mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
- assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r );
- assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) );
- assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 );
/* pMem is the register that is changing. But also mark pX as
** undefined so that we can quickly detect the shallow-copy error */
@@ -75646,7 +76616,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
}
#endif /* SQLITE_DEBUG */
-
/*
** Make an shallow copy of pFrom into pTo. Prior contents of
** pTo are freed. The pFrom->z field is not duplicated. If
@@ -75792,10 +76761,19 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
pMem->n = nByte;
pMem->flags = flags;
- pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
+ if( enc ){
+ pMem->enc = enc;
+#ifdef SQLITE_ENABLE_SESSION
+ }else if( pMem->db==0 ){
+ pMem->enc = SQLITE_UTF8;
+#endif
+ }else{
+ assert( pMem->db!=0 );
+ pMem->enc = ENC(pMem->db);
+ }
#ifndef SQLITE_OMIT_UTF16
- if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
+ if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
return SQLITE_NOMEM_BKPT;
}
#endif
@@ -75822,7 +76800,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
** If this routine fails for any reason (malloc returns NULL or unable
** to read from the disk) then the pMem is left in an inconsistent state.
*/
-static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
u32 offset, /* Offset from the start of data to return bytes from. */
u32 amt, /* Number of bytes to return. */
@@ -75845,13 +76823,11 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
}
return rc;
}
-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(
BtCursor *pCur, /* Cursor pointing at record to retrieve. */
- u32 offset, /* Offset from the start of data to return bytes from. */
u32 amt, /* Number of bytes to return. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
- char *zData; /* Data from the btree layer */
u32 available = 0; /* Number of bytes available on the local btree page */
int rc = SQLITE_OK; /* Return code */
@@ -75861,15 +76837,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
/* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
** that both the BtShared and database handle mutexes are held. */
assert( !sqlite3VdbeMemIsRowSet(pMem) );
- zData = (char *)sqlite3BtreePayloadFetch(pCur, &available);
- assert( zData!=0 );
+ pMem->z = (char *)sqlite3BtreePayloadFetch(pCur, &available);
+ assert( pMem->z!=0 );
- if( offset+amt<=available ){
- pMem->z = &zData[offset];
+ if( amt<=available ){
pMem->flags = MEM_Blob|MEM_Ephem;
pMem->n = (int)amt;
}else{
- rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, amt, pMem);
}
return rc;
@@ -76212,7 +77187,11 @@ static int valueFromExpr(
if( pVal->flags & MEM_Real ){
pVal->u.r = -pVal->u.r;
}else if( pVal->u.i==SMALLEST_INT64 ){
+#ifndef SQLITE_OMIT_FLOATING_POINT
pVal->u.r = -(double)SMALLEST_INT64;
+#else
+ pVal->u.r = LARGEST_INT64;
+#endif
MemSetTypeFlag(pVal, MEM_Real);
}else{
pVal->u.i = -pVal->u.i;
@@ -76571,6 +77550,10 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */
+/* Forward references */
+static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef);
+static void vdbeFreeOpArray(sqlite3 *, Op *, int);
+
/*
** Create a new virtual database engine.
*/
@@ -76599,6 +77582,13 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
}
/*
+** Return the Parse object that owns a Vdbe object.
+*/
+SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe *p){
+ return p->pParse;
+}
+
+/*
** Change the error string stored in Vdbe.zErrMsg
*/
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
@@ -76678,7 +77668,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
zTmp = pA->zSql;
pA->zSql = pB->zSql;
pB->zSql = zTmp;
-#if 0
+#ifdef SQLITE_ENABLE_NORMALIZE
zTmp = pA->zNormSql;
pA->zNormSql = pB->zNormSql;
pB->zNormSql = zTmp;
@@ -76739,9 +77729,16 @@ static int growOpArray(Vdbe *v, int nOp){
#ifdef SQLITE_DEBUG
/* This routine is just a convenient place to set a breakpoint that will
** fire after each opcode is inserted and displayed using
-** "PRAGMA vdbe_addoptrace=on".
+** "PRAGMA vdbe_addoptrace=on". Parameters "pc" (program counter) and
+** pOp are available to make the breakpoint conditional.
+**
+** Other useful labels for breakpoints include:
+** test_trace_breakpoint(pc,pOp)
+** sqlite3CorruptError(lineno)
+** sqlite3MisuseError(lineno)
+** sqlite3CantopenError(lineno)
*/
-static void test_addop_breakpoint(void){
+static void test_addop_breakpoint(int pc, Op *pOp){
static int n = 0;
n++;
}
@@ -76794,7 +77791,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
- test_addop_breakpoint();
+ test_addop_breakpoint(i, &p->aOp[i]);
}
#endif
#ifdef VDBE_PROFILE
@@ -76878,6 +77875,49 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4(
}
/*
+** Add an OP_Function or OP_PureFunc opcode.
+**
+** The eCallCtx argument is information (typically taken from Expr.op2)
+** that describes the calling context of the function. 0 means a general
+** function call. NC_IsCheck means called by a check constraint,
+** NC_IdxExpr means called as part of an index expression. NC_PartIdx
+** means in the WHERE clause of a partial index. NC_GenCol means called
+** while computing a generated column value. 0 is the usual case.
+*/
+SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(
+ Parse *pParse, /* Parsing context */
+ int p1, /* Constant argument mask */
+ int p2, /* First argument register */
+ int p3, /* Register into which results are written */
+ int nArg, /* Number of argument */
+ const FuncDef *pFunc, /* The function to be invoked */
+ int eCallCtx /* Calling context */
+){
+ Vdbe *v = pParse->pVdbe;
+ int nByte;
+ int addr;
+ sqlite3_context *pCtx;
+ assert( v );
+ nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*);
+ pCtx = sqlite3DbMallocRawNN(pParse->db, nByte);
+ if( pCtx==0 ){
+ assert( pParse->db->mallocFailed );
+ freeEphemeralFunction(pParse->db, (FuncDef*)pFunc);
+ return 0;
+ }
+ pCtx->pOut = 0;
+ pCtx->pFunc = (FuncDef*)pFunc;
+ pCtx->pVdbe = 0;
+ pCtx->isError = 0;
+ pCtx->argc = nArg;
+ pCtx->iOp = sqlite3VdbeCurrentAddr(v);
+ addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function,
+ p1, p2, p3, (char*)pCtx, P4_FUNCCTX);
+ sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef);
+ return addr;
+}
+
+/*
** Add an opcode that includes the p4 value with a P4_INT64 or
** P4_REAL type.
*/
@@ -76919,7 +77959,7 @@ SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
#endif
/*
-** Add a new OP_ opcode.
+** Add a new OP_Explain opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
@@ -77169,6 +78209,7 @@ static Op *opIterNext(VdbeOpIter *p){
** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort.
** * OP_Destroy
** * OP_VUpdate
+** * OP_VCreate
** * OP_VRename
** * OP_FkCounter with P2==0 (immediate foreign key constraint)
** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine
@@ -77196,6 +78237,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
int opcode = pOp->opcode;
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
|| opcode==OP_VDestroy
+ || opcode==OP_VCreate
|| (opcode==OP_ParseSchema && pOp->p4.z==0)
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
&& ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
@@ -77558,6 +78600,34 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
sqlite3VdbeChangeP2(p, addr, p->nOp);
}
+/*
+** Change the P2 operand of the jump instruction at addr so that
+** the jump lands on the next opcode. Or if the jump instruction was
+** the previous opcode (and is thus a no-op) then simply back up
+** the next instruction counter by one slot so that the jump is
+** overwritten by the next inserted opcode.
+**
+** This routine is an optimization of sqlite3VdbeJumpHere() that
+** strives to omit useless byte-code like this:
+**
+** 7 Once 0 8 0
+** 8 ...
+*/
+SQLITE_PRIVATE void sqlite3VdbeJumpHereOrPopInst(Vdbe *p, int addr){
+ if( addr==p->nOp-1 ){
+ assert( p->aOp[addr].opcode==OP_Once
+ || p->aOp[addr].opcode==OP_If
+ || p->aOp[addr].opcode==OP_FkIfZero );
+ assert( p->aOp[addr].p4type==0 );
+#ifdef SQLITE_VDBE_COVERAGE
+ sqlite3VdbeGetOp(p,-1)->iSrcLine = 0; /* Erase VdbeCoverage() macros */
+#endif
+ p->nOp--;
+ }else{
+ sqlite3VdbeChangeP2(p, addr, p->nOp);
+ }
+}
+
/*
** If the input FuncDef structure is ephemeral, then free it. If
@@ -77569,8 +78639,6 @@ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){
}
}
-static void vdbeFreeOpArray(sqlite3 *, Op *, int);
-
/*
** Delete a P4 value if necessary.
*/
@@ -77580,7 +78648,7 @@ static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){
}
static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){
freeEphemeralFunction(db, p->pFunc);
- sqlite3DbFreeNN(db, p);
+ sqlite3DbFreeNN(db, p);
}
static void freeP4(sqlite3 *db, int p4type, void *p4){
assert( db );
@@ -77655,6 +78723,13 @@ SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){
}
/*
+** Return true if the given Vdbe has any SubPrograms.
+*/
+SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){
+ return pVdbe->pProgram!=0;
+}
+
+/*
** Change the opcode at addr into OP_Noop
*/
SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
@@ -77681,6 +78756,41 @@ SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
}
}
+#ifdef SQLITE_DEBUG
+/*
+** Generate an OP_ReleaseReg opcode to indicate that a range of
+** registers, except any identified by mask, are no longer in use.
+*/
+SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(
+ Parse *pParse, /* Parsing context */
+ int iFirst, /* Index of first register to be released */
+ int N, /* Number of registers to release */
+ u32 mask, /* Mask of registers to NOT release */
+ int bUndefine /* If true, mark registers as undefined */
+){
+ if( N==0 ) return;
+ assert( pParse->pVdbe );
+ assert( iFirst>=1 );
+ assert( iFirst+N-1<=pParse->nMem );
+ if( N<=31 && mask!=0 ){
+ while( N>0 && (mask&1)!=0 ){
+ mask >>= 1;
+ iFirst++;
+ N--;
+ }
+ while( N>0 && N<=32 && (mask & MASKBIT32(N-1))!=0 ){
+ mask &= ~MASKBIT32(N-1);
+ N--;
+ }
+ }
+ if( N>0 ){
+ sqlite3VdbeAddOp3(pParse->pVdbe, OP_ReleaseReg, iFirst, N, *(int*)&mask);
+ if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1);
+ }
+}
+#endif /* SQLITE_DEBUG */
+
+
/*
** Change the value of the P4 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
@@ -77798,7 +78908,8 @@ SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
*/
static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
assert( p->nOp>0 || p->aOp==0 );
- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
+ assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed
+ || p->pParse->nErr>0 );
if( p->nOp ){
assert( p->aOp );
sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
@@ -77888,17 +78999,19 @@ static int translateP(char c, const Op *pOp){
** "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(
+SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
+ sqlite3 *db, /* Optional - Oom error reporting only */
const Op *pOp, /* The opcode to be commented */
- const char *zP4, /* Previously obtained value for P4 */
- char *zTemp, /* Write result here */
- int nTemp /* Space available in zTemp[] */
+ const char *zP4 /* Previously obtained value for P4 */
){
const char *zOpName;
const char *zSynopsis;
int nOpName;
- int ii, jj;
+ int ii;
char zAlt[50];
+ StrAccum x;
+
+ sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
zOpName = sqlite3OpcodeName(pOp->opcode);
nOpName = sqlite3Strlen30(zOpName);
if( zOpName[nOpName+1] ){
@@ -77913,53 +79026,64 @@ static int displayComment(
}
zSynopsis = zAlt;
}
- for(ii=jj=0; jj<nTemp-1 && (c = zSynopsis[ii])!=0; ii++){
+ for(ii=0; (c = zSynopsis[ii])!=0; ii++){
if( c=='P' ){
c = zSynopsis[++ii];
if( c=='4' ){
- sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", zP4);
+ sqlite3_str_appendall(&x, zP4);
}else if( c=='X' ){
- sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", pOp->zComment);
+ sqlite3_str_appendall(&x, pOp->zComment);
seenCom = 1;
}else{
int v1 = translateP(c, pOp);
int v2;
- sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1);
if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){
ii += 3;
- jj += sqlite3Strlen30(zTemp+jj);
v2 = translateP(zSynopsis[ii], pOp);
if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){
ii += 2;
v2++;
}
- if( v2>1 ){
- sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ if( v2<2 ){
+ sqlite3_str_appendf(&x, "%d", v1);
+ }else{
+ sqlite3_str_appendf(&x, "%d..%d", v1, v1+v2-1);
+ }
+ }else if( strncmp(zSynopsis+ii+1, "@NP", 3)==0 ){
+ sqlite3_context *pCtx = pOp->p4.pCtx;
+ if( pOp->p4type!=P4_FUNCCTX || pCtx->argc==1 ){
+ sqlite3_str_appendf(&x, "%d", v1);
+ }else if( pCtx->argc>1 ){
+ sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1);
+ }else{
+ assert( x.nChar>2 );
+ x.nChar -= 2;
+ ii++;
+ }
+ ii += 3;
+ }else{
+ sqlite3_str_appendf(&x, "%d", v1);
+ if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
+ ii += 4;
}
- }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
- ii += 4;
}
}
- jj += sqlite3Strlen30(zTemp+jj);
}else{
- zTemp[jj++] = c;
+ sqlite3_str_appendchar(&x, 1, c);
}
}
- if( !seenCom && jj<nTemp-5 && pOp->zComment ){
- sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment);
- jj += sqlite3Strlen30(zTemp+jj);
+ if( !seenCom && pOp->zComment ){
+ sqlite3_str_appendf(&x, "; %s", pOp->zComment);
}
- if( jj<nTemp ) zTemp[jj] = 0;
}else if( pOp->zComment ){
- sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment);
- jj = sqlite3Strlen30(zTemp);
- }else{
- zTemp[0] = 0;
- jj = 0;
+ sqlite3_str_appendall(&x, pOp->zComment);
}
- return jj;
+ if( (x.accError & SQLITE_NOMEM)!=0 && db!=0 ){
+ sqlite3OomFault(db);
+ }
+ return sqlite3StrAccumFinish(&x);
}
-#endif /* SQLITE_DEBUG */
+#endif /* SQLITE_ENABLE_EXPLAIN_COMMENTS */
#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
/*
@@ -78040,11 +79164,11 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){
** Compute a string that describes the P4 parameter for an opcode.
** Use zTemp for any required temporary buffer space.
*/
-static char *displayP4(Op *pOp, char *zTemp, int nTemp){
- char *zP4 = zTemp;
+SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
+ char *zP4 = 0;
StrAccum x;
- assert( nTemp>=20 );
- sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
+
+ sqlite3StrAccumInit(&x, 0, 0, 0, SQLITE_MAX_LENGTH);
switch( pOp->p4type ){
case P4_KEYINFO: {
int j;
@@ -78070,8 +79194,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
}
#endif
case P4_COLLSEQ: {
+ static const char *const encnames[] = {"?", "8", "16LE", "16BE"};
CollSeq *pColl = pOp->p4.pColl;
- sqlite3_str_appendf(&x, "(%.20s)", pColl->zName);
+ assert( pColl->enc>=0 && pColl->enc<4 );
+ sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName,
+ encnames[pColl->enc]);
break;
}
case P4_FUNCDEF: {
@@ -78079,13 +79206,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
case P4_FUNCCTX: {
FuncDef *pDef = pOp->p4.pCtx->pFunc;
sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
-#endif
case P4_INT64: {
sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64);
break;
@@ -78127,36 +79252,32 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
for(i=1; i<=n; i++){
- sqlite3_str_appendf(&x, ",%d", ai[i]);
+ sqlite3_str_appendf(&x, "%c%d", (i==1 ? '[' : ','), ai[i]);
}
- zTemp[0] = '[';
sqlite3_str_append(&x, "]", 1);
break;
}
case P4_SUBPROGRAM: {
- sqlite3_str_appendf(&x, "program");
+ zP4 = "program";
break;
}
case P4_DYNBLOB:
case P4_ADVANCE: {
- zTemp[0] = 0;
break;
}
case P4_TABLE: {
- sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName);
+ zP4 = pOp->p4.pTab->zName;
break;
}
default: {
zP4 = pOp->p4.z;
- if( zP4==0 ){
- zP4 = zTemp;
- zTemp[0] = 0;
- }
}
}
- sqlite3StrAccumFinish(&x);
- assert( zP4!=0 );
- return zP4;
+ if( zP4 ) sqlite3_str_appendall(&x, zP4);
+ if( (x.accError & SQLITE_NOMEM)!=0 ){
+ sqlite3OomFault(db);
+ }
+ return sqlite3StrAccumFinish(&x);
}
#endif /* VDBE_DISPLAY_P4 */
@@ -78246,24 +79367,30 @@ SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){
*/
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){
char *zP4;
- char zPtr[50];
- char zCom[100];
+ char *zCom;
+ sqlite3 dummyDb;
static const char *zFormat1 = "%4d %-13s %4d %4d %4d %-13s %.2X %s\n";
if( pOut==0 ) pOut = stdout;
- zP4 = displayP4(pOp, zPtr, sizeof(zPtr));
+ sqlite3BeginBenignMalloc();
+ dummyDb.mallocFailed = 1;
+ zP4 = sqlite3VdbeDisplayP4(&dummyDb, pOp);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- displayComment(pOp, zP4, zCom, sizeof(zCom));
+ zCom = sqlite3VdbeDisplayComment(0, pOp, zP4);
#else
- zCom[0] = 0;
+ zCom = 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
+ sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3,
+ zP4 ? zP4 : "", pOp->p5,
+ zCom ? zCom : ""
);
fflush(pOut);
+ sqlite3_free(zP4);
+ sqlite3_free(zCom);
+ sqlite3EndBenignMalloc();
}
#endif
@@ -78354,6 +79481,121 @@ SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){
pFrame->v->pDelFrame = pFrame;
}
+#if defined(SQLITE_ENABLE_BYTECODE_VTAB) || !defined(SQLITE_OMIT_EXPLAIN)
+/*
+** Locate the next opcode to be displayed in EXPLAIN or EXPLAIN
+** QUERY PLAN output.
+**
+** Return SQLITE_ROW on success. Return SQLITE_DONE if there are no
+** more opcodes to be displayed.
+*/
+SQLITE_PRIVATE int sqlite3VdbeNextOpcode(
+ Vdbe *p, /* The statement being explained */
+ Mem *pSub, /* Storage for keeping track of subprogram nesting */
+ int eMode, /* 0: normal. 1: EQP. 2: TablesUsed */
+ int *piPc, /* IN/OUT: Current rowid. Overwritten with next rowid */
+ int *piAddr, /* OUT: Write index into (*paOp)[] here */
+ Op **paOp /* OUT: Write the opcode array here */
+){
+ int nRow; /* Stop when row count reaches this */
+ int nSub = 0; /* Number of sub-vdbes seen so far */
+ SubProgram **apSub = 0; /* Array of sub-vdbes */
+ int i; /* Next instruction address */
+ int rc = SQLITE_OK; /* Result code */
+ Op *aOp = 0; /* Opcode array */
+ int iPc; /* Rowid. Copy of value in *piPc */
+
+ /* When the number of output rows reaches nRow, that means the
+ ** listing has finished and sqlite3_step() should return SQLITE_DONE.
+ ** nRow is the sum of the number of rows in the main program, plus
+ ** the sum of the number of rows in all trigger subprograms encountered
+ ** so far. The nRow value will increase as new trigger subprograms are
+ ** encountered, but p->pc will eventually catch up to nRow.
+ */
+ nRow = p->nOp;
+ if( pSub!=0 ){
+ if( pSub->flags&MEM_Blob ){
+ /* pSub is initiallly NULL. It is initialized to a BLOB by
+ ** the P4_SUBPROGRAM processing logic below */
+ nSub = pSub->n/sizeof(Vdbe*);
+ apSub = (SubProgram **)pSub->z;
+ }
+ for(i=0; i<nSub; i++){
+ nRow += apSub[i]->nOp;
+ }
+ }
+ iPc = *piPc;
+ while(1){ /* Loop exits via break */
+ i = iPc++;
+ if( i>=nRow ){
+ p->rc = SQLITE_OK;
+ rc = SQLITE_DONE;
+ break;
+ }
+ if( i<p->nOp ){
+ /* The rowid is small enough that we are still in the
+ ** main program. */
+ aOp = p->aOp;
+ }else{
+ /* We are currently listing subprograms. Figure out which one and
+ ** pick up the appropriate opcode. */
+ int j;
+ i -= p->nOp;
+ assert( apSub!=0 );
+ assert( nSub>0 );
+ for(j=0; i>=apSub[j]->nOp; j++){
+ i -= apSub[j]->nOp;
+ assert( i<apSub[j]->nOp || j+1<nSub );
+ }
+ aOp = apSub[j]->aOp;
+ }
+
+ /* When an OP_Program opcode is encounter (the only opcode that has
+ ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
+ ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
+ ** has not already been seen.
+ */
+ if( pSub!=0 && aOp[i].p4type==P4_SUBPROGRAM ){
+ int nByte = (nSub+1)*sizeof(SubProgram*);
+ int j;
+ for(j=0; j<nSub; j++){
+ if( apSub[j]==aOp[i].p4.pProgram ) break;
+ }
+ if( j==nSub ){
+ p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
+ if( p->rc!=SQLITE_OK ){
+ rc = SQLITE_ERROR;
+ break;
+ }
+ apSub = (SubProgram **)pSub->z;
+ apSub[nSub++] = aOp[i].p4.pProgram;
+ MemSetTypeFlag(pSub, MEM_Blob);
+ pSub->n = nSub*sizeof(SubProgram*);
+ nRow += aOp[i].p4.pProgram->nOp;
+ }
+ }
+ if( eMode==0 ) break;
+#ifdef SQLITE_ENABLE_BYTECODE_VTAB
+ if( eMode==2 ){
+ Op *pOp = aOp + i;
+ if( pOp->opcode==OP_OpenRead ) break;
+ if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break;
+ if( pOp->opcode==OP_ReopenIdx ) break;
+ }else
+#endif
+ {
+ assert( eMode==1 );
+ if( aOp[i].opcode==OP_Explain ) break;
+ if( aOp[i].opcode==OP_Init && iPc>1 ) break;
+ }
+ }
+ *piPc = iPc;
+ *piAddr = i;
+ *paOp = aOp;
+ return rc;
+}
+#endif /* SQLITE_ENABLE_BYTECODE_VTAB || !SQLITE_OMIT_EXPLAIN */
+
/*
** Delete a VdbeFrame object and its contents. VdbeFrame objects are
@@ -78394,16 +79636,14 @@ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
SQLITE_PRIVATE int sqlite3VdbeList(
Vdbe *p /* The VDBE */
){
- int nRow; /* Stop when row count reaches this */
- int nSub = 0; /* Number of sub-vdbes seen so far */
- SubProgram **apSub = 0; /* Array of sub-vdbes */
Mem *pSub = 0; /* Memory cell hold array of subprogs */
sqlite3 *db = p->db; /* The database connection */
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
- Op *pOp = 0;
+ Op *aOp; /* Array of opcodes */
+ Op *pOp; /* Current opcode */
assert( p->explain );
assert( p->magic==VDBE_MAGIC_RUN );
@@ -78423,14 +79663,6 @@ SQLITE_PRIVATE int sqlite3VdbeList(
return SQLITE_ERROR;
}
- /* When the number of output rows reaches nRow, that means the
- ** listing has finished and sqlite3_step() should return SQLITE_DONE.
- ** nRow is the sum of the number of rows in the main program, plus
- ** the sum of the number of rows in all trigger subprograms encountered
- ** so far. The nRow value will increase as new trigger subprograms are
- ** encountered, but p->pc will eventually catch up to nRow.
- */
- nRow = p->nOp;
if( bListSubprogs ){
/* The first 8 memory cells are used for the result set. So we will
** commandeer the 9th cell to use as storage for an array of pointers
@@ -78438,147 +79670,55 @@ SQLITE_PRIVATE int sqlite3VdbeList(
** cells. */
assert( p->nMem>9 );
pSub = &p->aMem[9];
- if( pSub->flags&MEM_Blob ){
- /* On the first call to sqlite3_step(), pSub will hold a NULL. It is
- ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */
- nSub = pSub->n/sizeof(Vdbe*);
- apSub = (SubProgram **)pSub->z;
- }
- for(i=0; i<nSub; i++){
- nRow += apSub[i]->nOp;
- }
+ }else{
+ pSub = 0;
}
- while(1){ /* Loop exits via break */
- i = p->pc++;
- if( i>=nRow ){
- p->rc = SQLITE_OK;
- rc = SQLITE_DONE;
- break;
- }
- if( i<p->nOp ){
- /* The output line number is small enough that we are still in the
- ** main program. */
- pOp = &p->aOp[i];
- }else{
- /* We are currently listing subprograms. Figure out which one and
- ** pick up the appropriate opcode. */
- int j;
- i -= p->nOp;
- assert( apSub!=0 );
- assert( nSub>0 );
- for(j=0; i>=apSub[j]->nOp; j++){
- i -= apSub[j]->nOp;
- assert( i<apSub[j]->nOp || j+1<nSub );
- }
- pOp = &apSub[j]->aOp[i];
- }
-
- /* When an OP_Program opcode is encounter (the only opcode that has
- ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
- ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
- ** has not already been seen.
- */
- if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
- int nByte = (nSub+1)*sizeof(SubProgram*);
- int j;
- for(j=0; j<nSub; j++){
- if( apSub[j]==pOp->p4.pProgram ) break;
- }
- if( j==nSub ){
- p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
- if( p->rc!=SQLITE_OK ){
- rc = SQLITE_ERROR;
- break;
- }
- apSub = (SubProgram **)pSub->z;
- apSub[nSub++] = pOp->p4.pProgram;
- pSub->flags |= MEM_Blob;
- pSub->n = nSub*sizeof(SubProgram*);
- nRow += pOp->p4.pProgram->nOp;
- }
- }
- if( p->explain<2 ) break;
- if( pOp->opcode==OP_Explain ) break;
- if( pOp->opcode==OP_Init && p->pc>1 ) break;
- }
+ /* Figure out which opcode is next to display */
+ rc = sqlite3VdbeNextOpcode(p, pSub, p->explain==2, &p->pc, &i, &aOp);
if( rc==SQLITE_OK ){
- if( db->u1.isInterrupted ){
+ pOp = aOp + i;
+ if( AtomicLoad(&db->u1.isInterrupted) ){
p->rc = SQLITE_INTERRUPT;
rc = SQLITE_ERROR;
sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
}else{
- char *zP4;
- if( p->explain==1 ){
- pMem->flags = MEM_Int;
- pMem->u.i = i; /* Program counter */
- pMem++;
-
- pMem->flags = MEM_Static|MEM_Str|MEM_Term;
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem++;
- }
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p1; /* P1 */
- pMem++;
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p2; /* P2 */
- pMem++;
-
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p3; /* P3 */
- pMem++;
-
- if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Str|MEM_Term;
- zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
- if( zP4!=pMem->z ){
- pMem->n = 0;
- sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
+ char *zP4 = sqlite3VdbeDisplayP4(db, pOp);
+ if( p->explain==2 ){
+ sqlite3VdbeMemSetInt64(pMem, pOp->p1);
+ sqlite3VdbeMemSetInt64(pMem+1, pOp->p2);
+ sqlite3VdbeMemSetInt64(pMem+2, pOp->p3);
+ sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free);
+ p->nResColumn = 4;
}else{
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- }
- pMem++;
-
- if( p->explain==1 ){
- if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Str|MEM_Term;
- pMem->n = 2;
- sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
- pMem->enc = SQLITE_UTF8;
- pMem++;
-
+ sqlite3VdbeMemSetInt64(pMem+0, i);
+ sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode),
+ -1, SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3VdbeMemSetInt64(pMem+2, pOp->p1);
+ sqlite3VdbeMemSetInt64(pMem+3, pOp->p2);
+ sqlite3VdbeMemSetInt64(pMem+4, pOp->p3);
+ /* pMem+5 for p4 is done last */
+ sqlite3VdbeMemSetInt64(pMem+6, pOp->p5);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
+ {
+ char *zCom = sqlite3VdbeDisplayComment(db, pOp, zP4);
+ sqlite3VdbeMemSetStr(pMem+7, zCom, -1, SQLITE_UTF8, sqlite3_free);
}
- pMem->flags = MEM_Str|MEM_Term;
- pMem->n = displayComment(pOp, zP4, pMem->z, 500);
- pMem->enc = SQLITE_UTF8;
#else
- pMem->flags = MEM_Null; /* Comment */
+ sqlite3VdbeMemSetNull(pMem+7);
#endif
+ sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
+ p->nResColumn = 8;
+ }
+ p->pResultSet = pMem;
+ if( db->mallocFailed ){
+ p->rc = SQLITE_NOMEM;
+ rc = SQLITE_ERROR;
+ }else{
+ p->rc = SQLITE_OK;
+ rc = SQLITE_ROW;
}
-
- p->nResColumn = 8 - 4*(p->explain-1);
- p->pResultSet = &p->aMem[1];
- p->rc = SQLITE_OK;
- rc = SQLITE_ROW;
}
}
return rc;
@@ -78779,8 +79919,27 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
- if( pParse->explain && nMem<10 ){
- nMem = 10;
+ if( pParse->explain ){
+ static const char * const azColName[] = {
+ "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+ "id", "parent", "notused", "detail"
+ };
+ int iFirst, mx, i;
+ if( nMem<10 ) nMem = 10;
+ p->explain = pParse->explain;
+ if( pParse->explain==2 ){
+ sqlite3VdbeSetNumCols(p, 4);
+ iFirst = 8;
+ mx = 12;
+ }else{
+ sqlite3VdbeSetNumCols(p, 8);
+ iFirst = 0;
+ mx = 8;
+ }
+ for(i=iFirst; i<mx; i++){
+ sqlite3VdbeSetColName(p, i-iFirst, COLNAME_NAME,
+ azColName[i], SQLITE_STATIC);
+ }
}
p->expired = 0;
@@ -78818,7 +79977,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
p->pVList = pParse->pVList;
pParse->pVList = 0;
- p->explain = pParse->explain;
if( db->mallocFailed ){
p->nVar = 0;
p->nCursor = 0;
@@ -79130,8 +80288,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
/* Select a master journal file name */
nMainFile = sqlite3Strlen30(zMainFile);
- zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
+ zMaster = sqlite3MPrintf(db, "%.4c%s%.16c", 0,zMainFile,0);
if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
+ zMaster += 4;
do {
u32 iRandom;
if( retryCount ){
@@ -79161,7 +80320,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
);
}
if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster);
+ sqlite3DbFree(db, zMaster-4);
return rc;
}
@@ -79184,7 +80343,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
if( rc!=SQLITE_OK ){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster);
+ sqlite3DbFree(db, zMaster-4);
return rc;
}
}
@@ -79198,7 +80357,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
){
sqlite3OsCloseFree(pMaster);
sqlite3OsDelete(pVfs, zMaster, 0);
- sqlite3DbFree(db, zMaster);
+ sqlite3DbFree(db, zMaster-4);
return rc;
}
@@ -79221,7 +80380,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
sqlite3OsCloseFree(pMaster);
assert( rc!=SQLITE_BUSY );
if( rc!=SQLITE_OK ){
- sqlite3DbFree(db, zMaster);
+ sqlite3DbFree(db, zMaster-4);
return rc;
}
@@ -79230,7 +80389,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** transaction files are deleted.
*/
rc = sqlite3OsDelete(pVfs, zMaster, 1);
- sqlite3DbFree(db, zMaster);
+ sqlite3DbFree(db, zMaster-4);
zMaster = 0;
if( rc ){
return rc;
@@ -79869,7 +81028,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
** carried out. Seek the cursor now. If an error occurs, return
** the appropriate error code.
*/
-static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
+SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){
int res, rc;
#ifdef SQLITE_TEST
extern int sqlite3_search_count;
@@ -79936,12 +81095,12 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
if( p->deferredMoveto ){
int iMap;
- if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
+ if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){
*pp = p->pAltCursor;
*piCol = iMap - 1;
return SQLITE_OK;
}
- return handleDeferredMoveto(p);
+ return sqlite3VdbeFinishMoveto(p);
}
if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
return handleMovedCursor(p);
@@ -80939,7 +82098,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
/* RHS is a string */
else if( pRhs->flags & MEM_Str ){
- getVarint32(&aKey1[idx1], serial_type);
+ getVarint32NR(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 ){
rc = -1;
@@ -80973,7 +82132,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
/* RHS is a blob */
else if( pRhs->flags & MEM_Blob ){
assert( (pRhs->flags & MEM_Zero)==0 || pRhs->n==0 );
- getVarint32(&aKey1[idx1], serial_type);
+ getVarint32NR(&aKey1[idx1], serial_type);
testcase( serial_type==12 );
if( serial_type<12 || (serial_type & 0x01) ){
rc = -1;
@@ -81162,7 +82321,10 @@ static int vdbeRecordCompareString(
assert( pPKey2->aMem[0].flags & MEM_Str );
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
- getVarint32(&aKey1[1], serial_type);
+ serial_type = (u8)(aKey1[1]);
+ if( serial_type >= 0x80 ){
+ sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
+ }
if( serial_type<12 ){
res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
}else if( !(serial_type & 0x01) ){
@@ -81283,13 +82445,13 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
/* Read in the complete content of the index entry */
sqlite3VdbeMemInit(&m, db, 0);
- rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
+ rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
if( rc ){
return rc;
}
/* The index entry must begin with a header size */
- (void)getVarint32((u8*)m.z, szHdr);
+ getVarint32NR((u8*)m.z, szHdr);
testcase( szHdr==3 );
testcase( szHdr==m.n );
testcase( szHdr>0x7fffffff );
@@ -81300,7 +82462,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
/* The last field of the index should be an integer - the ROWID.
** Verify that the last entry really is an integer. */
- (void)getVarint32((u8*)&m.z[szHdr-1], typeRowid);
+ getVarint32NR((u8*)&m.z[szHdr-1], typeRowid);
testcase( typeRowid==1 );
testcase( typeRowid==2 );
testcase( typeRowid==3 );
@@ -81365,7 +82527,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
return SQLITE_CORRUPT_BKPT;
}
sqlite3VdbeMemInit(&m, db, 0);
- rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
+ rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
if( rc ){
return rc;
}
@@ -81481,13 +82643,25 @@ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
** features such as 'now'.
*/
SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){
+ const VdbeOp *pOp;
#ifdef SQLITE_ENABLE_STAT4
if( pCtx->pVdbe==0 ) return 1;
#endif
- if( pCtx->pVdbe->aOp[pCtx->iOp].opcode==OP_PureFunc ){
- sqlite3_result_error(pCtx,
- "non-deterministic function in index expression or CHECK constraint",
- -1);
+ pOp = pCtx->pVdbe->aOp + pCtx->iOp;
+ if( pOp->opcode==OP_PureFunc ){
+ const char *zContext;
+ char *zMsg;
+ if( pOp->p5 & NC_IsCheck ){
+ zContext = "a CHECK constraint";
+ }else if( pOp->p5 & NC_GenCol ){
+ zContext = "a generated column";
+ }else{
+ zContext = "an index";
+ }
+ zMsg = sqlite3_mprintf("non-deterministic use of %s() in %s",
+ pCtx->pFunc->zName, zContext);
+ sqlite3_result_error(pCtx, zMsg, -1);
+ sqlite3_free(zMsg);
return 0;
}
return 1;
@@ -82266,7 +83440,7 @@ static int sqlite3Step(Vdbe *p){
** from interrupting a statement that has not yet started.
*/
if( db->nVdbeActive==0 ){
- db->u1.isInterrupted = 0;
+ AtomicStore(&db->u1.isInterrupted, 0);
}
assert( db->nVdbeWrite>0 || db->autoCommit==0
@@ -82958,7 +84132,7 @@ static int vdbeUnbind(Vdbe *p, int i){
/* If the bit corresponding to this variable in Vdbe.expmask is set, then
** binding a new value to this variable invalidates the current query plan.
**
- ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host
+ ** IMPLEMENTATION-OF: R-57496-20354 If the specific value bound to a host
** parameter in the WHERE clause might influence the choice of query plan
** for a statement, then the statement will be automatically recompiled,
** as if there had been a schema change, on the first sqlite3_step() call
@@ -83434,7 +84608,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa
goto preupdate_old_out;
}
if( p->pPk ){
- iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
+ iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
}
if( iIdx>=p->pCsr->nField || iIdx<0 ){
rc = SQLITE_RANGE;
@@ -83524,7 +84698,7 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa
goto preupdate_new_out;
}
if( p->pPk && p->op!=SQLITE_UPDATE ){
- iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
+ iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);
}
if( iIdx>=p->pCsr->nField || iIdx<0 ){
rc = SQLITE_RANGE;
@@ -83972,6 +85146,26 @@ SQLITE_API int sqlite3_found_count = 0;
# define UPDATE_MAX_BLOBSIZE(P)
#endif
+#ifdef SQLITE_DEBUG
+/* This routine provides a convenient place to set a breakpoint during
+** tracing with PRAGMA vdbe_trace=on. The breakpoint fires right after
+** each opcode is printed. Variables "pc" (program counter) and pOp are
+** available to add conditionals to the breakpoint. GDB example:
+**
+** break test_trace_breakpoint if pc=22
+**
+** Other useful labels for breakpoints include:
+** test_addop_breakpoint(pc,pOp)
+** sqlite3CorruptError(lineno)
+** sqlite3MisuseError(lineno)
+** sqlite3CantopenError(lineno)
+*/
+static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){
+ static int n = 0;
+ n++;
+}
+#endif
+
/*
** Invoke the VDBE coverage callback, if that callback is defined. This
** feature is used for test suite validation only and does not appear an
@@ -84316,12 +85510,9 @@ static u16 numericType(Mem *pMem){
** Write a nice string representation of the contents of cell pMem
** into buffer zBuf, length nBuf.
*/
-SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
- char *zCsr = zBuf;
+SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){
int f = pMem->flags;
-
static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"};
-
if( f&MEM_Blob ){
int i;
char c;
@@ -84337,57 +85528,40 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
}else{
c = 's';
}
- *(zCsr++) = c;
- *(zCsr++) = 'x';
- sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
- zCsr += sqlite3Strlen30(zCsr);
+ sqlite3_str_appendf(pStr, "%cx[", c);
for(i=0; i<25 && i<pMem->n; i++){
- sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF));
- zCsr += sqlite3Strlen30(zCsr);
+ sqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF));
}
- *zCsr++ = '|';
+ sqlite3_str_appendf(pStr, "|");
for(i=0; i<25 && i<pMem->n; i++){
char z = pMem->z[i];
- if( z<32 || z>126 ) *zCsr++ = '.';
- else *zCsr++ = z;
+ sqlite3_str_appendchar(pStr, 1, (z<32||z>126)?'.':z);
}
- *(zCsr++) = ']';
+ sqlite3_str_appendf(pStr,"]");
if( f & MEM_Zero ){
- sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
- zCsr += sqlite3Strlen30(zCsr);
+ sqlite3_str_appendf(pStr, "+%dz",pMem->u.nZero);
}
- *zCsr = '\0';
}else if( f & MEM_Str ){
- int j, k;
- zBuf[0] = ' ';
+ int j;
+ u8 c;
if( f & MEM_Dyn ){
- zBuf[1] = 'z';
+ c = 'z';
assert( (f & (MEM_Static|MEM_Ephem))==0 );
}else if( f & MEM_Static ){
- zBuf[1] = 't';
+ c = 't';
assert( (f & (MEM_Dyn|MEM_Ephem))==0 );
}else if( f & MEM_Ephem ){
- zBuf[1] = 'e';
+ c = 'e';
assert( (f & (MEM_Static|MEM_Dyn))==0 );
}else{
- zBuf[1] = 's';
+ c = 's';
}
- k = 2;
- sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n);
- k += sqlite3Strlen30(&zBuf[k]);
- zBuf[k++] = '[';
+ sqlite3_str_appendf(pStr, " %c%d[", c, pMem->n);
for(j=0; j<25 && j<pMem->n; j++){
- u8 c = pMem->z[j];
- if( c>=0x20 && c<0x7f ){
- zBuf[k++] = c;
- }else{
- zBuf[k++] = '.';
- }
+ c = pMem->z[j];
+ sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.');
}
- zBuf[k++] = ']';
- sqlite3_snprintf(100,&zBuf[k], encnames[pMem->enc]);
- k += sqlite3Strlen30(&zBuf[k]);
- zBuf[k++] = 0;
+ sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
}
}
#endif
@@ -84414,21 +85588,38 @@ static void memTracePrint(Mem *p){
}else if( sqlite3VdbeMemIsRowSet(p) ){
printf(" (rowset)");
}else{
- char zBuf[200];
- sqlite3VdbeMemPrettyPrint(p, zBuf);
- printf(" %s", zBuf);
+ StrAccum acc;
+ char zBuf[1000];
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ sqlite3VdbeMemPrettyPrint(p, &acc);
+ printf(" %s", sqlite3StrAccumFinish(&acc));
}
if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
- printf("REG[%d] = ", iReg);
+ printf("R[%d] = ", iReg);
memTracePrint(p);
+ if( p->pScopyFrom ){
+ printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
+ }
printf("\n");
sqlite3VdbeCheckMemInvariants(p);
}
#endif
#ifdef SQLITE_DEBUG
+/*
+** Show the values of all registers in the virtual machine. Used for
+** interactive debugging.
+*/
+SQLITE_PRIVATE void sqlite3VdbeRegisterDump(Vdbe *v){
+ int i;
+ for(i=1; i<v->nMem; i++) registerTrace(i, v->aMem+i);
+}
+#endif /* SQLITE_DEBUG */
+
+
+#ifdef SQLITE_DEBUG
# define REGISTER_TRACE(R,M) if(db->flags&SQLITE_VdbeTrace)registerTrace(R,M)
#else
# define REGISTER_TRACE(R,M)
@@ -84456,7 +85647,7 @@ static void registerTrace(int iReg, Mem *p){
******************************************************************************
**
** This file contains inline asm code for retrieving "high-performance"
-** counters for x86 class CPUs.
+** counters for x86 and x86_64 class CPUs.
*/
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
@@ -84467,8 +85658,9 @@ static void registerTrace(int iReg, Mem *p){
** processor and returns that value. This can be used for high-res
** profiling.
*/
-#if (defined(__GNUC__) || defined(_MSC_VER)) && \
- (defined(i386) || defined(__i386__) || defined(_M_IX86))
+#if !defined(__STRICT_ANSI__) && \
+ (defined(__GNUC__) || defined(_MSC_VER)) && \
+ (defined(i386) || defined(__i386__) || defined(_M_IX86))
#if defined(__GNUC__)
@@ -84489,7 +85681,7 @@ static void registerTrace(int iReg, Mem *p){
#endif
-#elif (defined(__GNUC__) && defined(__x86_64__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long val;
@@ -84497,7 +85689,7 @@ static void registerTrace(int iReg, Mem *p){
return val;
}
-#elif (defined(__GNUC__) && defined(__ppc__))
+#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long long retval;
@@ -84514,14 +85706,13 @@ static void registerTrace(int iReg, Mem *p){
#else
- #error Need implementation of sqlite3Hwtime() for your platform.
-
/*
- ** To compile without implementing sqlite3Hwtime() for your platform,
- ** you can remove the above #error and use the following
- ** stub function. You will lose timing support for many
- ** of the debugging and testing utilities, but it should at
- ** least compile and run.
+ ** asm() is needed for hardware timing support. Without asm(),
+ ** disable the sqlite3Hwtime() routine.
+ **
+ ** sqlite3Hwtime() is only used for some obscure debugging
+ ** and analysis configurations, not in any deliverable, so this
+ ** should not be a great loss.
*/
SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
@@ -84629,12 +85820,14 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
goto no_mem;
}
assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
+ testcase( p->rc!=SQLITE_OK );
+ p->rc = SQLITE_OK;
assert( p->bIsReader || p->readOnly!=0 );
p->iCurrentTime = 0;
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
- if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
+ if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
sqlite3VdbeIOTraceSql(p);
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
@@ -84682,6 +85875,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
#ifdef SQLITE_DEBUG
if( db->flags & SQLITE_VdbeTrace ){
sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
+ test_trace_breakpoint((int)(pOp - aOp),pOp,p);
}
#endif
@@ -84789,6 +85983,20 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
+
+#ifdef SQLITE_DEBUG
+ /* In debuggging mode, when the p5 flags is set on an OP_Goto, that
+ ** means we should really jump back to the preceeding OP_ReleaseReg
+ ** instruction. */
+ if( pOp->p5 ){
+ assert( pOp->p2 < (int)(pOp - aOp) );
+ assert( pOp->p2 > 1 );
+ pOp = &aOp[pOp->p2 - 2];
+ assert( pOp[1].opcode==OP_ReleaseReg );
+ goto check_for_interrupt;
+ }
+#endif
+
jump_to_p2_and_check_for_interrupt:
pOp = &aOp[pOp->p2 - 1];
@@ -84803,7 +86011,7 @@ jump_to_p2_and_check_for_interrupt:
** checks on every opcode. This helps sqlite3_step() to run about 1.5%
** faster according to "valgrind --tool=cachegrind" */
check_for_interrupt:
- if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
+ if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/* Call the progress callback if it is configured and the required number
** of VDBE ops have been executed (either since this invocation of
@@ -85265,8 +86473,13 @@ case OP_Move: {
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
- pOut->pScopyFrom += pOp->p2 - p1;
+ pIn1->pScopyFrom = 0;
+ { int i;
+ for(i=1; i<p->nMem; i++){
+ if( aMem[i].pScopyFrom==pIn1 ){
+ aMem[i].pScopyFrom = pOut;
+ }
+ }
}
#endif
Deephemeralize(pOut);
@@ -85407,6 +86620,14 @@ case OP_ResultRow: {
|| (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
sqlite3VdbeMemNulTerminate(&pMem[i]);
REGISTER_TRACE(pOp->p1+i, &pMem[i]);
+#ifdef SQLITE_DEBUG
+ /* The registers in the result will not be used again when the
+ ** prepared statement restarts. This is because sqlite3_column()
+ ** APIs might have caused type conversions of made other changes to
+ ** the register values. Therefore, we can go ahead and break any
+ ** OP_SCopy dependencies. */
+ pMem[i].pScopyFrom = 0;
+#endif
}
if( db->mallocFailed ) goto no_mem;
@@ -85414,6 +86635,7 @@ case OP_ResultRow: {
db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
}
+
/* Return SQLITE_ROW
*/
p->pc = (int)(pOp - aOp) + 1;
@@ -85442,7 +86664,6 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
pOut = &aMem[pOp->p3];
- testcase( pIn1==pIn2 );
testcase( pOut==pIn2 );
assert( pIn1!=pOut );
flags1 = pIn1->flags;
@@ -85810,9 +87031,11 @@ case OP_Cast: { /* in1 */
pIn1 = &aMem[pOp->p1];
memAboutToChange(p, pIn1);
rc = ExpandBlob(pIn1);
- sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
- UPDATE_MAX_BLOBSIZE(pIn1);
if( rc ) goto abort_due_to_error;
+ rc = sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
+ if( rc ) goto abort_due_to_error;
+ UPDATE_MAX_BLOBSIZE(pIn1);
+ REGISTER_TRACE(pOp->p1, pIn1);
break;
}
#endif /* SQLITE_OMIT_CAST */
@@ -85972,11 +87195,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
assert( flags3==pIn3->flags );
- /* testcase( flags3!=pIn3->flags );
- ** this used to be possible with pIn1==pIn3, but not since
- ** the column cache was removed. The following assignment
- ** is essentially a no-op. But, it provides defense-in-depth
- ** in case our analysis is incorrect, so it is left in. */
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
@@ -85999,7 +87217,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
sqlite3VdbeMemStringify(pIn1, encoding, 1);
testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
- assert( pIn1!=pIn3 );
+ if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
}
if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
testcase( pIn3->flags & MEM_Int );
@@ -86034,10 +87252,10 @@ compare_op:
}
/* Undo any changes made by applyAffinity() to the input registers. */
- assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
- pIn1->flags = flags1;
assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
pIn3->flags = flags3;
+ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
+ pIn1->flags = flags1;
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
@@ -86073,16 +87291,31 @@ compare_op:
/* Opcode: ElseNotEq * P2 * * *
**
-** This opcode must immediately follow an OP_Lt or OP_Gt comparison operator.
-** If result of an OP_Eq comparison on the same two operands
-** would have be NULL or false (0), then then jump to P2.
-** If the result of an OP_Eq comparison on the two previous operands
-** would have been true (1), then fall through.
+** This opcode must follow an OP_Lt or OP_Gt comparison operator. There
+** can be zero or more OP_ReleaseReg opcodes intervening, but no other
+** opcodes are allowed to occur between this instruction and the previous
+** OP_Lt or OP_Gt. Furthermore, the prior OP_Lt or OP_Gt must have the
+** SQLITE_STOREP2 bit set in the P5 field.
+**
+** If result of an OP_Eq comparison on the same two operands as the
+** prior OP_Lt or OP_Gt would have been NULL or false (0), then then
+** jump to P2. If the result of an OP_Eq comparison on the two previous
+** operands would have been true (1), then fall through.
*/
case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */
- assert( pOp>aOp );
- assert( pOp[-1].opcode==OP_Lt || pOp[-1].opcode==OP_Gt );
- assert( pOp[-1].p5 & SQLITE_STOREP2 );
+
+#ifdef SQLITE_DEBUG
+ /* Verify the preconditions of this opcode - that it follows an OP_Lt or
+ ** OP_Gt with the SQLITE_STOREP2 flag set, with zero or more intervening
+ ** OP_ReleaseReg opcodes */
+ int iAddr;
+ for(iAddr = (int)(pOp - aOp) - 1; ALWAYS(iAddr>=0); iAddr--){
+ if( aOp[iAddr].opcode==OP_ReleaseReg ) continue;
+ assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt );
+ assert( aOp[iAddr].p5 & SQLITE_STOREP2 );
+ break;
+ }
+#endif /* SQLITE_DEBUG */
VdbeBranchTaken(iCompare!=0, 2);
if( iCompare!=0 ) goto jump_to_p2;
break;
@@ -86493,7 +87726,9 @@ case OP_Column: {
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
p2 = pOp->p2;
/* If the cursor cache is stale (meaning it is not currently point at
@@ -86505,7 +87740,6 @@ case OP_Column: {
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pDest = &aMem[pOp->p3];
memAboutToChange(p, pDest);
- assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pC!=0 );
assert( p2<pC->nField );
aOffset = pC->aOffset;
@@ -86598,7 +87832,7 @@ case OP_Column: {
/* Make sure zData points to enough of the record to cover the header. */
if( pC->aRow==0 ){
memset(&sMem, 0, sizeof(sMem));
- rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem);
+ rc = sqlite3VdbeMemFromBtreeZeroOffset(pC->uc.pCursor,aOffset[0],&sMem);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
zData = (u8*)sMem.z;
}else{
@@ -86716,10 +87950,11 @@ case OP_Column: {
**
** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the
** buffer passed to it, debugging function VdbeMemPrettyPrint() may
- ** read up to 16. So 16 bytes of bogus content is supplied.
+ ** read more. Use the global constant sqlite3CtypeMap[] as the array,
+ ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint())
+ ** and it begins with a bunch of zeros.
*/
- static u8 aZero[16]; /* This is the bogus content */
- sqlite3VdbeSerialGet(aZero, t, pDest);
+ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
}else{
rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
@@ -86762,7 +87997,7 @@ case OP_Affinity: {
pIn1 = &aMem[pOp->p1];
while( 1 /*exit-by-break*/ ){
assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] );
- assert( memIsValid(pIn1) );
+ assert( zAffinity[0]==SQLITE_AFF_NONE || memIsValid(pIn1) );
applyAffinity(pIn1, zAffinity[0], encoding);
if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){
/* When applying REAL affinity, if the result is still an MEM_Int
@@ -87072,13 +88307,16 @@ case OP_MakeRecord: {
break;
}
-/* Opcode: Count P1 P2 * * *
+/* Opcode: Count P1 P2 p3 * *
** Synopsis: r[P2]=count()
**
** Store the number of entries (an integer value) in the table or index
-** opened by cursor P1 in register P2
+** opened by cursor P1 in register P2.
+**
+** If P3==0, then an exact count is obtained, which involves visiting
+** every btree page of the table. But if P3 is non-zero, an estimate
+** is returned based on the current cursor position.
*/
-#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2 */
i64 nEntry;
BtCursor *pCrsr;
@@ -87086,14 +88324,17 @@ case OP_Count: { /* out2 */
assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
assert( pCrsr );
- nEntry = 0; /* Not needed. Only used to silence a warning. */
- rc = sqlite3BtreeCount(pCrsr, &nEntry);
- if( rc ) goto abort_due_to_error;
+ if( pOp->p3 ){
+ nEntry = sqlite3BtreeRowCountEst(pCrsr);
+ }else{
+ nEntry = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
+ if( rc ) goto abort_due_to_error;
+ }
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
- break;
+ goto check_for_interrupt;
}
-#endif
/* Opcode: Savepoint P1 * * P4 *
**
@@ -87208,8 +88449,12 @@ case OP_Savepoint: {
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
- db->isTransactionSavepoint = 0;
rc = p->rc;
+ if( rc ){
+ db->autoCommit = 0;
+ }else{
+ db->isTransactionSavepoint = 0;
+ }
}else{
int isSchemaChange;
iSavepoint = db->nSavepoint - iSavepoint - 1;
@@ -87237,6 +88482,7 @@ case OP_Savepoint: {
db->mDbFlags |= DBFLAG_SchemaChange;
}
}
+ if( rc ) goto abort_due_to_error;
/* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
** savepoints nested inside of the savepoint being operated on. */
@@ -87319,7 +88565,6 @@ case OP_AutoCommit: {
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
- assert( db->nStatement==0 );
sqlite3CloseSavepoints(db);
if( p->rc==SQLITE_OK ){
rc = SQLITE_DONE;
@@ -87400,7 +88645,8 @@ case OP_Transaction: {
goto abort_due_to_error;
}
- if( pOp->p2 && p->usesStmtJournal
+ if( p->usesStmtJournal
+ && pOp->p2
&& (db->autoCommit==0 || db->nVdbeRead>1)
){
assert( sqlite3BtreeIsInTrans(pBt) );
@@ -87544,7 +88790,7 @@ case OP_SetCookie: {
** <ul>
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
-** of OP_SeekLE/OP_IdxGT)
+** of OP_SeekLE/OP_IdxLT)
** </ul>
**
** The P4 value may be either an integer (P4_INT32) or a pointer to
@@ -87574,7 +88820,7 @@ case OP_SetCookie: {
** <ul>
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
-** of OP_SeekLE/OP_IdxGT)
+** of OP_SeekLE/OP_IdxLT)
** </ul>
**
** See also: OP_OpenRead, OP_OpenWrite
@@ -87598,7 +88844,7 @@ case OP_SetCookie: {
** <ul>
** <li> <b>0x02 OPFLAG_SEEKEQ</b>: This cursor will only be used for
** equality lookups (implemented as a pair of opcodes OP_SeekGE/OP_IdxGT
-** of OP_SeekLE/OP_IdxGT)
+** of OP_SeekLE/OP_IdxLT)
** <li> <b>0x08 OPFLAG_FORDELETE</b>: This cursor is used only to seek
** and subsequently delete entries in an index btree. This is a
** hint to the storage engine that the storage engine is allowed to
@@ -87710,9 +88956,7 @@ open_cursor_set_hints:
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
testcase( pOp->p5 & OPFLAG_BULKCSR );
-#ifdef SQLITE_ENABLE_CURSOR_HINTS
testcase( pOp->p2 & OPFLAG_SEEKEQ );
-#endif
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
if( rc ) goto abort_due_to_error;
@@ -87732,6 +88976,7 @@ case OP_OpenDup: {
VdbeCursor *pCx; /* The new cursor */
pOrig = p->apCsr[pOp->p2];
+ assert( pOrig );
assert( pOrig->pBtx!=0 ); /* Only ephemeral cursors can be duplicated */
pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
@@ -87795,15 +89040,13 @@ case OP_OpenEphemeral: {
assert( pOp->p1>=0 );
assert( pOp->p2>=0 );
pCx = p->apCsr[pOp->p1];
- if( pCx ){
+ if( pCx && pCx->pBtx ){
/* If the ephermeral table is already open, erase all existing content
** so that the table is empty again, rather than creating a new table. */
assert( pCx->isEphemeral );
pCx->seqCount = 0;
pCx->cacheStatus = CACHE_STALE;
- if( pCx->pBtx ){
- rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
- }
+ rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
}else{
pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
if( pCx==0 ) goto no_mem;
@@ -87969,11 +89212,13 @@ case OP_ColumnsUsed: {
** greater than or equal to the key and P2 is not zero, then jump to P2.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
-** opcode will always land on a record that equally equals the key, or
-** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
-** opcode must be followed by an IdxLE opcode with the same arguments.
-** The IdxLE opcode will be skipped if this opcode succeeds, but the
-** IdxLE opcode will be used on subsequent loop iterations.
+** opcode will either land on a record that exactly matches the key, or
+** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
+** this opcode must be followed by an IdxLE opcode with the same arguments.
+** The IdxGT opcode will be skipped if this opcode succeeds, but the
+** IdxGT opcode will be used on subsequent loop iterations. The
+** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
+** is an equality search.
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end. In other words, the cursor is
@@ -87989,7 +89234,7 @@ case OP_ColumnsUsed: {
** to an SQL index, then P3 is the first in an array of P4 registers
** that are used as an unpacked index key.
**
-** Reposition cursor P1 so that it points to the smallest entry that
+** Reposition cursor P1 so that it points to the smallest entry that
** is greater than the key value. If there are no records greater than
** the key and P2 is not zero, then jump to P2.
**
@@ -88034,11 +89279,13 @@ case OP_ColumnsUsed: {
** configured to use Prev, not Next.
**
** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this
-** opcode will always land on a record that equally equals the key, or
-** else jump immediately to P2. When the cursor is OPFLAG_SEEKEQ, this
-** opcode must be followed by an IdxGE opcode with the same arguments.
+** opcode will either land on a record that exactly matches the key, or
+** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ,
+** this opcode must be followed by an IdxLE opcode with the same arguments.
** The IdxGE opcode will be skipped if this opcode succeeds, but the
-** IdxGE opcode will be used on subsequent loop iterations.
+** IdxGE opcode will be used on subsequent loop iterations. The
+** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this
+** is an equality search.
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
@@ -88075,7 +89322,7 @@ case OP_SeekGT: { /* jump, in3, group */
pC->cacheStatus = CACHE_STALE;
if( pC->isTable ){
u16 flags3, newType;
- /* The BTREE_SEEK_EQ flag is only set on index cursors */
+ /* The OPFLAG_SEEKEQ/BTREE_SEEK_EQ flag is only set on index cursors */
assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
|| CORRUPT_DB );
@@ -88134,14 +89381,17 @@ case OP_SeekGT: { /* jump, in3, group */
goto abort_due_to_error;
}
}else{
- /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
- ** OP_SeekLE opcodes are allowed, and these must be immediately followed
- ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
+ /* For a cursor with the OPFLAG_SEEKEQ/BTREE_SEEK_EQ hint, only the
+ ** OP_SeekGE and OP_SeekLE opcodes are allowed, and these must be
+ ** immediately followed by an OP_IdxGT or OP_IdxLT opcode, respectively,
+ ** with the same key.
*/
if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){
eqOnly = 1;
assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
+ assert( pOp->opcode==OP_SeekGE || pOp[1].opcode==OP_IdxLT );
+ assert( pOp->opcode==OP_SeekLE || pOp[1].opcode==OP_IdxGT );
assert( pOp[1].p1==pOp[0].p1 );
assert( pOp[1].p2==pOp[0].p2 );
assert( pOp[1].p3==pOp[0].p3 );
@@ -88235,7 +89485,7 @@ seek_not_found:
** Synopsis: seekHit=P2
**
** Set the seekHit flag on cursor P1 to the value in P2.
-** The seekHit flag is used by the IfNoHope opcode.
+* The seekHit flag is used by the IfNoHope opcode.
**
** P1 must be a valid b-tree cursor. P2 must be a boolean value,
** either 0 or 1.
@@ -88250,6 +89500,20 @@ case OP_SeekHit: {
break;
}
+/* Opcode: IfNotOpen P1 P2 * * *
+** Synopsis: if( !csr[P1] ) goto P2
+**
+** If cursor P1 is not open, jump to instruction P2. Otherwise, fall through.
+*/
+case OP_IfNotOpen: { /* jump */
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ VdbeBranchTaken(p->apCsr[pOp->p1]==0, 2);
+ if( !p->apCsr[pOp->p1] ){
+ goto jump_to_p2_and_check_for_interrupt;
+ }
+ break;
+}
+
/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
**
@@ -88738,6 +90002,7 @@ case OP_Insert: {
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->deferredMoveto==0 );
assert( pC->uc.pCursor!=0 );
assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
@@ -88855,7 +90120,11 @@ case OP_Delete: {
sqlite3VdbeIncrWriteCounter(p, pC);
#ifdef SQLITE_DEBUG
- if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 ){
+ if( pOp->p4type==P4_TABLE
+ && HasRowid(pOp->p4.pTab)
+ && pOp->p5==0
+ && sqlite3BtreeCursorIsValidNN(pC->uc.pCursor)
+ ){
/* If p5 is zero, the seek operation that positioned the cursor prior to
** OP_Delete will have also set the pC->movetoTarget field to the rowid of
** the row that is being deleted */
@@ -89070,7 +90339,7 @@ case OP_RowData: {
goto too_big;
}
testcase( n==0 );
- rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut);
+ rc = sqlite3VdbeMemFromBtreeZeroOffset(pCrsr, n, pOut);
if( rc ) goto abort_due_to_error;
if( !pOp->p3 ) Deephemeralize(pOut);
UPDATE_MAX_BLOBSIZE(pOut);
@@ -89448,6 +90717,36 @@ next_tail:
** This instruction only works for indices. The equivalent instruction
** for tables is OP_Insert.
*/
+case OP_IdxInsert: { /* in2 */
+ VdbeCursor *pC;
+ BtreePayload x;
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ sqlite3VdbeIncrWriteCounter(p, pC);
+ assert( pC!=0 );
+ assert( !isSorter(pC) );
+ pIn2 = &aMem[pOp->p2];
+ assert( pIn2->flags & MEM_Blob );
+ if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
+ assert( pC->eCurType==CURTYPE_BTREE );
+ assert( pC->isTable==0 );
+ rc = ExpandBlob(pIn2);
+ if( rc ) goto abort_due_to_error;
+ x.nKey = pIn2->n;
+ x.pKey = pIn2->z;
+ x.aMem = aMem + pOp->p3;
+ x.nMem = (u16)pOp->p4.i;
+ rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
+ (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)),
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+ );
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
+ if( rc) goto abort_due_to_error;
+ break;
+}
+
/* Opcode: SorterInsert P1 P2 * * *
** Synopsis: key=r[P2]
**
@@ -89455,47 +90754,37 @@ next_tail:
** MakeRecord instructions. This opcode writes that key
** into the sorter P1. Data for the entry is nil.
*/
-case OP_SorterInsert: /* in2 */
-case OP_IdxInsert: { /* in2 */
+case OP_SorterInsert: { /* in2 */
VdbeCursor *pC;
- BtreePayload x;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
sqlite3VdbeIncrWriteCounter(p, pC);
assert( pC!=0 );
- assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
+ assert( isSorter(pC) );
pIn2 = &aMem[pOp->p2];
assert( pIn2->flags & MEM_Blob );
- if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc ) goto abort_due_to_error;
- if( pOp->opcode==OP_SorterInsert ){
- rc = sqlite3VdbeSorterWrite(pC, pIn2);
- }else{
- x.nKey = pIn2->n;
- x.pKey = pIn2->z;
- x.aMem = aMem + pOp->p3;
- x.nMem = (u16)pOp->p4.i;
- rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
- (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)),
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
- );
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
- }
+ rc = sqlite3VdbeSorterWrite(pC, pIn2);
if( rc) goto abort_due_to_error;
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;
@@ -89512,7 +90801,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;
@@ -89522,6 +90810,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;
@@ -89611,6 +90902,24 @@ case OP_IdxRowid: { /* out2 */
break;
}
+/* Opcode: FinishSeek P1 * * * *
+**
+** If cursor P1 was previously moved via OP_DeferredSeek, complete that
+** seek operation now, without further delay. If the cursor seek has
+** already occurred, this instruction is a no-op.
+*/
+case OP_FinishSeek: {
+ VdbeCursor *pC; /* The P1 index cursor */
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ if( pC->deferredMoveto ){
+ rc = sqlite3VdbeFinishMoveto(pC);
+ if( rc ) goto abort_due_to_error;
+ }
+ break;
+}
+
/* Opcode: IdxGE P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
@@ -90047,7 +91356,7 @@ case OP_IntegrityCk: {
pIn1 = &aMem[pOp->p1];
assert( pOp->p5<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p5) );
- z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
+ z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
(int)pnErr->u.i+1, &nErr);
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
@@ -90060,7 +91369,7 @@ case OP_IntegrityCk: {
}
UPDATE_MAX_BLOBSIZE(pIn1);
sqlite3VdbeChangeEncoding(pIn1, encoding);
- break;
+ goto check_for_interrupt;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -90306,7 +91615,7 @@ case OP_Program: { /* jump */
int i;
for(i=0; i<p->nMem; i++){
aMem[i].pScopyFrom = 0; /* Prevent false-positive AboutToChange() errs */
- aMem[i].flags |= MEM_Undefined; /* Cause a fault if this reg is reused */
+ MemSetTypeFlag(&aMem[i], MEM_Undefined); /* Fault if this reg is reused */
}
}
#endif
@@ -90917,6 +92226,36 @@ case OP_Expire: {
break;
}
+/* Opcode: CursorLock P1 * * * *
+**
+** Lock the btree to which cursor P1 is pointing so that the btree cannot be
+** written by an other cursor.
+*/
+case OP_CursorLock: {
+ VdbeCursor *pC;
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ sqlite3BtreeCursorPin(pC->uc.pCursor);
+ break;
+}
+
+/* Opcode: CursorUnlock P1 * * * *
+**
+** Unlock the btree to which cursor P1 is pointing so that it can be
+** written by other cursors.
+*/
+case OP_CursorUnlock: {
+ VdbeCursor *pC;
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->eCurType==CURTYPE_BTREE );
+ sqlite3BtreeCursorUnpin(pC->uc.pCursor);
+ break;
+}
+
#ifndef SQLITE_OMIT_SHARED_CACHE
/* Opcode: TableLock P1 P2 P3 P4 *
** Synopsis: iDb=P1 root=P2 write=P3
@@ -91161,7 +92500,7 @@ case OP_VColumn: {
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
- testcase( (pOp->p5 & OPFLAG_NOCHNG)==0 && pOp->p5!=0 );
+ assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
if( pOp->p5 & OPFLAG_NOCHNG ){
sqlite3VdbeMemSetNull(pDest);
pDest->flags = MEM_Null|MEM_Zero;
@@ -91386,13 +92725,15 @@ case OP_MaxPgcnt: { /* out2 */
}
#endif
-/* Opcode: Function0 P1 P2 P3 P4 P5
-** Synopsis: r[P3]=func(r[P2@P5])
+/* Opcode: Function P1 P2 P3 P4 *
+** Synopsis: r[P3]=func(r[P2@NP])
**
-** Invoke a user function (P4 is a pointer to a FuncDef object that
-** defines the function) with P5 arguments taken from register P2 and
-** successors. The result of the function is stored in register P3.
-** Register P3 must not be one of the function inputs.
+** Invoke a user function (P4 is a pointer to an sqlite3_context object that
+** contains a pointer to the function to be run) with arguments taken
+** from register P2 and successors. The number of arguments is in
+** the sqlite3_context object that P4 points to.
+** The result of the function is stored
+** in register P3. Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the
** function was determined to be constant at compile time. If the first
@@ -91401,14 +92742,16 @@ case OP_MaxPgcnt: { /* out2 */
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
-** See also: Function, AggStep, AggFinal
+** See also: AggStep, AggFinal, PureFunc
*/
-/* Opcode: Function P1 P2 P3 P4 P5
-** Synopsis: r[P3]=func(r[P2@P5])
+/* Opcode: PureFunc P1 P2 P3 P4 *
+** Synopsis: r[P3]=func(r[P2@NP])
**
** Invoke a user function (P4 is a pointer to an sqlite3_context object that
-** contains a pointer to the function to be run) with P5 arguments taken
-** from register P2 and successors. The result of the function is stored
+** contains a pointer to the function to be run) with arguments taken
+** from register P2 and successors. The number of arguments is in
+** the sqlite3_context object that P4 points to.
+** The result of the function is stored
** in register P3. Register P3 must not be one of the function inputs.
**
** P1 is a 32-bit bitmask indicating whether or not each argument to the
@@ -91418,40 +92761,16 @@ case OP_MaxPgcnt: { /* out2 */
** sqlite3_set_auxdata() API may be safely retained until the next
** invocation of this opcode.
**
-** SQL functions are initially coded as OP_Function0 with P4 pointing
-** to a FuncDef object. But on first evaluation, the P4 operand is
-** automatically converted into an sqlite3_context object and the operation
-** changed to this OP_Function opcode. In this way, the initialization of
-** the sqlite3_context object occurs only once, rather than once for each
-** evaluation of the function.
+** This opcode works exactly like OP_Function. The only difference is in
+** its name. This opcode is used in places where the function must be
+** purely non-deterministic. Some built-in date/time functions can be
+** either determinitic of non-deterministic, depending on their arguments.
+** When those function are used in a non-deterministic way, they will check
+** to see if they were called using OP_PureFunc instead of OP_Function, and
+** if they were, they throw an error.
**
-** See also: Function0, AggStep, AggFinal
+** See also: AggStep, AggFinal, Function
*/
-case OP_PureFunc0: /* group */
-case OP_Function0: { /* group */
- int n;
- sqlite3_context *pCtx;
-
- assert( pOp->p4type==P4_FUNCDEF );
- n = pOp->p5;
- assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
- assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
- pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
- if( pCtx==0 ) goto no_mem;
- pCtx->pOut = 0;
- pCtx->pFunc = pOp->p4.pFunc;
- pCtx->iOp = (int)(pOp - aOp);
- pCtx->pVdbe = p;
- pCtx->isError = 0;
- pCtx->argc = n;
- pOp->p4type = P4_FUNCCTX;
- pOp->p4.pCtx = pCtx;
- assert( OP_PureFunc == OP_PureFunc0+2 );
- assert( OP_Function == OP_Function0+2 );
- pOp->opcode += 2;
- /* Fall through into OP_Function */
-}
case OP_PureFunc: /* group */
case OP_Function: { /* group */
int i;
@@ -91466,9 +92785,11 @@ case OP_Function: { /* group */
** reinitializes the relavant parts of the sqlite3_context object */
pOut = &aMem[pOp->p3];
if( pCtx->pOut != pOut ){
+ pCtx->pVdbe = p;
pCtx->pOut = pOut;
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
+ assert( pCtx->pVdbe==p );
memAboutToChange(p, pOut);
#ifdef SQLITE_DEBUG
@@ -91640,6 +92961,55 @@ case OP_Abortable: {
}
#endif
+#ifdef SQLITE_DEBUG
+/* Opcode: ReleaseReg P1 P2 P3 * P5
+** Synopsis: release r[P1@P2] mask P3
+**
+** Release registers from service. Any content that was in the
+** the registers is unreliable after this opcode completes.
+**
+** The registers released will be the P2 registers starting at P1,
+** except if bit ii of P3 set, then do not release register P1+ii.
+** In other words, P3 is a mask of registers to preserve.
+**
+** Releasing a register clears the Mem.pScopyFrom pointer. That means
+** that if the content of the released register was set using OP_SCopy,
+** a change to the value of the source register for the OP_SCopy will no longer
+** generate an assertion fault in sqlite3VdbeMemAboutToChange().
+**
+** If P5 is set, then all released registers have their type set
+** to MEM_Undefined so that any subsequent attempt to read the released
+** register (before it is reinitialized) will generate an assertion fault.
+**
+** P5 ought to be set on every call to this opcode.
+** However, there are places in the code generator will release registers
+** before their are used, under the (valid) assumption that the registers
+** will not be reallocated for some other purpose before they are used and
+** hence are safe to release.
+**
+** This opcode is only available in testing and debugging builds. It is
+** not generated for release builds. The purpose of this opcode is to help
+** validate the generated bytecode. This opcode does not actually contribute
+** to computing an answer.
+*/
+case OP_ReleaseReg: {
+ Mem *pMem;
+ int i;
+ u32 constMask;
+ assert( pOp->p1>0 );
+ assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
+ pMem = &aMem[pOp->p1];
+ constMask = pOp->p3;
+ for(i=0; i<pOp->p2; i++, pMem++){
+ if( i>=32 || (constMask & MASKBIT32(i))==0 ){
+ pMem->pScopyFrom = 0;
+ if( i<32 && pOp->p5 ) MemSetTypeFlag(pMem, MEM_Undefined);
+ }
+ }
+ break;
+}
+#endif
+
/* Opcode: Noop * * * * *
**
** Do nothing. This instruction is often useful as a jump
@@ -91691,6 +93061,12 @@ default: { /* This is really OP_Noop, OP_Explain */
if( opProperty & OPFLG_OUT3 ){
registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
}
+ if( opProperty==0xff ){
+ /* Never happens. This code exists to avoid a harmless linkage
+ ** warning aboud sqlite3VdbeRegisterDump() being defined but not
+ ** used. */
+ sqlite3VdbeRegisterDump(p);
+ }
}
#endif /* SQLITE_DEBUG */
#endif /* NDEBUG */
@@ -91758,7 +93134,7 @@ no_mem:
** flag.
*/
abort_due_to_interrupt:
- assert( db->u1.isInterrupted );
+ assert( AtomicLoad(&db->u1.isInterrupted) );
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
p->rc = rc;
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
@@ -93096,8 +94472,8 @@ static int vdbeSorterCompareText(
int n2;
int res;
- getVarint32(&p1[1], n1);
- getVarint32(&p2[1], n2);
+ getVarint32NR(&p1[1], n1);
+ getVarint32NR(&p2[1], n2);
res = memcmp(v1, v2, (MIN(n1, n2) - 13)/2);
if( res==0 ){
res = n1 - n2;
@@ -93677,20 +95053,16 @@ static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
*/
static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
int i;
- SorterRecord **aSlot;
SorterRecord *p;
int rc;
+ SorterRecord *aSlot[64];
rc = vdbeSortAllocUnpacked(pTask);
if( rc!=SQLITE_OK ) return rc;
p = pList->pList;
pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
-
- aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
- if( !aSlot ){
- return SQLITE_NOMEM_BKPT;
- }
+ memset(aSlot, 0, sizeof(aSlot));
while( p ){
SorterRecord *pNext;
@@ -93715,13 +95087,12 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
}
p = 0;
- for(i=0; i<64; i++){
+ for(i=0; i<ArraySize(aSlot); i++){
if( aSlot[i]==0 ) continue;
p = p ? vdbeSorterMerge(pTask, p, aSlot[i]) : aSlot[i];
}
pList->pList = p;
- sqlite3_free(aSlot);
assert( pTask->pUnpacked->errCode==SQLITE_OK
|| pTask->pUnpacked->errCode==SQLITE_NOMEM
);
@@ -94059,7 +95430,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
assert( pCsr->eCurType==CURTYPE_SORTER );
pSorter = pCsr->uc.pSorter;
- getVarint32((const u8*)&pVal->z[1], t);
+ getVarint32NR((const u8*)&pVal->z[1], t);
if( t>0 && t<10 && t!=7 ){
pSorter->typeMask &= SORTER_TYPE_INTEGER;
}else if( t>10 && (t & 0x01) ){
@@ -95046,6 +96417,433 @@ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
}
/************** End of vdbesort.c ********************************************/
+/************** Begin file vdbevtab.c ****************************************/
+/*
+** 2020-03-23
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file implements virtual-tables for examining the bytecode content
+** of a prepared statement.
+*/
+/* #include "sqliteInt.h" */
+#if defined(SQLITE_ENABLE_BYTECODE_VTAB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
+/* #include "vdbeInt.h" */
+
+/* An instance of the bytecode() table-valued function.
+*/
+typedef struct bytecodevtab bytecodevtab;
+struct bytecodevtab {
+ sqlite3_vtab base; /* Base class - must be first */
+ sqlite3 *db; /* Database connection */
+ int bTablesUsed; /* 2 for tables_used(). 0 for bytecode(). */
+};
+
+/* A cursor for scanning through the bytecode
+*/
+typedef struct bytecodevtab_cursor bytecodevtab_cursor;
+struct bytecodevtab_cursor {
+ sqlite3_vtab_cursor base; /* Base class - must be first */
+ sqlite3_stmt *pStmt; /* The statement whose bytecode is displayed */
+ int iRowid; /* The rowid of the output table */
+ int iAddr; /* Address */
+ int needFinalize; /* Cursors owns pStmt and must finalize it */
+ int showSubprograms; /* Provide a listing of subprograms */
+ Op *aOp; /* Operand array */
+ char *zP4; /* Rendered P4 value */
+ const char *zType; /* tables_used.type */
+ const char *zSchema; /* tables_used.schema */
+ const char *zName; /* tables_used.name */
+ Mem sub; /* Subprograms */
+};
+
+/*
+** Create a new bytecode() table-valued function.
+*/
+static int bytecodevtabConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ bytecodevtab *pNew;
+ int rc;
+ int isTabUsed = pAux!=0;
+ const char *azSchema[2] = {
+ /* bytecode() schema */
+ "CREATE TABLE x("
+ "addr INT,"
+ "opcode TEXT,"
+ "p1 INT,"
+ "p2 INT,"
+ "p3 INT,"
+ "p4 TEXT,"
+ "p5 INT,"
+ "comment TEXT,"
+ "subprog TEXT,"
+ "stmt HIDDEN"
+ ");",
+
+ /* Tables_used() schema */
+ "CREATE TABLE x("
+ "type TEXT,"
+ "schema TEXT,"
+ "name TEXT,"
+ "wr INT,"
+ "subprog TEXT,"
+ "stmt HIDDEN"
+ ");"
+ };
+
+ rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
+ if( rc==SQLITE_OK ){
+ pNew = sqlite3_malloc( sizeof(*pNew) );
+ *ppVtab = (sqlite3_vtab*)pNew;
+ if( pNew==0 ) return SQLITE_NOMEM;
+ memset(pNew, 0, sizeof(*pNew));
+ pNew->db = db;
+ pNew->bTablesUsed = isTabUsed*2;
+ }
+ return rc;
+}
+
+/*
+** This method is the destructor for bytecodevtab objects.
+*/
+static int bytecodevtabDisconnect(sqlite3_vtab *pVtab){
+ bytecodevtab *p = (bytecodevtab*)pVtab;
+ sqlite3_free(p);
+ return SQLITE_OK;
+}
+
+/*
+** Constructor for a new bytecodevtab_cursor object.
+*/
+static int bytecodevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+ bytecodevtab *pVTab = (bytecodevtab*)p;
+ bytecodevtab_cursor *pCur;
+ pCur = sqlite3_malloc( sizeof(*pCur) );
+ if( pCur==0 ) return SQLITE_NOMEM;
+ memset(pCur, 0, sizeof(*pCur));
+ sqlite3VdbeMemInit(&pCur->sub, pVTab->db, 1);
+ *ppCursor = &pCur->base;
+ return SQLITE_OK;
+}
+
+/*
+** Clear all internal content from a bytecodevtab cursor.
+*/
+static void bytecodevtabCursorClear(bytecodevtab_cursor *pCur){
+ sqlite3_free(pCur->zP4);
+ pCur->zP4 = 0;
+ sqlite3VdbeMemRelease(&pCur->sub);
+ sqlite3VdbeMemSetNull(&pCur->sub);
+ if( pCur->needFinalize ){
+ sqlite3_finalize(pCur->pStmt);
+ }
+ pCur->pStmt = 0;
+ pCur->needFinalize = 0;
+ pCur->zType = 0;
+ pCur->zSchema = 0;
+ pCur->zName = 0;
+}
+
+/*
+** Destructor for a bytecodevtab_cursor.
+*/
+static int bytecodevtabClose(sqlite3_vtab_cursor *cur){
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
+ bytecodevtabCursorClear(pCur);
+ sqlite3_free(pCur);
+ return SQLITE_OK;
+}
+
+
+/*
+** Advance a bytecodevtab_cursor to its next row of output.
+*/
+static int bytecodevtabNext(sqlite3_vtab_cursor *cur){
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
+ bytecodevtab *pTab = (bytecodevtab*)cur->pVtab;
+ int rc;
+ if( pCur->zP4 ){
+ sqlite3_free(pCur->zP4);
+ pCur->zP4 = 0;
+ }
+ if( pCur->zName ){
+ pCur->zName = 0;
+ pCur->zType = 0;
+ pCur->zSchema = 0;
+ }
+ rc = sqlite3VdbeNextOpcode(
+ (Vdbe*)pCur->pStmt,
+ pCur->showSubprograms ? &pCur->sub : 0,
+ pTab->bTablesUsed,
+ &pCur->iRowid,
+ &pCur->iAddr,
+ &pCur->aOp);
+ if( rc!=SQLITE_OK ){
+ sqlite3VdbeMemSetNull(&pCur->sub);
+ pCur->aOp = 0;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Return TRUE if the cursor has been moved off of the last
+** row of output.
+*/
+static int bytecodevtabEof(sqlite3_vtab_cursor *cur){
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
+ return pCur->aOp==0;
+}
+
+/*
+** Return values of columns for the row at which the bytecodevtab_cursor
+** is currently pointing.
+*/
+static int bytecodevtabColumn(
+ sqlite3_vtab_cursor *cur, /* The cursor */
+ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
+ int i /* Which column to return */
+){
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
+ bytecodevtab *pVTab = (bytecodevtab*)cur->pVtab;
+ Op *pOp = pCur->aOp + pCur->iAddr;
+ if( pVTab->bTablesUsed ){
+ if( i==4 ){
+ i = 8;
+ }else{
+ if( i<=2 && pCur->zType==0 ){
+ Schema *pSchema;
+ HashElem *k;
+ int iDb = pOp->p3;
+ int iRoot = pOp->p2;
+ sqlite3 *db = pVTab->db;
+ pSchema = db->aDb[iDb].pSchema;
+ pCur->zSchema = db->aDb[iDb].zDbSName;
+ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
+ Table *pTab = (Table*)sqliteHashData(k);
+ if( !IsVirtual(pTab) && pTab->tnum==iRoot ){
+ pCur->zName = pTab->zName;
+ pCur->zType = "table";
+ break;
+ }
+ }
+ if( pCur->zName==0 ){
+ for(k=sqliteHashFirst(&pSchema->idxHash); k; k=sqliteHashNext(k)){
+ Index *pIdx = (Index*)sqliteHashData(k);
+ if( pIdx->tnum==iRoot ){
+ pCur->zName = pIdx->zName;
+ pCur->zType = "index";
+ }
+ }
+ }
+ }
+ i += 10;
+ }
+ }
+ switch( i ){
+ case 0: /* addr */
+ sqlite3_result_int(ctx, pCur->iAddr);
+ break;
+ case 1: /* opcode */
+ sqlite3_result_text(ctx, (char*)sqlite3OpcodeName(pOp->opcode),
+ -1, SQLITE_STATIC);
+ break;
+ case 2: /* p1 */
+ sqlite3_result_int(ctx, pOp->p1);
+ break;
+ case 3: /* p2 */
+ sqlite3_result_int(ctx, pOp->p2);
+ break;
+ case 4: /* p3 */
+ sqlite3_result_int(ctx, pOp->p3);
+ break;
+ case 5: /* p4 */
+ case 7: /* comment */
+ if( pCur->zP4==0 ){
+ pCur->zP4 = sqlite3VdbeDisplayP4(pVTab->db, pOp);
+ }
+ if( i==5 ){
+ sqlite3_result_text(ctx, pCur->zP4, -1, SQLITE_STATIC);
+ }else{
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+ char *zCom = sqlite3VdbeDisplayComment(pVTab->db, pOp, pCur->zP4);
+ sqlite3_result_text(ctx, zCom, -1, sqlite3_free);
+#endif
+ }
+ break;
+ case 6: /* p5 */
+ sqlite3_result_int(ctx, pOp->p5);
+ break;
+ case 8: { /* subprog */
+ Op *aOp = pCur->aOp;
+ assert( aOp[0].opcode==OP_Init );
+ assert( aOp[0].p4.z==0 || strncmp(aOp[0].p4.z,"-" "- ",3)==0 );
+ if( pCur->iRowid==pCur->iAddr+1 ){
+ break; /* Result is NULL for the main program */
+ }else if( aOp[0].p4.z!=0 ){
+ sqlite3_result_text(ctx, aOp[0].p4.z+3, -1, SQLITE_STATIC);
+ }else{
+ sqlite3_result_text(ctx, "(FK)", 4, SQLITE_STATIC);
+ }
+ break;
+ }
+ case 10: /* tables_used.type */
+ sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC);
+ break;
+ case 11: /* tables_used.schema */
+ sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC);
+ break;
+ case 12: /* tables_used.name */
+ sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC);
+ break;
+ case 13: /* tables_used.wr */
+ sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite);
+ break;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Return the rowid for the current row. In this implementation, the
+** rowid is the same as the output value.
+*/
+static int bytecodevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor*)cur;
+ *pRowid = pCur->iRowid;
+ return SQLITE_OK;
+}
+
+/*
+** Initialize a cursor.
+**
+** idxNum==0 means show all subprograms
+** idxNum==1 means show only the main bytecode and omit subprograms.
+*/
+static int bytecodevtabFilter(
+ sqlite3_vtab_cursor *pVtabCursor,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
+ bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
+ int rc = SQLITE_OK;
+
+ bytecodevtabCursorClear(pCur);
+ pCur->iRowid = 0;
+ pCur->iAddr = 0;
+ pCur->showSubprograms = idxNum==0;
+ assert( argc==1 );
+ if( sqlite3_value_type(argv[0])==SQLITE_TEXT ){
+ const char *zSql = (const char*)sqlite3_value_text(argv[0]);
+ if( zSql==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ rc = sqlite3_prepare_v2(pVTab->db, zSql, -1, &pCur->pStmt, 0);
+ pCur->needFinalize = 1;
+ }
+ }else{
+ pCur->pStmt = (sqlite3_stmt*)sqlite3_value_pointer(argv[0],"stmt-pointer");
+ }
+ if( pCur->pStmt==0 ){
+ pVTab->base.zErrMsg = sqlite3_mprintf(
+ "argument to %s() is not a valid SQL statement",
+ pVTab->bTablesUsed ? "tables_used" : "bytecode"
+ );
+ rc = SQLITE_ERROR;
+ }else{
+ bytecodevtabNext(pVtabCursor);
+ }
+ return rc;
+}
+
+/*
+** We must have a single stmt=? constraint that will be passed through
+** into the xFilter method. If there is no valid stmt=? constraint,
+** then return an SQLITE_CONSTRAINT error.
+*/
+static int bytecodevtabBestIndex(
+ sqlite3_vtab *tab,
+ sqlite3_index_info *pIdxInfo
+){
+ int i;
+ int rc = SQLITE_CONSTRAINT;
+ struct sqlite3_index_constraint *p;
+ bytecodevtab *pVTab = (bytecodevtab*)tab;
+ int iBaseCol = pVTab->bTablesUsed ? 4 : 8;
+ pIdxInfo->estimatedCost = (double)100;
+ pIdxInfo->estimatedRows = 100;
+ pIdxInfo->idxNum = 0;
+ for(i=0, p=pIdxInfo->aConstraint; i<pIdxInfo->nConstraint; i++, p++){
+ if( p->usable==0 ) continue;
+ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==iBaseCol+1 ){
+ rc = SQLITE_OK;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ }
+ if( p->op==SQLITE_INDEX_CONSTRAINT_ISNULL && p->iColumn==iBaseCol ){
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ pIdxInfo->idxNum = 1;
+ }
+ }
+ return rc;
+}
+
+/*
+** This following structure defines all the methods for the
+** virtual table.
+*/
+static sqlite3_module bytecodevtabModule = {
+ /* iVersion */ 0,
+ /* xCreate */ 0,
+ /* xConnect */ bytecodevtabConnect,
+ /* xBestIndex */ bytecodevtabBestIndex,
+ /* xDisconnect */ bytecodevtabDisconnect,
+ /* xDestroy */ 0,
+ /* xOpen */ bytecodevtabOpen,
+ /* xClose */ bytecodevtabClose,
+ /* xFilter */ bytecodevtabFilter,
+ /* xNext */ bytecodevtabNext,
+ /* xEof */ bytecodevtabEof,
+ /* xColumn */ bytecodevtabColumn,
+ /* xRowid */ bytecodevtabRowid,
+ /* xUpdate */ 0,
+ /* xBegin */ 0,
+ /* xSync */ 0,
+ /* xCommit */ 0,
+ /* xRollback */ 0,
+ /* xFindMethod */ 0,
+ /* xRename */ 0,
+ /* xSavepoint */ 0,
+ /* xRelease */ 0,
+ /* xRollbackTo */ 0,
+ /* xShadowName */ 0
+};
+
+
+SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){
+ int rc;
+ rc = sqlite3_create_module(db, "bytecode", &bytecodevtabModule, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3_create_module(db, "tables_used", &bytecodevtabModule, &db);
+ }
+ return rc;
+}
+#elif defined(SQLITE_ENABLE_BYTECODE_VTAB)
+SQLITE_PRIVATE int sqlite3VdbeBytecodeVtabInit(sqlite3 *db){ return SQLITE_OK; }
+#endif /* SQLITE_ENABLE_BYTECODE_VTAB */
+
+/************** End of vdbevtab.c ********************************************/
/************** Begin file memjournal.c **************************************/
/*
** 2008 October 7
@@ -95554,8 +97352,8 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc ) return rc & WRC_Abort;
if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
+ assert( pExpr->x.pList==0 || pExpr->pRight==0 );
if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
- assert( pExpr->x.pList==0 || pExpr->pRight==0 );
if( pExpr->pRight ){
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
pExpr = pExpr->pRight;
@@ -95637,15 +97435,16 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
struct SrcList_item *pItem;
pSrc = p->pSrc;
- assert( pSrc!=0 );
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
- return WRC_Abort;
- }
- if( pItem->fg.isTabFunc
- && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
- ){
- return WRC_Abort;
+ if( pSrc ){
+ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+ if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
+ return WRC_Abort;
+ }
+ if( pItem->fg.isTabFunc
+ && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
+ }
}
}
return WRC_Continue;
@@ -95688,6 +97487,43 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
return WRC_Continue;
}
+/* Increase the walkerDepth when entering a subquery, and
+** descrease when leaving the subquery.
+*/
+SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){
+ UNUSED_PARAMETER(pSelect);
+ pWalker->walkerDepth++;
+ return WRC_Continue;
+}
+SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker *pWalker, Select *pSelect){
+ UNUSED_PARAMETER(pSelect);
+ pWalker->walkerDepth--;
+}
+
+
+/*
+** No-op routine for the parse-tree walker.
+**
+** When this routine is the Walker.xExprCallback then expression trees
+** are walked without any actions being taken at each node. Presumably,
+** when this routine is used for Walker.xExprCallback then
+** Walker.xSelectCallback is set to do something useful for every
+** subquery in the parser tree.
+*/
+SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ return WRC_Continue;
+}
+
+/*
+** No-op routine for the parse-tree walker for SELECT statements.
+** subquery in the parser tree.
+*/
+SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){
+ UNUSED_PARAMETER2(NotUsed, NotUsed2);
+ return WRC_Continue;
+}
+
/************** End of walker.c **********************************************/
/************** Begin file resolve.c *****************************************/
/*
@@ -95716,6 +97552,8 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
**
** incrAggFunctionDepth(pExpr,n) is the main routine. incrAggDepth(..)
** is a helper function - a callback for the tree walker.
+**
+** See also the sqlite3WindowExtraAggFuncDepth() routine in window.c
*/
static int incrAggDepth(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
@@ -95824,13 +97662,16 @@ static int nameInUsingClause(IdList *pUsing, const char *zCol){
** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will
** match anything.
*/
-SQLITE_PRIVATE int sqlite3MatchSpanName(
- const char *zSpan,
+SQLITE_PRIVATE int sqlite3MatchEName(
+ const struct ExprList_item *pItem,
const char *zCol,
const char *zTab,
const char *zDb
){
int n;
+ const char *zSpan;
+ if( pItem->eEName!=ENAME_TAB ) return 0;
+ zSpan = pItem->zEName;
for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
return 0;
@@ -95865,6 +97706,31 @@ static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){
}
/*
+** The argument is guaranteed to be a non-NULL Expr node of type TK_COLUMN.
+** return the appropriate colUsed mask.
+*/
+SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){
+ int n;
+ Table *pExTab;
+
+ n = pExpr->iColumn;
+ pExTab = pExpr->y.pTab;
+ assert( pExTab!=0 );
+ if( (pExTab->tabFlags & TF_HasGenerated)!=0
+ && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
+ ){
+ testcase( pExTab->nCol==BMS-1 );
+ testcase( pExTab->nCol==BMS );
+ return pExTab->nCol>=BMS ? ALLBITS : MASKBIT(pExTab->nCol)-1;
+ }else{
+ testcase( n==BMS-1 );
+ testcase( n==BMS );
+ if( n>=BMS ) n = BMS-1;
+ return ((Bitmask)1)<<n;
+ }
+}
+
+/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
** expression node refer back to that source column. The following changes
@@ -95941,6 +97807,12 @@ static int lookupName(
break;
}
}
+ if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){
+ /* This branch is taken when the main database has been renamed
+ ** using SQLITE_DBCONFIG_MAINDBNAME. */
+ pSchema = db->aDb[0].pSchema;
+ zDb = db->aDb[0].zDbSName;
+ }
}
}
@@ -95952,6 +97824,7 @@ static int lookupName(
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
+ u8 hCol;
pTab = pItem->pTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 );
@@ -95959,7 +97832,7 @@ static int lookupName(
int hit = 0;
pEList = pItem->pSelect->pEList;
for(j=0; j<pEList->nExpr; j++){
- if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
+ if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
cnt++;
cntTab = 2;
pMatch = pItem;
@@ -95985,8 +97858,9 @@ static int lookupName(
if( 0==(cntTab++) ){
pMatch = pItem;
}
+ hCol = sqlite3StrIHash(zCol);
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
- if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
+ if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
/* If there has been exactly one prior match and this match
** is for the right-hand table of a NATURAL JOIN or is in a
** USING clause, then skip this match.
@@ -96047,10 +97921,11 @@ static int lookupName(
if( pTab ){
int iCol;
+ u8 hCol = sqlite3StrIHash(zCol);
pSchema = pTab->pSchema;
cntTab++;
for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){
- if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
+ if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){
if( iCol==pTab->iPKey ){
iCol = -1;
}
@@ -96106,7 +97981,7 @@ static int lookupName(
if( cnt==0
&& cntTab==1
&& pMatch
- && (pNC->ncFlags & NC_IdxExpr)==0
+ && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0
&& sqlite3IsRowid(zCol)
&& VisibleRowid(pMatch->pTab)
){
@@ -96140,8 +98015,10 @@ static int lookupName(
pEList = pNC->uNC.pEList;
assert( pEList!=0 );
for(j=0; j<pEList->nExpr; j++){
- char *zAs = pEList->a[j].zName;
- if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
+ char *zAs = pEList->a[j].zEName;
+ if( pEList->a[j].eEName==ENAME_NAME
+ && sqlite3_stricmp(zAs, zCol)==0
+ ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
@@ -96151,7 +98028,9 @@ static int lookupName(
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
- if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
+ if( ExprHasProperty(pOrig, EP_Win)
+ && ((pNC->ncFlags&NC_AllowWin)==0 || pNC!=pTopNC )
+ ){
sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
return WRC_Abort;
}
@@ -96243,18 +98122,20 @@ static int lookupName(
/* If a column from a table in pSrcList is referenced, then record
** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes
- ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the
- ** column number is greater than the number of bits in the bitmask
- ** then set the high-order bit of the bitmask.
+ ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is
+ ** set if the 63rd or any subsequent column is used.
+ **
+ ** The colUsed mask is an optimization used to help determine if an
+ ** index is a covering index. The correct answer is still obtained
+ ** if the mask contains extra set bits. However, it is important to
+ ** avoid setting bits beyond the maximum column number of the table.
+ ** (See ticket [b92e5e8ec2cdbaa1]).
+ **
+ ** If a generated column is referenced, set bits for every column
+ ** of the table.
*/
if( pExpr->iColumn>=0 && pMatch!=0 ){
- int n = pExpr->iColumn;
- testcase( n==BMS-1 );
- if( n>=BMS ){
- n = BMS-1;
- }
- assert( pMatch->iCursor==pExpr->iTable );
- pMatch->colUsed |= ((Bitmask)1)<<n;
+ pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
}
/* Clean up and return
@@ -96293,15 +98174,23 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
if( p ){
struct SrcList_item *pItem = &pSrc->a[iSrc];
- p->y.pTab = pItem->pTab;
+ Table *pTab = p->y.pTab = pItem->pTab;
p->iTable = pItem->iCursor;
if( p->y.pTab->iPKey==iCol ){
p->iColumn = -1;
}else{
p->iColumn = (ynVar)iCol;
- testcase( iCol==BMS );
- testcase( iCol==BMS-1 );
- pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
+ if( (pTab->tabFlags & TF_HasGenerated)!=0
+ && (pTab->aCol[iCol].colFlags & COLFLAG_GENERATED)!=0
+ ){
+ testcase( pTab->nCol==63 );
+ testcase( pTab->nCol==64 );
+ pItem->colUsed = pTab->nCol>=64 ? ALLBITS : MASKBIT(pTab->nCol)-1;
+ }else{
+ testcase( iCol==BMS );
+ testcase( iCol==BMS-1 );
+ pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
+ }
}
}
return p;
@@ -96310,23 +98199,39 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr
/*
** Report an error that an expression is not valid for some set of
** pNC->ncFlags values determined by validMask.
-*/
-static void notValid(
- Parse *pParse, /* Leave error message here */
- NameContext *pNC, /* The name context */
- const char *zMsg, /* Type of error */
- int validMask /* Set of contexts for which prohibited */
-){
- assert( (validMask&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr))==0 );
- if( (pNC->ncFlags & validMask)!=0 ){
- const char *zIn = "partial index WHERE clauses";
- if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
+**
+** static void notValid(
+** Parse *pParse, // Leave error message here
+** NameContext *pNC, // The name context
+** const char *zMsg, // Type of error
+** int validMask, // Set of contexts for which prohibited
+** Expr *pExpr // Invalidate this expression on error
+** ){...}
+**
+** As an optimization, since the conditional is almost always false
+** (because errors are rare), the conditional is moved outside of the
+** function call using a macro.
+*/
+static void notValidImpl(
+ Parse *pParse, /* Leave error message here */
+ NameContext *pNC, /* The name context */
+ const char *zMsg, /* Type of error */
+ Expr *pExpr /* Invalidate this expression on error */
+){
+ const char *zIn = "partial index WHERE clauses";
+ if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions";
#ifndef SQLITE_OMIT_CHECK
- else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
+ else if( pNC->ncFlags & NC_IsCheck ) zIn = "CHECK constraints";
#endif
- sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
- }
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns";
+#endif
+ sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn);
+ if( pExpr ) pExpr->op = TK_NULL;
}
+#define sqlite3ResolveNotValid(P,N,M,X,E) \
+ assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \
+ if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E);
/*
** Expression p should encode a floating point value between 1.0 and 0.0.
@@ -96415,7 +98320,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
zColumn = pExpr->u.zToken;
}else{
Expr *pLeft = pExpr->pLeft;
- notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
+ testcase( pNC->ncFlags & NC_IdxExpr );
+ testcase( pNC->ncFlags & NC_GenCol );
+ sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator",
+ NC_IdxExpr|NC_GenCol, 0);
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
zDb = 0;
@@ -96504,33 +98412,39 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
/* For the purposes of the EP_ConstFunc flag, date and time
** functions and other functions that change slowly are considered
- ** constant because they are constant for the duration of one query */
+ ** constant because they are constant for the duration of one query.
+ ** This allows them to be factored out of inner loops. */
ExprSetProperty(pExpr,EP_ConstFunc);
}
if( (pDef->funcFlags & SQLITE_FUNC_CONSTANT)==0 ){
- /* Date/time functions that use 'now', and other functions like
+ /* Clearly non-deterministic functions like random(), but also
+ ** date/time functions that use 'now', and other functions like
** sqlite_version() that might change over time cannot be used
- ** in an index. */
- notValid(pParse, pNC, "non-deterministic functions",
- NC_IdxExpr|NC_PartIdx);
+ ** in an index or generated column. Curiously, they can be used
+ ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
+ ** all this. */
+ sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
+ NC_IdxExpr|NC_PartIdx|NC_GenCol, 0);
+ }else{
+ assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
+ pExpr->op2 = pNC->ncFlags & NC_SelfRef;
+ if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
}
if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
&& pParse->nested==0
- && sqlite3Config.bInternalFunctions==0
+ && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0
){
/* Internal-use-only functions are disallowed unless the
- ** SQL is being compiled using sqlite3NestedParse() */
+ ** SQL is being compiled using sqlite3NestedParse() or
+ ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be
+ ** used to activate internal functionsn for testing purposes */
no_such_func = 1;
pDef = 0;
}else
- if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
- && ExprHasProperty(pExpr, EP_Indirect)
+ if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
&& !IN_RENAME_OBJECT
){
- /* Functions tagged with SQLITE_DIRECTONLY may not be used
- ** inside of triggers and views */
- sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views",
- pDef->zName);
+ sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
}
}
@@ -96611,7 +98525,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
Select *pSel = pNC->pWinSelect;
assert( pWin==pExpr->y.pWin );
if( IN_RENAME_OBJECT==0 ){
- sqlite3WindowUpdate(pParse, pSel->pWinDefn, pWin, pDef);
+ sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
}
sqlite3WalkExprList(pWalker, pWin->pPartition);
sqlite3WalkExprList(pWalker, pWin->pOrderBy);
@@ -96656,7 +98570,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
- notValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
+ testcase( pNC->ncFlags & NC_IsCheck );
+ testcase( pNC->ncFlags & NC_PartIdx );
+ testcase( pNC->ncFlags & NC_IdxExpr );
+ testcase( pNC->ncFlags & NC_GenCol );
+ sqlite3ResolveNotValid(pParse, pNC, "subqueries",
+ NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
@@ -96667,7 +98586,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
break;
}
case TK_VARIABLE: {
- notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
+ testcase( pNC->ncFlags & NC_IsCheck );
+ testcase( pNC->ncFlags & NC_PartIdx );
+ testcase( pNC->ncFlags & NC_IdxExpr );
+ testcase( pNC->ncFlags & NC_GenCol );
+ sqlite3ResolveNotValid(pParse, pNC, "parameters",
+ NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);
break;
}
case TK_IS:
@@ -96676,7 +98600,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( !ExprHasProperty(pExpr, EP_Reduced) );
/* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE",
** and "x IS NOT FALSE". */
- if( pRight->op==TK_ID ){
+ if( pRight && pRight->op==TK_ID ){
int rc = resolveExprStep(pWalker, pRight);
if( rc==WRC_Abort ) return WRC_Abort;
if( pRight->op==TK_TRUEFALSE ){
@@ -96749,8 +98673,9 @@ static int resolveAsName(
if( pE->op==TK_ID ){
char *zCol = pE->u.zToken;
for(i=0; i<pEList->nExpr; i++){
- char *zAs = pEList->a[i].zName;
- if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
+ if( pEList->a[i].eEName==ENAME_NAME
+ && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0
+ ){
return i+1;
}
}
@@ -96801,7 +98726,7 @@ static int resolveOrderByTermToExprList(
nc.nErr = 0;
db = pParse->db;
savedSuppErr = db->suppressErr;
- db->suppressErr = 1;
+ if( IN_RENAME_OBJECT==0 ) db->suppressErr = 1;
rc = sqlite3ResolveExprNames(&nc, pE);
db->suppressErr = savedSuppErr;
if( rc ) return 0;
@@ -97436,11 +99361,41 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames(
ExprList *pList /* The expression list to be analyzed. */
){
int i;
- if( pList ){
- for(i=0; i<pList->nExpr; i++){
- if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort;
+ int savedHasAgg = 0;
+ Walker w;
+ if( pList==0 ) return WRC_Continue;
+ w.pParse = pNC->pParse;
+ w.xExprCallback = resolveExprStep;
+ w.xSelectCallback = resolveSelectStep;
+ w.xSelectCallback2 = 0;
+ w.u.pNC = pNC;
+ savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
+ pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
+ for(i=0; i<pList->nExpr; i++){
+ Expr *pExpr = pList->a[i].pExpr;
+ if( pExpr==0 ) continue;
+#if SQLITE_MAX_EXPR_DEPTH>0
+ w.pParse->nHeight += pExpr->nHeight;
+ if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){
+ return WRC_Abort;
}
+#endif
+ sqlite3WalkExpr(&w, pExpr);
+#if SQLITE_MAX_EXPR_DEPTH>0
+ w.pParse->nHeight -= pExpr->nHeight;
+#endif
+ assert( EP_Agg==NC_HasAgg );
+ assert( EP_Win==NC_HasWin );
+ testcase( pNC->ncFlags & NC_HasAgg );
+ testcase( pNC->ncFlags & NC_HasWin );
+ if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin) ){
+ ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
+ savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
+ pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
+ }
+ if( pNC->nErr>0 || w.pParse->nErr>0 ) return WRC_Abort;
}
+ pNC->ncFlags |= savedHasAgg;
return WRC_Continue;
}
@@ -97476,10 +99431,13 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
** Resolve names in expressions that can only reference a single table
** or which cannot reference any tables at all. Examples:
**
-** (1) CHECK constraints
-** (2) WHERE clauses on partial indices
-** (3) Expressions in indexes on expressions
-** (4) Expression arguments to VACUUM INTO.
+** "type" flag
+** ------------
+** (1) CHECK constraints NC_IsCheck
+** (2) WHERE clauses on partial indices NC_PartIdx
+** (3) Expressions in indexes on expressions NC_IdxExpr
+** (4) Expression arguments to VACUUM INTO. 0
+** (5) GENERATED ALWAYS as expressions NC_GenCol
**
** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
** nodes of the expression is set to -1 and the Expr.iColumn value is
@@ -97488,18 +99446,19 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames(
** Any errors cause an error message to be set in pParse.
*/
SQLITE_PRIVATE int sqlite3ResolveSelfReference(
- Parse *pParse, /* Parsing context */
- Table *pTab, /* The table being referenced, or NULL */
- int type, /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
- Expr *pExpr, /* Expression to resolve. May be NULL. */
- ExprList *pList /* Expression list to resolve. May be NULL. */
+ Parse *pParse, /* Parsing context */
+ Table *pTab, /* The table being referenced, or NULL */
+ int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */
+ Expr *pExpr, /* Expression to resolve. May be NULL. */
+ ExprList *pList /* Expression list to resolve. May be NULL. */
){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
int rc;
assert( type==0 || pTab!=0 );
- assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
+ assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr
+ || type==NC_GenCol || pTab==0 );
memset(&sNC, 0, sizeof(sNC));
memset(&sSrc, 0, sizeof(sSrc));
if( pTab ){
@@ -97507,6 +99466,11 @@ SQLITE_PRIVATE int sqlite3ResolveSelfReference(
sSrc.a[0].zName = pTab->zName;
sSrc.a[0].pTab = pTab;
sSrc.a[0].iCursor = -1;
+ if( pTab->pSchema!=pParse->db->aDb[1].pSchema ){
+ /* Cause EP_FromDDL to be set on TK_FUNCTION nodes of non-TEMP
+ ** schema elements */
+ type |= NC_FromDDL;
+ }
}
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
@@ -97562,10 +99526,10 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){
** SELECT a AS b FROM t1 WHERE b;
** SELECT * FROM t1 WHERE (select a from t1);
*/
-SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
+SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
int op;
while( ExprHasProperty(pExpr, EP_Skip) ){
- assert( pExpr->op==TK_COLLATE );
+ assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
assert( pExpr!=0 );
}
@@ -97590,6 +99554,9 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
);
}
+ if( op==TK_VECTOR ){
+ return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
+ }
return pExpr->affExpr;
}
@@ -97629,7 +99596,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
*/
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){
- assert( pExpr->op==TK_COLLATE );
+ assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
}
return pExpr;
@@ -97648,7 +99615,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
}else{
- assert( pExpr->op==TK_COLLATE );
+ assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW );
pExpr = pExpr->pLeft;
}
}
@@ -97669,10 +99636,10 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
** COLLATE operators take first precedence. Left operands take
** precedence over right operands.
*/
-SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
+SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
sqlite3 *db = pParse->db;
CollSeq *pColl = 0;
- Expr *p = pExpr;
+ const Expr *p = pExpr;
while( p ){
int op = p->op;
if( op==TK_REGISTER ) op = p->op2;
@@ -97692,6 +99659,10 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
p = p->pLeft;
continue;
}
+ if( op==TK_VECTOR ){
+ p = p->x.pList->a[0].pExpr;
+ continue;
+ }
if( op==TK_COLLATE ){
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
break;
@@ -97703,12 +99674,12 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
Expr *pNext = p->pRight;
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( p->x.pList==0 || p->pRight==0 );
- /* p->flags holds EP_Collate and p->pLeft->flags does not. And
- ** p->x.pSelect cannot. So if p->x.pLeft exists, it must hold at
- ** least one EP_Collate. Thus the following two ALWAYS. */
- if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
+ if( p->x.pList!=0
+ && !db->mallocFailed
+ && ALWAYS(!ExprHasProperty(p, EP_xIsSelect))
+ ){
int i;
- for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
+ for(i=0; i<p->x.pList->nExpr; i++){
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
pNext = p->x.pList->a[i].pExpr;
break;
@@ -97737,7 +99708,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
** The sqlite3ExprCollSeq() routine works the same except that it
** returns NULL if there is no defined collation.
*/
-SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr){
CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
if( p==0 ) p = pParse->db->pDfltColl;
assert( p!=0 );
@@ -97747,7 +99718,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
/*
** Return TRUE if the two expressions have equivalent collating sequences.
*/
-SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, const Expr *pE1, const Expr *pE2){
CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
@@ -97758,7 +99729,7 @@ SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
** type affinity of the other operand. This routine returns the
** type affinity that should be used for the comparison operator.
*/
-SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){
+SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2){
char aff1 = sqlite3ExprAffinity(pExpr);
if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){
/* Both sides of the comparison are columns. If one has numeric
@@ -97780,7 +99751,7 @@ SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){
** pExpr is a comparison operator. Return the type affinity that should
** be applied to both operands prior to doing the comparison.
*/
-static char comparisonAffinity(Expr *pExpr){
+static char comparisonAffinity(const Expr *pExpr){
char aff;
assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
@@ -97803,7 +99774,7 @@ static char comparisonAffinity(Expr *pExpr){
** if the index with affinity idx_affinity may be used to implement
** the comparison in pExpr.
*/
-SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
+SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity){
char aff = comparisonAffinity(pExpr);
if( aff<SQLITE_AFF_TEXT ){
return 1;
@@ -97818,7 +99789,11 @@ SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){
** Return the P5 value that should be used for a binary comparison
** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
*/
-static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
+static u8 binaryCompareP5(
+ const Expr *pExpr1, /* Left operand */
+ const Expr *pExpr2, /* Right operand */
+ int jumpIfNull /* Extra flags added to P5 */
+){
u8 aff = (char)sqlite3ExprAffinity(pExpr2);
aff = (u8)sqlite3CompareAffinity(pExpr1, aff) | (u8)jumpIfNull;
return aff;
@@ -97838,8 +99813,8 @@ static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
*/
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(
Parse *pParse,
- Expr *pLeft,
- Expr *pRight
+ const Expr *pLeft,
+ const Expr *pRight
){
CollSeq *pColl;
assert( pLeft );
@@ -97856,6 +99831,22 @@ SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(
return pColl;
}
+/* Expresssion p is a comparison operator. Return a collation sequence
+** appropriate for the comparison operator.
+**
+** This is normally just a wrapper around sqlite3BinaryCompareCollSeq().
+** However, if the OP_Commuted flag is set, then the order of the operands
+** is reversed in the sqlite3BinaryCompareCollSeq() call so that the
+** correct collating sequence is found.
+*/
+SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, const Expr *p){
+ if( ExprHasProperty(p, EP_Commuted) ){
+ return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft);
+ }else{
+ return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight);
+ }
+}
+
/*
** Generate code for a comparison operator.
*/
@@ -97866,13 +99857,19 @@ static int codeCompare(
int opcode, /* The comparison opcode */
int in1, int in2, /* Register holding operands */
int dest, /* Jump here if true. */
- int jumpIfNull /* If true, jump if either operand is NULL */
+ int jumpIfNull, /* If true, jump if either operand is NULL */
+ int isCommuted /* The comparison has been commuted */
){
int p5;
int addr;
CollSeq *p4;
- p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
+ if( pParse->nErr ) return 0;
+ if( isCommuted ){
+ p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft);
+ }else{
+ p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
+ }
p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
(void*)p4, P4_COLLSEQ);
@@ -98083,7 +100080,10 @@ static void codeVectorCompare(
int regRight = 0;
u8 opx = op;
int addrDone = sqlite3VdbeMakeLabel(pParse);
+ int isCommuted = ExprHasProperty(pExpr,EP_Commuted);
+ assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
+ if( pParse->nErr ) return;
if( nLeft!=sqlite3ExprVectorSize(pRight) ){
sqlite3ErrorMsg(pParse, "row value misused");
return;
@@ -98112,7 +100112,7 @@ static void codeVectorCompare(
assert( i>=0 && i<nLeft );
r1 = exprVectorRegister(pParse, pLeft, i, regLeft, &pL, &regFree1);
r2 = exprVectorRegister(pParse, pRight, i, regRight, &pR, &regFree2);
- codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5);
+ codeCompare(pParse, pL, pR, opx, r1, r2, dest, p5, isCommuted);
testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
@@ -98422,9 +100422,11 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
return pRight;
}else if( pRight==0 ){
return pLeft;
- }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){
- sqlite3ExprUnmapAndDelete(pParse, pLeft);
- sqlite3ExprUnmapAndDelete(pParse, pRight);
+ }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight))
+ && !IN_RENAME_OBJECT
+ ){
+ sqlite3ExprDelete(db, pLeft);
+ sqlite3ExprDelete(db, pRight);
return sqlite3Expr(db, TK_INTEGER, "0");
}else{
return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
@@ -98461,6 +100463,40 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(
}
/*
+** Check to see if a function is usable according to current access
+** rules:
+**
+** SQLITE_FUNC_DIRECT - Only usable from top-level SQL
+**
+** SQLITE_FUNC_UNSAFE - Usable if TRUSTED_SCHEMA or from
+** top-level SQL
+**
+** If the function is not usable, create an error.
+*/
+SQLITE_PRIVATE void sqlite3ExprFunctionUsable(
+ Parse *pParse, /* Parsing and code generating context */
+ Expr *pExpr, /* The function invocation */
+ FuncDef *pDef /* The function being invoked */
+){
+ assert( !IN_RENAME_OBJECT );
+ assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 );
+ if( ExprHasProperty(pExpr, EP_FromDDL) ){
+ if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
+ || (pParse->db->flags & SQLITE_TrustedSchema)==0
+ ){
+ /* Functions prohibited in triggers and views if:
+ ** (1) tagged with SQLITE_DIRECTONLY
+ ** (2) not tagged with SQLITE_INNOCUOUS (which means it
+ ** is tagged with SQLITE_FUNC_UNSAFE) and
+ ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning
+ ** that the schema is possibly tainted).
+ */
+ sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName);
+ }
+ }
+}
+
+/*
** Assign a variable number to an expression that encodes a wildcard
** in the original SQL statement.
**
@@ -98659,7 +100695,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasProperty(p, EP_FromJoin) );
assert( !ExprHasProperty(p, EP_MemToken) );
- assert( !ExprHasProperty(p, EP_NoReduce) );
+ assert( !ExprHasVVAProperty(p, EP_NoReduce) );
if( p->pLeft || p->x.pList ){
nSize = EXPR_REDUCEDSIZE | EP_Reduced;
}else{
@@ -98764,6 +100800,10 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static|EP_MemToken);
pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
pNew->flags |= staticFlag;
+ ExprClearVVAProperties(pNew);
+ if( dupFlags ){
+ ExprSetVVAProperty(pNew, EP_Immutable);
+ }
/* Copy the p->u.zToken string, if any. */
if( nToken ){
@@ -98927,12 +100967,11 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
pNewExpr->pLeft = pPriorSelectCol;
}
}
- pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
- pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
+ pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
pItem->sortFlags = pOldItem->sortFlags;
+ pItem->eEName = pOldItem->eEName;
pItem->done = 0;
pItem->bNulls = pOldItem->bNulls;
- pItem->bSpanIsTab = pOldItem->bSpanIsTab;
pItem->bSorterRef = pOldItem->bSorterRef;
pItem->u = pOldItem->u;
}
@@ -99099,9 +101138,9 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
pList = pNew;
}
pItem = &pList->a[pList->nExpr++];
- assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
+ assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) );
assert( offsetof(struct ExprList_item,pExpr)==0 );
- memset(&pItem->zName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zName));
+ memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName));
pItem->pExpr = pExpr;
return pList;
@@ -99158,7 +101197,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
if( pList ){
assert( pList->nExpr==iFirst+i+1 );
- pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
+ pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName;
pColumns->a[i].zName = 0;
}
}
@@ -99218,7 +101257,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int
}
/*
-** Set the ExprList.a[].zName element of the most recently added item
+** Set the ExprList.a[].zEName element of the most recently added item
** on the expression list.
**
** pList might be NULL following an OOM error. But pName should never be
@@ -99232,15 +101271,22 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(
int dequote /* True to cause the name to be dequoted */
){
assert( pList!=0 || pParse->db->mallocFailed!=0 );
+ assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
if( pList ){
struct ExprList_item *pItem;
assert( pList->nExpr>0 );
pItem = &pList->a[pList->nExpr-1];
- assert( pItem->zName==0 );
- pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
- if( dequote ) sqlite3Dequote(pItem->zName);
- if( IN_RENAME_OBJECT ){
- sqlite3RenameTokenMap(pParse, (void*)pItem->zName, pName);
+ assert( pItem->zEName==0 );
+ assert( pItem->eEName==ENAME_NAME );
+ pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
+ if( dequote ){
+ /* If dequote==0, then pName->z does not point to part of a DDL
+ ** statement handled by the parser. And so no token need be added
+ ** to the token-map. */
+ sqlite3Dequote(pItem->zEName);
+ if( IN_RENAME_OBJECT ){
+ sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
+ }
}
}
}
@@ -99264,8 +101310,10 @@ SQLITE_PRIVATE void sqlite3ExprListSetSpan(
if( pList ){
struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
assert( pList->nExpr>0 );
- sqlite3DbFree(db, pItem->zSpan);
- pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd);
+ if( pItem->zEName==0 ){
+ pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd);
+ pItem->eEName = ENAME_SPAN;
+ }
}
}
@@ -99295,8 +101343,7 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){
assert( pList->nExpr>0 );
do{
sqlite3ExprDelete(db, pItem->pExpr);
- sqlite3DbFree(db, pItem->zName);
- sqlite3DbFree(db, pItem->zSpan);
+ sqlite3DbFree(db, pItem->zEName);
pItem++;
}while( --i>0 );
sqlite3DbFreeNN(db, pList);
@@ -99335,18 +101382,33 @@ SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
}
/*
+** Check the input string to see if it is "true" or "false" (in any case).
+**
+** If the string is.... Return
+** "true" EP_IsTrue
+** "false" EP_IsFalse
+** anything else 0
+*/
+SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char *zIn){
+ if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue;
+ if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse;
+ return 0;
+}
+
+
+/*
** If the input expression is an ID with the name "true" or "false"
** then convert it into an TK_TRUEFALSE term. Return non-zero if
** the conversion happened, and zero if the expression is unaltered.
*/
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
+ u32 v;
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
if( !ExprHasProperty(pExpr, EP_Quoted)
- && (sqlite3StrICmp(pExpr->u.zToken, "true")==0
- || sqlite3StrICmp(pExpr->u.zToken, "false")==0)
+ && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0
){
pExpr->op = TK_TRUEFALSE;
- ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse);
+ ExprSetProperty(pExpr, v);
return 1;
}
return 0;
@@ -99408,10 +101470,11 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
** is found to not be a constant.
**
-** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
-** in a CREATE TABLE statement. The Walker.eCode value is 5 when parsing
-** an existing schema and 4 when processing a new statement. A bound
-** parameter raises an error for new statements, but is silently converted
+** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT
+** expressions in a CREATE TABLE statement. The Walker.eCode value is 5
+** when parsing an existing schema out of the sqlite_master table and 4
+** when processing a new CREATE TABLE statement. A bound parameter raises
+** an error for new statements, but is silently converted
** to NULL for existing schemas. This allows sqlite_master tables that
** contain a bound parameter because they were generated by older versions
** of SQLite to be parsed by newer versions of SQLite without raising a
@@ -99432,7 +101495,10 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
** and either pWalker->eCode==4 or 5 or the function has the
** SQLITE_FUNC_CONST flag. */
case TK_FUNCTION:
- if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
+ if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc))
+ && !ExprHasProperty(pExpr, EP_WinFunc)
+ ){
+ if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL);
return WRC_Continue;
}else{
pWalker->eCode = 0;
@@ -99520,7 +101586,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
**
** When this routine returns true, it indicates that the expression
** can be added to the pParse->pConstExpr list and evaluated once when
-** the prepared statement starts up. See sqlite3ExprCodeAtInit().
+** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
*/
SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
return exprIsConst(p, 2, 0);
@@ -99596,9 +101662,21 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprLi
}
/*
-** Walk an expression tree. Return non-zero if the expression is constant
-** or a function call with constant arguments. Return and 0 if there
-** are any variables.
+** Walk an expression tree for the DEFAULT field of a column definition
+** in a CREATE TABLE statement. Return non-zero if the expression is
+** acceptable for use as a DEFAULT. That is to say, return non-zero if
+** the expression is constant or a function call with constant arguments.
+** Return and 0 if there are any variables.
+**
+** isInit is true when parsing from sqlite_master. isInit is false when
+** processing a new CREATE TABLE statement. When isInit is true, parameters
+** (such as ? or $abc) in the expression are converted into NULL. When
+** isInit is false, parameters raise an error. Parameters should not be
+** allowed in a CREATE TABLE statement, but some legacy versions of SQLite
+** allowed it, so we need to support it when reading sqlite_master for
+** backwards compatibility.
+**
+** If isInit is true, set EP_FromDDL on every TK_FUNCTION node.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
@@ -99695,7 +101773,9 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
case TK_COLUMN:
return ExprHasProperty(p, EP_CanBeNull) ||
p->y.pTab==0 || /* Reference to column of index on expression */
- (p->iColumn>=0 && p->y.pTab->aCol[p->iColumn].notNull==0);
+ (p->iColumn>=0
+ && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */
+ && p->y.pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
}
@@ -100172,8 +102252,10 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){
** "sub-select returns N columns - expected M"
*/
SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){
- const char *zFmt = "sub-select returns %d columns - expected %d";
- sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
+ if( pParse->nErr==0 ){
+ const char *zFmt = "sub-select returns %d columns - expected %d";
+ sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect);
+ }
}
#endif
@@ -100267,6 +102349,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
/* Begin coding the subroutine */
ExprSetProperty(pExpr, EP_Subrtn);
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr =
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
@@ -100348,6 +102431,8 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
affinity = sqlite3ExprAffinity(pLeft);
if( affinity<=SQLITE_AFF_NONE ){
affinity = SQLITE_AFF_BLOB;
+ }else if( affinity==SQLITE_AFF_REAL ){
+ affinity = SQLITE_AFF_NUMERIC;
}
if( pKeyInfo ){
assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
@@ -100586,7 +102671,9 @@ static void sqlite3ExprCodeIN(
int destNotNull; /* Jump here if a comparison is not true in step 6 */
int addrTop; /* Top of the step-6 loop */
int iTab = 0; /* Index to use */
+ u8 okConstFactor = pParse->okConstFactor;
+ assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
pLeft = pExpr->pLeft;
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
zAff = exprINAffinity(pParse, pExpr);
@@ -100629,8 +102716,14 @@ static void sqlite3ExprCodeIN(
** so that the fields are in the same order as an existing index. The
** aiMap[] array contains a mapping from the original LHS field order to
** the field order that matches the RHS index.
- */
+ **
+ ** Avoid factoring the LHS of the IN(...) expression out of the loop,
+ ** even if it is constant, as OP_Affinity may be used on the register
+ ** by code generated below. */
+ assert( pParse->okConstFactor==okConstFactor );
+ pParse->okConstFactor = 0;
rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
+ pParse->okConstFactor = okConstFactor;
for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
if( i==nVector ){
/* LHS fields are not reordered */
@@ -100656,37 +102749,35 @@ static void sqlite3ExprCodeIN(
int r2, regToFree;
int regCkNull = 0;
int ii;
- int bLhsReal; /* True if the LHS of the IN has REAL affinity */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
}
- bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL;
for(ii=0; ii<pList->nExpr; ii++){
- if( bLhsReal ){
- r2 = regToFree = sqlite3GetTempReg(pParse);
- sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2);
- sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC);
- }else{
- r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
- }
+ r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
}
+ sqlite3ReleaseTempReg(pParse, regToFree);
if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){
- sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2,
+ int op = rLhs!=r2 ? OP_Eq : OP_NotNull;
+ sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2,
(void*)pColl, P4_COLLSEQ);
- VdbeCoverageIf(v, ii<pList->nExpr-1);
- VdbeCoverageIf(v, ii==pList->nExpr-1);
+ VdbeCoverageIf(v, ii<pList->nExpr-1 && op==OP_Eq);
+ VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq);
+ VdbeCoverageIf(v, ii<pList->nExpr-1 && op==OP_NotNull);
+ VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull);
sqlite3VdbeChangeP5(v, zAff[0]);
}else{
+ int op = rLhs!=r2 ? OP_Ne : OP_IsNull;
assert( destIfNull==destIfFalse );
- sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2,
- (void*)pColl, P4_COLLSEQ); VdbeCoverage(v);
+ sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2,
+ (void*)pColl, P4_COLLSEQ);
+ VdbeCoverageIf(v, op==OP_Ne);
+ VdbeCoverageIf(v, op==OP_IsNull);
sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
}
- sqlite3ReleaseTempReg(pParse, regToFree);
}
if( regCkNull ){
sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
@@ -100706,6 +102797,7 @@ static void sqlite3ExprCodeIN(
}else{
destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
}
+ if( pParse->nErr ) goto sqlite3ExprCodeIN_finished;
for(i=0; i<nVector; i++){
Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
if( sqlite3ExprCanBeNull(p) ){
@@ -100887,16 +102979,45 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(
}
}
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+/*
+** Generate code that will compute the value of generated column pCol
+** and store the result in register regOut
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(
+ Parse *pParse,
+ Column *pCol,
+ int regOut
+){
+ int iAddr;
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ assert( pParse->iSelfTab!=0 );
+ if( pParse->iSelfTab>0 ){
+ iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut);
+ }else{
+ iAddr = 0;
+ }
+ sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut);
+ if( pCol->affinity>=SQLITE_AFF_TEXT ){
+ sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
+ }
+ if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
+}
+#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
+
/*
** Generate code to extract the value of the iCol-th column of a table.
*/
SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
- Vdbe *v, /* The VDBE under construction */
+ Vdbe *v, /* Parsing context */
Table *pTab, /* The table containing the value */
int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */
int iCol, /* Index of the column to extract */
int regOut /* Extract the value into this register */
){
+ Column *pCol;
+ assert( v!=0 );
if( pTab==0 ){
sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut);
return;
@@ -100904,14 +103025,36 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
if( iCol<0 || iCol==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
}else{
- int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
- int x = iCol;
- if( !HasRowid(pTab) && !IsVirtual(pTab) ){
- x = sqlite3ColumnOfIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
+ int op;
+ int x;
+ if( IsVirtual(pTab) ){
+ op = OP_VColumn;
+ x = iCol;
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){
+ Parse *pParse = sqlite3VdbeParser(v);
+ if( pCol->colFlags & COLFLAG_BUSY ){
+ sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName);
+ }else{
+ int savedSelfTab = pParse->iSelfTab;
+ pCol->colFlags |= COLFLAG_BUSY;
+ pParse->iSelfTab = iTabCur+1;
+ sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut);
+ pParse->iSelfTab = savedSelfTab;
+ pCol->colFlags &= ~COLFLAG_BUSY;
+ }
+ return;
+#endif
+ }else if( !HasRowid(pTab) ){
+ testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) );
+ x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol);
+ op = OP_Column;
+ }else{
+ x = sqlite3TableColumnToStorage(pTab,iCol);
+ testcase( x!=iCol );
+ op = OP_Column;
}
sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut);
- }
- if( iCol>=0 ){
sqlite3ColumnDefault(v, pTab, iCol, regOut);
}
}
@@ -100931,11 +103074,11 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
int iReg, /* Store results here */
u8 p5 /* P5 value for OP_Column + FLAGS */
){
- Vdbe *v = pParse->pVdbe;
- assert( v!=0 );
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iTable, iColumn, iReg);
+ assert( pParse->pVdbe!=0 );
+ sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg);
if( p5 ){
- sqlite3VdbeChangeP5(v, p5);
+ VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
+ if( pOp->opcode==OP_Column ) pOp->p5 = p5;
}
return iReg;
}
@@ -100945,7 +103088,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
** over to iTo..iTo+nReg-1.
*/
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
- assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
}
@@ -100997,6 +103139,124 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
return iResult;
}
+/*
+** If the last opcode is a OP_Copy, then set the do-not-merge flag (p5)
+** so that a subsequent copy will not be merged into this one.
+*/
+static void setDoNotMergeFlagOnCopy(Vdbe *v){
+ if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){
+ sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */
+ }
+}
+
+/*
+** Generate code to implement special SQL functions that are implemented
+** in-line rather than by using the usual callbacks.
+*/
+static int exprCodeInlineFunction(
+ Parse *pParse, /* Parsing context */
+ ExprList *pFarg, /* List of function arguments */
+ int iFuncId, /* Function ID. One of the INTFUNC_... values */
+ int target /* Store function result in this register */
+){
+ int nFarg;
+ Vdbe *v = pParse->pVdbe;
+ assert( v!=0 );
+ assert( pFarg!=0 );
+ nFarg = pFarg->nExpr;
+ assert( nFarg>0 ); /* All in-line functions have at least one argument */
+ switch( iFuncId ){
+ case INLINEFUNC_coalesce: {
+ /* Attempt a direct implementation of the built-in COALESCE() and
+ ** IFNULL() functions. This avoids unnecessary evaluation of
+ ** arguments past the first non-NULL argument.
+ */
+ int endCoalesce = sqlite3VdbeMakeLabel(pParse);
+ int i;
+ assert( nFarg>=2 );
+ sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
+ for(i=1; i<nFarg; i++){
+ sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
+ VdbeCoverage(v);
+ sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
+ }
+ setDoNotMergeFlagOnCopy(v);
+ sqlite3VdbeResolveLabel(v, endCoalesce);
+ break;
+ }
+ case INLINEFUNC_iif: {
+ Expr caseExpr;
+ memset(&caseExpr, 0, sizeof(caseExpr));
+ caseExpr.op = TK_CASE;
+ caseExpr.x.pList = pFarg;
+ return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
+ }
+
+ default: {
+ /* The UNLIKELY() function is a no-op. The result is the value
+ ** of the first argument.
+ */
+ assert( nFarg==1 || nFarg==2 );
+ target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
+ break;
+ }
+
+ /***********************************************************************
+ ** Test-only SQL functions that are only usable if enabled
+ ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
+ */
+ case INLINEFUNC_expr_compare: {
+ /* Compare two expressions using sqlite3ExprCompare() */
+ assert( nFarg==2 );
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
+ target);
+ break;
+ }
+
+ case INLINEFUNC_expr_implies_expr: {
+ /* Compare two expressions using sqlite3ExprImpliesExpr() */
+ assert( nFarg==2 );
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
+ target);
+ break;
+ }
+
+ case INLINEFUNC_implies_nonnull_row: {
+ /* REsult of sqlite3ExprImpliesNonNullRow() */
+ Expr *pA1;
+ assert( nFarg==2 );
+ pA1 = pFarg->a[1].pExpr;
+ if( pA1->op==TK_COLUMN ){
+ sqlite3VdbeAddOp2(v, OP_Integer,
+ sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable),
+ target);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+ }
+ break;
+ }
+
+#ifdef SQLITE_DEBUG
+ case INLINEFUNC_affinity: {
+ /* The AFFINITY() function evaluates to a string that describes
+ ** the type affinity of the argument. This is used for testing of
+ ** the SQLite type logic.
+ */
+ const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
+ char aff;
+ assert( nFarg==1 );
+ aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
+ sqlite3VdbeLoadString(v, target,
+ (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
+ break;
+ }
+#endif
+ }
+ return target;
+}
+
/*
** Generate code into the current Vdbe to evaluate the given
@@ -101029,24 +103289,38 @@ expr_code_doover:
if( pExpr==0 ){
op = TK_NULL;
}else{
+ assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
op = pExpr->op;
}
switch( op ){
case TK_AGG_COLUMN: {
AggInfo *pAggInfo = pExpr->pAggInfo;
- struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
+ struct AggInfo_col *pCol;
+ assert( pAggInfo!=0 );
+ assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
+ pCol = &pAggInfo->aCol[pExpr->iAgg];
if( !pAggInfo->directMode ){
assert( pCol->iMem>0 );
return pCol->iMem;
}else if( pAggInfo->useSortingIdx ){
+ Table *pTab = pCol->pTab;
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
pCol->iSorterColumn, target);
+ if( pCol->iColumn<0 ){
+ VdbeComment((v,"%s.rowid",pTab->zName));
+ }else{
+ VdbeComment((v,"%s.%s",pTab->zName,pTab->aCol[pCol->iColumn].zName));
+ if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
+ sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
+ }
+ }
return target;
}
/* Otherwise, fall thru into the TK_COLUMN case */
}
case TK_COLUMN: {
int iTab = pExpr->iTable;
+ int iReg;
if( ExprHasProperty(pExpr, EP_FixedCol) ){
/* This COLUMN expression is really a constant due to WHERE clause
** constraints, and that constant is coded by the pExpr->pLeft
@@ -101054,16 +103328,17 @@ expr_code_doover:
** datatype by applying the Affinity of the table column to the
** constant.
*/
- int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
- int aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+ int aff;
+ iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
+ if( pExpr->y.pTab ){
+ aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+ }else{
+ aff = pExpr->affExpr;
+ }
if( aff>SQLITE_AFF_BLOB ){
static const char zAff[] = "B\000C\000D\000E";
assert( SQLITE_AFF_BLOB=='A' );
assert( SQLITE_AFF_TEXT=='B' );
- if( iReg!=target ){
- sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
- iReg = target;
- }
sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
&zAff[(aff-'B')*2], P4_STATIC);
}
@@ -101071,19 +103346,46 @@ expr_code_doover:
}
if( iTab<0 ){
if( pParse->iSelfTab<0 ){
- /* Generating CHECK constraints or inserting into partial index */
- assert( pExpr->y.pTab!=0 );
- assert( pExpr->iColumn>=XN_ROWID );
- assert( pExpr->iColumn<pExpr->y.pTab->nCol );
- if( pExpr->iColumn>=0
- && pExpr->y.pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
- ){
- sqlite3VdbeAddOp2(v, OP_SCopy, pExpr->iColumn - pParse->iSelfTab,
- target);
+ /* Other columns in the same row for CHECK constraints or
+ ** generated columns or for inserting into partial index.
+ ** The row is unpacked into registers beginning at
+ ** 0-(pParse->iSelfTab). The rowid (if any) is in a register
+ ** immediately prior to the first column.
+ */
+ Column *pCol;
+ Table *pTab = pExpr->y.pTab;
+ int iSrc;
+ int iCol = pExpr->iColumn;
+ assert( pTab!=0 );
+ assert( iCol>=XN_ROWID );
+ assert( iCol<pTab->nCol );
+ if( iCol<0 ){
+ return -1-pParse->iSelfTab;
+ }
+ pCol = pTab->aCol + iCol;
+ testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) );
+ iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab;
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ if( pCol->colFlags & COLFLAG_GENERATED ){
+ if( pCol->colFlags & COLFLAG_BUSY ){
+ sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"",
+ pCol->zName);
+ return 0;
+ }
+ pCol->colFlags |= COLFLAG_BUSY;
+ if( pCol->colFlags & COLFLAG_NOTAVAIL ){
+ sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc);
+ }
+ pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL);
+ return iSrc;
+ }else
+#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
+ if( pCol->affinity==SQLITE_AFF_REAL ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target);
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
return target;
}else{
- return pExpr->iColumn - pParse->iSelfTab;
+ return iSrc;
}
}else{
/* Coding an expression that is part of an index where column names
@@ -101091,9 +103393,13 @@ expr_code_doover:
iTab = pParse->iSelfTab - 1;
}
}
- return sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
+ iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
+ if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){
+ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
+ }
+ return iReg;
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
@@ -101115,7 +103421,12 @@ expr_code_doover:
sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
return target;
}
- case TK_NULL: {
+ default: {
+ /* Make NULL the default case so that if a bug causes an illegal
+ ** Expr node to be passed into this function, it will be handled
+ ** sanely and not crash. But keep the assert() to bring the problem
+ ** to the attention of the developers. */
+ assert( op==TK_NULL );
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
return target;
}
@@ -101142,7 +103453,7 @@ expr_code_doover:
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
- assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
+ assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) );
pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
}
@@ -101182,7 +103493,8 @@ expr_code_doover:
r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pLeft, pExpr->pRight, op,
- r1, r2, inReg, SQLITE_STOREP2 | p5);
+ r1, r2, inReg, SQLITE_STOREP2 | p5,
+ ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
@@ -101240,6 +103552,7 @@ expr_code_doover:
tempX.op = TK_INTEGER;
tempX.flags = EP_IntValue|EP_TokenOnly;
tempX.u.iValue = 0;
+ ExprClearVVAProperties(&tempX);
r1 = sqlite3ExprCodeTemp(pParse, &tempX, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree2);
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
@@ -101285,7 +103598,10 @@ expr_code_doover:
}
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
- if( pInfo==0 ){
+ if( pInfo==0
+ || NEVER(pExpr->iAgg<0)
+ || NEVER(pExpr->iAgg>=pInfo->nFunc)
+ ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
@@ -101311,16 +103627,13 @@ expr_code_doover:
#endif
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
- /* SQL functions can be expensive. So try to move constant functions
- ** out of the inner loop, even if that means an extra OP_Copy. */
- return sqlite3ExprCodeAtInit(pParse, pExpr, -1);
+ /* SQL functions can be expensive. So try to avoid running them
+ ** multiple times if we know they always give the same result */
+ return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- if( ExprHasProperty(pExpr, EP_TokenOnly) ){
- pFarg = 0;
- }else{
- pFarg = pExpr->x.pList;
- }
+ assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
+ pFarg = pExpr->x.pList;
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
zId = pExpr->u.zToken;
@@ -101334,48 +103647,15 @@ expr_code_doover:
sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
break;
}
-
- /* Attempt a direct implementation of the built-in COALESCE() and
- ** IFNULL() functions. This avoids unnecessary evaluation of
- ** arguments past the first non-NULL argument.
- */
- if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
- int endCoalesce = sqlite3VdbeMakeLabel(pParse);
- assert( nFarg>=2 );
- sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
- for(i=1; i<nFarg; i++){
- sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
- VdbeCoverage(v);
- sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
- }
- sqlite3VdbeResolveLabel(v, endCoalesce);
- break;
+ if( pDef->funcFlags & SQLITE_FUNC_INLINE ){
+ assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 );
+ assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 );
+ return exprCodeInlineFunction(pParse, pFarg,
+ SQLITE_PTR_TO_INT(pDef->pUserData), target);
+ }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){
+ sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
}
- /* The UNLIKELY() function is a no-op. The result is the value
- ** of the first argument.
- */
- if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
- assert( nFarg>=1 );
- return sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
- }
-
-#ifdef SQLITE_DEBUG
- /* The AFFINITY() function evaluates to a string that describes
- ** the type affinity of the argument. This is used for testing of
- ** the SQLite type logic.
- */
- if( pDef->funcFlags & SQLITE_FUNC_AFFINITY ){
- const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
- char aff;
- assert( nFarg==1 );
- aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
- sqlite3VdbeLoadString(v, target,
- (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
- return target;
- }
-#endif
-
for(i=0; i<nFarg; i++){
if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
testcase( i==31 );
@@ -101451,12 +103731,15 @@ expr_code_doover:
}else
#endif
{
- sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
- constMask, r1, target, (char*)pDef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, (u8)nFarg);
+ sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
+ pDef, pExpr->op2);
}
- if( nFarg && constMask==0 ){
- sqlite3ReleaseTempRange(pParse, r1, nFarg);
+ if( nFarg ){
+ if( constMask==0 ){
+ sqlite3ReleaseTempRange(pParse, r1, nFarg);
+ }else{
+ sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1);
+ }
}
return target;
}
@@ -101550,17 +103833,19 @@ expr_code_doover:
** p1==2 -> old.b p1==5 -> new.b
*/
Table *pTab = pExpr->y.pTab;
- int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn;
+ int iCol = pExpr->iColumn;
+ int p1 = pExpr->iTable * (pTab->nCol+1) + 1
+ + sqlite3TableColumnToStorage(pTab, iCol);
assert( pExpr->iTable==0 || pExpr->iTable==1 );
- assert( pExpr->iColumn>=-1 && pExpr->iColumn<pTab->nCol );
- assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey );
+ assert( iCol>=-1 && iCol<pTab->nCol );
+ assert( pTab->iPKey<0 || iCol!=pTab->iPKey );
assert( p1>=0 && p1<(pTab->nCol*2+2) );
sqlite3VdbeAddOp2(v, OP_Param, p1, target);
VdbeComment((v, "r[%d]=%s.%s", target,
(pExpr->iTable ? "new" : "old"),
- (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[pExpr->iColumn].zName)
+ (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zName)
));
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -101569,9 +103854,7 @@ expr_code_doover:
**
** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
** floating point when extracting it from the record. */
- if( pExpr->iColumn>=0
- && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
- ){
+ if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, target);
}
#endif
@@ -101626,7 +103909,7 @@ expr_code_doover:
** or if there is no matching Ei, the ELSE term Y, or if there is
** no ELSE term, NULL.
*/
- default: assert( op==TK_CASE ); {
+ case TK_CASE: {
int endLabel; /* GOTO label for end of CASE stmt */
int nextCase; /* GOTO label for next WHEN clause */
int nExpr; /* 2x number of WHEN terms */
@@ -101685,6 +103968,7 @@ expr_code_doover:
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
sqlite3ExprDelete(db, pDel);
+ setDoNotMergeFlagOnCopy(v);
sqlite3VdbeResolveLabel(v, endLabel);
break;
}
@@ -101695,7 +103979,7 @@ expr_code_doover:
|| pExpr->affExpr==OE_Fail
|| pExpr->affExpr==OE_Ignore
);
- if( !pParse->pTriggerTab ){
+ if( !pParse->pTriggerTab && !pParse->nested ){
sqlite3ErrorMsg(pParse,
"RAISE() may only be used within a trigger-program");
return 0;
@@ -101709,8 +103993,9 @@ expr_code_doover:
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
VdbeCoverage(v);
}else{
- sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
- pExpr->affExpr, pExpr->u.zToken, 0, 0);
+ sqlite3HaltConstraint(pParse,
+ pParse->pTriggerTab ? SQLITE_CONSTRAINT_TRIGGER : SQLITE_ERROR,
+ pExpr->affExpr, pExpr->u.zToken, 0, 0);
}
break;
@@ -101723,15 +104008,23 @@ expr_code_doover:
}
/*
-** Factor out the code of the given expression to initialization time.
+** Generate code that will evaluate expression pExpr just one time
+** per prepared statement execution.
+**
+** If the expression uses functions (that might throw an exception) then
+** guard them with an OP_Once opcode to ensure that the code is only executed
+** once. If no functions are involved, then factor the code out and put it at
+** the end of the prepared statement in the initialization section.
**
** If regDest>=0 then the result is always stored in that register and the
** result is not reusable. If regDest<0 then this routine is free to
** store the value whereever it wants. The register where the expression
-** is stored is returned. When regDest<0, two identical expressions will
-** code to the same register.
+** is stored is returned. When regDest<0, two identical expressions might
+** code to the same register, if they do not contain function calls and hence
+** are factored out into the initialization section at the end of the
+** prepared statement.
*/
-SQLITE_PRIVATE int sqlite3ExprCodeAtInit(
+SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(
Parse *pParse, /* Parsing context */
Expr *pExpr, /* The expression to code when the VDBE initializes */
int regDest /* Store the value in this register */
@@ -101749,14 +104042,29 @@ SQLITE_PRIVATE int sqlite3ExprCodeAtInit(
}
}
pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
- p = sqlite3ExprListAppend(pParse, p, pExpr);
- if( p ){
- struct ExprList_item *pItem = &p->a[p->nExpr-1];
- pItem->reusable = regDest<0;
- if( regDest<0 ) regDest = ++pParse->nMem;
- pItem->u.iConstExprReg = regDest;
+ if( pExpr!=0 && ExprHasProperty(pExpr, EP_HasFunc) ){
+ Vdbe *v = pParse->pVdbe;
+ int addr;
+ assert( v );
+ addr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ pParse->okConstFactor = 0;
+ if( !pParse->db->mallocFailed ){
+ if( regDest<0 ) regDest = ++pParse->nMem;
+ sqlite3ExprCode(pParse, pExpr, regDest);
+ }
+ pParse->okConstFactor = 1;
+ sqlite3ExprDelete(pParse->db, pExpr);
+ sqlite3VdbeJumpHere(v, addr);
+ }else{
+ p = sqlite3ExprListAppend(pParse, p, pExpr);
+ if( p ){
+ struct ExprList_item *pItem = &p->a[p->nExpr-1];
+ pItem->reusable = regDest<0;
+ if( regDest<0 ) regDest = ++pParse->nMem;
+ pItem->u.iConstExprReg = regDest;
+ }
+ pParse->pConstExpr = p;
}
- pParse->pConstExpr = p;
return regDest;
}
@@ -101781,7 +104089,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
*pReg = 0;
- r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
+ r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
}else{
int r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
@@ -101803,15 +104111,18 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
+ assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
assert( target>0 && target<=pParse->nMem );
- if( pExpr && pExpr->op==TK_REGISTER ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, pExpr->iTable, target);
- }else{
- inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
- assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
- if( inReg!=target && pParse->pVdbe ){
- sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
+ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
+ assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
+ if( inReg!=target && pParse->pVdbe ){
+ u8 op;
+ if( ExprHasProperty(pExpr,EP_Subquery) ){
+ op = OP_Copy;
+ }else{
+ op = OP_SCopy;
}
+ sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target);
}
}
@@ -101835,37 +104146,13 @@ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
*/
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
- sqlite3ExprCodeAtInit(pParse, pExpr, target);
+ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
}else{
- sqlite3ExprCode(pParse, pExpr, target);
+ sqlite3ExprCodeCopy(pParse, pExpr, target);
}
}
/*
-** Generate code that evaluates the given expression and puts the result
-** in register target.
-**
-** Also make a copy of the expression results into another "cache" register
-** and modify the expression so that the next time it is evaluated,
-** the result is a copy of the cache register.
-**
-** This routine is used for expressions that are used multiple
-** times. They are evaluated once and the results of the expression
-** are reused.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
- Vdbe *v = pParse->pVdbe;
- int iMem;
-
- assert( target>0 );
- assert( pExpr->op!=TK_REGISTER );
- sqlite3ExprCode(pParse, pExpr, target);
- iMem = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
- exprToRegister(pExpr, iMem);
-}
-
-/*
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**
@@ -101919,7 +104206,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
}else if( (flags & SQLITE_ECEL_FACTOR)!=0
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
- sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
+ sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
@@ -101928,6 +104215,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
&& (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
&& pOp->p1+pOp->p3+1==inReg
&& pOp->p2+pOp->p3+1==target+i
+ && pOp->p5==0 /* The do-not-merge flag must be clear */
){
pOp->p3++;
}else{
@@ -102041,6 +104329,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
if( NEVER(pExpr==0) ) return; /* No way this can happen */
+ assert( !ExprHasVVAProperty(pExpr, EP_Immutable) );
op = pExpr->op;
switch( op ){
case TK_AND:
@@ -102102,7 +104391,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull);
+ r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
@@ -102182,6 +104471,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
if( NEVER(v==0) ) return; /* Existence of VDBE checked by caller */
if( pExpr==0 ) return;
+ assert( !ExprHasVVAProperty(pExpr,EP_Immutable) );
/* The value of pExpr->op and op are related as follows:
**
@@ -102277,7 +104567,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, dest, jumpIfNull);
+ r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted));
assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
@@ -102463,8 +104753,9 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
return 2;
}
}
- if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
- if( (combinedFlags & EP_TokenOnly)==0 ){
+ if( (pA->flags & (EP_Distinct|EP_Commuted))
+ != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
+ if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
if( combinedFlags & EP_xIsSelect ) return 2;
if( (combinedFlags & EP_FixedCol)==0
&& sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
@@ -102472,21 +104763,22 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
if( pA->op!=TK_STRING
&& pA->op!=TK_TRUEFALSE
- && (combinedFlags & EP_Reduced)==0
+ && ALWAYS((combinedFlags & EP_Reduced)==0)
){
if( pA->iColumn!=pB->iColumn ) return 2;
- if( pA->op2!=pB->op2 ) return 2;
- if( pA->op!=TK_IN
- && pA->iTable!=pB->iTable
- && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
+ if( pA->op2!=pB->op2 && pA->op==TK_TRUTH ) return 2;
+ if( pA->op!=TK_IN && pA->iTable!=pB->iTable && pA->iTable!=iTab ){
+ return 2;
+ }
}
}
return 0;
}
/*
-** Compare two ExprList objects. Return 0 if they are identical and
-** non-zero if they differ in any way.
+** Compare two ExprList objects. Return 0 if they are identical, 1
+** if they are certainly different, or 2 if it is not possible to
+** determine if they are identical or not.
**
** If any subelement of pB has Expr.iTable==(-1) then it is allowed
** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
@@ -102505,10 +104797,11 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
if( pA==0 || pB==0 ) return 1;
if( pA->nExpr!=pB->nExpr ) return 1;
for(i=0; i<pA->nExpr; i++){
+ int res;
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
- if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1;
+ if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
}
return 0;
}
@@ -102645,7 +104938,7 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, i
}
/*
-** This is the Expr node callback for sqlite3ExprImpliesNotNullRow().
+** This is the Expr node callback for sqlite3ExprImpliesNonNullRow().
** If the expression node requires that the table at pWalker->iCur
** have one or more non-NULL column, then set pWalker->eCode to 1 and abort.
**
@@ -102663,6 +104956,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
case TK_NOTNULL:
case TK_IS:
case TK_OR:
+ case TK_VECTOR:
case TK_CASE:
case TK_IN:
case TK_FUNCTION:
@@ -102672,6 +104966,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_NOTNULL );
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_OR );
+ testcase( pExpr->op==TK_VECTOR );
testcase( pExpr->op==TK_CASE );
testcase( pExpr->op==TK_IN );
testcase( pExpr->op==TK_FUNCTION );
@@ -102685,15 +104980,20 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
return WRC_Prune;
case TK_AND:
- if( sqlite3ExprImpliesNonNullRow(pExpr->pLeft, pWalker->u.iCur)
- && sqlite3ExprImpliesNonNullRow(pExpr->pRight, pWalker->u.iCur)
- ){
- pWalker->eCode = 1;
+ if( pWalker->eCode==0 ){
+ sqlite3WalkExpr(pWalker, pExpr->pLeft);
+ if( pWalker->eCode ){
+ pWalker->eCode = 0;
+ sqlite3WalkExpr(pWalker, pExpr->pRight);
+ }
}
return WRC_Prune;
case TK_BETWEEN:
- sqlite3WalkExpr(pWalker, pExpr->pLeft);
+ if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){
+ assert( pWalker->eCode );
+ return WRC_Abort;
+ }
return WRC_Prune;
/* Virtual tables are allowed to use constraints like x=NULL. So
@@ -102704,19 +105004,25 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
case TK_LT:
case TK_LE:
case TK_GT:
- case TK_GE:
+ case TK_GE: {
+ Expr *pLeft = pExpr->pLeft;
+ Expr *pRight = pExpr->pRight;
testcase( pExpr->op==TK_EQ );
testcase( pExpr->op==TK_NE );
testcase( pExpr->op==TK_LT );
testcase( pExpr->op==TK_LE );
testcase( pExpr->op==TK_GT );
testcase( pExpr->op==TK_GE );
- if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->y.pTab))
- || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->y.pTab))
+ /* The y.pTab=0 assignment in wherecode.c always happens after the
+ ** impliesNotNullRow() test */
+ if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0)
+ && IsVirtual(pLeft->y.pTab))
+ || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0)
+ && IsVirtual(pRight->y.pTab))
){
- return WRC_Prune;
+ return WRC_Prune;
}
-
+ }
default:
return WRC_Continue;
}
@@ -102747,14 +105053,13 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
Walker w;
p = sqlite3ExprSkipCollateAndLikely(p);
- while( p ){
- if( p->op==TK_NOTNULL ){
- p = p->pLeft;
- }else if( p->op==TK_AND ){
+ if( p==0 ) return 0;
+ if( p->op==TK_NOTNULL ){
+ p = p->pLeft;
+ }else{
+ while( p->op==TK_AND ){
if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
p = p->pRight;
- }else{
- break;
}
}
w.xExprCallback = impliesNotNullRow;
@@ -102786,7 +105091,7 @@ struct IdxCover {
static int exprIdxCover(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_COLUMN
&& pExpr->iTable==pWalker->u.pIdxCover->iCur
- && sqlite3ColumnOfIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
+ && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0
){
pWalker->eCode = 1;
return WRC_Abort;
@@ -102837,12 +105142,13 @@ struct SrcCount {
** Count the number of references to columns.
*/
static int exprSrcCount(Walker *pWalker, Expr *pExpr){
- /* The NEVER() on the second term is because sqlite3FunctionUsesThisSrc()
- ** is always called before sqlite3ExprAnalyzeAggregates() and so the
- ** TK_COLUMNs have not yet been converted into TK_AGG_COLUMN. If
- ** sqlite3FunctionUsesThisSrc() is used differently in the future, the
- ** NEVER() will need to be removed. */
- if( pExpr->op==TK_COLUMN || NEVER(pExpr->op==TK_AGG_COLUMN) ){
+ /* There was once a NEVER() on the second term on the grounds that
+ ** sqlite3FunctionUsesThisSrc() was always called before
+ ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
+ ** been converted into TK_AGG_COLUMN. But this is no longer true due
+ ** to window functions - sqlite3WindowRewrite() may now indirectly call
+ ** FunctionUsesThisSrc() when creating a new sub-select. */
+ if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
int i;
struct SrcCount *p = pWalker->u.pSrcCount;
SrcList *pSrc = p->pSrc;
@@ -102880,6 +105186,11 @@ SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
cnt.nThis = 0;
cnt.nOther = 0;
sqlite3WalkExprList(&w, pExpr->x.pList);
+#ifndef SQLITE_OMIT_WINDOWFUNC
+ if( ExprHasProperty(pExpr, EP_WinFunc) ){
+ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
+ }
+#endif
return cnt.nThis>0 || cnt.nOther==0;
}
@@ -103046,15 +105357,6 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
return WRC_Continue;
}
-static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
- UNUSED_PARAMETER(pSelect);
- pWalker->walkerDepth++;
- return WRC_Continue;
-}
-static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
- UNUSED_PARAMETER(pSelect);
- pWalker->walkerDepth--;
-}
/*
** Analyze the pExpr expression looking for aggregate functions and
@@ -103068,8 +105370,8 @@ static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
Walker w;
w.xExprCallback = analyzeAggregate;
- w.xSelectCallback = analyzeAggregatesInSelect;
- w.xSelectCallback2 = analyzeAggregatesInSelectEnd;
+ w.xSelectCallback = sqlite3WalkerDepthIncrease;
+ w.xSelectCallback2 = sqlite3WalkerDepthDecrease;
w.walkerDepth = 0;
w.u.pNC = pNC;
w.pParse = 0;
@@ -103108,8 +105410,11 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
** purpose.
*/
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
- if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- pParse->aTempReg[pParse->nTempReg++] = iReg;
+ if( iReg ){
+ sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0);
+ if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+ pParse->aTempReg[pParse->nTempReg++] = iReg;
+ }
}
}
@@ -103135,6 +105440,7 @@ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
sqlite3ReleaseTempReg(pParse, iReg);
return;
}
+ sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
pParse->iRangeReg = iReg;
@@ -103212,9 +105518,8 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
static int isAlterableTable(Parse *pParse, Table *pTab){
if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7)
#ifndef SQLITE_OMIT_VIRTUALTABLE
- || ( (pTab->tabFlags & TF_Shadow)
- && (pParse->db->flags & SQLITE_Defensive)
- && pParse->db->nVdbeExec==0
+ || ( (pTab->tabFlags & TF_Shadow)!=0
+ && sqlite3ReadOnlyShadowTables(pParse->db)
)
#endif
){
@@ -103305,7 +105610,10 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
/* Check that a table or index named 'zName' does not already exist
** in database iDb. If so, this is an error.
*/
- if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
+ if( sqlite3FindTable(db, zName, zDb)
+ || sqlite3FindIndex(db, zName, zDb)
+ || sqlite3IsShadowTableOf(db, pTab, zName)
+ ){
sqlite3ErrorMsg(pParse,
"there is already another table or index with this name: %s", zName);
goto exit_rename_table;
@@ -103438,6 +105746,22 @@ exit_rename_table:
}
/*
+** Write code that will raise an error if the table described by
+** zDb and zTab is not empty.
+*/
+static void sqlite3ErrorIfNotEmpty(
+ Parse *pParse, /* Parsing context */
+ const char *zDb, /* Schema holding the table */
+ const char *zTab, /* Table to check for empty */
+ const char *zErr /* Error message text */
+){
+ sqlite3NestedParse(pParse,
+ "SELECT raise(ABORT,%Q) FROM \"%w\".\"%w\"",
+ zErr, zDb, zTab
+ );
+}
+
+/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
@@ -103479,14 +105803,6 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
}
#endif
- /* If the default value for the new column was specified with a
- ** literal NULL, then set pDflt to 0. This simplifies checking
- ** for an SQL NULL default below.
- */
- assert( pDflt==0 || pDflt->op==TK_SPAN );
- if( pDflt && pDflt->pLeft->op==TK_NULL ){
- pDflt = 0;
- }
/* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
** If there is a NOT NULL constraint, then the default value for the
@@ -103497,39 +105813,52 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
return;
}
if( pNew->pIndex ){
- sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
- return;
- }
- if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a REFERENCES column with non-NULL default value");
- return;
- }
- if( pCol->notNull && !pDflt ){
- sqlite3ErrorMsg(pParse,
- "Cannot add a NOT NULL column with default value NULL");
+ sqlite3ErrorMsg(pParse,
+ "Cannot add a UNIQUE column");
return;
}
-
- /* Ensure the default expression is something that sqlite3ValueFromExpr()
- ** can handle (i.e. not CURRENT_TIME etc.)
- */
- if( pDflt ){
- sqlite3_value *pVal = 0;
- int rc;
- rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
- assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
- if( rc!=SQLITE_OK ){
- assert( db->mallocFailed == 1 );
- return;
+ if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){
+ /* If the default value for the new column was specified with a
+ ** literal NULL, then set pDflt to 0. This simplifies checking
+ ** for an SQL NULL default below.
+ */
+ assert( pDflt==0 || pDflt->op==TK_SPAN );
+ if( pDflt && pDflt->pLeft->op==TK_NULL ){
+ pDflt = 0;
}
- if( !pVal ){
- sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
- return;
+ if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
+ "Cannot add a REFERENCES column with non-NULL default value");
+ }
+ if( pCol->notNull && !pDflt ){
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
+ "Cannot add a NOT NULL column with default value NULL");
+ }
+
+
+ /* Ensure the default expression is something that sqlite3ValueFromExpr()
+ ** can handle (i.e. not CURRENT_TIME etc.)
+ */
+ if( pDflt ){
+ sqlite3_value *pVal = 0;
+ int rc;
+ rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal);
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+ if( rc!=SQLITE_OK ){
+ assert( db->mallocFailed == 1 );
+ return;
+ }
+ if( !pVal ){
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
+ "Cannot add a column with non-constant default");
+ }
+ sqlite3ValueFree(pVal);
}
- sqlite3ValueFree(pVal);
+ }else if( pCol->colFlags & COLFLAG_STORED ){
+ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "cannot add a STORED column");
}
+
/* Modify the CREATE TABLE statement. */
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
@@ -103645,6 +105974,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
for(i=0; i<pNew->nCol; i++){
Column *pCol = &pNew->aCol[i];
pCol->zName = sqlite3DbStrDup(db, pCol->zName);
+ pCol->hName = sqlite3StrIHash(pCol->zName);
pCol->zColl = 0;
pCol->pDflt = 0;
}
@@ -103873,12 +106203,14 @@ SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pTo
RenameToken *pNew;
assert( pPtr || pParse->db->mallocFailed );
renameTokenCheckAll(pParse, pPtr);
- pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
- if( pNew ){
- pNew->p = pPtr;
- pNew->t = *pToken;
- pNew->pNext = pParse->pRename;
- pParse->pRename = pNew;
+ if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){
+ pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
+ if( pNew ){
+ pNew->p = pPtr;
+ pNew->t = *pToken;
+ pNew->pNext = pParse->pRename;
+ pParse->pRename = pNew;
+ }
}
return pPtr;
@@ -103910,16 +106242,53 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
}
/*
+** Iterate through the Select objects that are part of WITH clauses attached
+** to select statement pSelect.
+*/
+static void renameWalkWith(Walker *pWalker, Select *pSelect){
+ With *pWith = pSelect->pWith;
+ if( pWith ){
+ int i;
+ for(i=0; i<pWith->nCte; i++){
+ Select *p = pWith->a[i].pSelect;
+ NameContext sNC;
+ memset(&sNC, 0, sizeof(sNC));
+ sNC.pParse = pWalker->pParse;
+ sqlite3SelectPrep(sNC.pParse, p, &sNC);
+ sqlite3WalkSelect(pWalker, p);
+ sqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols);
+ }
+ }
+}
+
+/*
+** Unmap all tokens in the IdList object passed as the second argument.
+*/
+static void unmapColumnIdlistNames(
+ Parse *pParse,
+ IdList *pIdList
+){
+ if( pIdList ){
+ int ii;
+ for(ii=0; ii<pIdList->nId; ii++){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pIdList->a[ii].zName);
+ }
+ }
+}
+
+/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
int i;
+ if( pParse->nErr ) return WRC_Abort;
+ if( NEVER(p->selFlags & SF_View) ) return WRC_Prune;
if( ALWAYS(p->pEList) ){
ExprList *pList = p->pEList;
for(i=0; i<pList->nExpr; i++){
- if( pList->a[i].zName ){
- sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zName);
+ if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
}
}
}
@@ -103927,8 +106296,12 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
SrcList *pSrc = p->pSrc;
for(i=0; i<pSrc->nSrc; i++){
sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
+ if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
+ unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
}
}
+
+ renameWalkWith(pWalker, p);
return WRC_Continue;
}
@@ -103936,12 +106309,15 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
** Remove all nodes that are part of expression pExpr from the rename list.
*/
SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){
+ u8 eMode = pParse->eParseMode;
Walker sWalker;
memset(&sWalker, 0, sizeof(Walker));
sWalker.pParse = pParse;
sWalker.xExprCallback = renameUnmapExprCb;
sWalker.xSelectCallback = renameUnmapSelectCb;
+ pParse->eParseMode = PARSE_MODE_UNMAP;
sqlite3WalkExpr(&sWalker, pExpr);
+ pParse->eParseMode = eMode;
}
/*
@@ -103957,7 +106333,9 @@ SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){
sWalker.xExprCallback = renameUnmapExprCb;
sqlite3WalkExprList(&sWalker, pEList);
for(i=0; i<pEList->nExpr; i++){
- sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zName);
+ if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){
+ sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName);
+ }
}
}
}
@@ -103996,29 +106374,12 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){
}
/*
-** Iterate through the Select objects that are part of WITH clauses attached
-** to select statement pSelect.
-*/
-static void renameWalkWith(Walker *pWalker, Select *pSelect){
- if( pSelect->pWith ){
- int i;
- for(i=0; i<pSelect->pWith->nCte; i++){
- Select *p = pSelect->pWith->a[i].pSelect;
- NameContext sNC;
- memset(&sNC, 0, sizeof(sNC));
- sNC.pParse = pWalker->pParse;
- sqlite3SelectPrep(sNC.pParse, p, &sNC);
- sqlite3WalkSelect(pWalker, p);
- }
- }
-}
-
-/*
** This is a Walker select callback. It does nothing. It is only required
** because without a dummy callback, sqlite3WalkExpr() and similar do not
** descend into sub-select statements.
*/
static int renameColumnSelectCb(Walker *pWalker, Select *p){
+ if( p->selFlags & SF_View ) return WRC_Prune;
renameWalkWith(pWalker, p);
return WRC_Continue;
}
@@ -104112,8 +106473,11 @@ static void renameColumnElistNames(
if( pEList ){
int i;
for(i=0; i<pEList->nExpr; i++){
- char *zName = pEList->a[i].zName;
- if( 0==sqlite3_stricmp(zName, zOld) ){
+ char *zName = pEList->a[i].zEName;
+ if( ALWAYS(pEList->a[i].eEName==ENAME_NAME)
+ && ALWAYS(zName!=0)
+ && 0==sqlite3_stricmp(zName, zOld)
+ ){
renameTokenFind(pParse, pCtx, (void*)zName);
}
}
@@ -104142,6 +106506,7 @@ static void renameColumnIdlistNames(
}
}
+
/*
** Parse the SQL statement zSql using Parse object (*p). The Parse object
** is initialized by this function before it is used.
@@ -104149,7 +106514,6 @@ static void renameColumnIdlistNames(
static int renameParseSql(
Parse *p, /* Memory to use for Parse object */
const char *zDb, /* Name of schema SQL belongs to */
- int bTable, /* 1 -> RENAME TABLE, 0 -> RENAME COLUMN */
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL to parse */
int bTemp /* True if SQL is from temp schema */
@@ -104163,7 +106527,7 @@ static int renameParseSql(
** occurs and the parse does not result in a new table, index or
** trigger object, the database must be corrupt. */
memset(p, 0, sizeof(Parse));
- p->eParseMode = (bTable ? PARSE_MODE_RENAME_TABLE : PARSE_MODE_RENAME_COLUMN);
+ p->eParseMode = PARSE_MODE_RENAME;
p->db = db;
p->nQueryLoop = 1;
rc = sqlite3RunParser(p, zSql, &zErr);
@@ -104470,7 +106834,7 @@ static void renameColumnFunc(
#ifndef SQLITE_OMIT_AUTHORIZATION
db->xAuth = 0;
#endif
- rc = renameParseSql(&sParse, zDb, 0, db, zSql, bTemp);
+ rc = renameParseSql(&sParse, zDb, db, zSql, bTemp);
/* Find tokens that need to be replaced. */
memset(&sWalker, 0, sizeof(Walker));
@@ -104484,8 +106848,9 @@ static void renameColumnFunc(
if( sParse.pNewTable ){
Select *pSelect = sParse.pNewTable->pSelect;
if( pSelect ){
+ pSelect->selFlags &= ~SF_View;
sParse.rc = SQLITE_OK;
- sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0);
+ sqlite3SelectPrep(&sParse, pSelect, 0);
rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
if( rc==SQLITE_OK ){
sqlite3WalkSelect(&sWalker, pSelect);
@@ -104512,6 +106877,11 @@ static void renameColumnFunc(
sqlite3WalkExprList(&sWalker, pIdx->aColExpr);
}
}
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ for(i=0; i<sParse.pNewTable->nCol; i++){
+ sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt);
+ }
+#endif
for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
for(i=0; i<pFKey->nCol; i++){
@@ -104597,6 +106967,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){
int i;
RenameCtx *p = pWalker->u.pRename;
SrcList *pSrc = pSelect->pSrc;
+ if( pSelect->selFlags & SF_View ) return WRC_Prune;
if( pSrc==0 ){
assert( pWalker->pParse->db->mallocFailed );
return WRC_Abort;
@@ -104667,7 +107038,7 @@ static void renameTableFunc(
sWalker.xSelectCallback = renameTableSelectCb;
sWalker.u.pRename = &sCtx;
- rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
+ rc = renameParseSql(&sParse, zDb, db, zInput, bTemp);
if( rc==SQLITE_OK ){
int isLegacy = (db->flags & SQLITE_LegacyAlter);
@@ -104676,13 +107047,19 @@ static void renameTableFunc(
if( pTab->pSelect ){
if( isLegacy==0 ){
+ Select *pSelect = pTab->pSelect;
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = &sParse;
+ assert( pSelect->selFlags & SF_View );
+ pSelect->selFlags &= ~SF_View;
sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC);
- if( sParse.nErr ) rc = sParse.rc;
- sqlite3WalkSelect(&sWalker, pTab->pSelect);
+ if( sParse.nErr ){
+ rc = sParse.rc;
+ }else{
+ sqlite3WalkSelect(&sWalker, pTab->pSelect);
+ }
}
}else{
/* Modify any FK definitions to point to the new table. */
@@ -104803,7 +107180,7 @@ static void renameTableTest(
if( zDb && zInput ){
int rc;
Parse sParse;
- rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);
+ rc = renameParseSql(&sParse, zDb, db, zInput, bTemp);
if( rc==SQLITE_OK ){
if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
NameContext sNC;
@@ -105041,6 +107418,11 @@ static void openStatTable(
Vdbe *v = sqlite3GetVdbe(pParse);
int aRoot[ArraySize(aTable)];
u8 aCreateTbl[ArraySize(aTable)];
+#ifdef SQLITE_ENABLE_STAT4
+ const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
+#else
+ const int nToOpen = 1;
+#endif
if( v==0 ) return;
assert( sqlite3BtreeHoldsAllMutexes(db) );
@@ -105053,8 +107435,9 @@ static void openStatTable(
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
+ aCreateTbl[i] = 0;
if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
- if( aTable[i].zCols ){
+ if( i<nToOpen ){
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
@@ -105070,7 +107453,6 @@ static void openStatTable(
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
- aCreateTbl[i] = 0;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
@@ -105089,7 +107471,7 @@ static void openStatTable(
}
/* Open the sqlite_stat[134] tables for writing. */
- for(i=0; aTable[i].zCols; i++){
+ for(i=0; i<nToOpen; i++){
assert( i<ArraySize(aTable) );
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
@@ -105109,9 +107491,9 @@ static void openStatTable(
** share an instance of the following structure to hold their state
** information.
*/
-typedef struct Stat4Accum Stat4Accum;
-typedef struct Stat4Sample Stat4Sample;
-struct Stat4Sample {
+typedef struct StatAccum StatAccum;
+typedef struct StatSample StatSample;
+struct StatSample {
tRowcnt *anEq; /* sqlite_stat4.nEq */
tRowcnt *anDLt; /* sqlite_stat4.nDLt */
#ifdef SQLITE_ENABLE_STAT4
@@ -105126,27 +107508,32 @@ struct Stat4Sample {
u32 iHash; /* Tiebreaker hash */
#endif
};
-struct Stat4Accum {
- tRowcnt nRow; /* Number of rows in the entire table */
- tRowcnt nPSample; /* How often to do a periodic sample */
+struct StatAccum {
+ sqlite3 *db; /* Database connection, for malloc() */
+ tRowcnt nEst; /* Estimated number of rows */
+ tRowcnt nRow; /* Number of rows visited so far */
+ int nLimit; /* Analysis row-scan limit */
int nCol; /* Number of columns in index + pk/rowid */
int nKeyCol; /* Number of index columns w/o the pk/rowid */
+ u8 nSkipAhead; /* Number of times of skip-ahead */
+ StatSample current; /* Current row as a StatSample */
+#ifdef SQLITE_ENABLE_STAT4
+ tRowcnt nPSample; /* How often to do a periodic sample */
int mxSample; /* Maximum number of samples to accumulate */
- Stat4Sample current; /* Current row as a Stat4Sample */
u32 iPrn; /* Pseudo-random number used for sampling */
- Stat4Sample *aBest; /* Array of nCol best samples */
+ StatSample *aBest; /* Array of nCol best samples */
int iMin; /* Index in a[] of entry with minimum score */
int nSample; /* Current number of samples */
int nMaxEqZero; /* Max leading 0 in anEq[] for any a[] entry */
int iGet; /* Index of current sample accessed by stat_get() */
- Stat4Sample *a; /* Array of mxSample Stat4Sample objects */
- sqlite3 *db; /* Database connection, for malloc() */
+ StatSample *a; /* Array of mxSample StatSample objects */
+#endif
};
-/* Reclaim memory used by a Stat4Sample
+/* Reclaim memory used by a StatSample
*/
#ifdef SQLITE_ENABLE_STAT4
-static void sampleClear(sqlite3 *db, Stat4Sample *p){
+static void sampleClear(sqlite3 *db, StatSample *p){
assert( db!=0 );
if( p->nRowid ){
sqlite3DbFree(db, p->u.aRowid);
@@ -105158,7 +107545,7 @@ static void sampleClear(sqlite3 *db, Stat4Sample *p){
/* Initialize the BLOB value of a ROWID
*/
#ifdef SQLITE_ENABLE_STAT4
-static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
+static void sampleSetRowid(sqlite3 *db, StatSample *p, int n, const u8 *pData){
assert( db!=0 );
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
p->u.aRowid = sqlite3DbMallocRawNN(db, n);
@@ -105174,7 +107561,7 @@ static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){
/* Initialize the INTEGER value of a ROWID.
*/
#ifdef SQLITE_ENABLE_STAT4
-static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
+static void sampleSetRowidInt64(sqlite3 *db, StatSample *p, i64 iRowid){
assert( db!=0 );
if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid);
p->nRowid = 0;
@@ -105187,7 +107574,7 @@ static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){
** Copy the contents of object (*pFrom) into (*pTo).
*/
#ifdef SQLITE_ENABLE_STAT4
-static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
+static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
pTo->isPSample = pFrom->isPSample;
pTo->iCol = pFrom->iCol;
pTo->iHash = pFrom->iHash;
@@ -105203,40 +107590,41 @@ static void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){
#endif
/*
-** Reclaim all memory of a Stat4Accum structure.
+** Reclaim all memory of a StatAccum structure.
*/
-static void stat4Destructor(void *pOld){
- Stat4Accum *p = (Stat4Accum*)pOld;
+static void statAccumDestructor(void *pOld){
+ StatAccum *p = (StatAccum*)pOld;
#ifdef SQLITE_ENABLE_STAT4
- int i;
- for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
- for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
- sampleClear(p->db, &p->current);
+ if( p->mxSample ){
+ int i;
+ for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
+ for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
+ sampleClear(p->db, &p->current);
+ }
#endif
sqlite3DbFree(p->db, p);
}
/*
-** Implementation of the stat_init(N,K,C) SQL function. The three parameters
+** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
** are:
** N: The number of columns in the index including the rowid/pk (note 1)
** K: The number of columns in the index excluding the rowid/pk.
-** C: The number of rows in the index (note 2)
+** C: Estimated number of rows in the index
+** L: A limit on the number of rows to scan, or 0 for no-limit
**
** Note 1: In the special case of the covering index that implements a
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
** total number of columns in the table.
**
-** Note 2: C is only used for STAT4.
-**
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
** PRIMARY KEY of the table. The covering index that implements the
** original WITHOUT ROWID table as N==K as a special case.
**
-** This routine allocates the Stat4Accum object in heap memory. The return
-** value is a pointer to the Stat4Accum object. The datatype of the
-** return value is BLOB, but it is really just a pointer to the Stat4Accum
+** This routine allocates the StatAccum object in heap memory. The return
+** value is a pointer to the StatAccum object. The datatype of the
+** return value is BLOB, but it is really just a pointer to the StatAccum
** object.
*/
static void statInit(
@@ -105244,14 +107632,15 @@ static void statInit(
int argc,
sqlite3_value **argv
){
- Stat4Accum *p;
+ StatAccum *p;
int nCol; /* Number of columns in index being sampled */
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
int n; /* Bytes of space to allocate */
- sqlite3 *db; /* Database connection */
+ sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
#ifdef SQLITE_ENABLE_STAT4
- int mxSample = SQLITE_STAT4_SAMPLES;
+ /* Maximum number of samples. 0 if STAT4 data is not collected */
+ int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
#endif
/* Decode the three function arguments */
@@ -105263,16 +107652,17 @@ static void statInit(
assert( nKeyCol<=nCol );
assert( nKeyCol>0 );
- /* Allocate the space required for the Stat4Accum object */
+ /* Allocate the space required for the StatAccum object */
n = sizeof(*p)
- + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
- + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
+ + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
+ + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
#ifdef SQLITE_ENABLE_STAT4
- + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */
- + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */
- + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
+ if( mxSample ){
+ n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
+ + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
+ + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
+ }
#endif
- ;
db = sqlite3_context_db_handle(context);
p = sqlite3DbMallocZero(db, n);
if( p==0 ){
@@ -105281,25 +107671,28 @@ static void statInit(
}
p->db = db;
+ p->nEst = sqlite3_value_int64(argv[2]);
p->nRow = 0;
+ p->nLimit = sqlite3_value_int64(argv[3]);
p->nCol = nCol;
p->nKeyCol = nKeyCol;
+ p->nSkipAhead = 0;
p->current.anDLt = (tRowcnt*)&p[1];
p->current.anEq = &p->current.anDLt[nColUp];
#ifdef SQLITE_ENABLE_STAT4
- {
+ p->mxSample = p->nLimit==0 ? mxSample : 0;
+ if( mxSample ){
u8 *pSpace; /* Allocated space not yet assigned */
int i; /* Used to iterate through p->aSample[] */
p->iGet = -1;
- p->mxSample = mxSample;
- p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
+ p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
p->current.anLt = &p->current.anEq[nColUp];
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
- /* Set up the Stat4Accum.a[] and aBest[] arrays */
- p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
+ /* Set up the StatAccum.a[] and aBest[] arrays */
+ p->a = (struct StatSample*)&p->current.anLt[nColUp];
p->aBest = &p->a[mxSample];
pSpace = (u8*)(&p->a[mxSample+nCol]);
for(i=0; i<(mxSample+nCol); i++){
@@ -105319,10 +107712,10 @@ static void statInit(
** only the pointer (the 2nd parameter) matters. The size of the object
** (given by the 3rd parameter) is never used and can be any positive
** value. */
- sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
+ sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
}
static const FuncDef statInitFuncdef = {
- 2+IsStat4, /* nArg */
+ 4, /* nArg */
SQLITE_UTF8, /* funcFlags */
0, /* pUserData */
0, /* pNext */
@@ -105346,9 +107739,9 @@ static const FuncDef statInitFuncdef = {
** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid.
*/
static int sampleIsBetterPost(
- Stat4Accum *pAccum,
- Stat4Sample *pNew,
- Stat4Sample *pOld
+ StatAccum *pAccum,
+ StatSample *pNew,
+ StatSample *pOld
){
int nCol = pAccum->nCol;
int i;
@@ -105370,9 +107763,9 @@ static int sampleIsBetterPost(
** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid.
*/
static int sampleIsBetter(
- Stat4Accum *pAccum,
- Stat4Sample *pNew,
- Stat4Sample *pOld
+ StatAccum *pAccum,
+ StatSample *pNew,
+ StatSample *pOld
){
tRowcnt nEqNew = pNew->anEq[pNew->iCol];
tRowcnt nEqOld = pOld->anEq[pOld->iCol];
@@ -105392,21 +107785,21 @@ static int sampleIsBetter(
** Copy the contents of sample *pNew into the p->a[] array. If necessary,
** remove the least desirable sample from p->a[] to make room.
*/
-static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
- Stat4Sample *pSample = 0;
+static void sampleInsert(StatAccum *p, StatSample *pNew, int nEqZero){
+ StatSample *pSample = 0;
int i;
assert( IsStat4 || nEqZero==0 );
- /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
- ** values in the anEq[] array of any sample in Stat4Accum.a[]. In
+ /* StatAccum.nMaxEqZero is set to the maximum number of leading 0
+ ** values in the anEq[] array of any sample in StatAccum.a[]. In
** other words, if nMaxEqZero is n, then it is guaranteed that there
- ** are no samples with Stat4Sample.anEq[m]==0 for (m>=n). */
+ ** are no samples with StatSample.anEq[m]==0 for (m>=n). */
if( nEqZero>p->nMaxEqZero ){
p->nMaxEqZero = nEqZero;
}
if( pNew->isPSample==0 ){
- Stat4Sample *pUpgrade = 0;
+ StatSample *pUpgrade = 0;
assert( pNew->anEq[pNew->iCol]>0 );
/* This sample is being added because the prefix that ends in column
@@ -105415,7 +107808,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
** this one. Instead, upgrade the priority of the highest priority
** existing sample that shares this prefix. */
for(i=p->nSample-1; i>=0; i--){
- Stat4Sample *pOld = &p->a[i];
+ StatSample *pOld = &p->a[i];
if( pOld->anEq[pNew->iCol]==0 ){
if( pOld->isPSample ) return;
assert( pOld->iCol>pNew->iCol );
@@ -105434,7 +107827,7 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
/* If necessary, remove sample iMin to make room for the new sample. */
if( p->nSample>=p->mxSample ){
- Stat4Sample *pMin = &p->a[p->iMin];
+ StatSample *pMin = &p->a[p->iMin];
tRowcnt *anEq = pMin->anEq;
tRowcnt *anLt = pMin->anLt;
tRowcnt *anDLt = pMin->anDLt;
@@ -105477,20 +107870,20 @@ find_new_min:
}
#endif /* SQLITE_ENABLE_STAT4 */
+#ifdef SQLITE_ENABLE_STAT4
/*
** Field iChng of the index being scanned has changed. So at this point
** p->current contains a sample that reflects the previous row of the
** index. The value of anEq[iChng] and subsequent anEq[] elements are
** correct at this point.
*/
-static void samplePushPrevious(Stat4Accum *p, int iChng){
-#ifdef SQLITE_ENABLE_STAT4
+static void samplePushPrevious(StatAccum *p, int iChng){
int i;
/* Check if any samples from the aBest[] array should be pushed
** into IndexSample.a[] at this point. */
for(i=(p->nCol-2); i>=iChng; i--){
- Stat4Sample *pBest = &p->aBest[i];
+ StatSample *pBest = &p->aBest[i];
pBest->anEq[i] = p->current.anEq[i];
if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){
sampleInsert(p, pBest, i);
@@ -105514,27 +107907,25 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
}
p->nMaxEqZero = iChng;
}
-#endif
-
-#ifndef SQLITE_ENABLE_STAT4
- UNUSED_PARAMETER( p );
- UNUSED_PARAMETER( iChng );
-#endif
}
+#endif /* SQLITE_ENABLE_STAT4 */
/*
** Implementation of the stat_push SQL function: stat_push(P,C,R)
** Arguments:
**
-** P Pointer to the Stat4Accum object created by stat_init()
+** P Pointer to the StatAccum object created by stat_init()
** C Index of left-most column to differ from previous row
** R Rowid for the current row. Might be a key record for
** WITHOUT ROWID tables.
**
-** This SQL function always returns NULL. It's purpose it to accumulate
-** statistical data and/or samples in the Stat4Accum object about the
-** index being analyzed. The stat_get() SQL function will later be used to
-** extract relevant information for constructing the sqlite_statN tables.
+** The purpose of this routine is to collect statistical data and/or
+** samples from the index being analyzed into the StatAccum object.
+** The stat_get() SQL function will be used afterwards to
+** retrieve the information gathered.
+**
+** This SQL function usually returns NULL, but might return an integer
+** if it wants the byte-code to do special processing.
**
** The R parameter is only used for STAT4
*/
@@ -105546,7 +107937,7 @@ static void statPush(
int i;
/* The three function arguments */
- Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
+ StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
int iChng = sqlite3_value_int(argv[1]);
UNUSED_PARAMETER( argc );
@@ -105559,7 +107950,9 @@ static void statPush(
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
}else{
/* Second and subsequent calls get processed here */
- samplePushPrevious(p, iChng);
+#ifdef SQLITE_ENABLE_STAT4
+ if( p->mxSample ) samplePushPrevious(p, iChng);
+#endif
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
** to the current row of the index. */
@@ -105569,26 +107962,25 @@ static void statPush(
for(i=iChng; i<p->nCol; i++){
p->current.anDLt[i]++;
#ifdef SQLITE_ENABLE_STAT4
- p->current.anLt[i] += p->current.anEq[i];
+ if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
#endif
p->current.anEq[i] = 1;
}
}
- p->nRow++;
-#ifdef SQLITE_ENABLE_STAT4
- if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
- sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
- }else{
- sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
- sqlite3_value_blob(argv[2]));
- }
- p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
-#endif
+ p->nRow++;
#ifdef SQLITE_ENABLE_STAT4
- {
- tRowcnt nLt = p->current.anLt[p->nCol-1];
+ if( p->mxSample ){
+ tRowcnt nLt;
+ if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
+ sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
+ }else{
+ sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
+ sqlite3_value_blob(argv[2]));
+ }
+ p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
+ nLt = p->current.anLt[p->nCol-1];
/* Check if this is to be a periodic sample. If so, add it. */
if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
p->current.isPSample = 1;
@@ -105604,9 +107996,14 @@ static void statPush(
sampleCopy(p, &p->aBest[i], &p->current);
}
}
- }
+ }else
#endif
+ if( p->nLimit && p->nRow>(tRowcnt)p->nLimit*(p->nSkipAhead+1) ){
+ p->nSkipAhead++;
+ sqlite3_result_int(context, p->current.anDLt[0]>0);
+ }
}
+
static const FuncDef statPushFuncdef = {
2+IsStat4, /* nArg */
SQLITE_UTF8, /* funcFlags */
@@ -105628,15 +108025,15 @@ static const FuncDef statPushFuncdef = {
/*
** Implementation of the stat_get(P,J) SQL function. This routine is
** used to query statistical information that has been gathered into
-** the Stat4Accum object by prior calls to stat_push(). The P parameter
-** has type BLOB but it is really just a pointer to the Stat4Accum object.
+** the StatAccum object by prior calls to stat_push(). The P parameter
+** has type BLOB but it is really just a pointer to the StatAccum object.
** The content to returned is determined by the parameter J
** which is one of the STAT_GET_xxxx values defined above.
**
** The stat_get(P,J) function is not available to generic SQL. It is
** inserted as part of a manually constructed bytecode program. (See
** the callStatGet() routine below.) It is guaranteed that the P
-** parameter will always be a poiner to a Stat4Accum object, never a
+** parameter will always be a pointer to a StatAccum object, never a
** NULL.
**
** If STAT4 is not enabled, then J is always
@@ -105649,7 +108046,7 @@ static void statGet(
int argc,
sqlite3_value **argv
){
- Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
+ StatAccum *p = (StatAccum*)sqlite3_value_blob(argv[0]);
#ifdef SQLITE_ENABLE_STAT4
/* STAT4 has a parameter on this routine. */
int eCall = sqlite3_value_int(argv[1]);
@@ -105658,6 +108055,7 @@ static void statGet(
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
|| eCall==STAT_GET_NDLT
);
+ assert( eCall==STAT_GET_STAT1 || p->mxSample );
if( eCall==STAT_GET_STAT1 )
#else
assert( argc==1 );
@@ -105670,7 +108068,7 @@ static void statGet(
** the index. The first integer in the list is the total number of
** entries in the index. There is one additional integer in the list
** for each indexed column. This additional integer is an estimate of
- ** the number of rows matched by a stabbing query on the index using
+ ** the number of rows matched by a equality query on the index using
** a key with the corresponding number of fields. In other words,
** if the index is on columns (a,b) and the sqlite_stat1 value is
** "100 10 2", then SQLite estimates that:
@@ -105693,7 +108091,8 @@ static void statGet(
return;
}
- sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
+ sqlite3_snprintf(24, zRet, "%llu",
+ p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
z = zRet + sqlite3Strlen30(zRet);
for(i=0; i<p->nKeyCol; i++){
u64 nDistinct = p->current.anDLt[i] + 1;
@@ -105713,7 +108112,7 @@ static void statGet(
p->iGet = 0;
}
if( p->iGet<p->nSample ){
- Stat4Sample *pS = p->a + p->iGet;
+ StatSample *pS = p->a + p->iGet;
if( pS->nRowid==0 ){
sqlite3_result_int64(context, pS->u.iRowid);
}else{
@@ -105769,18 +108168,17 @@ static const FuncDef statGetFuncdef = {
{0}
};
-static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){
- assert( regOut!=regStat4 && regOut!=regStat4+1 );
+static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
#ifdef SQLITE_ENABLE_STAT4
- sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1);
+ sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
#elif SQLITE_DEBUG
assert( iParam==STAT_GET_STAT1 );
#else
UNUSED_PARAMETER( iParam );
#endif
- sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut,
- (char*)&statGetFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 1 + IsStat4);
+ assert( regOut!=regStat && regOut!=regStat+1 );
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
+ &statGetFuncdef, 0);
}
/*
@@ -105805,12 +108203,11 @@ static void analyzeOneTable(
int iDb; /* Index of database containing pTab */
u8 needTableCnt = 1; /* True to count the table */
int regNewRowid = iMem++; /* Rowid for the inserted record */
- int regStat4 = iMem++; /* Register to hold Stat4Accum object */
+ int regStat = iMem++; /* Register to hold StatAccum object */
int regChng = iMem++; /* Index of changed index field */
-#ifdef SQLITE_ENABLE_STAT4
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
-#endif
int regTemp = iMem++; /* Temporary use register */
+ int regTemp2 = iMem++; /* Second temporary use register */
int regTabname = iMem++; /* Register containing table name */
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
@@ -105938,19 +108335,27 @@ static void analyzeOneTable(
** (1) the number of columns in the index including the rowid
** (or for a WITHOUT ROWID table, the number of PK columns),
** (2) the number of columns in the key without the rowid/pk
- ** (3) the number of rows in the index,
- **
- **
- ** The third argument is only used for STAT4
+ ** (3) estimated number of rows in the index,
*/
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
+ assert( regRowid==regStat+2 );
+ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
#ifdef SQLITE_ENABLE_STAT4
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
+ if( OptimizationEnabled(db, SQLITE_Stat4) ){
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
+ }else
#endif
- sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
- sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
- sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4,
- (char*)&statInitFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 2+IsStat4);
+ {
+ addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
+ }
+ assert( regTemp2==regStat+4 );
+ sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
+ sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
+ &statInitFuncdef, 0);
/* Implementation of the following:
**
@@ -105960,8 +108365,6 @@ static void analyzeOneTable(
** goto next_push_0;
**
*/
- addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
- VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrNextRow = sqlite3VdbeCurrentAddr(v);
@@ -105994,6 +108397,7 @@ static void analyzeOneTable(
char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
+ VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
aGotoChng[i] =
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
@@ -106014,6 +108418,7 @@ static void analyzeOneTable(
for(i=0; i<nColTest; i++){
sqlite3VdbeJumpHere(v, aGotoChng[i]);
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
+ VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
}
sqlite3VdbeResolveLabel(v, endDistinctTest);
sqlite3DbFree(db, aGotoChng);
@@ -106027,31 +108432,46 @@ static void analyzeOneTable(
** if !eof(csr) goto next_row;
*/
#ifdef SQLITE_ENABLE_STAT4
- assert( regRowid==(regStat4+2) );
- if( HasRowid(pTab) ){
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
- }else{
- Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
- int j, k, regKey;
- regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
- for(j=0; j<pPk->nKeyCol; j++){
- k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
- assert( k>=0 && k<pIdx->nColumn );
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
- VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
+ if( OptimizationEnabled(db, SQLITE_Stat4) ){
+ assert( regRowid==(regStat+2) );
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
+ int j, k, regKey;
+ regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
+ for(j=0; j<pPk->nKeyCol; j++){
+ k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
+ assert( k>=0 && k<pIdx->nColumn );
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
+ VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
+ sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
- sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
}
#endif
- assert( regChng==(regStat4+1) );
- sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp,
- (char*)&statPushFuncdef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, 2+IsStat4);
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+ assert( regChng==(regStat+1) );
+ {
+ sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
+ &statPushFuncdef, 0);
+ if( db->nAnalysisLimit ){
+ int j1, j2, j3;
+ j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
+ j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
+ j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
+ VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, j1);
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+ sqlite3VdbeJumpHere(v, j2);
+ sqlite3VdbeJumpHere(v, j3);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
+ }
+ }
/* Add the entry to the stat1 table. */
- callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
+ callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
assert( "BBB"[0]==SQLITE_AFF_TEXT );
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
@@ -106063,7 +108483,7 @@ static void analyzeOneTable(
/* Add the entries to the stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
- {
+ if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
int regEq = regStat1;
int regLt = regStat1+1;
int regDLt = regStat1+2;
@@ -106077,12 +108497,12 @@ static void analyzeOneTable(
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
addrNext = sqlite3VdbeCurrentAddr(v);
- callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
+ callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
VdbeCoverage(v);
- callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
- callStatGet(v, regStat4, STAT_GET_NLT, regLt);
- callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
+ callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
+ callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
+ callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
VdbeCoverage(v);
for(i=0; i<nCol; i++){
@@ -106707,9 +109127,9 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Load the statistics from the sqlite_stat4 table. */
#ifdef SQLITE_ENABLE_STAT4
if( rc==SQLITE_OK ){
- db->lookaside.bDisable++;
+ DisableLookaside;
rc = loadStat4(db, sInfo.zDatabase);
- db->lookaside.bDisable--;
+ EnableLookaside;
}
for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
@@ -106777,6 +109197,17 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
}
/*
+** Return true if zName points to a name that may be used to refer to
+** database iDb attached to handle db.
+*/
+SQLITE_PRIVATE int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){
+ return (
+ sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0
+ || (iDb==0 && sqlite3StrICmp("main", zName)==0)
+ );
+}
+
+/*
** An SQL user-function registered to do the work of an ATTACH statement. The
** three arguments to the function come directly from an attach statement:
**
@@ -106848,9 +109279,8 @@ static void attachFunc(
goto attach_error;
}
for(i=0; i<db->nDb; i++){
- char *z = db->aDb[i].zDbSName;
- assert( z && zName );
- if( sqlite3StrICmp(z, zName)==0 ){
+ assert( zName );
+ if( sqlite3DbIsNamed(db, i, zName) ){
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
goto attach_error;
}
@@ -106918,43 +109348,7 @@ static void attachFunc(
if( rc==SQLITE_OK && pNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
-
-
-#ifdef SQLITE_HAS_CODEC
- if( rc==SQLITE_OK ){
- extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
- extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
- int nKey;
- char *zKey;
- int t = sqlite3_value_type(argv[2]);
- switch( t ){
- case SQLITE_INTEGER:
- case SQLITE_FLOAT:
- zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
- rc = SQLITE_ERROR;
- break;
-
- case SQLITE_TEXT:
- case SQLITE_BLOB:
- nKey = sqlite3_value_bytes(argv[2]);
- zKey = (char *)sqlite3_value_blob(argv[2]);
- rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
- break;
-
- case SQLITE_NULL:
- /* No key specified. Use the key from URI filename, or if none,
- ** use the key from the main database. */
- if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){
- sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
- rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
- }
- }
- break;
- }
- }
-#endif
- sqlite3_free( zPath );
+ sqlite3_free_filename( zPath );
/* If the file was opened successfully, read the schema for the new database.
** If this fails, or if opening the file failed, then close the file and
@@ -107039,7 +109433,7 @@ static void detachFunc(
for(i=0; i<db->nDb; i++){
pDb = &db->aDb[i];
if( pDb->pBt==0 ) continue;
- if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
+ if( sqlite3DbIsNamed(db, i, zName) ) break;
}
if( i>=db->nDb ){
@@ -107132,11 +109526,8 @@ static void codeAttach(
assert( v || db->mallocFailed );
if( v ){
- sqlite3VdbeAddOp4(v, OP_Function0, 0, regArgs+3-pFunc->nArg, regArgs+3,
- (char *)pFunc, P4_FUNCDEF);
- assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
- sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
-
+ sqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3,
+ pFunc->nArg, pFunc, 0);
/* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
** statement only). For DETACH, set it to false (expire all existing
** statements).
@@ -107211,7 +109602,7 @@ SQLITE_PRIVATE void sqlite3FixInit(
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
- pFix->bVarOnly = (iDb==1);
+ pFix->bTemp = (iDb==1);
}
/*
@@ -107233,22 +109624,24 @@ SQLITE_PRIVATE int sqlite3FixSrcList(
SrcList *pList /* The Source list to check and modify */
){
int i;
- const char *zDb;
struct SrcList_item *pItem;
+ sqlite3 *db = pFix->pParse->db;
+ int iDb = sqlite3FindDbName(db, pFix->zDb);
if( NEVER(pList==0) ) return 0;
- zDb = pFix->zDb;
+
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
- if( pFix->bVarOnly==0 ){
- if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){
+ if( pFix->bTemp==0 ){
+ if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){
sqlite3ErrorMsg(pFix->pParse,
"%s %T cannot reference objects in database %s",
pFix->zType, pFix->pName, pItem->zDatabase);
return 1;
}
- sqlite3DbFree(pFix->pParse->db, pItem->zDatabase);
+ sqlite3DbFree(db, pItem->zDatabase);
pItem->zDatabase = 0;
pItem->pSchema = pFix->pSchema;
+ pItem->fg.fromDDL = 1;
}
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
@@ -107304,7 +109697,7 @@ SQLITE_PRIVATE int sqlite3FixExpr(
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- ExprSetProperty(pExpr, EP_Indirect);
+ if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL);
if( pExpr->op==TK_VARIABLE ){
if( pFix->pParse->db->init.busy ){
pExpr->op = TK_NULL;
@@ -107967,22 +110360,39 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha
return 0;
}
#endif
- while(1){
- for(i=OMIT_TEMPDB; i<db->nDb; i++){
- int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
- assert( sqlite3SchemaMutexHeld(db, j, 0) );
- p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
- if( p ) return p;
+ if( zDatabase ){
+ for(i=0; i<db->nDb; i++){
+ if( sqlite3StrICmp(zDatabase, db->aDb[i].zDbSName)==0 ) break;
+ }
+ if( i>=db->nDb ){
+ /* No match against the official names. But always match "main"
+ ** to schema 0 as a legacy fallback. */
+ if( sqlite3StrICmp(zDatabase,"main")==0 ){
+ i = 0;
+ }else{
+ return 0;
}
}
- /* Not found. If the name we were looking for was temp.sqlite_master
- ** then change the name to sqlite_temp_master and try again. */
- if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break;
- if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break;
- zName = TEMP_MASTER_NAME;
+ p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
+ if( p==0 && i==1 && sqlite3StrICmp(zName, MASTER_NAME)==0 ){
+ /* All temp.sqlite_master to be an alias for sqlite_temp_master */
+ p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, TEMP_MASTER_NAME);
+ }
+ }else{
+ /* Match against TEMP first */
+ p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, zName);
+ if( p ) return p;
+ /* The main database is second */
+ p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, zName);
+ if( p ) return p;
+ /* Attached databases are in order of attachment */
+ for(i=2; i<db->nDb; i++){
+ assert( sqlite3SchemaMutexHeld(db, i, 0) );
+ p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
+ if( p ) break;
+ }
}
- return 0;
+ return p;
}
/*
@@ -108092,7 +110502,7 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
assert( pSchema );
- if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
+ if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&pSchema->idxHash, zName);
if( p ) break;
@@ -108245,6 +110655,7 @@ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
+ assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) );
sqlite3DbFree(db, pCol->zName);
sqlite3ExprDelete(db, pCol->pDflt);
sqlite3DbFree(db, pCol->zColl);
@@ -108511,13 +110922,14 @@ SQLITE_PRIVATE int sqlite3CheckObjectName(
}
}
}else{
- if( pParse->nested==0
- && 0==sqlite3StrNICmp(zName, "sqlite_", 7)
+ if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7))
+ || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName))
){
sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s",
zName);
return SQLITE_ERROR;
}
+
}
return SQLITE_OK;
}
@@ -108532,10 +110944,12 @@ SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){
}
/*
-** Return the column of index pIdx that corresponds to table
-** column iCol. Return -1 if not found.
+** Convert an table column number into a index column number. That is,
+** for the column iCol in the table (as defined by the CREATE TABLE statement)
+** find the (first) offset of that column in index pIdx. Or return -1
+** if column iCol is not used in index pIdx.
*/
-SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
+SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){
int i;
for(i=0; i<pIdx->nColumn; i++){
if( iCol==pIdx->aiColumn[i] ) return i;
@@ -108543,6 +110957,84 @@ SQLITE_PRIVATE i16 sqlite3ColumnOfIndex(Index *pIdx, i16 iCol){
return -1;
}
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+/* Convert a storage column number into a table column number.
+**
+** The storage column number (0,1,2,....) is the index of the value
+** as it appears in the record on disk. The true column number
+** is the index (0,1,2,...) of the column in the CREATE TABLE statement.
+**
+** The storage column number is less than the table column number if
+** and only there are VIRTUAL columns to the left.
+**
+** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro.
+*/
+SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){
+ if( pTab->tabFlags & TF_HasVirtual ){
+ int i;
+ for(i=0; i<=iCol; i++){
+ if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) iCol++;
+ }
+ }
+ return iCol;
+}
+#endif
+
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+/* Convert a table column number into a storage column number.
+**
+** The storage column number (0,1,2,....) is the index of the value
+** as it appears in the record on disk. Or, if the input column is
+** the N-th virtual column (zero-based) then the storage number is
+** the number of non-virtual columns in the table plus N.
+**
+** The true column number is the index (0,1,2,...) of the column in
+** the CREATE TABLE statement.
+**
+** If the input column is a VIRTUAL column, then it should not appear
+** in storage. But the value sometimes is cached in registers that
+** follow the range of registers used to construct storage. This
+** avoids computing the same VIRTUAL column multiple times, and provides
+** values for use by OP_Param opcodes in triggers. Hence, if the
+** input column is a VIRTUAL table, put it after all the other columns.
+**
+** In the following, N means "normal column", S means STORED, and
+** V means VIRTUAL. Suppose the CREATE TABLE has columns like this:
+**
+** CREATE TABLE ex(N,S,V,N,S,V,N,S,V);
+** -- 0 1 2 3 4 5 6 7 8
+**
+** Then the mapping from this function is as follows:
+**
+** INPUTS: 0 1 2 3 4 5 6 7 8
+** OUTPUTS: 0 1 6 2 3 7 4 5 8
+**
+** So, in other words, this routine shifts all the virtual columns to
+** the end.
+**
+** If SQLITE_OMIT_GENERATED_COLUMNS then there are no virtual columns and
+** this routine is a no-op macro. If the pTab does not have any virtual
+** columns, then this routine is no-op that always return iCol. If iCol
+** is negative (indicating the ROWID column) then this routine return iCol.
+*/
+SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){
+ int i;
+ i16 n;
+ assert( iCol<pTab->nCol );
+ if( (pTab->tabFlags & TF_HasVirtual)==0 || iCol<0 ) return iCol;
+ for(i=0, n=0; i<iCol; i++){
+ if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) n++;
+ }
+ if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ){
+ /* iCol is a virtual column itself */
+ return pTab->nNVCol + i - n;
+ }else{
+ /* iCol is a normal or stored column */
+ return n;
+ }
+}
+#endif
+
/*
** Begin constructing a new table representation in memory. This is
** the first of several action routines that get called in response
@@ -108812,6 +111304,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
pCol = &p->aCol[p->nCol];
memset(pCol, 0, sizeof(p->aCol[0]));
pCol->zName = z;
+ pCol->hName = sqlite3StrIHash(z);
sqlite3ColumnPropertiesFromName(p, pCol);
if( pType->n==0 ){
@@ -108833,6 +111326,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
pCol->colFlags |= COLFLAG_HASTYPE;
}
p->nCol++;
+ p->nNVCol++;
pParse->constraintName.n = 0;
}
@@ -108977,10 +111471,17 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(
sqlite3 *db = pParse->db;
p = pParse->pNewTable;
if( p!=0 ){
+ int isInit = db->init.busy && db->init.iDb!=1;
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){
+ if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ }else if( pCol->colFlags & COLFLAG_GENERATED ){
+ testcase( pCol->colFlags & COLFLAG_VIRTUAL );
+ testcase( pCol->colFlags & COLFLAG_STORED );
+ sqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column");
+#endif
}else{
/* A copy of pExpr is used instead of the original, as pExpr contains
** tokens that point to volatile memory.
@@ -109027,6 +111528,21 @@ static void sqlite3StringToId(Expr *p){
}
/*
+** Tag the given column as being part of the PRIMARY KEY
+*/
+static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){
+ pCol->colFlags |= COLFLAG_PRIMKEY;
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ if( pCol->colFlags & COLFLAG_GENERATED ){
+ testcase( pCol->colFlags & COLFLAG_VIRTUAL );
+ testcase( pCol->colFlags & COLFLAG_STORED );
+ sqlite3ErrorMsg(pParse,
+ "generated columns cannot be part of the PRIMARY KEY");
+ }
+#endif
+}
+
+/*
** Designate the PRIMARY KEY for the table. pList is a list of names
** of columns that form the primary key. If pList is NULL, then the
** most recently added column of the table is the primary key.
@@ -109065,7 +111581,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
if( pList==0 ){
iCol = pTab->nCol - 1;
pCol = &pTab->aCol[iCol];
- pCol->colFlags |= COLFLAG_PRIMKEY;
+ makeColumnPartOfPrimaryKey(pParse, pCol);
nTerm = 1;
}else{
nTerm = pList->nExpr;
@@ -109078,7 +111594,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
for(iCol=0; iCol<pTab->nCol; iCol++){
if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
pCol = &pTab->aCol[iCol];
- pCol->colFlags |= COLFLAG_PRIMKEY;
+ makeColumnPartOfPrimaryKey(pParse, pCol);
break;
}
}
@@ -109099,6 +111615,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
assert( autoInc==0 || autoInc==1 );
pTab->tabFlags |= autoInc*TF_Autoincrement;
if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags;
+ (void)sqlite3HasExplicitNulls(pParse, pList);
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
@@ -109175,41 +111692,58 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
}
}
-/*
-** This function returns the collation sequence for database native text
-** encoding identified by the string zName, length nName.
-**
-** If the requested collation sequence is not available, or not available
-** in the database native encoding, the collation factory is invoked to
-** request it. If the collation factory does not supply such a sequence,
-** and the sequence is available in another text encoding, then that is
-** returned instead.
-**
-** If no versions of the requested collations sequence are available, or
-** another error occurs, NULL is returned and an error message written into
-** pParse.
-**
-** This routine is a wrapper around sqlite3FindCollSeq(). This routine
-** invokes the collation factory if the named collation cannot be found
-** and generates an error message.
-**
-** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
+/* Change the most recently parsed column to be a GENERATED ALWAYS AS
+** column.
*/
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
- sqlite3 *db = pParse->db;
- u8 enc = ENC(db);
- u8 initbusy = db->init.busy;
- CollSeq *pColl;
-
- pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
- if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName);
+SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ u8 eType = COLFLAG_VIRTUAL;
+ Table *pTab = pParse->pNewTable;
+ Column *pCol;
+ if( pTab==0 ){
+ /* generated column in an CREATE TABLE IF NOT EXISTS that already exists */
+ goto generated_done;
+ }
+ pCol = &(pTab->aCol[pTab->nCol-1]);
+ if( IN_DECLARE_VTAB ){
+ sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns");
+ goto generated_done;
+ }
+ if( pCol->pDflt ) goto generated_error;
+ if( pType ){
+ if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){
+ /* no-op */
+ }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){
+ eType = COLFLAG_STORED;
+ }else{
+ goto generated_error;
+ }
+ }
+ if( eType==COLFLAG_VIRTUAL ) pTab->nNVCol--;
+ pCol->colFlags |= eType;
+ assert( TF_HasVirtual==COLFLAG_VIRTUAL );
+ assert( TF_HasStored==COLFLAG_STORED );
+ pTab->tabFlags |= eType;
+ if( pCol->colFlags & COLFLAG_PRIMKEY ){
+ makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */
}
+ pCol->pDflt = pExpr;
+ pExpr = 0;
+ goto generated_done;
- return pColl;
+generated_error:
+ sqlite3ErrorMsg(pParse, "error in generated column \"%s\"",
+ pCol->zName);
+generated_done:
+ sqlite3ExprDelete(pParse->db, pExpr);
+#else
+ /* Throw and error for the GENERATED ALWAYS AS clause if the
+ ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */
+ sqlite3ErrorMsg(pParse, "generated columns not supported");
+ sqlite3ExprDelete(pParse->db, pExpr);
+#endif
}
-
/*
** Generate code that will increment the schema cookie.
**
@@ -109467,15 +112001,24 @@ static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){
** high-order bit of colNotIdxed is always 1. All unindexed columns
** of the table have a 1.
**
+** 2019-10-24: For the purpose of this computation, virtual columns are
+** not considered to be covered by the index, even if they are in the
+** index, because we do not trust the logic in whereIndexExprTrans() to be
+** able to find all instances of a reference to the indexed table column
+** and convert them into references to the index. Hence we always want
+** the actual table at hand in order to recompute the virtual column, if
+** necessary.
+**
** The colNotIdxed mask is AND-ed with the SrcList.a[].colUsed mask
** to determine if the index is covering index.
*/
static void recomputeColumnsNotIndexed(Index *pIdx){
Bitmask m = 0;
int j;
+ Table *pTab = pIdx->pTable;
for(j=pIdx->nColumn-1; j>=0; j--){
int x = pIdx->aiColumn[j];
- if( x>=0 ){
+ if( x>=0 && (pTab->aCol[x].colFlags & COLFLAG_VIRTUAL)==0 ){
testcase( x==BMS-1 );
testcase( x==BMS-2 );
if( x<BMS-1 ) m |= MASKBIT(x);
@@ -109526,6 +112069,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
pTab->aCol[i].notNull = OE_Abort;
}
}
+ pTab->tabFlags |= TF_HasNotNull;
}
/* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
@@ -109633,11 +112177,14 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
*/
nExtra = 0;
for(i=0; i<pTab->nCol; i++){
- if( !hasColumn(pPk->aiColumn, nPk, i) ) nExtra++;
+ if( !hasColumn(pPk->aiColumn, nPk, i)
+ && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ) nExtra++;
}
if( resizeIndexObject(db, pPk, nPk+nExtra) ) return;
for(i=0, j=nPk; i<pTab->nCol; i++){
- if( !hasColumn(pPk->aiColumn, j, i) ){
+ if( !hasColumn(pPk->aiColumn, j, i)
+ && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0
+ ){
assert( j<pPk->nColumn );
pPk->aiColumn[j] = i;
pPk->azColl[j] = sqlite3StrBINARY;
@@ -109645,10 +112192,32 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}
}
assert( pPk->nColumn==j );
- assert( pTab->nCol<=j );
+ assert( pTab->nNVCol<=j );
recomputeColumnsNotIndexed(pPk);
}
+
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*
+** Return true if pTab is a virtual table and zName is a shadow table name
+** for that virtual table.
+*/
+SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char *zName){
+ int nName; /* Length of zName */
+ Module *pMod; /* Module for the virtual table */
+
+ if( !IsVirtual(pTab) ) return 0;
+ nName = sqlite3Strlen30(pTab->zName);
+ if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0;
+ if( zName[nName]!='_' ) return 0;
+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
+ if( pMod==0 ) return 0;
+ if( pMod->pModule->iVersion<3 ) return 0;
+ if( pMod->pModule->xShadowName==0 ) return 0;
+ return pMod->pModule->xShadowName(zName+nName+1);
+}
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if zName is a shadow table name in the current database
@@ -109657,11 +112226,9 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** zName is temporarily modified while this routine is running, but is
** restored to its original value prior to this routine returning.
*/
-static int isShadowTableName(sqlite3 *db, char *zName){
+SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
char *zTail; /* Pointer to the last "_" in zName */
Table *pTab; /* Table that zName is a shadow of */
- Module *pMod; /* Module for the virtual table */
-
zTail = strrchr(zName, '_');
if( zTail==0 ) return 0;
*zTail = 0;
@@ -109669,16 +112236,37 @@ static int isShadowTableName(sqlite3 *db, char *zName){
*zTail = '_';
if( pTab==0 ) return 0;
if( !IsVirtual(pTab) ) return 0;
- pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
- if( pMod==0 ) return 0;
- if( pMod->pModule->iVersion<3 ) return 0;
- if( pMod->pModule->xShadowName==0 ) return 0;
- return pMod->pModule->xShadowName(zTail+1);
+ return sqlite3IsShadowTableOf(db, pTab, zName);
}
-#else
-# define isShadowTableName(x,y) 0
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+
+#ifdef SQLITE_DEBUG
+/*
+** Mark all nodes of an expression as EP_Immutable, indicating that
+** they should not be changed. Expressions attached to a table or
+** index definition are tagged this way to help ensure that we do
+** not pass them into code generator routines by mistake.
+*/
+static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){
+ ExprSetVVAProperty(pExpr, EP_Immutable);
+ return WRC_Continue;
+}
+static void markExprListImmutable(ExprList *pList){
+ if( pList ){
+ Walker w;
+ memset(&w, 0, sizeof(w));
+ w.xExprCallback = markImmutableExprStep;
+ w.xSelectCallback = sqlite3SelectWalkNoop;
+ w.xSelectCallback2 = 0;
+ sqlite3WalkExprList(&w, pList);
+ }
+}
+#else
+#define markExprListImmutable(X) /* no-op */
+#endif /* SQLITE_DEBUG */
+
+
/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
@@ -109718,7 +112306,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
p = pParse->pNewTable;
if( p==0 ) return;
- if( pSelect==0 && isShadowTableName(db, p->zName) ){
+ if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){
p->tabFlags |= TF_Shadow;
}
@@ -109754,12 +112342,11 @@ SQLITE_PRIVATE void sqlite3EndTable(
}
if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
- }else{
- p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
- convertToWithoutRowidTable(pParse, p);
+ return;
}
+ p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
+ convertToWithoutRowidTable(pParse, p);
}
-
iDb = sqlite3SchemaToIndex(db, p->pSchema);
#ifndef SQLITE_OMIT_CHECK
@@ -109767,8 +112354,47 @@ SQLITE_PRIVATE void sqlite3EndTable(
*/
if( p->pCheck ){
sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
+ if( pParse->nErr ){
+ /* If errors are seen, delete the CHECK constraints now, else they might
+ ** actually be used if PRAGMA writable_schema=ON is set. */
+ sqlite3ExprListDelete(db, p->pCheck);
+ p->pCheck = 0;
+ }else{
+ markExprListImmutable(p->pCheck);
+ }
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
+#ifndef SQLITE_OMIT_GENERATED_COLUMNS
+ if( p->tabFlags & TF_HasGenerated ){
+ int ii, nNG = 0;
+ testcase( p->tabFlags & TF_HasVirtual );
+ testcase( p->tabFlags & TF_HasStored );
+ for(ii=0; ii<p->nCol; ii++){
+ u32 colFlags = p->aCol[ii].colFlags;
+ if( (colFlags & COLFLAG_GENERATED)!=0 ){
+ Expr *pX = p->aCol[ii].pDflt;
+ testcase( colFlags & COLFLAG_VIRTUAL );
+ testcase( colFlags & COLFLAG_STORED );
+ if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){
+ /* If there are errors in resolving the expression, change the
+ ** expression to a NULL. This prevents code generators that operate
+ ** on the expression from inserting extra parts into the expression
+ ** tree that have been allocated from lookaside memory, which is
+ ** illegal in a schema and will lead to errors or heap corruption
+ ** when the database connection closes. */
+ sqlite3ExprDelete(db, pX);
+ p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
+ }
+ }else{
+ nNG++;
+ }
+ }
+ if( nNG==0 ){
+ sqlite3ErrorMsg(pParse, "must have at least one non-generated column");
+ return;
+ }
+ }
+#endif
/* Estimate the average row size for the table and for all implied indices */
estimateTableWidth(p);
@@ -109845,7 +112471,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB);
if( pSelTab==0 ) return;
assert( p->aCol==0 );
- p->nCol = pSelTab->nCol;
+ p->nCol = p->nNVCol = pSelTab->nCol;
p->aCol = pSelTab->aCol;
pSelTab->nCol = 0;
pSelTab->aCol = 0;
@@ -109918,7 +112544,6 @@ SQLITE_PRIVATE void sqlite3EndTable(
sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName));
}
-
/* Add the table to the in-memory representation of the database.
*/
if( db->init.busy ){
@@ -109989,6 +112614,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
** allocated rather than point to the input string - which means that
** they will persist after the current sqlite3_exec() call returns.
*/
+ pSelect->selFlags |= SF_View;
if( IN_RENAME_OBJECT ){
p->pSelect = pSelect;
pSelect = 0;
@@ -110102,7 +112728,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
n = pParse->nTab;
sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
pTable->nCol = -1;
- db->lookaside.bDisable++;
+ DisableLookaside;
#ifndef SQLITE_OMIT_AUTHORIZATION
xAuth = db->xAuth;
db->xAuth = 0;
@@ -110112,7 +112738,10 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
#endif
pParse->nTab = n;
- if( pTable->pCheck ){
+ if( pSelTab==0 ){
+ pTable->nCol = 0;
+ nErr++;
+ }else if( pTable->pCheck ){
/* CREATE VIEW name(arglist) AS ...
** The names of the columns in the table are taken from
** arglist which is stored in pTable->pCheck. The pCheck field
@@ -110128,7 +112757,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
SQLITE_AFF_NONE);