summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-29 16:10:41 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-29 16:10:41 +0200
commitcd0b3a0048aa8aa62442d0465db4200f7aad257e (patch)
tree4c51afd0189ab479a7a0d5f83d83f25f4c1f78eb
parent1d50611d9aa6f34cab5293514172d24eb44e26cc (diff)
Update to upstream 3.18.0
Session export is still broken on Windows so keeping disabled.
-rw-r--r--libsqlite3/buildfile2
-rw-r--r--libsqlite3/sqlite3.c16051
-rw-r--r--libsqlite3/sqlite3.h831
-rw-r--r--libsqlite3/sqlite3ext.h4
4 files changed, 10642 insertions, 6246 deletions
diff --git a/libsqlite3/buildfile b/libsqlite3/buildfile
index b3b1015..9f8d6c5 100644
--- a/libsqlite3/buildfile
+++ b/libsqlite3/buildfile
@@ -19,7 +19,7 @@ else
#
# PREUPDATE_HOOK is required by SESSION
#
-# -DSQLITE_ENABLE_SESSION=1 removed for now due to bug in 3.14.1.
+# -DSQLITE_ENABLE_SESSION=1 removed for now due to bug in 3.18.0.
#
# Note that if disabling any previously-released features, then will need to
# increment abi_major.
diff --git a/libsqlite3/sqlite3.c b/libsqlite3/sqlite3.c
index ccddfe6..af83f89 100644
--- a/libsqlite3/sqlite3.c
+++ b/libsqlite3/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.14.1. By combining all the individual C code files into this
+** version 3.18.0. 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
@@ -9,7 +9,7 @@
**
** This file is all you need to compile SQLite. To use SQLite in other
** programs, you need this file and the "sqlite3.h" header file that defines
-** the programming interface to the SQLite library. (If you do not have
+** the programming interface to the SQLite library. (If you do not have
** the "sqlite3.h" header file at hand, you will find a copy embedded within
** the text of this file. Search for "Begin file sqlite3.h" to find the start
** of the embedded sqlite3.h header file.) Additional code files may be needed
@@ -204,12 +204,29 @@
# define _LARGEFILE_SOURCE 1
#endif
-/* What version of GCC is being used. 0 means GCC is not being used */
-#ifdef __GNUC__
+/* The GCC_VERSION and MSVC_VERSION macros are used to
+** conditionally include optimizations for each of these compilers. A
+** value of 0 means that compiler is not being used. The
+** SQLITE_DISABLE_INTRINSIC macro means do not use any compiler-specific
+** optimizations, and hence set all compiler macros to 0
+**
+** There was once also a CLANG_VERSION macro. However, we learn that the
+** version numbers in clang are for "marketing" only and are inconsistent
+** and unreliable. Fortunately, all versions of clang also recognize the
+** gcc version numbers and have reasonable settings for gcc version numbers,
+** so the GCC_VERSION macro will be set to a correct non-zero value even
+** when compiling with clang.
+*/
+#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
#else
# define GCC_VERSION 0
#endif
+#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define MSVC_VERSION _MSC_VER
+#else
+# define MSVC_VERSION 0
+#endif
/* Needed for various definitions... */
#if defined(__GNUC__) && !defined(_GNU_SOURCE)
@@ -368,25 +385,26 @@ extern "C" {
** be held constant and Z will be incremented or else Y will be incremented
** and Z will be reset to zero.
**
-** Since version 3.6.18, SQLite source code has been stored in the
+** Since [version 3.6.18] ([dateof:3.6.18]),
+** SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">Fossil configuration management
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and an SHA1
-** hash of the entire source tree.
+** string contains the date and time of the check-in (UTC) and a SHA1
+** or SHA3-256 hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.14.1"
-#define SQLITE_VERSION_NUMBER 3014001
-#define SQLITE_SOURCE_ID "2016-08-11 18:53:32 a12d8059770df4bca59e321c266410344242bf7b"
+#define SQLITE_VERSION "3.18.0"
+#define SQLITE_VERSION_NUMBER 3018000
+#define SQLITE_SOURCE_ID "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37"
/*
** CAPI3REF: Run-Time Library Version Numbers
-** KEYWORDS: sqlite3_version, sqlite3_sourceid
+** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
@@ -415,9 +433,9 @@ extern "C" {
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
+SQLITE_API const char *sqlite3_libversion(void);
+SQLITE_API const char *sqlite3_sourceid(void);
+SQLITE_API int sqlite3_libversion_number(void);
/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -442,8 +460,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
** [sqlite_compileoption_get()] and the [compile_options pragma].
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *sqlite3_compileoption_get(int N);
#endif
/*
@@ -482,7 +500,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
**
** See the [threading mode] documentation for additional information.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
+SQLITE_API int sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
@@ -518,7 +536,11 @@ typedef struct sqlite3 sqlite3;
*/
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+# ifdef SQLITE_UINT64_TYPE
+ typedef SQLITE_UINT64_TYPE sqlite_uint64;
+# else
+ typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+# endif
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 sqlite_int64;
typedef unsigned __int64 sqlite_uint64;
@@ -579,8 +601,8 @@ typedef sqlite_uint64 sqlite3_uint64;
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
** argument is a harmless no-op.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
+SQLITE_API int sqlite3_close(sqlite3*);
+SQLITE_API int sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@@ -651,7 +673,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** </ul>
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
@@ -712,7 +734,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
** [result codes]. However, experience has shown that many of
** these result codes are too coarse-grained. They do not provide as
** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 and later) include
+** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
+** and later) include
** support for additional result codes that provide more detailed information
** about errors. These [extended result codes] are enabled or disabled
** on a per database connection basis using the
@@ -830,7 +853,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
** file that were written at the application level might have changed
** and that adjacent bytes, even bytes within the same sector are
** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
-** flag indicate that a file cannot be deleted when open. The
+** flag indicates that a file cannot be deleted when open. The
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
** read-only media and cannot be changed even by processes with
** elevated privileges.
@@ -980,6 +1003,9 @@ struct sqlite3_file {
** <li> [SQLITE_IOCAP_ATOMIC64K]
** <li> [SQLITE_IOCAP_SAFE_APPEND]
** <li> [SQLITE_IOCAP_SEQUENTIAL]
+** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
+** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
+** <li> [SQLITE_IOCAP_IMMUTABLE]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -1236,6 +1262,12 @@ struct sqlite3_io_methods {
** on whether or not the file has been renamed, moved, or deleted since it
** was first opened.
**
+** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
+** underlying native file handle associated with a file handle. This file
+** control interprets its argument as a pointer to a native file handle and
+** writes the resulting value there.
+**
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
** opcode causes the xFileControl method to swap the file handle with the one
@@ -1286,6 +1318,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_RBU 26
#define SQLITE_FCNTL_VFS_POINTER 27
#define SQLITE_FCNTL_JOURNAL_POINTER 28
+#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
+#define SQLITE_FCNTL_PDB 30
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1650,10 +1684,10 @@ struct sqlite3_vfs {
** must return [SQLITE_OK] on success and some other [error code] upon
** failure.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
+SQLITE_API int sqlite3_initialize(void);
+SQLITE_API int sqlite3_shutdown(void);
+SQLITE_API int sqlite3_os_init(void);
+SQLITE_API int sqlite3_os_end(void);
/*
** CAPI3REF: Configuring The SQLite Library
@@ -1686,7 +1720,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
*/
-SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
+SQLITE_API int sqlite3_config(int, ...);
/*
** CAPI3REF: Configure database connections
@@ -1705,7 +1739,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
** the call is considered successful.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Memory Allocation Routines
@@ -2229,13 +2263,36 @@ struct sqlite3_mem_methods {
** be a NULL pointer, in which case the new setting is not reported back.
** </dd>
**
+** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
+** <dd> ^This option is used to change the name of the "main" database
+** schema. ^The sole argument is a pointer to a constant UTF8 string
+** which will become the new schema name in place of "main". ^SQLite
+** does not make a copy of the new main schema name string, so the application
+** must ensure that the argument passed into this DBCONFIG option is unchanged
+** until after the database connection closes.
+** </dd>
+**
+** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+** <dd> Usually, when a database in wal mode is closed or detached from a
+** database handle, SQLite checks if this will mean that there are now no
+** connections at all to the database. If so, it performs a checkpoint
+** operation before closing the connection. This option may be used to
+** override this behaviour. The first parameter passed to this operation
+** is an integer - non-zero to disable checkpoints-on-close, or zero (the
+** default) to enable them. The second parameter is a pointer to an integer
+** into which is written 0 or 1 to indicate whether checkpoints-on-close
+** have been disabled - 0 if they are not disabled, 1 if they are.
+** </dd>
+**
** </dl>
*/
+#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
+#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
/*
@@ -2246,7 +2303,7 @@ struct sqlite3_mem_methods {
** [extended result codes] feature of SQLite. ^The extended result
** codes are disabled by default for historical compatibility.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
@@ -2260,20 +2317,30 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff)
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
-** most recent successful [INSERT] into a rowid table or [virtual table]
-** on database connection D.
-** ^Inserts into [WITHOUT ROWID] tables are not recorded.
-** ^If no successful [INSERT]s into rowid tables
-** have ever occurred on the database connection D,
-** then sqlite3_last_insert_rowid(D) returns zero.
-**
-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
-** method, then this routine will return the [rowid] of the inserted
-** row as long as the trigger or virtual table method is running.
-** But once the trigger or virtual table method ends, the value returned
-** by this routine reverts to what it was before the trigger or virtual
-** table method began.)^
+** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+** the most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
+** on the database connection D, then sqlite3_last_insert_rowid(D) returns
+** zero.
+**
+** As well as being set automatically as rows are inserted into database
+** tables, the value returned by this function may be set explicitly by
+** [sqlite3_set_last_insert_rowid()]
+**
+** Some virtual table implementations may INSERT rows into rowid tables as
+** part of committing a transaction (e.g. to flush data accumulated in memory
+** to disk). In this case subsequent calls to this function return the rowid
+** associated with these internal INSERT operations, which leads to
+** unintuitive results. Virtual table implementations that do write to rowid
+** tables in this way can avoid this problem by restoring the original
+** rowid value using [sqlite3_set_last_insert_rowid()] before returning
+** control to the user.
+**
+** ^(If an [INSERT] occurs within a trigger then this routine will
+** return the [rowid] of the inserted row as long as the trigger is
+** running. Once the trigger program ends, the value returned
+** by this routine reverts to what it was before the trigger was fired.)^
**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
@@ -2298,7 +2365,17 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff)
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+
+/*
+** CAPI3REF: Set the Last Insert Rowid value.
+** METHOD: sqlite3
+**
+** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+** set the value returned by calling sqlite3_last_insert_rowid(D) to R
+** without inserting a row into the database.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
/*
** CAPI3REF: Count The Number Of Rows Modified
@@ -2351,7 +2428,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
+SQLITE_API int sqlite3_changes(sqlite3*);
/*
** CAPI3REF: Total Number Of Rows Modified
@@ -2375,7 +2452,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
+SQLITE_API int sqlite3_total_changes(sqlite3*);
/*
** CAPI3REF: Interrupt A Long-Running Query
@@ -2415,7 +2492,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
** If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
+SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2450,8 +2527,8 @@ SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
+SQLITE_API int sqlite3_complete(const char *sql);
+SQLITE_API int sqlite3_complete16(const void *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
@@ -2512,7 +2589,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
** A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
+SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
/*
** CAPI3REF: Set A Busy Timeout
@@ -2535,7 +2612,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*,int(*)(void*,int),vo
**
** See also: [PRAGMA busy_timeout]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Convenience Routines For Running Queries
@@ -2610,7 +2687,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
@@ -2618,7 +2695,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
+SQLITE_API void sqlite3_free_table(char **result);
/*
** CAPI3REF: Formatted String Printing Functions
@@ -2724,10 +2801,10 @@ SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
*/
-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *sqlite3_mprintf(const char*,...);
+SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
/*
** CAPI3REF: Memory Allocation Subsystem
@@ -2817,12 +2894,12 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list
** a block of memory after it has been released using
** [sqlite3_free()] or [sqlite3_realloc()].
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
-SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
+SQLITE_API void *sqlite3_malloc(int);
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *sqlite3_realloc(void*, int);
+SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
/*
** CAPI3REF: Memory Allocator Statistics
@@ -2847,8 +2924,8 @@ SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
** by [sqlite3_memory_highwater(1)] is the high-water mark
** prior to the reset.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
/*
** CAPI3REF: Pseudo-Random Number Generator
@@ -2871,7 +2948,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
+SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
@@ -2954,7 +3031,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
** as stated in the previous paragraph, sqlite3_step() invokes
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
@@ -3062,9 +3139,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
** sqlite3_profile() function is considered experimental and is
** subject to change in future versions of SQLite.
*/
-SQLITE_API SQLITE_DEPRECATED void *SQLITE_STDCALL sqlite3_trace(sqlite3*,
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_DEPRECATED void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
@@ -3153,7 +3230,7 @@ SQLITE_API SQLITE_DEPRECATED void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
** are deprecated.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_trace_v2(
+SQLITE_API int sqlite3_trace_v2(
sqlite3*,
unsigned uMask,
int(*xCallback)(unsigned,void*,void*,void*),
@@ -3192,7 +3269,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_trace_v2(
** database connections for the meaning of "modify" in this paragraph.
**
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
** CAPI3REF: Opening A New Database Connection
@@ -3421,15 +3498,15 @@ SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(vo
**
** See also: [sqlite3_temp_directory]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -3475,9 +3552,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
** VFS method, then the behavior of this routine is undefined and probably
** undesirable.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+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);
/*
@@ -3521,11 +3598,11 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const cha
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
+SQLITE_API int sqlite3_errcode(sqlite3 *db);
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errstr(int);
/*
** CAPI3REF: Prepared Statement Object
@@ -3593,7 +3670,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
**
** New run-time limit categories may be added in future releases.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
@@ -3624,9 +3701,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. This limit is not currently
-** enforced, though that might be added in some future release of
-** SQLite.</dd>)^
+** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
+** the equivalent tries to allocate space for more than this many opcodes
+** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
@@ -3664,6 +3741,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
+
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
@@ -3745,28 +3823,28 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
** </li>
** </ol>
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
+SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
+SQLITE_API int sqlite3_prepare16(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
@@ -3805,8 +3883,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
** is obtained from [sqlite3_malloc()] and must be free by the application
** by passing it to [sqlite3_free()].
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
-SQLITE_API char *SQLITE_STDCALL sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
@@ -3837,8 +3915,12 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_expanded_sql(sqlite3_stmt *pStmt);
** sqlite3_stmt_readonly() to return true since, while those statements
** change the configuration of a database connection, they do not make
** changes to the content of the database files on disk.
+** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
+** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
+** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
+** sqlite3_stmt_readonly() returns false for those commands.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
@@ -3859,7 +3941,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
@@ -4023,20 +4105,20 @@ typedef struct sqlite3_context sqlite3_context;
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
/*
** CAPI3REF: Number Of SQL Parameters
@@ -4057,7 +4139,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
@@ -4085,7 +4167,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
** CAPI3REF: Index Of A Parameter With A Given Name
@@ -4102,7 +4184,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*,
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_name()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
@@ -4112,19 +4194,23 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
** ^Use this routine to reset all host parameters to NULL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
/*
** CAPI3REF: Number Of Columns In A Result Set
** METHOD: sqlite3_stmt
**
** ^Return the number of columns in the result set returned by the
-** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
-** statement that does not return data (for example an [UPDATE]).
+** [prepared statement]. ^If this routine returns 0, that means the
+** [prepared statement] returns no data (for example an [UPDATE]).
+** ^However, just because this routine returns a positive number does not
+** mean that one or more rows of data will be returned. ^A SELECT statement
+** will always have a positive sqlite3_column_count() but depending on the
+** WHERE clause constraints and the table content, it might return no rows.
**
** See also: [sqlite3_data_count()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Column Names In A Result Set
@@ -4153,8 +4239,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/*
** CAPI3REF: Source Of Data In A Query Result
@@ -4202,12 +4288,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
** CAPI3REF: Declared Datatype Of A Query Result
@@ -4239,8 +4325,8 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*
** is associated with individual values, not with the containers
** used to hold those values.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** CAPI3REF: Evaluate An SQL Statement
@@ -4301,7 +4387,8 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,in
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began
+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
+** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
** break because any application that ever receives an SQLITE_MISUSE error
@@ -4320,7 +4407,7 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,in
** then the more specific [error codes] are returned directly
** by sqlite3_step(). The use of the "v2" interface is recommended.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
+SQLITE_API int sqlite3_step(sqlite3_stmt*);
/*
** CAPI3REF: Number of columns in a result set
@@ -4341,7 +4428,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
**
** See also: [sqlite3_column_count()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Fundamental Datatypes
@@ -4531,16 +4618,16 @@ SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
** pointer. Subsequent calls to [sqlite3_errcode()] will return
** [SQLITE_NOMEM].)^
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
/*
** CAPI3REF: Destroy A Prepared Statement Object
@@ -4568,7 +4655,7 @@ SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int
** statement after it has been finalized can result in undefined and
** undesirable behavior such as segfaults and heap corruption.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Reset A Prepared Statement Object
@@ -4595,7 +4682,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
@@ -4695,7 +4782,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
+SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4705,7 +4792,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -4715,7 +4802,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
+SQLITE_API int sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4761,12 +4848,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
** these functions, we will not explain what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
void*,sqlite3_int64);
#endif
@@ -4816,18 +4903,18 @@ SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(voi
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API double sqlite3_value_double(sqlite3_value*);
+SQLITE_API int sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int sqlite3_value_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -4843,7 +4930,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
** from the result of one [application-defined SQL function] into the
** input of another.
*/
-SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
+SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
/*
** CAPI3REF: Copy And Free SQL Values
@@ -4859,8 +4946,8 @@ SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
-SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
+SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
+SQLITE_API void sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
@@ -4905,7 +4992,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** CAPI3REF: User Data For Functions
@@ -4920,7 +5007,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int
** This routine must be called from the same thread in which
** the application-defined function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *sqlite3_user_data(sqlite3_context*);
/*
** CAPI3REF: Database Connection For Functions
@@ -4932,7 +5019,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
@@ -4986,8 +5073,8 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
** These routines must be called from the same thread in which
** the SQL function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
@@ -5123,27 +5210,27 @@ typedef void (*sqlite3_destructor_type)(void*);
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
+SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void sqlite3_result_null(sqlite3_context*);
+SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
-SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
+SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
/*
@@ -5158,7 +5245,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context*, sqlite
** The number of subtype bytes preserved by SQLite might increase
** in future releases of SQLite.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context*,unsigned int);
+SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
/*
** CAPI3REF: Define New Collating Sequences
@@ -5240,14 +5327,14 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context*,unsigned
**
** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3*,
const char *zName,
int eTextRep,
void *pArg,
int(*xCompare)(void*,int,const void*,int,const void*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3*,
const char *zName,
int eTextRep,
@@ -5255,7 +5342,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDestroy)(void*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3*,
const void *zName,
int eTextRep,
@@ -5290,12 +5377,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const char*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -5309,11 +5396,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_key(
+SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
+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 */
@@ -5327,11 +5414,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
+SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
+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 */
@@ -5341,7 +5428,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
** Specify the activation key for a SEE database. Unless
** activated, none of the SEE routines will work.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
+SQLITE_API void sqlite3_activate_see(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5351,7 +5438,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
+SQLITE_API void sqlite3_activate_cerod(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5373,7 +5460,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
+SQLITE_API int sqlite3_sleep(int);
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -5492,7 +5579,7 @@ SQLITE_API char *sqlite3_data_directory;
** connection while this routine is running, then the return value
** is undefined.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
@@ -5505,7 +5592,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
@@ -5522,7 +5609,7 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
@@ -5532,7 +5619,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const cha
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Find the next prepared statement
@@ -5548,7 +5635,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbNa
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
@@ -5597,8 +5684,8 @@ SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_
**
** See also the [sqlite3_update_hook()] interface.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Data Change Notification Callbacks
@@ -5628,7 +5715,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
-** is not invoked when duplication rows are deleted because of an
+** is not invoked when conflicting rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
** The exceptions defined in this paragraph might change in a future
@@ -5649,7 +5736,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
** and [sqlite3_preupdate_hook()] interfaces.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
@@ -5664,7 +5751,8 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
** and disabled if the argument is false.)^
**
** ^Cache sharing is enabled and disabled for an entire process.
-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
+** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
+** In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** ^(The cache sharing mode set by this interface effects all subsequent
@@ -5689,7 +5777,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
**
** See Also: [SQLite Shared-Cache Mode]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
+SQLITE_API int sqlite3_enable_shared_cache(int);
/*
** CAPI3REF: Attempt To Free Heap Memory
@@ -5705,7 +5793,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
**
** See also: [sqlite3_db_release_memory()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
+SQLITE_API int sqlite3_release_memory(int);
/*
** CAPI3REF: Free Memory Used By A Database Connection
@@ -5719,7 +5807,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
**
** See also: [sqlite3_release_memory()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
@@ -5758,7 +5846,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
** from the heap.
** </ul>)^
**
-** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
+** 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
@@ -5771,7 +5860,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
** The circumstances under which SQLite will enforce the soft heap limit may
** changes in future releases of SQLite.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -5782,7 +5871,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64
** only. All new applications should use the
** [sqlite3_soft_heap_limit64()] interface rather than this one.
*/
-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
/*
@@ -5852,7 +5941,7 @@ SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
** parsed, if that has not already been done, and returns an error if
** any errors are encountered while loading the schema.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -5908,7 +5997,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
**
** See also the [load_extension() SQL function].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Derived from zFile if 0 */
@@ -5940,7 +6029,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
** remains disabled. This will prevent SQL injections from giving attackers
** access to extension loading capabilities.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
/*
** CAPI3REF: Automatically Load Statically Linked Extensions
@@ -5978,7 +6067,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int ono
** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Cancel Automatic Extension Loading
@@ -5990,7 +6079,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void(*xEntryPoint)(void));
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
@@ -5998,7 +6087,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void(*xEntryPoint)(v
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
+SQLITE_API void sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
@@ -6152,13 +6241,15 @@ struct sqlite3_module {
** the xUpdate method are automatically rolled back by SQLite.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
-** structure for SQLite version 3.8.2. If a virtual table extension is
+** structure for SQLite [version 3.8.2] ([dateof:3.8.2]).
+** 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
** 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. It may therefore only be used if
+** was added for [version 3.9.0] ([dateof:3.9.0]).
+** It may therefore only be used if
** sqlite3_libversion_number() returns a value greater than or equal to
** 3009000.
*/
@@ -6243,13 +6334,13 @@ struct sqlite3_index_info {
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
void *pClientData /* Client data for xCreate/xConnect */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
@@ -6312,7 +6403,7 @@ struct sqlite3_vtab_cursor {
** to declare the format (the names and datatypes of the columns) of
** the virtual tables they implement.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/*
** CAPI3REF: Overload A Function For A Virtual Table
@@ -6331,7 +6422,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
** purpose is to be a placeholder function that can be overloaded
** by a [virtual table].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
@@ -6406,6 +6497,12 @@ typedef struct sqlite3_blob sqlite3_blob;
** [database connection] error code and message accessible via
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
**
+** A BLOB referenced by sqlite3_blob_open() may be read using the
+** [sqlite3_blob_read()] interface and modified by using
+** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a
+** different row of the same table using the [sqlite3_blob_reopen()]
+** interface. However, the column, table, or database of a [BLOB handle]
+** cannot be changed after the [BLOB handle] is opened.
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -6429,8 +6526,12 @@ typedef struct sqlite3_blob sqlite3_blob;
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
+**
+** See also: [sqlite3_blob_close()],
+** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
+** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3*,
const char *zDb,
const char *zTable,
@@ -6444,11 +6545,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
** CAPI3REF: Move a BLOB Handle to a New Row
** METHOD: sqlite3_blob
**
-** ^This function is used to move an existing blob handle so that it points
+** ^This function is used to move an existing [BLOB handle] so that it points
** to a different row of the same database table. ^The new row is identified
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
-** remain the same. Moving an existing blob handle to a new row can be
+** remain the same. Moving an existing [BLOB handle] to a new row is
** faster than closing the existing handle and opening a new one.
**
** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
@@ -6463,7 +6564,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
**
** ^This function sets the database handle error code and message.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
@@ -6486,7 +6587,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64)
** is passed a valid open blob handle, the values returned by the
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
@@ -6502,7 +6603,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
/*
** CAPI3REF: Read Data From A BLOB Incrementally
@@ -6531,7 +6632,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
**
** See also: [sqlite3_blob_write()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
** CAPI3REF: Write Data Into A BLOB Incrementally
@@ -6573,7 +6674,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N,
**
** See also: [sqlite3_blob_read()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
** CAPI3REF: Virtual File System Objects
@@ -6604,9 +6705,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z,
** ^(If the default VFS is unregistered, another VFS is chosen as
** the default. The choice for the new VFS is arbitrary.)^
*/
-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
/*
** CAPI3REF: Mutexes
@@ -6722,11 +6823,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
/*
** CAPI3REF: Mutex Methods Object
@@ -6836,8 +6937,8 @@ struct sqlite3_mutex_methods {
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif
/*
@@ -6856,7 +6957,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
+#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
@@ -6877,7 +6978,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
** ^If the [threading mode] is Single-thread or Multi-thread then this
** routine returns a NULL pointer.
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
@@ -6912,7 +7013,7 @@ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
**
** See also: [SQLITE_FCNTL_LOCKSTATE]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
** CAPI3REF: Testing Interface
@@ -6931,7 +7032,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName
** Unlike most of the SQLite API, this function is not guaranteed to
** operate consistently from one release to the next.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
+SQLITE_API int sqlite3_test_control(int op, ...);
/*
** CAPI3REF: Testing Interface Operation Codes
@@ -6960,6 +7061,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
+#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_BYTEORDER 22
@@ -6994,8 +7096,8 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
**
** See also: [sqlite3_db_status()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int sqlite3_status64(
int op,
sqlite3_int64 *pCurrent,
sqlite3_int64 *pHighwater,
@@ -7120,7 +7222,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status64(
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
@@ -7263,7 +7365,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
@@ -7732,16 +7834,16 @@ typedef struct sqlite3_backup sqlite3_backup;
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
sqlite3 *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
@@ -7858,7 +7960,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
@@ -7873,8 +7975,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
** strings in a case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
+SQLITE_API int sqlite3_stricmp(const char *, const char *);
+SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
@@ -7891,7 +7993,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
**
** See also: [sqlite3_strlike()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
+SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
/*
** CAPI3REF: String LIKE Matching
@@ -7914,7 +8016,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zSt
**
** See also: [sqlite3_strglob()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
+SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
/*
** CAPI3REF: Error Logging Interface
@@ -7937,7 +8039,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zGlob, const char *zSt
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
@@ -7973,7 +8075,7 @@ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...)
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
** overwrite any prior [sqlite3_wal_hook()] settings.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3*,
int(*)(void *,sqlite3*,const char*,int),
void*
@@ -8008,7 +8110,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
** is only necessary if the default setting is found to be suboptimal
** for a particular application.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/*
** CAPI3REF: Checkpoint a database
@@ -8030,7 +8132,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
** start a callback but which do not need the full power (and corresponding
** complication) of [sqlite3_wal_checkpoint_v2()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Checkpoint a database
@@ -8124,7 +8226,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zD
** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
** from SQL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -8160,7 +8262,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
** may be added in the future.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
@@ -8213,7 +8315,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Conflict resolution modes
@@ -8318,7 +8420,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -8334,7 +8436,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/*
** CAPI3REF: Flush caches to disk mid-transaction
@@ -8366,7 +8468,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
** ^This function does not set the database handle error code or message
** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
+SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
/*
** CAPI3REF: The pre-update hook.
@@ -8376,7 +8478,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
**
** ^The [sqlite3_preupdate_hook()] interface registers a callback function
** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
-** on a [rowid table].
+** on a database table.
** ^At most one preupdate hook may be registered at a time on a single
** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
** the previous setting.
@@ -8385,9 +8487,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
** the first parameter to callbacks.
**
-** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate
-** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID]
-** tables.
+** ^The preupdate hook only fires for changes to real database tables; the
+** preupdate hook is not invoked for changes to [virtual tables] or to
+** system tables like sqlite_master or sqlite_stat1.
**
** ^The second parameter to the preupdate callback is a pointer to
** the [database connection] that registered the preupdate hook.
@@ -8401,12 +8503,16 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
** databases.)^
** ^The fifth parameter to the preupdate callback is the name of the
** table that is being modified.
-** ^The sixth parameter to the preupdate callback is the initial [rowid] of the
-** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is
-** undefined for SQLITE_INSERT changes.
-** ^The seventh parameter to the preupdate callback is the final [rowid] of
-** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is
-** undefined for SQLITE_DELETE changes.
+**
+** For an UPDATE or DELETE operation on a [rowid table], the sixth
+** parameter passed to the preupdate callback is the initial [rowid] of the
+** row being modified or deleted. For an INSERT operation on a rowid table,
+** or any operation on a WITHOUT ROWID table, the value of the sixth
+** parameter is undefined. For an INSERT or UPDATE on a rowid table the
+** seventh parameter is the final rowid value of the row being inserted
+** or updated. The value of the seventh parameter passed to the callback
+** function is not defined for operations on WITHOUT ROWID tables, or for
+** INSERT operations on rowid tables.
**
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
@@ -8446,7 +8552,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
**
** See also: [sqlite3_update_hook()]
*/
-SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_preupdate_hook(
+#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+SQLITE_API void *sqlite3_preupdate_hook(
sqlite3 *db,
void(*xPreUpdate)(
void *pCtx, /* Copy of third arg to preupdate_hook() */
@@ -8459,10 +8566,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_preupdate_hook(
),
void*
);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_count(sqlite3 *);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_depth(sqlite3 *);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
+SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+#endif
/*
** CAPI3REF: Low-level system error code
@@ -8474,11 +8582,11 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3
** called to get back the underlying "errno" that caused the problem, such
** as ENOSPC, EAUTH, EISDIR, and so forth.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*);
+SQLITE_API int sqlite3_system_errno(sqlite3*);
/*
** CAPI3REF: Database Snapshot
-** KEYWORDS: {snapshot}
+** KEYWORDS: {snapshot} {sqlite3_snapshot}
** EXPERIMENTAL
**
** An instance of the snapshot object records the state of a [WAL mode]
@@ -8502,7 +8610,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*);
** to an historical snapshot (if possible). The destructor for
** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
*/
-typedef struct sqlite3_snapshot sqlite3_snapshot;
+typedef struct sqlite3_snapshot {
+ unsigned char hidden[48];
+} sqlite3_snapshot;
/*
** CAPI3REF: Record A Database Snapshot
@@ -8513,9 +8623,32 @@ typedef struct sqlite3_snapshot sqlite3_snapshot;
** schema S in database connection D. ^On success, the
** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
-** ^If schema S of [database connection] D is not a [WAL mode] database
-** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)]
-** leaves the *P value unchanged and returns an appropriate [error code].
+** If there is not already a read-transaction open on schema S when
+** this function is called, one is opened automatically.
+**
+** The following must be true for this function to succeed. If any of
+** the following statements are false when sqlite3_snapshot_get() is
+** called, SQLITE_ERROR is returned. The final value of *P is undefined
+** in this case.
+**
+** <ul>
+** <li> The database handle must be in [autocommit mode].
+**
+** <li> Schema S of [database connection] D must be a [WAL mode] database.
+**
+** <li> There must not be a write transaction open on schema S of database
+** connection D.
+**
+** <li> One or more transactions must have been written to the current wal
+** file since it was created on disk (by any connection). This means
+** that a snapshot cannot be taken on a wal mode database with no wal
+** file immediately after it is first opened. At least one transaction
+** must be written to it first.
+** </ul>
+**
+** This function may also return SQLITE_NOMEM. If it is called with the
+** database handle in autocommit mode but fails for some other reason,
+** whether or not a read transaction is opened on schema S is undefined.
**
** The [sqlite3_snapshot] object returned from a successful call to
** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
@@ -8524,7 +8657,7 @@ typedef struct sqlite3_snapshot sqlite3_snapshot;
** The [sqlite3_snapshot_get()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot **ppSnapshot
@@ -8562,7 +8695,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
** The [sqlite3_snapshot_open()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot *pSnapshot
@@ -8579,7 +8712,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
** The [sqlite3_snapshot_free()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
-SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot*);
+SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** CAPI3REF: Compare the ages of two snapshot handles.
@@ -8603,12 +8736,34 @@ SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3
** snapshot than P2, zero if the two handles refer to the same database
** snapshot, and a positive value if P1 is a newer snapshot than P2.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_cmp(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
sqlite3_snapshot *p1,
sqlite3_snapshot *p2
);
/*
+** CAPI3REF: Recover snapshots from a wal file
+** EXPERIMENTAL
+**
+** If all connections disconnect from a database file but do not perform
+** a checkpoint, the existing wal file is opened along with the database
+** file the next time the database is opened. At this point it is only
+** possible to successfully call sqlite3_snapshot_open() to open the most
+** recent snapshot of the database (the one at the head of the wal file),
+** even though the wal file may contain other valid snapshots for which
+** clients have sqlite3_snapshot handles.
+**
+** This function attempts to scan the wal file associated with database zDb
+** of database handle db and make all valid snapshots available to
+** sqlite3_snapshot_open(). It is an error if there is already a read
+** transaction open on the database, or if the database is not a wal mode
+** database.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+
+/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
@@ -8661,7 +8816,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
@@ -8687,7 +8842,7 @@ struct sqlite3_rtree_geometry {
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db,
const char *zQueryFunc,
int (*xQueryFunc)(sqlite3_rtree_query_info*),
@@ -8793,7 +8948,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
** attached database. It is not an error if database zDb is not attached
** to the database when the session object is created.
*/
-int sqlite3session_create(
+SQLITE_API int sqlite3session_create(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of db (e.g. "main") */
sqlite3_session **ppSession /* OUT: New session object */
@@ -8811,7 +8966,7 @@ int sqlite3session_create(
** are attached is closed. Refer to the documentation for
** [sqlite3session_create()] for details.
*/
-void sqlite3session_delete(sqlite3_session *pSession);
+SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
/*
@@ -8831,7 +8986,7 @@ void sqlite3session_delete(sqlite3_session *pSession);
** The return value indicates the final state of the session object: 0 if
** the session is disabled, or 1 if it is enabled.
*/
-int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
+SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
/*
** CAPI3REF: Set Or Clear the Indirect Change Flag
@@ -8860,7 +9015,7 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
** The return value indicates the final state of the indirect flag: 0 if
** it is clear, or 1 if it is set.
*/
-int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
+SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
/*
** CAPI3REF: Attach A Table To A Session Object
@@ -8890,7 +9045,7 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
** SQLITE_OK is returned if the call completes without error. Or, if an error
** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
*/
-int sqlite3session_attach(
+SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
const char *zTab /* Table name */
);
@@ -8899,12 +9054,12 @@ int sqlite3session_attach(
** CAPI3REF: Set a table filter on a Session Object.
**
** The second argument (xFilter) is the "filter callback". For changes to rows
-** in tables that are not attached to the Session oject, the filter is called
+** 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
** attached, xFilter will not be called again.
*/
-void sqlite3session_table_filter(
+SQLITE_API void sqlite3session_table_filter(
sqlite3_session *pSession, /* Session object */
int(*xFilter)(
void *pCtx, /* Copy of third arg to _filter_table() */
@@ -9017,7 +9172,7 @@ void sqlite3session_table_filter(
** another field of the same row is updated while the session is enabled, the
** resulting changeset will contain an UPDATE change that updates both fields.
*/
-int sqlite3session_changeset(
+SQLITE_API int sqlite3session_changeset(
sqlite3_session *pSession, /* Session object */
int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
void **ppChangeset /* OUT: Buffer containing changeset */
@@ -9061,7 +9216,8 @@ int sqlite3session_changeset(
** the from-table, a DELETE record is added to the session object.
**
** <li> For each row (primary key) that exists in both tables, but features
-** different in each, an UPDATE record is added to the session.
+** different non-PK values in each, an UPDATE record is added to the
+** session.
** </ul>
**
** To clarify, if this function is called and then a changeset constructed
@@ -9078,7 +9234,7 @@ int sqlite3session_changeset(
** message. It is the responsibility of the caller to free this buffer using
** sqlite3_free().
*/
-int sqlite3session_diff(
+SQLITE_API int sqlite3session_diff(
sqlite3_session *pSession,
const char *zFromDb,
const char *zTbl,
@@ -9114,7 +9270,7 @@ int sqlite3session_diff(
** a single table are grouped together, tables appear in the order in which
** they were attached to the session object).
*/
-int sqlite3session_patchset(
+SQLITE_API int sqlite3session_patchset(
sqlite3_session *pSession, /* Session object */
int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
void **ppPatchset /* OUT: Buffer containing changeset */
@@ -9135,7 +9291,7 @@ int sqlite3session_patchset(
** guaranteed that a call to sqlite3session_changeset() will return a
** changeset containing zero changes.
*/
-int sqlite3session_isempty(sqlite3_session *pSession);
+SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
@@ -9165,12 +9321,12 @@ int sqlite3session_isempty(sqlite3_session *pSession);
** [sqlite3changeset_invert()] functions, all changes within the changeset
** that apply to a single table are grouped together. This means that when
** an application iterates through a changeset using an iterator created by
-** this function, all changes that relate to a single table are visted
+** this function, all changes that relate to a single table are visited
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
** another change for table X.
*/
-int sqlite3changeset_start(
+SQLITE_API int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset /* Pointer to blob containing changeset */
@@ -9199,7 +9355,7 @@ int sqlite3changeset_start(
** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or
** SQLITE_NOMEM.
*/
-int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
+SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
@@ -9227,7 +9383,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
** SQLite error code is returned. The values of the output variables may not
** be trusted in this case.
*/
-int sqlite3changeset_op(
+SQLITE_API int sqlite3changeset_op(
sqlite3_changeset_iter *pIter, /* Iterator object */
const char **pzTab, /* OUT: Pointer to table name */
int *pnCol, /* OUT: Number of columns in table */
@@ -9252,7 +9408,7 @@ int sqlite3changeset_op(
** 0x01 if the corresponding column is part of the tables primary key, or
** 0x00 if it is not.
**
-** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
+** If argument pnCol is not NULL, then *pnCol is set to the number of columns
** in the table.
**
** If this function is called when the iterator does not point to a valid
@@ -9260,7 +9416,7 @@ int sqlite3changeset_op(
** SQLITE_OK is returned and the output variables populated as described
** above.
*/
-int sqlite3changeset_pk(
+SQLITE_API int sqlite3changeset_pk(
sqlite3_changeset_iter *pIter, /* Iterator object */
unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
int *pnCol /* OUT: Number of entries in output array */
@@ -9290,7 +9446,7 @@ int sqlite3changeset_pk(
** If some other error occurs (e.g. an OOM condition), an SQLite error code
** is returned and *ppValue is set to NULL.
*/
-int sqlite3changeset_old(
+SQLITE_API int sqlite3changeset_old(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
@@ -9323,7 +9479,7 @@ int sqlite3changeset_old(
** If some other error occurs (e.g. an OOM condition), an SQLite error code
** is returned and *ppValue is set to NULL.
*/
-int sqlite3changeset_new(
+SQLITE_API int sqlite3changeset_new(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
@@ -9350,7 +9506,7 @@ int sqlite3changeset_new(
** If some other error occurs (e.g. an OOM condition), an SQLite error code
** is returned and *ppValue is set to NULL.
*/
-int sqlite3changeset_conflict(
+SQLITE_API int sqlite3changeset_conflict(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: Value from conflicting row */
@@ -9366,7 +9522,7 @@ int sqlite3changeset_conflict(
**
** In all other cases this function returns SQLITE_MISUSE.
*/
-int sqlite3changeset_fk_conflicts(
+SQLITE_API int sqlite3changeset_fk_conflicts(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int *pnOut /* OUT: Number of FK violations */
);
@@ -9399,7 +9555,7 @@ int sqlite3changeset_fk_conflicts(
** // An error has occurred
** }
*/
-int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Invert A Changeset
@@ -9429,7 +9585,7 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
** WARNING/TODO: This function currently assumes that the input is a valid
** changeset. If it is not, the results are undefined.
*/
-int sqlite3changeset_invert(
+SQLITE_API int sqlite3changeset_invert(
int nIn, const void *pIn, /* Input changeset */
int *pnOut, void **ppOut /* OUT: Inverse of input */
);
@@ -9458,7 +9614,7 @@ int sqlite3changeset_invert(
**
** Refer to the sqlite3_changegroup documentation below for details.
*/
-int sqlite3changeset_concat(
+SQLITE_API int sqlite3changeset_concat(
int nA, /* Number of bytes in buffer pA */
void *pA, /* Pointer to buffer containing changeset A */
int nB, /* Number of bytes in buffer pB */
@@ -9469,12 +9625,12 @@ int sqlite3changeset_concat(
/*
-** Changegroup handle.
+** CAPI3REF: Changegroup Handle
*/
typedef struct sqlite3_changegroup sqlite3_changegroup;
/*
-** CAPI3REF: Combine two or more changesets into a single changeset.
+** CAPI3REF: Create A New Changegroup Object
**
** An sqlite3_changegroup object is used to combine two or more changesets
** (or patchsets) into a single changeset (or patchset). A single changegroup
@@ -9511,6 +9667,8 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
+** CAPI3REF: Add A Changeset To A Changegroup
+**
** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
**
@@ -9525,7 +9683,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
** apply to the same row as a change already present in the changegroup if
** the two rows have the same primary key.
**
-** Changes to rows that that do not already appear in the changegroup are
+** Changes to rows that do not already appear in the changegroup are
** simply copied into it. Or, if both the new changeset and the changegroup
** contain changes that apply to a single row, the final contents of the
** changegroup depends on the type of each change, as follows:
@@ -9586,6 +9744,8 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
+** CAPI3REF: Obtain A Composite Changeset From A Changegroup
+**
** Obtain a buffer containing a changeset (or patchset) representing the
** current contents of the changegroup. If the inputs to the changegroup
** were themselves changesets, the output is a changeset. Or, if the
@@ -9614,7 +9774,7 @@ int sqlite3changegroup_output(
);
/*
-** Delete a changegroup object.
+** CAPI3REF: Delete A Changegroup Object
*/
void sqlite3changegroup_delete(sqlite3_changegroup*);
@@ -9642,7 +9802,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** <ul>
** <li> The table has the same name as the name recorded in the
** changeset, and
-** <li> The table has the same number of columns as recorded in the
+** <li> The table has at least as many columns as recorded in the
** changeset, and
** <li> The table has primary key columns in the same position as
** recorded in the changeset.
@@ -9687,7 +9847,11 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** If a row with matching primary key values is found, but one or more of
** the non-primary key fields contains a value different from the original
** row value stored in the changeset, the conflict-handler function is
-** invoked with [SQLITE_CHANGESET_DATA] as the second argument.
+** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
+** database table has more columns than are recorded in the changeset,
+** only the values of those non-primary key fields are compared against
+** the current database contents - any trailing database table columns
+** are ignored.
**
** If no row with matching primary key values is found in the database,
** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
@@ -9702,7 +9866,9 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** <dt>INSERT Changes<dd>
** For each INSERT change, an attempt is made to insert the new row into
-** the database.
+** the database. If the changeset row contains fewer fields than the
+** database table, the trailing fields are populated with their default
+** values.
**
** If the attempt to insert the row fails because the database already
** contains a row with the same primary key values, the conflict handler
@@ -9720,13 +9886,13 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** For each UPDATE change, this function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
-** stored in all non-primary key columns also match the values stored in
-** the changeset the row is updated within the target database.
+** stored in all modified non-primary key columns also match the values
+** stored in the changeset the row is updated within the target database.
**
** If a row with matching primary key values is found, but one or more of
-** the non-primary key fields contains a value different from an original
-** row value stored in the changeset, the conflict-handler function is
-** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
+** the modified non-primary key fields contains a value different from an
+** original row value stored in the changeset, the conflict-handler function
+** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
** UPDATE changes only contain values for non-primary key fields that are
** to be modified, only those fields need to match the original values to
** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
@@ -9754,7 +9920,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** rolled back, restoring the target database to its original state, and an
** SQLite error code returned.
*/
-int sqlite3changeset_apply(
+SQLITE_API int sqlite3changeset_apply(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
@@ -9955,7 +10121,7 @@ int sqlite3changeset_apply(
** parameter set to a value less than or equal to zero. Other than this,
** no guarantees are made as to the size of the chunks of data returned.
*/
-int sqlite3changeset_apply_strm(
+SQLITE_API int sqlite3changeset_apply_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
@@ -9970,7 +10136,7 @@ int sqlite3changeset_apply_strm(
),
void *pCtx /* First argument passed to xConflict */
);
-int sqlite3changeset_concat_strm(
+SQLITE_API int sqlite3changeset_concat_strm(
int (*xInputA)(void *pIn, void *pData, int *pnData),
void *pInA,
int (*xInputB)(void *pIn, void *pData, int *pnData),
@@ -9978,23 +10144,23 @@ int sqlite3changeset_concat_strm(
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3changeset_invert_strm(
+SQLITE_API int sqlite3changeset_invert_strm(
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3changeset_start_strm(
+SQLITE_API int sqlite3changeset_start_strm(
sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
-int sqlite3session_changeset_strm(
+SQLITE_API int sqlite3session_changeset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3session_patchset_strm(
+SQLITE_API int sqlite3session_patchset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
@@ -10703,7 +10869,7 @@ struct fts5_api {
** Not currently enforced.
*/
#ifndef SQLITE_MAX_VDBE_OP
-# define SQLITE_MAX_VDBE_OP 25000
+# define SQLITE_MAX_VDBE_OP 250000000
#endif
/*
@@ -10901,6 +11067,7 @@ struct fts5_api {
# include <intrin.h>
# pragma intrinsic(_byteswap_ushort)
# pragma intrinsic(_byteswap_ulong)
+# pragma intrinsic(_byteswap_uint64)
# pragma intrinsic(_ReadWriteBarrier)
# else
# include <cmnintrin.h>
@@ -11391,9 +11558,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_LIMIT 129
#define TK_WHERE 130
#define TK_INTO 131
-#define TK_INTEGER 132
-#define TK_FLOAT 133
-#define TK_BLOB 134
+#define TK_FLOAT 132
+#define TK_BLOB 133
+#define TK_INTEGER 134
#define TK_VARIABLE 135
#define TK_CASE 136
#define TK_WHEN 137
@@ -11417,10 +11584,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_UMINUS 155
#define TK_UPLUS 156
#define TK_REGISTER 157
-#define TK_ASTERISK 158
-#define TK_SPAN 159
-#define TK_SPACE 160
-#define TK_ILLEGAL 161
+#define TK_VECTOR 158
+#define TK_SELECT_COLUMN 159
+#define TK_ASTERISK 160
+#define TK_SPAN 161
+#define TK_SPACE 162
+#define TK_ILLEGAL 163
/* The token codes above must all fit in 8 bits */
#define TKFLG_MASK 0xff
@@ -11438,6 +11607,18 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#include <stddef.h>
/*
+** Use a macro to replace memcpy() if compiled with SQLITE_INLINE_MEMCPY.
+** This allows better measurements of where memcpy() is used when running
+** cachegrind. But this macro version of memcpy() is very slow so it
+** should not be used in production. This is a performance measurement
+** hack only.
+*/
+#ifdef SQLITE_INLINE_MEMCPY
+# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\
+ int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);}
+#endif
+
+/*
** If compiling for a processor that lacks floating point support,
** substitute integer for floating-point
*/
@@ -11521,9 +11702,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
** pagecaches for each database connection. A positive number is the
** number of pages. A negative number N translations means that a buffer
** of -1024*N bytes is allocated and used for as many pages as it will hold.
+**
+** The default value of "20" was choosen to minimize the run-time of the
+** speedtest1 test program with options: --shrink-memory --reprepare
*/
#ifndef SQLITE_DEFAULT_PCACHE_INITSZ
-# define SQLITE_DEFAULT_PCACHE_INITSZ 100
+# define SQLITE_DEFAULT_PCACHE_INITSZ 20
#endif
/*
@@ -11698,32 +11882,35 @@ typedef INT16_TYPE LogEst;
**
** For best performance, an attempt is made to guess at the byte-order
** using C-preprocessor macros. If that is unsuccessful, or if
-** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
+** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined
** at run-time.
*/
-#if (defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+#ifndef SQLITE_BYTEORDER
+# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
- defined(__arm__)) && !defined(SQLITE_RUNTIME_BYTEORDER)
-# define SQLITE_BYTEORDER 1234
-# define SQLITE_BIGENDIAN 0
-# define SQLITE_LITTLEENDIAN 1
-# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
+ defined(__arm__)
+# define SQLITE_BYTEORDER 1234
+# elif defined(sparc) || defined(__ppc__)
+# define SQLITE_BYTEORDER 4321
+# else
+# define SQLITE_BYTEORDER 0
+# endif
#endif
-#if (defined(sparc) || defined(__ppc__)) \
- && !defined(SQLITE_RUNTIME_BYTEORDER)
-# define SQLITE_BYTEORDER 4321
+#if SQLITE_BYTEORDER==4321
# define SQLITE_BIGENDIAN 1
# define SQLITE_LITTLEENDIAN 0
# define SQLITE_UTF16NATIVE SQLITE_UTF16BE
-#endif
-#if !defined(SQLITE_BYTEORDER)
+#elif SQLITE_BYTEORDER==1234
+# define SQLITE_BIGENDIAN 0
+# define SQLITE_LITTLEENDIAN 1
+# define SQLITE_UTF16NATIVE SQLITE_UTF16LE
+#else
# ifdef SQLITE_AMALGAMATION
const int sqlite3one = 1;
# else
extern const int sqlite3one;
# endif
-# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0)
# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1)
# define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE)
@@ -11902,8 +12089,8 @@ struct BusyHandler {
#define SQLITE_WSD const
#define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
#define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
-SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J);
-SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L);
+SQLITE_API int sqlite3_wsd_init(int N, int J);
+SQLITE_API void *sqlite3_wsd_find(void *K, int L);
#else
#define SQLITE_WSD
#define GLOBAL(t,v) v
@@ -11980,6 +12167,14 @@ typedef struct Walker Walker;
typedef struct WhereInfo WhereInfo;
typedef struct With With;
+/* A VList object records a mapping between parameters/variables/wildcards
+** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer
+** variable number associated with that parameter. See the format description
+** on the sqlite3VListAdd() routine for more information. A VList is really
+** just an array of integers.
+*/
+typedef int VList;
+
/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
@@ -12079,7 +12274,9 @@ SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*);
SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*);
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *));
SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree);
+#ifndef SQLITE_OMIT_SHARED_CACHE
SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock);
+#endif
SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int);
SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *);
@@ -12236,9 +12433,10 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*);
SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags);
-/* Allowed flags for the 2nd argument to sqlite3BtreeDelete() */
+/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */
#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */
#define BTREE_AUXDELETE 0x04 /* not the primary delete operation */
+#define BTREE_APPEND 0x08 /* Insert is likely an append */
/* An instance of the BtreePayload object describes the content of a single
** entry in either an index or table btree.
@@ -12262,28 +12460,33 @@ struct BtreePayload {
const void *pKey; /* Key content for indexes. NULL for tables */
sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */
const void *pData; /* Data for tables. NULL for indexes */
+ struct Mem *aMem; /* First of nMem value in the unpacked pKey */
+ u16 nMem; /* Number of aMem[] value. Might be zero */
int nData; /* Size of pData. 0 if none. */
int nZero; /* Extra zero data appended after pData,nData */
};
SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
- int bias, int seekResult);
+ int flags, int seekResult);
SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
+SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
+SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*);
+#ifndef SQLITE_OMIT_INCRBLOB
+SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *);
+#endif
SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
@@ -12293,6 +12496,7 @@ SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void);
#ifndef NDEBUG
SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
#endif
+SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*);
#ifndef SQLITE_OMIT_BTREECOUNT
SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *);
@@ -12397,8 +12601,7 @@ typedef struct SubProgram SubProgram;
struct VdbeOp {
u8 opcode; /* What operation to perform */
signed char p4type; /* One of the P4_xxx constants for p4 */
- u8 notUsed1;
- u8 p5; /* Fifth parameter is an unsigned character */
+ u16 p5; /* Fifth parameter is an unsigned 16-bit integer */
int p1; /* First operand */
int p2; /* Second parameter (often the jump destination) */
int p3; /* The third parameter */
@@ -12444,7 +12647,7 @@ struct SubProgram {
int nOp; /* Elements in aOp[] */
int nMem; /* Number of memory cells required */
int nCsr; /* Number of cursors required */
- int nOnce; /* Number of OP_Once instructions */
+ u8 *aOnce; /* Array of OP_Once flags */
void *token; /* id that may be used to recursive triggers */
SubProgram *pNext; /* Next sub-program already visited */
};
@@ -12467,22 +12670,21 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_NOTUSED 0 /* The P4 parameter is not used */
#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
#define P4_STATIC (-2) /* Pointer to a static string */
-#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
-#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
-#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
-#define P4_EXPR (-7) /* P4 is a pointer to an Expr tree */
-#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
+#define P4_COLLSEQ (-3) /* P4 is a pointer to a CollSeq structure */
+#define P4_FUNCDEF (-4) /* P4 is a pointer to a FuncDef structure */
+#define P4_KEYINFO (-5) /* P4 is a pointer to a KeyInfo structure */
+#define P4_EXPR (-6) /* P4 is a pointer to an Expr tree */
+#define P4_MEM (-7) /* P4 is a pointer to a Mem* structure */
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
-#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
-#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */
-#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
-#define P4_INT64 (-13) /* P4 is a 64-bit signed integer */
-#define P4_INT32 (-14) /* P4 is a 32-bit signed integer */
-#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
-#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */
-#define P4_ADVANCE (-19) /* P4 is a pointer to BtreeNext() or BtreePrev() */
-#define P4_TABLE (-20) /* P4 is a pointer to a Table structure */
-#define P4_FUNCCTX (-21) /* P4 is a pointer to an sqlite3_context object */
+#define P4_VTAB (-8) /* P4 is a pointer to an sqlite3_vtab structure */
+#define P4_REAL (-9) /* P4 is a 64-bit floating point value */
+#define P4_INT64 (-10) /* P4 is a 64-bit signed integer */
+#define P4_INT32 (-11) /* P4 is a 32-bit signed integer */
+#define P4_INTARRAY (-12) /* P4 is a vector of 32-bit integers */
+#define P4_SUBPROGRAM (-13) /* P4 is a pointer to a SubProgram structure */
+#define P4_ADVANCE (-14) /* P4 is a pointer to BtreeNext() or BtreePrev() */
+#define P4_TABLE (-15) /* P4 is a pointer to a Table structure */
+#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
@@ -12561,13 +12763,13 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_NotExists 33 /* synopsis: intkey=r[P3] */
#define OP_IsNull 34 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
#define OP_NotNull 35 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 36 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
-#define OP_Eq 37 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
-#define OP_Gt 38 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
-#define OP_Le 39 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
-#define OP_Lt 40 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
-#define OP_Ge 41 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
-#define OP_Last 42
+#define OP_Ne 36 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 37 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 38 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 39 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 40 /* same as TK_LT, synopsis: IF r[P3]<r[P1] */
+#define OP_Ge 41 /* same as TK_GE, synopsis: IF r[P3]>=r[P1] */
+#define OP_ElseNotEq 42 /* same as TK_ESCAPE */
#define OP_BitAnd 43 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
#define OP_BitOr 44 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
#define OP_ShiftLeft 45 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
@@ -12578,115 +12780,117 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Divide 50 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
#define OP_Remainder 51 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
#define OP_Concat 52 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_SorterSort 53
+#define OP_Last 53
#define OP_BitNot 54 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
-#define OP_Sort 55
-#define OP_Rewind 56
-#define OP_IdxLE 57 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGT 58 /* synopsis: key=r[P3@P4] */
-#define OP_IdxLT 59 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGE 60 /* synopsis: key=r[P3@P4] */
-#define OP_RowSetRead 61 /* synopsis: r[P3]=rowset(P1) */
-#define OP_RowSetTest 62 /* synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 63
-#define OP_FkIfZero 64 /* synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_IfPos 65 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IfNotZero 66 /* synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2 */
-#define OP_DecrJumpZero 67 /* synopsis: if (--r[P1])==0 goto P2 */
-#define OP_IncrVacuum 68
-#define OP_VNext 69
-#define OP_Init 70 /* synopsis: Start at P2 */
-#define OP_Return 71
-#define OP_EndCoroutine 72
-#define OP_HaltIfNull 73 /* synopsis: if r[P3]=null halt */
-#define OP_Halt 74
-#define OP_Integer 75 /* synopsis: r[P2]=P1 */
-#define OP_Int64 76 /* synopsis: r[P2]=P4 */
-#define OP_String 77 /* synopsis: r[P2]='P4' (len=P1) */
-#define OP_Null 78 /* synopsis: r[P2..P3]=NULL */
-#define OP_SoftNull 79 /* synopsis: r[P1]=NULL */
-#define OP_Blob 80 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 81 /* synopsis: r[P2]=parameter(P1,P4) */
-#define OP_Move 82 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_Copy 83 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
-#define OP_SCopy 84 /* synopsis: r[P2]=r[P1] */
-#define OP_IntCopy 85 /* synopsis: r[P2]=r[P1] */
-#define OP_ResultRow 86 /* synopsis: output=r[P1@P2] */
-#define OP_CollSeq 87
-#define OP_Function0 88 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_Function 89 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_AddImm 90 /* synopsis: r[P1]=r[P1]+P2 */
-#define OP_RealAffinity 91
-#define OP_Cast 92 /* synopsis: affinity(r[P1]) */
-#define OP_Permutation 93
-#define OP_Compare 94 /* synopsis: r[P1@P3] <-> r[P2@P3] */
-#define OP_Column 95 /* synopsis: r[P3]=PX */
-#define OP_Affinity 96 /* synopsis: affinity(r[P1@P2]) */
+#define OP_IfSmaller 55
+#define OP_SorterSort 56
+#define OP_Sort 57
+#define OP_Rewind 58
+#define OP_IdxLE 59 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGT 60 /* synopsis: key=r[P3@P4] */
+#define OP_IdxLT 61 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGE 62 /* synopsis: key=r[P3@P4] */
+#define OP_RowSetRead 63 /* synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 64 /* synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 65
+#define OP_FkIfZero 66 /* synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_IfPos 67 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero 68 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+#define OP_DecrJumpZero 69 /* synopsis: if (--r[P1])==0 goto P2 */
+#define OP_IncrVacuum 70
+#define OP_VNext 71
+#define OP_Init 72 /* synopsis: Start at P2 */
+#define OP_Return 73
+#define OP_EndCoroutine 74
+#define OP_HaltIfNull 75 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 76
+#define OP_Integer 77 /* synopsis: r[P2]=P1 */
+#define OP_Int64 78 /* synopsis: r[P2]=P4 */
+#define OP_String 79 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 80 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 81 /* synopsis: r[P1]=NULL */
+#define OP_Blob 82 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 83 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 84 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 85 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 86 /* synopsis: r[P2]=r[P1] */
+#define OP_IntCopy 87 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 88 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 89
+#define OP_Function0 90 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Function 91 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_AddImm 92 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_RealAffinity 93
+#define OP_Cast 94 /* synopsis: affinity(r[P1]) */
+#define OP_Permutation 95
+#define OP_Compare 96 /* synopsis: r[P1@P3] <-> r[P2@P3] */
#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_MakeRecord 98 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_Count 99 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 100
-#define OP_SetCookie 101
-#define OP_ReopenIdx 102 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenRead 103 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 104 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenAutoindex 105 /* synopsis: nColumn=P2 */
-#define OP_OpenEphemeral 106 /* synopsis: nColumn=P2 */
-#define OP_SorterOpen 107
-#define OP_SequenceTest 108 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
-#define OP_OpenPseudo 109 /* synopsis: P3 columns in r[P2] */
-#define OP_Close 110
-#define OP_ColumnsUsed 111
-#define OP_Sequence 112 /* synopsis: r[P2]=cursor[P1].ctr++ */
-#define OP_NewRowid 113 /* synopsis: r[P2]=rowid */
-#define OP_Insert 114 /* synopsis: intkey=r[P3] data=r[P2] */
-#define OP_InsertInt 115 /* synopsis: intkey=P3 data=r[P2] */
-#define OP_Delete 116
-#define OP_ResetCount 117
-#define OP_SorterCompare 118 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-#define OP_SorterData 119 /* synopsis: r[P2]=data */
-#define OP_RowKey 120 /* synopsis: r[P2]=key */
-#define OP_RowData 121 /* synopsis: r[P2]=data */
-#define OP_Rowid 122 /* synopsis: r[P2]=rowid */
-#define OP_NullRow 123
-#define OP_SorterInsert 124
-#define OP_IdxInsert 125 /* synopsis: key=r[P2] */
-#define OP_IdxDelete 126 /* synopsis: key=r[P2@P3] */
-#define OP_Seek 127 /* synopsis: Move P3 to P1.rowid */
-#define OP_IdxRowid 128 /* synopsis: r[P2]=rowid */
-#define OP_Destroy 129
-#define OP_Clear 130
-#define OP_ResetSorter 131
-#define OP_CreateIndex 132 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_CreateTable 134 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_ParseSchema 135
-#define OP_LoadAnalysis 136
-#define OP_DropTable 137
-#define OP_DropIndex 138
-#define OP_DropTrigger 139
-#define OP_IntegrityCk 140
-#define OP_RowSetAdd 141 /* synopsis: rowset(P1)=r[P2] */
-#define OP_Param 142
-#define OP_FkCounter 143 /* synopsis: fkctr[P1]+=P2 */
-#define OP_MemMax 144 /* synopsis: r[P1]=max(r[P1],r[P2]) */
-#define OP_OffsetLimit 145 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-#define OP_AggStep0 146 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggStep 147 /* synopsis: accum=r[P3] step(r[P2@P5]) */
-#define OP_AggFinal 148 /* synopsis: accum=r[P1] N=P2 */
-#define OP_Expire 149
-#define OP_TableLock 150 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 151
-#define OP_VCreate 152
-#define OP_VDestroy 153
-#define OP_VOpen 154
-#define OP_VColumn 155 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VRename 156
-#define OP_Pagecount 157
-#define OP_MaxPgcnt 158
-#define OP_CursorHint 159
-#define OP_Noop 160
-#define OP_Explain 161
+#define OP_Column 98 /* synopsis: r[P3]=PX */
+#define OP_Affinity 99 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 100 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 101 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 102
+#define OP_SetCookie 103
+#define OP_ReopenIdx 104 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenRead 105 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 106 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenAutoindex 107 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 108 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 109
+#define OP_SequenceTest 110 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
+#define OP_OpenPseudo 111 /* synopsis: P3 columns in r[P2] */
+#define OP_Close 112
+#define OP_ColumnsUsed 113
+#define OP_Sequence 114 /* synopsis: r[P2]=cursor[P1].ctr++ */
+#define OP_NewRowid 115 /* synopsis: r[P2]=rowid */
+#define OP_Insert 116 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_InsertInt 117 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 118
+#define OP_ResetCount 119
+#define OP_SorterCompare 120 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 121 /* synopsis: r[P2]=data */
+#define OP_RowData 122 /* synopsis: r[P2]=data */
+#define OP_Rowid 123 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 124
+#define OP_SorterInsert 125 /* synopsis: key=r[P2] */
+#define OP_IdxInsert 126 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 127 /* synopsis: key=r[P2@P3] */
+#define OP_Seek 128 /* synopsis: Move P3 to P1.rowid */
+#define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */
+#define OP_Destroy 130
+#define OP_Clear 131
+#define OP_Real 132 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
+#define OP_ResetSorter 133
+#define OP_CreateIndex 134 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_CreateTable 135 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_SqlExec 136
+#define OP_ParseSchema 137
+#define OP_LoadAnalysis 138
+#define OP_DropTable 139
+#define OP_DropIndex 140
+#define OP_DropTrigger 141
+#define OP_IntegrityCk 142
+#define OP_RowSetAdd 143 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Param 144
+#define OP_FkCounter 145 /* synopsis: fkctr[P1]+=P2 */
+#define OP_MemMax 146 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_OffsetLimit 147 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggStep0 148 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggStep 149 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggFinal 150 /* synopsis: accum=r[P1] N=P2 */
+#define OP_Expire 151
+#define OP_TableLock 152 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 153
+#define OP_VCreate 154
+#define OP_VDestroy 155
+#define OP_VOpen 156
+#define OP_VColumn 157 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VRename 158
+#define OP_Pagecount 159
+#define OP_MaxPgcnt 160
+#define OP_CursorHint 161
+#define OP_Noop 162
+#define OP_Explain 163
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
@@ -12706,20 +12910,20 @@ typedef struct VdbeOpList VdbeOpList;
/* 32 */ 0x09, 0x09, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
/* 40 */ 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26, 0x26,\
/* 48 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x01, 0x12, 0x01,\
-/* 56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x23, 0x0b, 0x01,\
-/* 64 */ 0x01, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01, 0x02,\
-/* 72 */ 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00,\
-/* 80 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
-/* 88 */ 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00,\
-/* 96 */ 0x00, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\
+/* 56 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x23,\
+/* 64 */ 0x0b, 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01,\
+/* 72 */ 0x01, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10,\
+/* 80 */ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10,\
+/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,\
+/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 112 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 120 */ 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00, 0x00,\
-/* 128 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00,\
-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\
-/* 144 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
-/* 160 */ 0x00, 0x00,}
+/* 112 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\
+/* 120 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x04, 0x00,\
+/* 128 */ 0x00, 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10,\
+/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\
+/* 144 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\
+/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+/* 160 */ 0x10, 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
@@ -12727,7 +12931,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 70 /* Maximum JUMP opcode */
+#define SQLITE_MX_JUMP_OPCODE 72 /* Maximum JUMP opcode */
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -12750,8 +12954,10 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int);
#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N);
+SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
#else
# define sqlite3VdbeVerifyNoMallocRequired(A,B)
+# define sqlite3VdbeVerifyNoResultRow(A)
#endif
SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
@@ -12759,11 +12965,12 @@ SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
+SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
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*);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
@@ -12799,7 +13006,7 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
-SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
+SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*);
typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
@@ -13004,7 +13211,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
int,
void(*)(DbPage*)
);
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager);
+SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*);
SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
/* Functions used to configure a Pager object. */
@@ -13055,15 +13262,21 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager);
#ifndef SQLITE_OMIT_WAL
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int, int*, int*);
+SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager);
SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager);
+SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
+# ifdef SQLITE_DIRECT_OVERFLOW_READ
+SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno);
+# endif
# 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 sqlite3PagerSnapshotRecover(Pager *pPager);
# endif
+#else
+# define sqlite3PagerUseWal(x,y) 0
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -13682,7 +13895,7 @@ SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *);
** and the one-based values are used internally.
*/
#ifndef SQLITE_DEFAULT_SYNCHRONOUS
-# define SQLITE_DEFAULT_SYNCHRONOUS (PAGER_SYNCHRONOUS_FULL-1)
+# define SQLITE_DEFAULT_SYNCHRONOUS 2
#endif
#ifndef SQLITE_DEFAULT_WAL_SYNCHRONOUS
# define SQLITE_DEFAULT_WAL_SYNCHRONOUS SQLITE_DEFAULT_SYNCHRONOUS
@@ -13696,7 +13909,7 @@ SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *);
** databases may be attached.
*/
struct Db {
- char *zName; /* Name of this database */
+ char *zDbSName; /* Name of this database. (schema name, not filename) */
Btree *pBt; /* The B*Tree structure for this database file */
u8 safety_level; /* How aggressive at syncing data to disk */
u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */
@@ -13887,6 +14100,8 @@ struct sqlite3 {
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
u8 mTrace; /* zero or more SQLITE_TRACE flags */
+ u8 skipBtreeMutex; /* True if no shared-cache backends */
+ u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */
int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite3_changes() */
@@ -14034,6 +14249,7 @@ struct sqlite3 {
#define SQLITE_Vacuum 0x10000000 /* Currently in a VACUUM */
#define SQLITE_CellSizeCk 0x20000000 /* Check btree cell sizes on load */
#define SQLITE_Fts3Tokenizer 0x40000000 /* Enable fts3_tokenizer(2) */
+#define SQLITE_NoCkptOnClose 0x80000000 /* No checkpoint on close()/DETACH */
/*
@@ -14059,13 +14275,8 @@ struct sqlite3 {
/*
** Macros for testing whether or not optimizations are enabled or disabled.
*/
-#ifndef SQLITE_OMIT_BUILTIN_TEST
#define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0)
#define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0)
-#else
-#define OptimizationDisabled(db, mask) 0
-#define OptimizationEnabled(db, mask) 1
-#endif
/*
** Return true if it OK to factor constant expressions into the initialization
@@ -14156,6 +14367,7 @@ struct FuncDestructor {
#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 */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -14332,6 +14544,7 @@ struct CollSeq {
** operator is NULL. It is added to certain comparison operators to
** prove that the operands are always NOT NULL.
*/
+#define SQLITE_KEEPNULL 0x08 /* Used by vector == or <> */
#define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */
#define SQLITE_STOREP2 0x20 /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ 0x80 /* NULL=NULL */
@@ -14403,15 +14616,15 @@ struct Table {
ExprList *pCheck; /* All CHECK constraints */
/* ... also used as column name list in a VIEW */
int tnum; /* Root BTree page for this table */
+ u32 nTabRef; /* Number of pointers to this 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 */
- u16 nRef; /* Number of pointers to this Table */
LogEst nRowLogEst; /* Estimated rows in table - from sqlite_stat1 table */
LogEst szTabRow; /* Estimated size of each table row in bytes */
#ifdef SQLITE_ENABLE_COSTMULT
LogEst costMult; /* Cost multiplier for using this table */
#endif
- u8 tabFlags; /* Mask of TF_* values */
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
#ifndef SQLITE_OMIT_ALTERTABLE
int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */
@@ -14435,15 +14648,17 @@ struct Table {
** the TF_OOOHidden attribute would apply in this case. Such tables require
** special handling during INSERT processing.
*/
-#define TF_Readonly 0x01 /* Read-only system table */
-#define TF_Ephemeral 0x02 /* An ephemeral table */
-#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
-#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
-#define TF_Virtual 0x10 /* Is a virtual table */
-#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
-#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
-#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
-
+#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_StatsUsed 0x0100 /* Query planner decisions affected by
+ ** Index.aiRowLogEst[] values */
+#define TF_HasNotNull 0x0200 /* Contains NOT NULL constraints */
/*
** Test to see whether or not a table is a virtual table. This is
@@ -14451,7 +14666,7 @@ struct Table {
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
-# define IsVirtual(X) (((X)->tabFlags & TF_Virtual)!=0)
+# define IsVirtual(X) ((X)->nModuleArg)
#else
# define IsVirtual(X) 0
#endif
@@ -14686,6 +14901,7 @@ struct Index {
unsigned isResized:1; /* True if resizeIndexObject() has been called */
unsigned isCovering:1; /* True if this is a covering index */
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
+ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -14896,9 +15112,11 @@ struct Expr {
int iTable; /* TK_COLUMN: cursor number of table holding column
** TK_REGISTER: register number
** TK_TRIGGER: 1 -> new, 0 -> old
- ** EP_Unlikely: 134217728 times likelihood */
+ ** EP_Unlikely: 134217728 times likelihood
+ ** TK_SELECT: 1st register of result vector */
ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid.
- ** TK_VARIABLE: variable number (always >= 1). */
+ ** TK_VARIABLE: variable number (always >= 1).
+ ** 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: original value of Expr.op
@@ -14934,6 +15152,7 @@ struct Expr {
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias 0x400000 /* Is an alias for a result set column */
+#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
/*
** Combinations of two or more EP_* flags
@@ -14993,7 +15212,7 @@ struct Expr {
struct ExprList {
int nExpr; /* Number of expressions on the list */
struct ExprList_item { /* For each expression in the list */
- Expr *pExpr; /* The list of expressions */
+ Expr *pExpr; /* The parse tree for this expression */
char *zName; /* Token associated with this expression */
char *zSpan; /* Original text of the expression */
u8 sortOrder; /* 1 for DESC or 0 for ASC */
@@ -15158,7 +15377,7 @@ struct SrcList {
#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */
#define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */
#define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */
- /* 0x1000 not currently used */
+#define WHERE_SEEK_UNIQ_TABLE 0x1000 /* Do not defer seeks if unique */
/* 0x2000 not currently used */
#define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */
/* 0x8000 not currently used */
@@ -15379,7 +15598,7 @@ struct Select {
*/
struct SelectDest {
u8 eDest; /* How to dispose of the results. On of SRT_* above. */
- char affSdst; /* Affinity used when eDest==SRT_Set */
+ char *zAffSdst; /* Affinity used when eDest==SRT_Set */
int iSDParm; /* A parameter used by the eDest disposal method */
int iSdst; /* Base register where results are written */
int nSdst; /* Number of registers allocated */
@@ -15485,36 +15704,23 @@ struct Parse {
u8 okConstFactor; /* OK to factor out constants */
u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 nColCache; /* Number of entries in aColCache[] */
- int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
- int nSet; /* Number of sets used so far */
- int nOnce; /* Number of OP_Once instructions so far */
int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
- int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */
int ckBase; /* Base register of data during check constraints */
int iSelfTab; /* Table of an index whose exprs are being coded */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
int nLabel; /* Number of labels used */
int *aLabel; /* Space to hold the labels */
- struct yColCache {
- int iTable; /* Table cursor number */
- i16 iColumn; /* Table column number */
- u8 tempReg; /* iReg is a temp register that needs to be freed */
- int iLevel; /* Nesting level */
- int iReg; /* Reg with value of this column. 0 means none. */
- int lru; /* Least recently used entry has the smallest value */
- } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
ExprList *pConstExpr;/* Constant expressions */
Token constraintName;/* Name of the constraint currently being parsed */
yDbMask writeMask; /* Start a write transaction on these databases */
yDbMask cookieMask; /* Bitmask of schema verified databases */
- int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
int regRowid; /* Register holding rowid of CREATE TABLE entry */
int regRoot; /* Register holding root page number for new objects */
int nMaxArg; /* Max args passed to user function by sub-program */
@@ -15527,8 +15733,6 @@ struct Parse {
TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
-
- /* Information used while coding trigger programs. */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
@@ -15539,35 +15743,50 @@ struct Parse {
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
u8 disableTriggers; /* True to disable triggers */
+ /**************************************************************************
+ ** Fields above must be initialized to zero. The fields that follow,
+ ** down to the beginning of the recursive section, do not need to be
+ ** initialized as they will be set before being used. The boundary is
+ ** determined by offsetof(Parse,aColCache).
+ **************************************************************************/
+
+ struct yColCache {
+ int iTable; /* Table cursor number */
+ i16 iColumn; /* Table column number */
+ u8 tempReg; /* iReg is a temp register that needs to be freed */
+ int iLevel; /* Nesting level */
+ int iReg; /* Reg with value of this column. 0 means none. */
+ int lru; /* Least recently used entry has the smallest value */
+ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
+ int aTempReg[8]; /* Holding area for temporary registers */
+ Token sNameToken; /* Token with unqualified schema object name */
+
/************************************************************************
** Above is constant between recursions. Below is reset before and after
** each recursion. The boundary between these two regions is determined
- ** using offsetof(Parse,nVar) so the nVar field must be the first field
- ** in the recursive region.
+ ** using offsetof(Parse,sLastToken) so the sLastToken field must be the
+ ** first field in the recursive region.
************************************************************************/
+ Token sLastToken; /* The last token parsed */
ynVar nVar; /* Number of '?' variables seen in the SQL so far */
- int nzVar; /* Number of available slots in azVar[] */
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
int nVtabLock; /* Number of virtual tables to lock */
#endif
- int nAlias; /* Number of aliased result set columns */
int nHeight; /* Expression tree height of current sub-select */
#ifndef SQLITE_OMIT_EXPLAIN
int iSelectId; /* ID of current select for EXPLAIN output */
int iNextSelectId; /* Next available select ID for EXPLAIN output */
#endif
- char **azVar; /* Pointers to names of parameters */
+ VList *pVList; /* Mapping between variable names and numbers */
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
- Token sNameToken; /* Token with unqualified schema object name */
- Token sLastToken; /* The last token parsed */
#ifndef SQLITE_OMIT_VIRTUALTABLE
Token sArg; /* Complete text of a module argument */
Table **apVtabLock; /* Pointer to virtual tables needing locking */
@@ -15579,6 +15798,14 @@ struct Parse {
};
/*
+** Sizes and pointers of various parts of the Parse object.
+*/
+#define PARSE_HDR_SZ offsetof(Parse,aColCache) /* Recursive part w/o aColCache*/
+#define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */
+#define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */
+#define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */
+
+/*
** Return true if currently inside an sqlite3_declare_vtab() call.
*/
#ifdef SQLITE_OMIT_VIRTUALTABLE
@@ -15611,13 +15838,11 @@ struct AuthContext {
#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */
/* Also used in P2 (not P5) of OP_Delete */
#define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */
-#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */
+#define OPFLAG_LASTROWID 0x20 /* Set to update db->lastRowid */
#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */
#define OPFLAG_APPEND 0x08 /* This is likely to be an append */
#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */
-#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
#define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */
-#endif
#define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */
#define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */
#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */
@@ -15625,7 +15850,7 @@ struct AuthContext {
#define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */
#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
-#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete: keep cursor position */
+#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */
#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
/*
@@ -15822,10 +16047,11 @@ struct Sqlite3Config {
void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */
void *pVdbeBranchArg; /* 1st argument */
#endif
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
+ int iOnceResetThreshold; /* When to reset OP_Once counters */
};
/*
@@ -16025,7 +16251,7 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void*);
SQLITE_PRIVATE void *sqlite3PageMalloc(int);
SQLITE_PRIVATE void sqlite3PageFree(void*);
SQLITE_PRIVATE void sqlite3MemSetDefault(void);
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
#endif
SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
@@ -16111,6 +16337,7 @@ SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
#if defined(SQLITE_DEBUG)
SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
+SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8);
@@ -16135,13 +16362,14 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int);
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
-SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
+SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
+SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
+SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int);
SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
@@ -16150,6 +16378,9 @@ SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName);
+#endif
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*);
SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int);
SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*);
@@ -16177,9 +16408,8 @@ SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
sqlite3_vfs**,char**,char **);
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
-SQLITE_PRIVATE int sqlite3CodeOnce(Parse *);
-#ifdef SQLITE_OMIT_BUILTIN_TEST
+#ifdef SQLITE_UNTESTABLE
# define sqlite3FaultSim(X) SQLITE_OK
#else
SQLITE_PRIVATE int sqlite3FaultSim(int);
@@ -16192,7 +16422,7 @@ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
#endif
@@ -16281,7 +16511,7 @@ SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
-SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
+SQLITE_PRIVATE int sqlite3ExprCodeAtInit(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
@@ -16289,6 +16519,7 @@ 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 */
#define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */
+#define SQLITE_ECEL_OMITREF 0x08 /* Omit if ExprList.u.x.iOrderByCol */
SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
@@ -16300,10 +16531,11 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_ite
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
-SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
-SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
+SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*);
+SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int);
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
+SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
@@ -16311,7 +16543,7 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
#endif
@@ -16342,6 +16574,11 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,I
SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
u8,u8,int,int*,int*);
+#ifdef SQLITE_ENABLE_NULL_TRIM
+SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*);
+#else
+# define sqlite3SetMakeRecordP5(A,B)
+#endif
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
@@ -16448,6 +16685,9 @@ SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
#endif
+SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
+SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int);
+SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int);
/*
** Routines to read and write variable-length integers. These used to
@@ -16477,6 +16717,7 @@ 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 sqlite3TableColumnAffinity(Table*,int);
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
@@ -16542,7 +16783,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
-SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
+SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr *, int, int);
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*);
@@ -16597,19 +16838,29 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
+#ifndef SQLITE_OMIT_SUBQUERY
+SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*);
+#else
+# define sqlite3ExprCheckIN(x,y) SQLITE_OK
+#endif
+
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
-SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
+SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
+ Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
+SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int);
#endif
/*
** The interface to the LEMON-generated parser
*/
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64));
-SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
+#ifndef SQLITE_AMALGAMATION
+SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64));
+SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
+#endif
SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
#ifdef YYTRACKMAXSTACKDEPTH
SQLITE_PRIVATE int sqlite3ParserStackPeak(void*);
@@ -16655,6 +16906,13 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*);
SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
+SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
+ sqlite3*,
+ const char*,
+ const sqlite3_module*,
+ void*,
+ void(*)(void*)
+ );
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
#endif
SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
@@ -16712,6 +16970,7 @@ SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *);
#define sqlite3FkDropTable(a,b,c)
#define sqlite3FkOldmask(a,b) 0
#define sqlite3FkRequired(a,b,c,d) 0
+ #define sqlite3FkReferences(a) 0
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*);
@@ -16730,10 +16989,10 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**);
/*
** The interface to the code in fault.c used for identifying "benign"
-** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
+** malloc failures. This is only present if SQLITE_UNTESTABLE
** is not defined.
*/
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void);
SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
#else
@@ -16755,7 +17014,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void);
#define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */
#define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */
#define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*);
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*);
SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *);
@@ -16860,6 +17119,12 @@ SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
#endif
+SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr);
+SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr);
+SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int);
+SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int);
+SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*);
+
#endif /* SQLITEINT_H */
/************** End of sqliteInt.h *******************************************/
@@ -16945,16 +17210,13 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
**
** (x & ~(map[x]&0x20))
**
-** Standard function tolower() is implemented using the sqlite3UpperToLower[]
+** The equivalent of tolower() is implemented using the sqlite3UpperToLower[]
** array. tolower() is used more often than toupper() by SQLite.
**
-** Bit 0x40 is set if the character non-alphanumeric and can be used in an
+** Bit 0x40 is set if the character is non-alphanumeric and can be used in an
** SQLite identifier. Identifiers are alphanumerics, "_", "$", and any
** non-ASCII UTF character. Hence the test for whether or not a character is
** part of an identifier is 0x46.
-**
-** SQLite's versions are identical to the standard versions assuming a
-** locale of "C". They are implemented as macros in sqliteInt.h.
*/
#ifdef SQLITE_ASCII
SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
@@ -17027,7 +17289,7 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
#endif
/* Statement journals spill to disk when their size exceeds the following
-** threashold (in bytes). 0 means that statement journals are created and
+** threshold (in bytes). 0 means that statement journals are created and
** written to disk immediately (the default behavior for SQLite versions
** before 3.12.0). -1 means always keep the entire statement journal in
** memory. (The statement journal is also always held entirely in memory
@@ -17039,6 +17301,19 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
#endif
/*
+** The default lookaside-configuration, the format "SZ,N". SZ is the
+** number of bytes in each lookaside slot (should be a multiple of 8)
+** and N is the number of slots. The lookaside-configuration can be
+** 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);
+*/
+#ifndef SQLITE_DEFAULT_LOOKASIDE
+# define SQLITE_DEFAULT_LOOKASIDE 1200,100
+#endif
+
+
+/*
** The following singleton contains the global configuration for
** the SQLite library.
*/
@@ -17050,8 +17325,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
0x7ffffffe, /* mxStrlen */
0, /* neverCorrupt */
- 128, /* szLookaside */
- 500, /* nLookaside */
+ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
SQLITE_STMTJRNL_SPILL, /* nStmtSpill */
{0,0,0,0,0,0,0,0}, /* m */
{0,0,0,0,0,0,0,0,0}, /* mutex */
@@ -17088,10 +17362,11 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, /* xVdbeBranch */
0, /* pVbeBranchArg */
#endif
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
- 0 /* bLocaltimeFault */
+ 0, /* bLocaltimeFault */
+ 0x7ffffffe /* iOnceResetThreshold */
};
/*
@@ -17114,7 +17389,7 @@ SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
** The value of the "pending" byte must be 0x40000000 (1 byte past the
** 1-gibabyte boundary) in a compatible database. SQLite never uses
** the database page that contains the pending byte. It never attempts
-** to read or write that page. The pending byte page is set assign
+** to read or write that page. The pending byte page is set aside
** for use by the VFS layers as space for managing file locks.
**
** During testing, it is often desirable to move the pending byte to
@@ -17207,7 +17482,7 @@ static const char * const azCompileOpt[] = {
#if SQLITE_COVERAGE_TEST
"COVERAGE_TEST",
#endif
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
"DEBUG",
#endif
#if SQLITE_DEFAULT_LOCKING_MODE
@@ -17216,6 +17491,15 @@ static const char * const azCompileOpt[] = {
#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
"DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
#endif
+#if SQLITE_DEFAULT_SYNCHRONOUS
+ "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS),
+#endif
+#if SQLITE_DEFAULT_WAL_SYNCHRONOUS
+ "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS),
+#endif
+#if SQLITE_DIRECT_OVERFLOW_READ
+ "DIRECT_OVERFLOW_READ",
+#endif
#if SQLITE_DISABLE_DIRSYNC
"DISABLE_DIRSYNC",
#endif
@@ -17302,6 +17586,9 @@ static const char * const azCompileOpt[] = {
#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
"ENABLE_UPDATE_DELETE_LIMIT",
#endif
+#if defined(SQLITE_ENABLE_URI_00_ERROR)
+ "ENABLE_URI_00_ERROR",
+#endif
#if SQLITE_HAS_CODEC
"HAS_CODEC",
#endif
@@ -17377,9 +17664,6 @@ static const char * const azCompileOpt[] = {
#if SQLITE_OMIT_BTREECOUNT
"OMIT_BTREECOUNT",
#endif
-#if SQLITE_OMIT_BUILTIN_TEST
- "OMIT_BUILTIN_TEST",
-#endif
#if SQLITE_OMIT_CAST
"OMIT_CAST",
#endif
@@ -17542,6 +17826,9 @@ static const char * const azCompileOpt[] = {
#if defined(SQLITE_THREADSAFE)
"THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
#endif
+#if SQLITE_UNTESTABLE
+ "UNTESTABLE"
+#endif
#if SQLITE_USE_ALLOCA
"USE_ALLOCA",
#endif
@@ -17563,7 +17850,7 @@ static const char * const azCompileOpt[] = {
** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
** is not required for a match.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
int i, n;
#if SQLITE_ENABLE_API_ARMOR
@@ -17591,7 +17878,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
** Return the N-th compile-time option string. If N is out of range,
** return a NULL pointer.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
+SQLITE_API const char *sqlite3_compileoption_get(int N){
if( N>=0 && N<ArraySize(azCompileOpt) ){
return azCompileOpt[N];
}
@@ -17674,9 +17961,6 @@ typedef unsigned Bool;
/* Opaque type used by code in vdbesort.c */
typedef struct VdbeSorter VdbeSorter;
-/* Opaque type used by the explainer */
-typedef struct Explain Explain;
-
/* Elements of the linked list at Vdbe.pAuxData */
typedef struct AuxData AuxData;
@@ -17698,59 +17982,68 @@ typedef struct AuxData AuxData;
*/
typedef struct VdbeCursor VdbeCursor;
struct VdbeCursor {
- u8 eCurType; /* One of the CURTYPE_* values above */
- i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
- u8 nullRow; /* True if pointing to a row with no data */
- u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
- u8 isTable; /* True for rowid tables. False for indexes */
+ u8 eCurType; /* One of the CURTYPE_* values above */
+ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */
+ u8 nullRow; /* True if pointing to a row with no data */
+ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
+ u8 isTable; /* True for rowid tables. False for indexes */
#ifdef SQLITE_DEBUG
- u8 seekOp; /* Most recent seek operation on this cursor */
- u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
-#endif
- Bool isEphemeral:1; /* True for an ephemeral table */
- Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
- Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
- Pgno pgnoRoot; /* Root page of the open btree cursor */
- i16 nField; /* Number of fields in the header */
- u16 nHdrParsed; /* Number of header fields parsed so far */
+ u8 seekOp; /* Most recent seek operation on this cursor */
+ u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */
+#endif
+ Bool isEphemeral:1; /* True for an ephemeral table */
+ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */
+ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */
+ Btree *pBtx; /* Separate file holding temporary table */
+ i64 seqCount; /* Sequence counter */
+ int *aAltMap; /* Mapping from table to index column numbers */
+
+ /* Cached OP_Column parse information is only valid if cacheStatus matches
+ ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
+ ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that
+ ** the cache is out of date. */
+ u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
+ int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0
+ ** if there have been no prior seeks on the cursor. */
+ /* NB: seekResult does not distinguish between "no seeks have ever occurred
+ ** on this cursor" and "the most recent seek was an exact match". */
+
+ /* When a new VdbeCursor is allocated, only the fields above are zeroed.
+ ** The fields that follow are uninitialized, and must be individually
+ ** initialized prior to first use. */
+ VdbeCursor *pAltCursor; /* Associated index cursor from which to read */
union {
BtCursor *pCursor; /* CURTYPE_BTREE. Btree cursor */
sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */
int pseudoTableReg; /* CURTYPE_PSEUDO. Reg holding content. */
VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */
} uc;
- Btree *pBt; /* Separate file holding temporary table */
- KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
- int seekResult; /* Result of previous sqlite3BtreeMoveto() */
- i64 seqCount; /* Sequence counter */
- i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
- VdbeCursor *pAltCursor; /* Associated index cursor from which to read */
- int *aAltMap; /* Mapping from table to index column numbers */
+ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
+ u32 iHdrOffset; /* Offset to next unparsed byte of the header */
+ Pgno pgnoRoot; /* Root page of the open btree cursor */
+ i16 nField; /* Number of fields in the header */
+ u16 nHdrParsed; /* Number of header fields parsed so far */
+ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
+ u32 *aOffset; /* Pointer to aType[nField] */
+ const u8 *aRow; /* Data for the current row, if all on one page */
+ u32 payloadSize; /* Total number of bytes in the record */
+ u32 szRow; /* Byte available in aRow */
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
- u64 maskUsed; /* Mask of columns used by this cursor */
+ u64 maskUsed; /* Mask of columns used by this cursor */
#endif
- /* Cached information about the header for the data record that the
- ** cursor is currently pointing to. Only valid if cacheStatus matches
- ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of
- ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
- ** the cache is out of date.
- **
- ** aRow might point to (ephemeral) data for the current row, or it might
- ** be NULL.
- */
- u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */
- u32 payloadSize; /* Total number of bytes in the record */
- u32 szRow; /* Byte available in aRow */
- u32 iHdrOffset; /* Offset to next unparsed byte of the header */
- const u8 *aRow; /* Data for the current row, if all on one page */
- u32 *aOffset; /* Pointer to aType[nField] */
- u32 aType[1]; /* Type values for all entries in the record */
/* 2*nField extra array elements allocated for aType[], beyond the one
** static element declared in the structure. nField total array slots for
** aType[] and nField+1 array slots for aOffset[] */
+ u32 aType[1]; /* Type values record decode. MUST BE LAST */
};
+
+/*
+** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
+*/
+#define CACHE_STALE 0
+
/*
** When a sub-program is executed (OP_Program), a structure of this type
** is allocated to store the current value of the program counter, as
@@ -17779,8 +18072,8 @@ struct VdbeFrame {
Op *aOp; /* Program instructions for parent frame */
i64 *anExec; /* Event counters from parent frame */
Mem *aMem; /* Array of memory cells for parent frame */
- u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
+ u8 *aOnce; /* Bitmask used by OP_Once */
void *token; /* Copy of SubProgram.token */
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
AuxData *pAuxData; /* Linked list of auxdata allocations */
@@ -17788,7 +18081,6 @@ struct VdbeFrame {
int pc; /* Program Counter in parent (calling) frame */
int nOp; /* Size of aOp array */
int nMem; /* Number of entries in aMem */
- int nOnceFlag; /* Number of entries in aOnceFlag */
int nChildMem; /* Number of memory cells for child frame */
int nChildCsr; /* Number of cursors for child frame */
int nChange; /* Statement changes (Vdbe.nChange) */
@@ -17798,11 +18090,6 @@ struct VdbeFrame {
#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
/*
-** A value for VdbeCursor.cacheValid that means the cache is always invalid.
-*/
-#define CACHE_STALE 0
-
-/*
** Internally, the vdbe manipulates nearly all SQL values as Mem
** structures. Each Mem struct may cache multiple representations (string,
** integer etc.) of the same value.
@@ -17942,18 +18229,6 @@ struct sqlite3_context {
sqlite3_value *argv[1]; /* Argument set */
};
-/*
-** An Explain object accumulates indented output which is helpful
-** in describing recursive data structures.
-*/
-struct Explain {
- Vdbe *pVdbe; /* Attach the explanation to this Vdbe */
- StrAccum str; /* The string being accumulated */
- int nIndent; /* Number of elements in aIndent */
- u16 aIndent[100]; /* Levels of indentation */
- char zBase[100]; /* Initial space */
-};
-
/* A bitfield type for use inside of structures. Always follow with :N where
** N is the number of bits.
*/
@@ -17978,34 +18253,46 @@ struct ScanStatus {
*/
struct Vdbe {
sqlite3 *db; /* The database connection that owns this statement */
+ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
+ Parse *pParse; /* Parsing context used to create this Vdbe */
+ ynVar nVar; /* Number of entries in aVar[] */
+ u32 magic; /* Magic number for sanity checking */
+ int nMem; /* Number of memory locations currently allocated */
+ int nCursor; /* Number of slots in apCsr[] */
+ u32 cacheCtr; /* VdbeCursor row cache generation counter */
+ int pc; /* The program counter */
+ int rc; /* Value to return */
+ int nChange; /* Number of db changes made since last reset */
+ int iStatement; /* Statement number (or 0 if has not opened stmt) */
+ i64 iCurrentTime; /* Value of julianday('now') for this statement */
+ i64 nFkConstraint; /* Number of imm. FK constraints this VM */
+ i64 nStmtDefCons; /* Number of def. constraints when stmt started */
+ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
+
+ /* When allocating a new Vdbe object, all of the fields below should be
+ ** initialized to zero or NULL */
+
Op *aOp; /* Space to hold the virtual machine's program */
Mem *aMem; /* The memory locations */
Mem **apArg; /* Arguments to currently executing user function */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
- Parse *pParse; /* Parsing context used to create this Vdbe */
- int nMem; /* Number of memory locations currently allocated */
- int nOp; /* Number of instructions in the program */
- int nCursor; /* Number of slots in apCsr[] */
- u32 magic; /* Magic number for sanity checking */
char *zErrMsg; /* Error message written here */
- Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
VdbeCursor **apCsr; /* One element of this array for each open cursor */
Mem *aVar; /* Values for the OP_Variable opcode. */
- char **azVar; /* Name of variables */
- ynVar nVar; /* Number of entries in aVar[] */
- ynVar nzVar; /* Number of entries in azVar[] */
- u32 cacheCtr; /* VdbeCursor row cache generation counter */
- int pc; /* The program counter */
- int rc; /* Value to return */
+ VList *pVList; /* Name of variables */
+#ifndef SQLITE_OMIT_TRACE
+ i64 startTime; /* Time when query started - used for profiling */
+#endif
+ int nOp; /* Number of instructions in the program */
#ifdef SQLITE_DEBUG
int rcApp; /* errcode set by sqlite3_result_error_code() */
#endif
u16 nResColumn; /* Number of columns in one row of the result set */
u8 errorAction; /* Recovery action to do in case of an error */
+ u8 minWriteFileFormat; /* Minimum file format for writable database files */
bft expired:1; /* True if the VM needs to be recompiled */
bft doingRerun:1; /* True if rerunning after an auto-reprepare */
- u8 minWriteFileFormat; /* Minimum file format for writable database files */
bft explain:2; /* True if EXPLAIN present on SQL command */
bft changeCntOn:1; /* True to update the change-counter */
bft runOnlyOnce:1; /* Automatically expire on reset */
@@ -18013,18 +18300,9 @@ struct Vdbe {
bft readOnly:1; /* True for statements that do not write */
bft bIsReader:1; /* True for statements that read */
bft isPrepareV2:1; /* True if prepared with prepare_v2() */
- int nChange; /* Number of db changes made since last reset */
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
- int iStatement; /* Statement number (or 0 if has not opened stmt) */
u32 aCounter[5]; /* Counters used by sqlite3_stmt_status() */
-#ifndef SQLITE_OMIT_TRACE
- i64 startTime; /* Time when query started - used for profiling */
-#endif
- i64 iCurrentTime; /* Value of julianday('now') for this statement */
- i64 nFkConstraint; /* Number of imm. FK constraints this VM */
- i64 nStmtDefCons; /* Number of def. constraints when stmt started */
- i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
char *zSql; /* Text of the SQL statement that generated this */
void *pFree; /* Free this when deleting the vdbe */
VdbeFrame *pFrame; /* Parent frame */
@@ -18032,8 +18310,6 @@ struct Vdbe {
int nFrame; /* Number of frames in pFrame list */
u32 expmask; /* Binding to these vars invalidates VM */
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
- int nOnceFlag; /* Size of array aOnceFlag[] */
- u8 *aOnceFlag; /* Flags for OP_Once */
AuxData *pAuxData; /* Linked list of auxdata allocations */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
i64 *anExec; /* Number of times each op has been executed */
@@ -18045,10 +18321,11 @@ struct Vdbe {
/*
** The following are allowed values for Vdbe.magic
*/
-#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
-#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
-#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
-#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
+#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */
+#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */
+#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */
+#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */
+#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */
/*
** Structure used to store the context required by the
@@ -18065,8 +18342,9 @@ struct PreUpdate {
int iNewReg; /* Register for new.* values */
i64 iKey1; /* First key value passed to hook */
i64 iKey2; /* Second key value passed to hook */
- int iPKey; /* If not negative index of IPK column */
Mem *aNew; /* Array of new.* values */
+ Table *pTab; /* Schema object being upated */
+ Index *pPk; /* PK index if pTab is WITHOUT ROWID */
};
/*
@@ -18119,7 +18397,7 @@ 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 sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
+SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
@@ -18301,7 +18579,7 @@ SQLITE_PRIVATE void sqlite3StatusHighwater(int op, int X){
/*
** Query status information.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+SQLITE_API int sqlite3_status64(
int op,
sqlite3_int64 *pCurrent,
sqlite3_int64 *pHighwater,
@@ -18326,7 +18604,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status64(
(void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */
return SQLITE_OK;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
sqlite3_int64 iCur = 0, iHwtr = 0;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -18343,7 +18621,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwa
/*
** Query status information for a single database connection
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
+SQLITE_API int sqlite3_db_status(
sqlite3 *db, /* The database connection whose status is desired */
int op, /* Status verb */
int *pCurrent, /* Write current value here */
@@ -18588,16 +18866,18 @@ struct tm *__cdecl localtime(const time_t *);
*/
typedef struct DateTime DateTime;
struct DateTime {
- sqlite3_int64 iJD; /* The julian day number times 86400000 */
- int Y, M, D; /* Year, month, and day */
- int h, m; /* Hour and minutes */
- int tz; /* Timezone offset in minutes */
- double s; /* Seconds */
- char validYMD; /* True (1) if Y,M,D are valid */
- char validHMS; /* True (1) if h,m,s are valid */
- char validJD; /* True (1) if iJD is valid */
- char validTZ; /* True (1) if tz is valid */
- char tzSet; /* Timezone was set explicitly */
+ sqlite3_int64 iJD; /* The julian day number times 86400000 */
+ int Y, M, D; /* Year, month, and day */
+ int h, m; /* Hour and minutes */
+ int tz; /* Timezone offset in minutes */
+ double s; /* Seconds */
+ char validJD; /* True (1) if iJD is valid */
+ char rawS; /* Raw numeric value stored in s */
+ char validYMD; /* True (1) if Y,M,D are valid */
+ char validHMS; /* True (1) if h,m,s are valid */
+ char validTZ; /* True (1) if tz is valid */
+ char tzSet; /* Timezone was set explicitly */
+ char isError; /* An overflow has occurred */
};
@@ -18745,6 +19025,7 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
s = 0;
}
p->validJD = 0;
+ p->rawS = 0;
p->validHMS = 1;
p->h = h;
p->m = m;
@@ -18755,6 +19036,14 @@ static int parseHhMmSs(const char *zDate, DateTime *p){
}
/*
+** Put the DateTime object into its error state.
+*/
+static void datetimeError(DateTime *p){
+ memset(p, 0, sizeof(*p));
+ p->isError = 1;
+}
+
+/*
** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
** that the YYYY-MM-DD is according to the Gregorian calendar.
**
@@ -18773,6 +19062,10 @@ static void computeJD(DateTime *p){
M = 1;
D = 1;
}
+ if( Y<-4713 || Y>9999 || p->rawS ){
+ datetimeError(p);
+ return;
+ }
if( M<=2 ){
Y--;
M += 12;
@@ -18854,6 +19147,21 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
}
/*
+** Input "r" is a numeric quantity which might be a julian day number,
+** or the number of seconds since 1970. If the value if r is within
+** range of a julian day number, install it as such and set validJD.
+** If the value is a valid unix timestamp, put it in p->s and set p->rawS.
+*/
+static void setRawDateNumber(DateTime *p, double r){
+ p->s = r;
+ p->rawS = 1;
+ if( r>=0.0 && r<5373484.5 ){
+ p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
+ p->validJD = 1;
+ }
+}
+
+/*
** Attempt to parse the given string into a julian day number. Return
** the number of errors.
**
@@ -18882,13 +19190,30 @@ static int parseDateOrTime(
}else if( sqlite3StrICmp(zDate,"now")==0){
return setDateTimeToCurrent(context, p);
}else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
- p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
- p->validJD = 1;
+ setRawDateNumber(p, r);
return 0;
}
return 1;
}
+/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999.
+** Multiplying this by 86400000 gives 464269060799999 as the maximum value
+** for DateTime.iJD.
+**
+** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with
+** such a large integer literal, so we have to encode it.
+*/
+#define INT_464269060799999 ((((i64)0x1a640)<<32)|0x1072fdff)
+
+/*
+** Return TRUE if the given julian day number is within range.
+**
+** The input is the JulianDay times 86400000.
+*/
+static int validJulianDay(sqlite3_int64 iJD){
+ return iJD>=0 && iJD<=INT_464269060799999;
+}
+
/*
** Compute the Year, Month, and Day from the julian day number.
*/
@@ -18900,6 +19225,7 @@ static void computeYMD(DateTime *p){
p->M = 1;
p->D = 1;
}else{
+ assert( validJulianDay(p->iJD) );
Z = (int)((p->iJD + 43200000)/86400000);
A = (int)((Z - 1867216.25)/36524.25);
A = Z + 1 + A - (A/4);
@@ -18930,6 +19256,7 @@ static void computeHMS(DateTime *p){
s -= p->h*3600;
p->m = s/60;
p->s += s - p->m*60;
+ p->rawS = 0;
p->validHMS = 1;
}
@@ -18991,14 +19318,14 @@ static int osLocaltime(time_t *t, struct tm *pTm){
#endif
sqlite3_mutex_enter(mutex);
pX = localtime(t);
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
#endif
if( pX ) *pTm = *pX;
sqlite3_mutex_leave(mutex);
rc = pX==0;
#else
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
#endif
#if HAVE_LOCALTIME_R
@@ -19069,7 +19396,9 @@ static sqlite3_int64 localtimeOffset(
y.validYMD = 1;
y.validHMS = 1;
y.validJD = 0;
+ y.rawS = 0;
y.validTZ = 0;
+ y.isError = 0;
computeJD(&y);
*pRc = SQLITE_OK;
return y.iJD - x.iJD;
@@ -19077,6 +19406,29 @@ static sqlite3_int64 localtimeOffset(
#endif /* SQLITE_OMIT_LOCALTIME */
/*
+** The following table defines various date transformations of the form
+**
+** 'NNN days'
+**
+** Where NNN is an arbitrary floating-point number and "days" can be one
+** of several units of time.
+*/
+static const struct {
+ u8 eType; /* Transformation type code */
+ u8 nName; /* Length of th name */
+ char *zName; /* Name of the transformation */
+ 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 },
+};
+
+/*
** Process a modifier to a date-time stamp. The modifiers are
** as follows:
**
@@ -19100,17 +19452,15 @@ static sqlite3_int64 localtimeOffset(
** to context pCtx. If the error is an unrecognized modifier, no error is
** written to pCtx.
*/
-static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
+static int parseModifier(
+ sqlite3_context *pCtx, /* Function context */
+ const char *z, /* The text of the modifier */
+ int n, /* Length of zMod in bytes */
+ DateTime *p /* The date/time value to be modified */
+){
int rc = 1;
- int n;
double r;
- char *z, zBuf[30];
- z = zBuf;
- for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
- z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
- }
- z[n] = 0;
- switch( z[0] ){
+ switch(sqlite3UpperToLower[(u8)z[0]] ){
#ifndef SQLITE_OMIT_LOCALTIME
case 'l': {
/* localtime
@@ -19118,7 +19468,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
** Assuming the current time value is UTC (a.k.a. GMT), shift it to
** show local time.
*/
- if( strcmp(z, "localtime")==0 ){
+ if( sqlite3_stricmp(z, "localtime")==0 ){
computeJD(p);
p->iJD += localtimeOffset(p, pCtx, &rc);
clearYMD_HMS_TZ(p);
@@ -19130,16 +19480,21 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
/*
** unixepoch
**
- ** Treat the current value of p->iJD as the number of
+ ** Treat the current value of p->s as the number of
** seconds since 1970. Convert to a real julian day number.
*/
- if( strcmp(z, "unixepoch")==0 && p->validJD ){
- p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
- clearYMD_HMS_TZ(p);
- rc = 0;
+ if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
+ r = p->s*1000.0 + 210866760000000.0;
+ if( r>=0.0 && r<464269060800000.0 ){
+ clearYMD_HMS_TZ(p);
+ p->iJD = (sqlite3_int64)r;
+ p->validJD = 1;
+ p->rawS = 0;
+ rc = 0;
+ }
}
#ifndef SQLITE_OMIT_LOCALTIME
- else if( strcmp(z, "utc")==0 ){
+ else if( sqlite3_stricmp(z, "utc")==0 ){
if( p->tzSet==0 ){
sqlite3_int64 c1;
computeJD(p);
@@ -19165,7 +19520,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
** weekday N where 0==Sunday, 1==Monday, and so forth. If the
** date is already on the appropriate weekday, this is a no-op.
*/
- if( strncmp(z, "weekday ", 8)==0
+ if( sqlite3_strnicmp(z, "weekday ", 8)==0
&& sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
&& (n=(int)r)==r && n>=0 && r<7 ){
sqlite3_int64 Z;
@@ -19188,23 +19543,24 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
** Move the date backwards to the beginning of the current day,
** or month or year.
*/
- if( strncmp(z, "start of ", 9)!=0 ) break;
+ if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
+ if( !p->validJD && !p->validYMD && !p->validHMS ) break;
z += 9;
computeYMD(p);
p->validHMS = 1;
p->h = p->m = 0;
p->s = 0.0;
+ p->rawS = 0;
p->validTZ = 0;
p->validJD = 0;
- if( strcmp(z,"month")==0 ){
+ if( sqlite3_stricmp(z,"month")==0 ){
p->D = 1;
rc = 0;
- }else if( strcmp(z,"year")==0 ){
- computeYMD(p);
+ }else if( sqlite3_stricmp(z,"year")==0 ){
p->M = 1;
p->D = 1;
rc = 0;
- }else if( strcmp(z,"day")==0 ){
+ }else if( sqlite3_stricmp(z,"day")==0 ){
rc = 0;
}
break;
@@ -19222,6 +19578,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
case '8':
case '9': {
double rRounder;
+ int i;
for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
rc = 1;
@@ -19250,46 +19607,48 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
rc = 0;
break;
}
+
+ /* If control reaches this point, it means the transformation is
+ ** one of the forms like "+NNN days". */
z += n;
while( sqlite3Isspace(*z) ) z++;
n = sqlite3Strlen30(z);
if( n>10 || n<3 ) break;
- if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
+ if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--;
computeJD(p);
- rc = 0;
+ rc = 1;
rRounder = r<0 ? -0.5 : +0.5;
- if( n==3 && strcmp(z,"day")==0 ){
- p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
- }else if( n==4 && strcmp(z,"hour")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
- }else if( n==6 && strcmp(z,"minute")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
- }else if( n==6 && strcmp(z,"second")==0 ){
- p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
- }else if( n==5 && strcmp(z,"month")==0 ){
- int x, y;
- computeYMD_HMS(p);
- p->M += (int)r;
- x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
- p->Y += x;
- p->M -= x*12;
- p->validJD = 0;
- computeJD(p);
- y = (int)r;
- if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
- }
- }else if( n==4 && strcmp(z,"year")==0 ){
- int y = (int)r;
- computeYMD_HMS(p);
- p->Y += y;
- p->validJD = 0;
- computeJD(p);
- if( y!=r ){
- p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
+ for(i=0; i<ArraySize(aXformType); i++){
+ if( aXformType[i].nName==n
+ && sqlite3_strnicmp(aXformType[i].zName, z, n)==0
+ && r>-aXformType[i].rLimit && r<aXformType[i].rLimit
+ ){
+ switch( aXformType[i].eType ){
+ case 1: { /* Special processing to add months */
+ int x;
+ computeYMD_HMS(p);
+ p->M += (int)r;
+ x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
+ p->Y += x;
+ p->M -= x*12;
+ p->validJD = 0;
+ r -= (int)r;
+ break;
+ }
+ case 2: { /* Special processing to add years */
+ int y = (int)r;
+ computeYMD_HMS(p);
+ p->Y += y;
+ p->validJD = 0;
+ r -= (int)r;
+ break;
+ }
+ }
+ computeJD(p);
+ p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder);
+ rc = 0;
+ break;
}
- }else{
- rc = 1;
}
clearYMD_HMS_TZ(p);
break;
@@ -19316,7 +19675,7 @@ static int isDate(
sqlite3_value **argv,
DateTime *p
){
- int i;
+ int i, n;
const unsigned char *z;
int eType;
memset(p, 0, sizeof(*p));
@@ -19325,8 +19684,7 @@ static int isDate(
}
if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
|| eType==SQLITE_INTEGER ){
- p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
- p->validJD = 1;
+ setRawDateNumber(p, sqlite3_value_double(argv[0]));
}else{
z = sqlite3_value_text(argv[0]);
if( !z || parseDateOrTime(context, (char*)z, p) ){
@@ -19335,8 +19693,11 @@ static int isDate(
}
for(i=1; i<argc; i++){
z = sqlite3_value_text(argv[i]);
- if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
+ n = sqlite3_value_bytes(argv[i]);
+ if( z==0 || parseModifier(context, (char*)z, n, p) ) return 1;
}
+ computeJD(p);
+ if( p->isError || !validJulianDay(p->iJD) ) return 1;
return 0;
}
@@ -20020,7 +20381,7 @@ static sqlite3_vfs * SQLITE_WSD vfsList = 0;
** Locate a VFS by name. If no name is given, simply return the
** first VFS on the list.
*/
-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
sqlite3_vfs *pVfs = 0;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex;
@@ -20066,7 +20427,7 @@ static void vfsUnlink(sqlite3_vfs *pVfs){
** VFS multiple times. The new VFS becomes the default if makeDflt is
** true.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -20094,7 +20455,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDf
/*
** Unregister a VFS so that it is no longer accessible.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
@@ -20134,7 +20495,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
/* #include "sqliteInt.h" */
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
/*
** Global variables.
@@ -20192,7 +20553,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
}
}
-#endif /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
+#endif /* #ifndef SQLITE_UNTESTABLE */
/************** End of fault.c ***********************************************/
/************** Begin file mem0.c ********************************************/
@@ -20317,7 +20678,9 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
*/
#include <sys/sysctl.h>
#include <malloc/malloc.h>
+#ifdef SQLITE_MIGHT_BE_SINGLE_CORE
#include <libkern/OSAtomic.h>
+#endif /* SQLITE_MIGHT_BE_SINGLE_CORE */
static malloc_zone_t* _sqliteZone_;
#define SQLITE_MALLOC(x) malloc_zone_malloc(_sqliteZone_, (x))
#define SQLITE_FREE(x) malloc_zone_free(_sqliteZone_, (x));
@@ -20385,7 +20748,9 @@ static malloc_zone_t* _sqliteZone_;
*/
static void *sqlite3MemMalloc(int nByte){
#ifdef SQLITE_MALLOCSIZE
- void *p = SQLITE_MALLOC( nByte );
+ void *p;
+ testcase( ROUND8(nByte)==nByte );
+ p = SQLITE_MALLOC( nByte );
if( p==0 ){
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte);
@@ -20394,7 +20759,7 @@ static void *sqlite3MemMalloc(int nByte){
#else
sqlite3_int64 *p;
assert( nByte>0 );
- nByte = ROUND8(nByte);
+ testcase( ROUND8(nByte)!=nByte );
p = SQLITE_MALLOC( nByte+8 );
if( p ){
p[0] = nByte;
@@ -20508,19 +20873,10 @@ static int sqlite3MemInit(void *NotUsed){
}else{
/* only 1 core, use our own zone to contention over global locks,
** e.g. we have our own dedicated locks */
- bool success;
- malloc_zone_t* newzone = malloc_create_zone(4096, 0);
- malloc_set_zone_name(newzone, "Sqlite_Heap");
- do{
- success = OSAtomicCompareAndSwapPtrBarrier(NULL, newzone,
- (void * volatile *)&_sqliteZone_);
- }while(!_sqliteZone_);
- if( !success ){
- /* somebody registered a zone first */
- malloc_destroy_zone(newzone);
- }
+ _sqliteZone_ = malloc_create_zone(4096, 0);
+ malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap");
}
-#endif
+#endif /* defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) */
UNUSED_PARAMETER(NotUsed);
return SQLITE_OK;
}
@@ -22445,7 +22801,7 @@ SQLITE_PRIVATE int sqlite3MutexEnd(void){
/*
** Retrieve a pointer to a static mutex or allocate a new dynamic one.
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
#ifndef SQLITE_OMIT_AUTOINIT
if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
@@ -22466,7 +22822,7 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
/*
** Free a dynamic mutex.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexFree );
sqlite3GlobalConfig.mutex.xMutexFree(p);
@@ -22477,7 +22833,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
** Obtain the mutex p. If some other thread already has the mutex, block
** until it can be obtained.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexEnter );
sqlite3GlobalConfig.mutex.xMutexEnter(p);
@@ -22488,7 +22844,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
int rc = SQLITE_OK;
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexTry );
@@ -22503,7 +22859,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
** is not currently entered. If a NULL pointer is passed as an argument
** this function is a no-op.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
if( p ){
assert( sqlite3GlobalConfig.mutex.xMutexLeave );
sqlite3GlobalConfig.mutex.xMutexLeave(p);
@@ -22515,11 +22871,11 @@ SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use inside assert() statements.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld );
return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
}
@@ -23516,8 +23872,7 @@ SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__)
__sync_synchronize();
-#elif !defined(SQLITE_DISABLE_INTRINSIC) && \
- defined(_MSC_VER) && _MSC_VER>=1300
+#elif MSVC_VERSION>=1300
_ReadWriteBarrier();
#elif defined(MemoryBarrier)
MemoryBarrier();
@@ -23551,8 +23906,8 @@ static int winMutex_isNt = -1; /* <0 means "need to query" */
*/
static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */
-SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */
+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
@@ -23728,8 +24083,8 @@ static void winMutexEnter(sqlite3_mutex *p){
p->owner = tid;
p->nRef++;
if( p->trace ){
- OSTRACE(("ENTER-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
- tid, p, p->trace, p->nRef));
+ OSTRACE(("ENTER-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
+ tid, p->id, p, p->trace, p->nRef));
}
#endif
}
@@ -23771,8 +24126,8 @@ static int winMutexTry(sqlite3_mutex *p){
#endif
#ifdef SQLITE_DEBUG
if( p->trace ){
- OSTRACE(("TRY-MUTEX tid=%lu, mutex=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
- tid, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
+ OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n",
+ tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc)));
}
#endif
return rc;
@@ -23800,8 +24155,8 @@ static void winMutexLeave(sqlite3_mutex *p){
LeaveCriticalSection(&p->mutex);
#ifdef SQLITE_DEBUG
if( p->trace ){
- OSTRACE(("LEAVE-MUTEX tid=%lu, mutex=%p (%d), nRef=%d\n",
- tid, p, p->trace, p->nRef));
+ OSTRACE(("LEAVE-MUTEX tid=%lu, mutex(%d)=%p (%d), nRef=%d\n",
+ tid, p->id, p, p->trace, p->nRef));
}
#endif
}
@@ -23852,7 +24207,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
** held by SQLite. An example of non-essential memory is memory used to
** cache database pages that are not currently in use.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){
+SQLITE_API int sqlite3_release_memory(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
return sqlite3PcacheReleaseMemory(n);
#else
@@ -23911,7 +24266,7 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){
** that was invoked when memory usage grew too large. Now it is a
** no-op.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
+SQLITE_API int sqlite3_memory_alarm(
void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
void *pArg,
sqlite3_int64 iThreshold
@@ -23927,7 +24282,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
** Set the soft heap-size limit for the library. Passing a zero or
** negative value indicates no limit.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
sqlite3_int64 nUsed;
@@ -23949,7 +24304,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64
if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
return priorLimit;
}
-SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
+SQLITE_API void sqlite3_soft_heap_limit(int n){
if( n<0 ) n = 0;
sqlite3_soft_heap_limit64(n);
}
@@ -24018,7 +24373,7 @@ SQLITE_PRIVATE void sqlite3MallocEnd(void){
/*
** Return the amount of memory currently checked out.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
sqlite3_int64 res, mx;
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
return res;
@@ -24029,7 +24384,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
** checked out since either the beginning of this process
** or since the most recent reset.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
sqlite3_int64 res, mx;
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
return mx;
@@ -24049,11 +24404,26 @@ static void sqlite3MallocAlarm(int nByte){
** Do a memory allocation with statistics and alarms. Assume the
** lock is already held.
*/
-static int mallocWithAlarm(int n, void **pp){
- int nFull;
+static void mallocWithAlarm(int n, void **pp){
void *p;
+ int nFull;
assert( sqlite3_mutex_held(mem0.mutex) );
+ assert( n>0 );
+
+ /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal
+ ** implementation of malloc_good_size(), which must be called in debug
+ ** mode and specifically when the DMD "Dark Matter Detector" is enabled
+ ** or else a crash results. Hence, do not attempt to optimize out the
+ ** 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);
@@ -24077,7 +24447,6 @@ static int mallocWithAlarm(int n, void **pp){
sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
}
*pp = p;
- return nFull;
}
/*
@@ -24109,13 +24478,13 @@ SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
** First make sure the memory subsystem is initialized, then do the
** allocation.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){
+SQLITE_API void *sqlite3_malloc(int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
return n<=0 ? 0 : sqlite3Malloc(n);
}
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -24243,7 +24612,7 @@ SQLITE_PRIVATE int sqlite3MallocSize(void *p){
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
assert( p!=0 );
if( db==0 || !isLookaside(db,p) ){
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
if( db==0 ){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
@@ -24258,7 +24627,7 @@ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
return db->lookaside.sz;
}
}
-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
+SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
@@ -24267,7 +24636,7 @@ SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
/*
** Free memory previously obtained from sqlite3Malloc().
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){
+SQLITE_API void sqlite3_free(void *p){
if( p==0 ) return; /* IMP: R-49053-54554 */
assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
@@ -24304,7 +24673,7 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/* Trash all content in the buffer being freed */
memset(p, 0xaa, db->lookaside.sz);
#endif
@@ -24351,7 +24720,7 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
sqlite3_mutex_enter(mem0.mutex);
sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
nDiff = nNew - nOld;
- if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
+ if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >=
mem0.alarmThreshold-nDiff ){
sqlite3MallocAlarm(nDiff);
}
@@ -24376,14 +24745,14 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
** The public interface to sqlite3Realloc. Make sure that the memory
** subsystem is initialized prior to invoking sqliteRealloc.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){
+SQLITE_API void *sqlite3_realloc(void *pOld, int n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
if( n<0 ) n = 0; /* IMP: R-26507-47431 */
return sqlite3Realloc(pOld, n);
}
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
+SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize() ) return 0;
#endif
@@ -24558,9 +24927,8 @@ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
if( z==0 ){
return 0;
}
- n = sqlite3Strlen30(z) + 1;
- assert( (n&0x7fffffff)==n );
- zNew = sqlite3DbMallocRaw(db, (int)n);
+ n = strlen(z) + 1;
+ zNew = sqlite3DbMallocRaw(db, n);
if( zNew ){
memcpy(zNew, z, n);
}
@@ -24674,7 +25042,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
** Conversion types fall into various categories as defined by the
** following enumeration.
*/
-#define etRADIX 0 /* Integer types. %d, %x, %o, and so forth */
+#define etRADIX 0 /* non-decimal integer types. %x %o */
#define etFLOAT 1 /* Floating point. %f */
#define etEXP 2 /* Exponentional notation. %e and %E */
#define etGENERIC 3 /* Floating or exponential, depending on exponent. %g */
@@ -24692,8 +25060,9 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
#define etPOINTER 13 /* The %p conversion */
#define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */
#define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
+#define etDECIMAL 16 /* %d or %u, but not %x, %o */
-#define etINVALID 16 /* Any unrecognized conversion type */
+#define etINVALID 17 /* Any unrecognized conversion type */
/*
@@ -24717,9 +25086,8 @@ typedef struct et_info { /* Information about each format field */
/*
** Allowed values for et_info.flags
*/
-#define FLAG_SIGNED 1 /* True if the value to convert is signed */
-#define FLAG_INTERN 2 /* True if for internal use only */
-#define FLAG_STRING 4 /* Allow infinity precision */
+#define FLAG_SIGNED 1 /* True if the value to convert is signed */
+#define FLAG_STRING 4 /* Allow infinite precision */
/*
@@ -24729,7 +25097,7 @@ typedef struct et_info { /* Information about each format field */
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[] = {
- { 'd', 10, 1, etRADIX, 0, 0 },
+ { 'd', 10, 1, etDECIMAL, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 4, etDYNSTRING, 0, 0 },
@@ -24738,7 +25106,7 @@ static const et_info fmtinfo[] = {
{ 'w', 0, 4, etSQLESCAPE3, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
- { 'u', 10, 0, etRADIX, 0, 0 },
+ { 'u', 10, 0, etDECIMAL, 0, 0 },
{ 'x', 16, 0, etRADIX, 16, 1 },
{ 'X', 16, 0, etRADIX, 0, 4 },
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -24747,16 +25115,15 @@ static const et_info fmtinfo[] = {
{ 'E', 0, 1, etEXP, 14, 0 },
{ 'G', 0, 1, etGENERIC, 14, 0 },
#endif
- { 'i', 10, 1, etRADIX, 0, 0 },
+ { 'i', 10, 1, etDECIMAL, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
-/* All the rest have the FLAG_INTERN bit set and are thus for internal
-** use only */
- { 'T', 0, 2, etTOKEN, 0, 0 },
- { 'S', 0, 2, etSRCLIST, 0, 0 },
- { 'r', 10, 3, etORDINAL, 0, 0 },
+ /* All the rest are undocumented and are for internal use only */
+ { 'T', 0, 0, etTOKEN, 0, 0 },
+ { 'S', 0, 0, etSRCLIST, 0, 0 },
+ { 'r', 10, 1, etORDINAL, 0, 0 },
};
/*
@@ -24840,17 +25207,15 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
int idx; /* A general purpose loop counter */
int width; /* Width of the current field */
etByte flag_leftjustify; /* True if "-" flag is present */
- etByte flag_plussign; /* True if "+" flag is present */
- etByte flag_blanksign; /* True if " " flag is present */
+ etByte flag_prefix; /* '+' or ' ' or 0 for prefix */
etByte flag_alternateform; /* True if "#" flag is present */
etByte flag_altform2; /* True if "!" flag is present */
etByte flag_zeropad; /* True if field width constant starts with zero */
- etByte flag_long; /* True if "l" flag is present */
- etByte flag_longlong; /* True if the "ll" flag is present */
+ etByte flag_long; /* 1 for the "l" flag, 2 for "ll", 0 by default */
etByte done; /* Loop termination flag */
+ etByte cThousand; /* Thousands separator for %d and %u */
etByte xtype = etINVALID; /* Conversion paradigm */
u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
- u8 useIntern; /* Ok to use internal conversions (ex: %T) */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
sqlite_uint64 longvalue; /* Value for integer types */
LONGDOUBLE_TYPE realvalue; /* Value for real types */
@@ -24869,13 +25234,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
char buf[etBUFSIZE]; /* Conversion buffer */
bufpt = 0;
- if( pAccum->printfFlags ){
- if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
- pArgList = va_arg(ap, PrintfArguments*);
- }
- useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL;
+ if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
+ pArgList = va_arg(ap, PrintfArguments*);
+ bArgList = 1;
}else{
- bArgList = useIntern = 0;
+ bArgList = 0;
}
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
@@ -24893,17 +25256,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
break;
}
/* Find out what flags are present */
- flag_leftjustify = flag_plussign = flag_blanksign =
+ flag_leftjustify = flag_prefix = cThousand =
flag_alternateform = flag_altform2 = flag_zeropad = 0;
done = 0;
do{
switch( c ){
case '-': flag_leftjustify = 1; break;
- case '+': flag_plussign = 1; break;
- case ' ': flag_blanksign = 1; break;
+ case '+': flag_prefix = '+'; break;
+ case ' ': flag_prefix = ' '; break;
case '#': flag_alternateform = 1; break;
case '!': flag_altform2 = 1; break;
case '0': flag_zeropad = 1; break;
+ case ',': cThousand = ','; break;
default: done = 1; break;
}
}while( !done && (c=(*++fmt))!=0 );
@@ -24973,13 +25337,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
flag_long = 1;
c = *++fmt;
if( c=='l' ){
- flag_longlong = 1;
+ flag_long = 2;
c = *++fmt;
- }else{
- flag_longlong = 0;
}
}else{
- flag_long = flag_longlong = 0;
+ flag_long = 0;
}
/* Fetch the info entry for the field */
infop = &fmtinfo[0];
@@ -24987,11 +25349,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
for(idx=0; idx<ArraySize(fmtinfo); idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
- if( useIntern || (infop->flags & FLAG_INTERN)==0 ){
- xtype = infop->type;
- }else{
- return;
- }
+ xtype = infop->type;
break;
}
}
@@ -25001,15 +25359,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
**
** flag_alternateform TRUE if a '#' is present.
** flag_altform2 TRUE if a '!' is present.
- ** flag_plussign TRUE if a '+' is present.
+ ** flag_prefix '+' or ' ' or zero
** flag_leftjustify TRUE if a '-' is present or if the
** field width was negative.
** flag_zeropad TRUE if the width began with 0.
- ** flag_long TRUE if the letter 'l' (ell) prefixed
- ** the conversion character.
- ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
- ** the conversion character.
- ** flag_blanksign TRUE if a ' ' is present.
+ ** flag_long 1 for "l", 2 for "ll"
** width The specified field width. This is
** always non-negative. Zero is the default.
** precision The specified precision. The default
@@ -25019,19 +25373,24 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
*/
switch( xtype ){
case etPOINTER:
- flag_longlong = sizeof(char*)==sizeof(i64);
- flag_long = sizeof(char*)==sizeof(long int);
+ flag_long = sizeof(char*)==sizeof(i64) ? 2 :
+ sizeof(char*)==sizeof(long int) ? 1 : 0;
/* Fall through into the next case */
case etORDINAL:
- case etRADIX:
+ case etRADIX:
+ cThousand = 0;
+ /* Fall through into the next case */
+ case etDECIMAL:
if( infop->flags & FLAG_SIGNED ){
i64 v;
if( bArgList ){
v = getIntArg(pArgList);
- }else if( flag_longlong ){
- v = va_arg(ap,i64);
}else if( flag_long ){
- v = va_arg(ap,long int);
+ if( flag_long==2 ){
+ v = va_arg(ap,i64) ;
+ }else{
+ v = va_arg(ap,long int);
+ }
}else{
v = va_arg(ap,int);
}
@@ -25044,17 +25403,17 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
prefix = '-';
}else{
longvalue = v;
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
+ prefix = flag_prefix;
}
}else{
if( bArgList ){
longvalue = (u64)getIntArg(pArgList);
- }else if( flag_longlong ){
- longvalue = va_arg(ap,u64);
}else if( flag_long ){
- longvalue = va_arg(ap,unsigned long int);
+ if( flag_long==2 ){
+ longvalue = va_arg(ap,u64);
+ }else{
+ longvalue = va_arg(ap,unsigned long int);
+ }
}else{
longvalue = va_arg(ap,unsigned int);
}
@@ -25064,16 +25423,17 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( flag_zeropad && precision<width-(prefix!=0) ){
precision = width-(prefix!=0);
}
- if( precision<etBUFSIZE-10 ){
+ if( precision<etBUFSIZE-10-etBUFSIZE/3 ){
nOut = etBUFSIZE;
zOut = buf;
}else{
- nOut = precision + 10;
- zOut = zExtra = sqlite3Malloc( nOut );
+ u64 n = (u64)precision + 10 + precision/3;
+ zOut = zExtra = sqlite3Malloc( n );
if( zOut==0 ){
setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
+ nOut = (int)n;
}
bufpt = &zOut[nOut-1];
if( xtype==etORDINAL ){
@@ -25094,8 +25454,23 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}while( longvalue>0 );
}
length = (int)(&zOut[nOut-1]-bufpt);
- for(idx=precision-length; idx>0; idx--){
+ while( precision>length ){
*(--bufpt) = '0'; /* Zero pad */
+ length++;
+ }
+ if( cThousand ){
+ int nn = (length - 1)/3; /* Number of "," to insert */
+ int ix = (length - 1)%3 + 1;
+ bufpt -= nn;
+ for(idx=0; nn>0; idx++){
+ bufpt[idx] = bufpt[idx+nn];
+ ix--;
+ if( ix==0 ){
+ bufpt[++idx] = cThousand;
+ nn--;
+ ix = 3;
+ }
+ }
}
if( prefix ) *(--bufpt) = prefix; /* Add sign */
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
@@ -25122,9 +25497,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
realvalue = -realvalue;
prefix = '-';
}else{
- if( flag_plussign ) prefix = '+';
- else if( flag_blanksign ) prefix = ' ';
- else prefix = 0;
+ prefix = flag_prefix;
}
if( xtype==etGENERIC && precision>0 ) precision--;
testcase( precision>0xfff );
@@ -25360,7 +25733,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
break;
}
case etTOKEN: {
- Token *pToken = va_arg(ap, Token*);
+ Token *pToken;
+ if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
+ pToken = va_arg(ap, Token*);
assert( bArgList==0 );
if( pToken && pToken->n ){
sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
@@ -25369,9 +25744,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
break;
}
case etSRCLIST: {
- SrcList *pSrc = va_arg(ap, SrcList*);
- int k = va_arg(ap, int);
- struct SrcList_item *pItem = &pSrc->a[k];
+ SrcList *pSrc;
+ int k;
+ struct SrcList_item *pItem;
+ if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
+ pSrc = va_arg(ap, SrcList*);
+ k = va_arg(ap, int);
+ pItem = &pSrc->a[k];
assert( bArgList==0 );
assert( k>=0 && k<pSrc->nSrc );
if( pItem->zDatabase ){
@@ -25393,9 +25772,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
** the output.
*/
width -= length;
- if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
- sqlite3StrAccumAppend(pAccum, bufpt, length);
- if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+ if( width>0 ){
+ if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+ sqlite3StrAccumAppend(pAccum, bufpt, length);
+ if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
+ }else{
+ sqlite3StrAccumAppend(pAccum, bufpt, length);
+ }
if( zExtra ){
sqlite3DbFree(pAccum->db, zExtra);
@@ -25500,7 +25883,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( p->accError==0 || p->nAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
enlargeAndAppend(p,z,N);
- }else{
+ }else if( N ){
assert( p->zText );
p->nChar += N;
memcpy(&p->zText[p->nChar-N], z, N);
@@ -25520,18 +25903,23 @@ SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
*/
+static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
+ assert( p->mxAlloc>0 && !isMalloced(p) );
+ p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
+ if( p->zText ){
+ memcpy(p->zText, p->zBase, p->nChar+1);
+ p->printfFlags |= SQLITE_PRINTF_MALLOCED;
+ }else{
+ setStrAccumError(p, STRACCUM_NOMEM);
+ }
+ return p->zText;
+}
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
assert( (p->zText==p->zBase)==!isMalloced(p) );
p->zText[p->nChar] = 0;
if( p->mxAlloc>0 && !isMalloced(p) ){
- p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
- if( p->zText ){
- memcpy(p->zText, p->zBase, p->nChar+1);
- p->printfFlags |= SQLITE_PRINTF_MALLOCED;
- }else{
- setStrAccumError(p, STRACCUM_NOMEM);
- }
+ return strAccumFinishRealloc(p);
}
}
return p->zText;
@@ -25610,7 +25998,7 @@ SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
** Print into memory obtained from sqlite3_malloc(). Omit the internal
** %-conversion extensions.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
+SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
char *z;
char zBase[SQLITE_PRINT_BUF_SIZE];
StrAccum acc;
@@ -25634,7 +26022,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap
** Print into memory obtained from sqlite3_malloc()(). Omit the internal
** %-conversion extensions.
*/
-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
+SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
va_list ap;
char *z;
#ifndef SQLITE_OMIT_AUTOINIT
@@ -25659,7 +26047,7 @@ SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
**
** sqlite3_vsnprintf() is the varargs version.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
+SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
StrAccum acc;
if( n<=0 ) return zBuf;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -25671,9 +26059,10 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char
#endif
sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
sqlite3VXPrintf(&acc, zFormat, ap);
- return sqlite3StrAccumFinish(&acc);
+ zBuf[acc.nChar] = 0;
+ return zBuf;
}
-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
+SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
char *z;
va_list ap;
va_start(ap,zFormat);
@@ -25709,7 +26098,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
/*
** Format and write a message to the log if logging is enabled.
*/
-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
va_list ap; /* Vararg list */
if( sqlite3GlobalConfig.xLog ){
va_start(ap, zFormat);
@@ -25819,6 +26208,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
va_start(ap, zFormat);
sqlite3VXPrintf(&acc, zFormat, ap);
va_end(ap);
+ assert( acc.nChar>0 );
if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
sqlite3StrAccumFinish(&acc);
fprintf(stdout,"%s", zBuf);
@@ -25874,11 +26264,15 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
/*
-** Generate a human-readable description of a the Select object.
+** Generate a human-readable description of a Select object.
*/
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
int n = 0;
int cnt = 0;
+ if( p==0 ){
+ sqlite3TreeViewLine(pView, "nil-SELECT");
+ return;
+ }
pView = sqlite3TreeViewPush(pView, moreToFollow);
if( p->pWith ){
sqlite3TreeViewWith(pView, p->pWith, 1);
@@ -26205,6 +26599,15 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
break;
}
+ case TK_VECTOR: {
+ sqlite3TreeViewBareExprList(pView, pExpr->x.pList, "VECTOR");
+ break;
+ }
+ case TK_SELECT_COLUMN: {
+ sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn);
+ sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
+ break;
+ }
default: {
sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
break;
@@ -26221,21 +26624,20 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
sqlite3TreeViewPop(pView);
}
+
/*
** Generate a human-readable explanation of an expression list.
*/
-SQLITE_PRIVATE void sqlite3TreeViewExprList(
+SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
TreeView *pView,
const ExprList *pList,
- u8 moreToFollow,
const char *zLabel
){
- int i;
- pView = sqlite3TreeViewPush(pView, moreToFollow);
if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
if( pList==0 ){
sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
}else{
+ int i;
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nExpr; i++){
int j = pList->a[i].u.x.iOrderByCol;
@@ -26247,6 +26649,15 @@ SQLITE_PRIVATE void sqlite3TreeViewExprList(
if( j ) sqlite3TreeViewPop(pView);
}
}
+}
+SQLITE_PRIVATE void sqlite3TreeViewExprList(
+ TreeView *pView,
+ const ExprList *pList,
+ u8 moreToFollow,
+ const char *zLabel
+){
+ pView = sqlite3TreeViewPush(pView, moreToFollow);
+ sqlite3TreeViewBareExprList(pView, pList, zLabel);
sqlite3TreeViewPop(pView);
}
@@ -26286,7 +26697,7 @@ static SQLITE_WSD struct sqlite3PrngType {
/*
** Return N random bytes.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){
+SQLITE_API void sqlite3_randomness(int N, void *pBuf){
unsigned char t;
unsigned char *zBuf = pBuf;
@@ -26362,7 +26773,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){
sqlite3_mutex_leave(mutex);
}
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
/*
** For testing purposes, we sometimes want to preserve the state of
** PRNG and restore the PRNG to its saved state at a later time, or
@@ -26387,7 +26798,7 @@ SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
sizeof(sqlite3Prng)
);
}
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
+#endif /* SQLITE_UNTESTABLE */
/************** End of random.c **********************************************/
/************** Begin file threads.c *****************************************/
@@ -27245,7 +27656,7 @@ SQLITE_PRIVATE void sqlite3Coverage(int x){
** Return whatever integer value the test callback returns, or return
** SQLITE_OK if no test callback is installed.
*/
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
return xCallback ? xCallback(iTest) : SQLITE_OK;
@@ -27489,7 +27900,7 @@ SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){
** case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){
+SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
@@ -27510,7 +27921,7 @@ SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){
}
return c;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
+SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
@@ -28343,13 +28754,11 @@ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
u32 x;
memcpy(&x,p,4);
return x;
-#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
- && defined(__GNUC__) && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
u32 x;
memcpy(&x,p,4);
return __builtin_bswap32(x);
-#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
- && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
u32 x;
memcpy(&x,p,4);
return _byteswap_ulong(x);
@@ -28361,12 +28770,10 @@ SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
#if SQLITE_BYTEORDER==4321
memcpy(p,&v,4);
-#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
- && defined(__GNUC__) && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
u32 x = __builtin_bswap32(v);
memcpy(p,&x,4);
-#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
- && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
u32 x = _byteswap_ulong(v);
memcpy(p,&x,4);
#else
@@ -28482,6 +28889,9 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
** overflow, leave *pA unchanged and return 1.
*/
SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
+#if GCC_VERSION>=5004000
+ return __builtin_add_overflow(*pA, iB, pA);
+#else
i64 iA = *pA;
testcase( iA==0 ); testcase( iA==1 );
testcase( iB==-1 ); testcase( iB==0 );
@@ -28496,8 +28906,12 @@ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
}
*pA += iB;
return 0;
+#endif
}
SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
+#if GCC_VERSION>=5004000
+ return __builtin_sub_overflow(*pA, iB, pA);
+#else
testcase( iB==SMALLEST_INT64+1 );
if( iB==SMALLEST_INT64 ){
testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
@@ -28507,38 +28921,28 @@ SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
}else{
return sqlite3AddInt64(pA, -iB);
}
+#endif
}
-#define TWOPOWER32 (((i64)1)<<32)
-#define TWOPOWER31 (((i64)1)<<31)
SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
+#if GCC_VERSION>=5004000
+ return __builtin_mul_overflow(*pA, iB, pA);
+#else
i64 iA = *pA;
- i64 iA1, iA0, iB1, iB0, r;
-
- iA1 = iA/TWOPOWER32;
- iA0 = iA % TWOPOWER32;
- iB1 = iB/TWOPOWER32;
- iB0 = iB % TWOPOWER32;
- if( iA1==0 ){
- if( iB1==0 ){
- *pA *= iB;
- return 0;
- }
- r = iA0*iB1;
- }else if( iB1==0 ){
- r = iA1*iB0;
- }else{
- /* If both iA1 and iB1 are non-zero, overflow will result */
- return 1;
- }
- testcase( r==(-TWOPOWER31)-1 );
- testcase( r==(-TWOPOWER31) );
- testcase( r==TWOPOWER31 );
- testcase( r==TWOPOWER31-1 );
- if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
- r *= TWOPOWER32;
- if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
- *pA = r;
+ if( iB>0 ){
+ if( iA>LARGEST_INT64/iB ) return 1;
+ if( iA<SMALLEST_INT64/iB ) return 1;
+ }else if( iB<0 ){
+ if( iA>0 ){
+ if( iB<SMALLEST_INT64/iA ) return 1;
+ }else if( iA<0 ){
+ if( iB==SMALLEST_INT64 ) return 1;
+ if( iA==SMALLEST_INT64 ) return 1;
+ if( -iA>LARGEST_INT64/-iB ) return 1;
+ }
+ }
+ *pA = iA*iB;
return 0;
+#endif
}
/*
@@ -28672,6 +29076,109 @@ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
}
#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
+/*
+** Add a new name/number pair to a VList. This might require that the
+** VList object be reallocated, so return the new VList. If an OOM
+** error occurs, the original VList returned and the
+** db->mallocFailed flag is set.
+**
+** A VList is really just an array of integers. To destroy a VList,
+** simply pass it to sqlite3DbFree().
+**
+** The first integer is the number of integers allocated for the whole
+** VList. The second integer is the number of integers actually used.
+** Each name/number pair is encoded by subsequent groups of 3 or more
+** integers.
+**
+** Each name/number pair starts with two integers which are the numeric
+** value for the pair and the size of the name/number pair, respectively.
+** The text name overlays one or more following integers. The text name
+** is always zero-terminated.
+**
+** Conceptually:
+**
+** struct VList {
+** int nAlloc; // Number of allocated slots
+** int nUsed; // Number of used slots
+** struct VListEntry {
+** int iValue; // Value for this entry
+** int nSlot; // Slots used by this entry
+** // ... variable name goes here
+** } a[0];
+** }
+**
+** During code generation, pointers to the variable names within the
+** VList are taken. When that happens, nAlloc is set to zero as an
+** indication that the VList may never again be enlarged, since the
+** accompanying realloc() would invalidate the pointers.
+*/
+SQLITE_PRIVATE VList *sqlite3VListAdd(
+ sqlite3 *db, /* The database connection used for malloc() */
+ VList *pIn, /* The input VList. Might be NULL */
+ const char *zName, /* Name of symbol to add */
+ int nName, /* Bytes of text in zName */
+ int iVal /* Value to associate with zName */
+){
+ int nInt; /* number of sizeof(int) objects needed for zName */
+ char *z; /* Pointer to where zName will be stored */
+ int i; /* Index in pIn[] where zName is stored */
+
+ nInt = nName/4 + 3;
+ assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */
+ if( pIn==0 || pIn[1]+nInt > pIn[0] ){
+ /* Enlarge the allocation */
+ int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
+ VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
+ if( pOut==0 ) return pIn;
+ if( pIn==0 ) pOut[1] = 2;
+ pIn = pOut;
+ pIn[0] = nAlloc;
+ }
+ i = pIn[1];
+ pIn[i] = iVal;
+ pIn[i+1] = nInt;
+ z = (char*)&pIn[i+2];
+ pIn[1] = i+nInt;
+ assert( pIn[1]<=pIn[0] );
+ memcpy(z, zName, nName);
+ z[nName] = 0;
+ return pIn;
+}
+
+/*
+** Return a pointer to the name of a variable in the given VList that
+** has the value iVal. Or return a NULL if there is no such variable in
+** the list
+*/
+SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){
+ int i, mx;
+ if( pIn==0 ) return 0;
+ mx = pIn[1];
+ i = 2;
+ do{
+ if( pIn[i]==iVal ) return (char*)&pIn[i+2];
+ i += pIn[i+1];
+ }while( i<mx );
+ return 0;
+}
+
+/*
+** Return the number of the variable named zName, if it is in VList.
+** or return 0 if there is no such variable.
+*/
+SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){
+ int i, mx;
+ if( pIn==0 ) return 0;
+ mx = pIn[1];
+ i = 2;
+ do{
+ const char *z = (const char*)&pIn[i+2];
+ if( strncmp(z,zName,nName)==0 && z[nName]==0 ) return pIn[i];
+ i += pIn[i+1];
+ }while( i<mx );
+ return 0;
+}
+
/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
@@ -28732,7 +29239,11 @@ static unsigned int strHash(const char *z){
unsigned int h = 0;
unsigned char c;
while( (c = (unsigned char)*z++)!=0 ){ /*OPTIMIZATION-IF-TRUE*/
- h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
+ /* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
+ ** 0x9e3779b1 is 2654435761 which is the closest prime number to
+ ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */
+ h += sqlite3UpperToLower[c];
+ h *= 0x9e3779b1;
}
return h;
}
@@ -28992,13 +29503,13 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 33 */ "NotExists" OpHelp("intkey=r[P3]"),
/* 34 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
/* 35 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 36 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"),
- /* 37 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"),
- /* 38 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"),
- /* 39 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"),
- /* 40 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"),
- /* 41 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"),
- /* 42 */ "Last" OpHelp(""),
+ /* 36 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 37 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 38 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 39 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 40 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
+ /* 41 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
+ /* 42 */ "ElseNotEq" OpHelp(""),
/* 43 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
/* 44 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
/* 45 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
@@ -29009,115 +29520,117 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 50 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
/* 51 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
/* 52 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 53 */ "SorterSort" OpHelp(""),
+ /* 53 */ "Last" OpHelp(""),
/* 54 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
- /* 55 */ "Sort" OpHelp(""),
- /* 56 */ "Rewind" OpHelp(""),
- /* 57 */ "IdxLE" OpHelp("key=r[P3@P4]"),
- /* 58 */ "IdxGT" OpHelp("key=r[P3@P4]"),
- /* 59 */ "IdxLT" OpHelp("key=r[P3@P4]"),
- /* 60 */ "IdxGE" OpHelp("key=r[P3@P4]"),
- /* 61 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
- /* 62 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
- /* 63 */ "Program" OpHelp(""),
- /* 64 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 65 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
- /* 66 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]-=P3, goto P2"),
- /* 67 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
- /* 68 */ "IncrVacuum" OpHelp(""),
- /* 69 */ "VNext" OpHelp(""),
- /* 70 */ "Init" OpHelp("Start at P2"),
- /* 71 */ "Return" OpHelp(""),
- /* 72 */ "EndCoroutine" OpHelp(""),
- /* 73 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
- /* 74 */ "Halt" OpHelp(""),
- /* 75 */ "Integer" OpHelp("r[P2]=P1"),
- /* 76 */ "Int64" OpHelp("r[P2]=P4"),
- /* 77 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
- /* 78 */ "Null" OpHelp("r[P2..P3]=NULL"),
- /* 79 */ "SoftNull" OpHelp("r[P1]=NULL"),
- /* 80 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 81 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
- /* 82 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 83 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
- /* 84 */ "SCopy" OpHelp("r[P2]=r[P1]"),
- /* 85 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
- /* 86 */ "ResultRow" OpHelp("output=r[P1@P2]"),
- /* 87 */ "CollSeq" OpHelp(""),
- /* 88 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 89 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 90 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
- /* 91 */ "RealAffinity" OpHelp(""),
- /* 92 */ "Cast" OpHelp("affinity(r[P1])"),
- /* 93 */ "Permutation" OpHelp(""),
- /* 94 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
- /* 95 */ "Column" OpHelp("r[P3]=PX"),
- /* 96 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 55 */ "IfSmaller" OpHelp(""),
+ /* 56 */ "SorterSort" OpHelp(""),
+ /* 57 */ "Sort" OpHelp(""),
+ /* 58 */ "Rewind" OpHelp(""),
+ /* 59 */ "IdxLE" OpHelp("key=r[P3@P4]"),
+ /* 60 */ "IdxGT" OpHelp("key=r[P3@P4]"),
+ /* 61 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 62 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 63 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 64 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 65 */ "Program" OpHelp(""),
+ /* 66 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 67 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 68 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+ /* 69 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
+ /* 70 */ "IncrVacuum" OpHelp(""),
+ /* 71 */ "VNext" OpHelp(""),
+ /* 72 */ "Init" OpHelp("Start at P2"),
+ /* 73 */ "Return" OpHelp(""),
+ /* 74 */ "EndCoroutine" OpHelp(""),
+ /* 75 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 76 */ "Halt" OpHelp(""),
+ /* 77 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 78 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 79 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 80 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 81 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 82 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 83 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 84 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 85 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 86 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 87 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
+ /* 88 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 89 */ "CollSeq" OpHelp(""),
+ /* 90 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 91 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 92 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 93 */ "RealAffinity" OpHelp(""),
+ /* 94 */ "Cast" OpHelp("affinity(r[P1])"),
+ /* 95 */ "Permutation" OpHelp(""),
+ /* 96 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
/* 97 */ "String8" OpHelp("r[P2]='P4'"),
- /* 98 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 99 */ "Count" OpHelp("r[P2]=count()"),
- /* 100 */ "ReadCookie" OpHelp(""),
- /* 101 */ "SetCookie" OpHelp(""),
- /* 102 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 103 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 104 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 105 */ "OpenAutoindex" OpHelp("nColumn=P2"),
- /* 106 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 107 */ "SorterOpen" OpHelp(""),
- /* 108 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
- /* 109 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
- /* 110 */ "Close" OpHelp(""),
- /* 111 */ "ColumnsUsed" OpHelp(""),
- /* 112 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
- /* 113 */ "NewRowid" OpHelp("r[P2]=rowid"),
- /* 114 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
- /* 115 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
- /* 116 */ "Delete" OpHelp(""),
- /* 117 */ "ResetCount" OpHelp(""),
- /* 118 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
- /* 119 */ "SorterData" OpHelp("r[P2]=data"),
- /* 120 */ "RowKey" OpHelp("r[P2]=key"),
- /* 121 */ "RowData" OpHelp("r[P2]=data"),
- /* 122 */ "Rowid" OpHelp("r[P2]=rowid"),
- /* 123 */ "NullRow" OpHelp(""),
- /* 124 */ "SorterInsert" OpHelp(""),
- /* 125 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 126 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
- /* 127 */ "Seek" OpHelp("Move P3 to P1.rowid"),
- /* 128 */ "IdxRowid" OpHelp("r[P2]=rowid"),
- /* 129 */ "Destroy" OpHelp(""),
- /* 130 */ "Clear" OpHelp(""),
- /* 131 */ "ResetSorter" OpHelp(""),
- /* 132 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
- /* 133 */ "Real" OpHelp("r[P2]=P4"),
- /* 134 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
- /* 135 */ "ParseSchema" OpHelp(""),
- /* 136 */ "LoadAnalysis" OpHelp(""),
- /* 137 */ "DropTable" OpHelp(""),
- /* 138 */ "DropIndex" OpHelp(""),
- /* 139 */ "DropTrigger" OpHelp(""),
- /* 140 */ "IntegrityCk" OpHelp(""),
- /* 141 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
- /* 142 */ "Param" OpHelp(""),
- /* 143 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
- /* 144 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
- /* 145 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
- /* 146 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 147 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
- /* 148 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
- /* 149 */ "Expire" OpHelp(""),
- /* 150 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 151 */ "VBegin" OpHelp(""),
- /* 152 */ "VCreate" OpHelp(""),
- /* 153 */ "VDestroy" OpHelp(""),
- /* 154 */ "VOpen" OpHelp(""),
- /* 155 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 156 */ "VRename" OpHelp(""),
- /* 157 */ "Pagecount" OpHelp(""),
- /* 158 */ "MaxPgcnt" OpHelp(""),
- /* 159 */ "CursorHint" OpHelp(""),
- /* 160 */ "Noop" OpHelp(""),
- /* 161 */ "Explain" OpHelp(""),
+ /* 98 */ "Column" OpHelp("r[P3]=PX"),
+ /* 99 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 100 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 101 */ "Count" OpHelp("r[P2]=count()"),
+ /* 102 */ "ReadCookie" OpHelp(""),
+ /* 103 */ "SetCookie" OpHelp(""),
+ /* 104 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
+ /* 105 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 106 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 107 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 108 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 109 */ "SorterOpen" OpHelp(""),
+ /* 110 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+ /* 111 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 112 */ "Close" OpHelp(""),
+ /* 113 */ "ColumnsUsed" OpHelp(""),
+ /* 114 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
+ /* 115 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 116 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 117 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 118 */ "Delete" OpHelp(""),
+ /* 119 */ "ResetCount" OpHelp(""),
+ /* 120 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 121 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 122 */ "RowData" OpHelp("r[P2]=data"),
+ /* 123 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 124 */ "NullRow" OpHelp(""),
+ /* 125 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 126 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 127 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 128 */ "Seek" OpHelp("Move P3 to P1.rowid"),
+ /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 130 */ "Destroy" OpHelp(""),
+ /* 131 */ "Clear" OpHelp(""),
+ /* 132 */ "Real" OpHelp("r[P2]=P4"),
+ /* 133 */ "ResetSorter" OpHelp(""),
+ /* 134 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
+ /* 135 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
+ /* 136 */ "SqlExec" OpHelp(""),
+ /* 137 */ "ParseSchema" OpHelp(""),
+ /* 138 */ "LoadAnalysis" OpHelp(""),
+ /* 139 */ "DropTable" OpHelp(""),
+ /* 140 */ "DropIndex" OpHelp(""),
+ /* 141 */ "DropTrigger" OpHelp(""),
+ /* 142 */ "IntegrityCk" OpHelp(""),
+ /* 143 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 144 */ "Param" OpHelp(""),
+ /* 145 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 146 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 147 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+ /* 148 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 149 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 150 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 151 */ "Expire" OpHelp(""),
+ /* 152 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 153 */ "VBegin" OpHelp(""),
+ /* 154 */ "VCreate" OpHelp(""),
+ /* 155 */ "VDestroy" OpHelp(""),
+ /* 156 */ "VOpen" OpHelp(""),
+ /* 157 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 158 */ "VRename" OpHelp(""),
+ /* 159 */ "Pagecount" OpHelp(""),
+ /* 160 */ "MaxPgcnt" OpHelp(""),
+ /* 161 */ "CursorHint" OpHelp(""),
+ /* 162 */ "Noop" OpHelp(""),
+ /* 163 */ "Explain" OpHelp(""),
};
return azName[i];
}
@@ -30386,7 +30899,14 @@ struct unixFileId {
#if OS_VXWORKS
struct vxworksFileId *pId; /* Unique file ID for vxworks. */
#else
- ino_t ino; /* Inode number */
+ /* We are told that some versions of Android contain a bug that
+ ** sizes ino_t at only 32-bits instead of 64-bits. (See
+ ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c)
+ ** To work around this, always allocate 64-bits for the inode number.
+ ** On small machines that only have 32-bit inodes, this wastes 4 bytes,
+ ** but that should not be a big deal. */
+ /* WAS: ino_t ino; */
+ u64 ino; /* Inode number */
#endif
};
@@ -30631,7 +31151,7 @@ static int findInodeInfo(
#if OS_VXWORKS
fileId.pId = pFile->pId;
#else
- fileId.ino = statbuf.st_ino;
+ fileId.ino = (u64)statbuf.st_ino;
#endif
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
@@ -30665,7 +31185,8 @@ static int fileHasMoved(unixFile *pFile){
#else
struct stat buf;
return pFile->pInode!=0 &&
- (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
+ (osStat(pFile->zPath, &buf)!=0
+ || (u64)buf.st_ino!=pFile->pInode->fileId.ino);
#endif
}
@@ -34837,7 +35358,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
unixEnterMutex();
pInode = inodeList;
while( pInode && (pInode->fileId.dev!=sStat.st_dev
- || pInode->fileId.ino!=sStat.st_ino) ){
+ || pInode->fileId.ino!=(u64)sStat.st_ino) ){
pInode = pInode->pNext;
}
if( pInode ){
@@ -34855,6 +35376,27 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
}
/*
+** Find the mode, uid and gid of file zFile.
+*/
+static int getFileMode(
+ const char *zFile, /* File name */
+ mode_t *pMode, /* OUT: Permissions of zFile */
+ uid_t *pUid, /* OUT: uid of zFile. */
+ gid_t *pGid /* OUT: gid of zFile. */
+){
+ struct stat sStat; /* Output of stat() on database file */
+ int rc = SQLITE_OK;
+ if( 0==osStat(zFile, &sStat) ){
+ *pMode = sStat.st_mode & 0777;
+ *pUid = sStat.st_uid;
+ *pGid = sStat.st_gid;
+ }else{
+ rc = SQLITE_IOERR_FSTAT;
+ }
+ return rc;
+}
+
+/*
** This function is called by unixOpen() to determine the unix permissions
** to create new files with. If no error occurs, then SQLITE_OK is returned
** and a value suitable for passing as the third argument to open(2) is
@@ -34889,7 +35431,6 @@ static int findCreateFileMode(
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
char zDb[MAX_PATHNAME+1]; /* Database file path */
int nDb; /* Number of valid bytes in zDb */
- struct stat sStat; /* Output of stat() on database file */
/* zPath is a path to a WAL or journal file. The following block derives
** the path to the associated database file from zPath. This block handles
@@ -34920,15 +35461,18 @@ static int findCreateFileMode(
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
- if( 0==osStat(zDb, &sStat) ){
- *pMode = sStat.st_mode & 0777;
- *pUid = sStat.st_uid;
- *pGid = sStat.st_gid;
- }else{
- rc = SQLITE_IOERR_FSTAT;
- }
+ rc = getFileMode(zDb, pMode, pUid, pGid);
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
*pMode = 0600;
+ }else if( flags & SQLITE_OPEN_URI ){
+ /* If this is a main database file and the file was opened using a URI
+ ** filename, check for the "modeof" parameter. If present, interpret
+ ** its value as a filename and try to copy the mode, uid and gid from
+ ** that file. */
+ const char *z = sqlite3_uri_parameter(zPath, "modeof");
+ if( z ){
+ rc = getFileMode(z, pMode, pUid, pGid);
+ }
}
return rc;
}
@@ -36809,7 +37353,7 @@ static int proxyClose(sqlite3_file *id) {
** necessarily been initialized when this routine is called, and so they
** should not be used.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
+SQLITE_API int sqlite3_os_init(void){
/*
** The following macro defines an initializer for an sqlite3_vfs object.
** The name of the VFS is NAME. The pAppData is a pointer to a pointer
@@ -36908,7 +37452,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
** to release dynamically allocated objects. But not on unix.
** This routine is a no-op for unix.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
+SQLITE_API int sqlite3_os_end(void){
return SQLITE_OK;
}
@@ -37468,7 +38012,34 @@ struct winVfsAppData {
******************************************************************************
*/
#ifndef SQLITE_WIN32_HEAP_CREATE
-# define SQLITE_WIN32_HEAP_CREATE (TRUE)
+# define SQLITE_WIN32_HEAP_CREATE (TRUE)
+#endif
+
+/*
+ * This is the maximum possible initial size of the Win32-specific heap, in
+ * bytes.
+ */
+#ifndef SQLITE_WIN32_HEAP_MAX_INIT_SIZE
+# define SQLITE_WIN32_HEAP_MAX_INIT_SIZE (4294967295U)
+#endif
+
+/*
+ * This is the extra space for the initial size of the Win32-specific heap,
+ * in bytes. This value may be zero.
+ */
+#ifndef SQLITE_WIN32_HEAP_INIT_EXTRA
+# define SQLITE_WIN32_HEAP_INIT_EXTRA (4194304)
+#endif
+
+/*
+ * Calculate the maximum legal cache size, in pages, based on the maximum
+ * possible initial heap size and the default page size, setting aside the
+ * needed extra space.
+ */
+#ifndef SQLITE_WIN32_MAX_CACHE_SIZE
+# define SQLITE_WIN32_MAX_CACHE_SIZE (((SQLITE_WIN32_HEAP_MAX_INIT_SIZE) - \
+ (SQLITE_WIN32_HEAP_INIT_EXTRA)) / \
+ (SQLITE_DEFAULT_PAGE_SIZE))
#endif
/*
@@ -37477,25 +38048,36 @@ struct winVfsAppData {
*/
#ifndef SQLITE_WIN32_CACHE_SIZE
# if SQLITE_DEFAULT_CACHE_SIZE>=0
-# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
+# define SQLITE_WIN32_CACHE_SIZE (SQLITE_DEFAULT_CACHE_SIZE)
# else
-# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
+# define SQLITE_WIN32_CACHE_SIZE (-(SQLITE_DEFAULT_CACHE_SIZE))
# endif
#endif
/*
+ * Make sure that the calculated cache size, in pages, cannot cause the
+ * initial size of the Win32-specific heap to exceed the maximum amount
+ * of memory that can be specified in the call to HeapCreate.
+ */
+#if SQLITE_WIN32_CACHE_SIZE>SQLITE_WIN32_MAX_CACHE_SIZE
+# undef SQLITE_WIN32_CACHE_SIZE
+# define SQLITE_WIN32_CACHE_SIZE (2000)
+#endif
+
+/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
-# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
- (SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
+# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_WIN32_CACHE_SIZE) * \
+ (SQLITE_DEFAULT_PAGE_SIZE) + \
+ (SQLITE_WIN32_HEAP_INIT_EXTRA))
#endif
/*
* The maximum size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_MAX_SIZE
-# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
+# define SQLITE_WIN32_HEAP_MAX_SIZE (0)
#endif
/*
@@ -37503,7 +38085,7 @@ struct winVfsAppData {
* zero for the default behavior.
*/
#ifndef SQLITE_WIN32_HEAP_FLAGS
-# define SQLITE_WIN32_HEAP_FLAGS (0)
+# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
@@ -38343,7 +38925,7 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
** "pnLargest" argument, if non-zero, will be used to return the size of the
** largest committed free block in the heap, in bytes.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
+SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
int rc = SQLITE_OK;
UINT nLargest = 0;
HANDLE hHeap;
@@ -38383,7 +38965,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
** be returned and no changes will be made to the Win32 native heap.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
+SQLITE_API int sqlite3_win32_reset_heap(){
int rc;
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */
@@ -38428,7 +39010,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
** (if available).
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
+SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
@@ -38474,7 +39056,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int n
static HANDLE sleepObj = NULL;
#endif
-SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
+SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
#if SQLITE_OS_WINRT
if ( sleepObj==NULL ){
sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
@@ -38523,7 +39105,7 @@ SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
** This function determines if the machine is running a version of Windows
** based on the NT kernel.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
+SQLITE_API int sqlite3_win32_is_nt(void){
#if SQLITE_OS_WINRT
/*
** NOTE: The WinRT sub-platform is always assumed to be based on the NT
@@ -38911,7 +39493,7 @@ static char *winUtf8ToMbcs(const char *zText, int useAnsi){
/*
** This is a public wrapper for the winUtf8ToUnicode() function.
*/
-SQLITE_API LPWSTR SQLITE_STDCALL sqlite3_win32_utf8_to_unicode(const char *zText){
+SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
@@ -38927,7 +39509,7 @@ SQLITE_API LPWSTR SQLITE_STDCALL sqlite3_win32_utf8_to_unicode(const char *zText
/*
** This is a public wrapper for the winUnicodeToUtf8() function.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
+SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zWideText ){
(void)SQLITE_MISUSE_BKPT;
@@ -38943,7 +39525,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText)
/*
** This is a public wrapper for the winMbcsToUtf8() function.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zText){
+SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
@@ -38959,7 +39541,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zText){
/*
** This is a public wrapper for the winMbcsToUtf8() function.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
+SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
@@ -38975,7 +39557,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8_v2(const char *zText,
/*
** This is a public wrapper for the winUtf8ToMbcs() function.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zText){
+SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
@@ -38991,7 +39573,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zText){
/*
** This is a public wrapper for the winUtf8ToMbcs() function.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
+SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !zText ){
(void)SQLITE_MISUSE_BKPT;
@@ -39011,7 +39593,7 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs_v2(const char *zText,
** argument is the name of the directory to use. The return value will be
** SQLITE_OK if successful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
+SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
char **ppDirectory = 0;
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
@@ -40604,6 +41186,12 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
+ case SQLITE_FCNTL_WIN32_GET_HANDLE: {
+ LPHANDLE phFile = (LPHANDLE)pArg;
+ *phFile = pFile->h;
+ OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+ return SQLITE_OK;
+ }
#ifdef SQLITE_TEST
case SQLITE_FCNTL_WIN32_SET_HANDLE: {
LPHANDLE phFile = (LPHANDLE)pArg;
@@ -42929,7 +43517,7 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
/*
** Initialize and deinitialize the operating system interface.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
+SQLITE_API int sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
@@ -43060,7 +43648,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
return SQLITE_OK;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
+SQLITE_API int sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj!=NULL ){
osCloseHandle(sleepObj);
@@ -43369,7 +43957,7 @@ SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
return p->iSize;
}
-#ifndef SQLITE_OMIT_BUILTIN_TEST
+#ifndef SQLITE_UNTESTABLE
/*
** Let V[] be an array of unsigned characters sufficient to hold
** up to N bits. Let I be an integer between 0 and N. 0<=I<N.
@@ -43484,7 +44072,7 @@ bitvec_end:
sqlite3BitvecDestroy(pBitvec);
return rc;
}
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
+#endif /* SQLITE_UNTESTABLE */
/************** End of bitvec.c **********************************************/
/************** Begin file pcache.c ******************************************/
@@ -43594,11 +44182,11 @@ struct PCache {
**
** assert( sqlite3PcachePageSanity(pPg) );
*/
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){
PCache *pCache;
assert( pPg!=0 );
- assert( pPg->pgno>0 ); /* Page number is 1 or more */
+ assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */
pCache = pPg->pCache;
assert( pCache!=0 ); /* Every page has an associated PCache */
if( pPg->flags & PGHDR_CLEAN ){
@@ -43774,6 +44362,12 @@ SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
** has already been allocated and is passed in as the p pointer.
** The caller discovers how much space needs to be allocated by
** calling sqlite3PcacheSize().
+**
+** szExtra is some extra space allocated for each page. The first
+** 8 bytes of the extra space will be zeroed as the page is allocated,
+** but remaining content will be uninitialized. Though it is opaque
+** to this module, the extra space really ends up being the MemPage
+** structure in the pager.
*/
SQLITE_PRIVATE int sqlite3PcacheOpen(
int szPage, /* Size of every page */
@@ -43786,6 +44380,7 @@ SQLITE_PRIVATE int sqlite3PcacheOpen(
memset(p, 0, sizeof(PCache));
p->szPage = 1;
p->szExtra = szExtra;
+ assert( szExtra>=8 ); /* First 8 bytes will be zeroed */
p->bPurgeable = bPurgeable;
p->eCreate = 2;
p->xStress = xStress;
@@ -43855,7 +44450,6 @@ SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
assert( pCache!=0 );
assert( pCache->pCache!=0 );
assert( createFlag==3 || createFlag==0 );
- assert( pgno>0 );
assert( pCache->eCreate==((pCache->bPurgeable && pCache->pDirty) ? 1 : 2) );
/* eCreate defines what to do if the page does not exist.
@@ -43951,11 +44545,11 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
assert( pPage!=0 );
pPgHdr = (PgHdr*)pPage->pExtra;
assert( pPgHdr->pPage==0 );
- memset(pPgHdr, 0, sizeof(PgHdr));
+ memset(&pPgHdr->pDirty, 0, sizeof(PgHdr) - offsetof(PgHdr,pDirty));
pPgHdr->pPage = pPage;
pPgHdr->pData = pPage->pBuf;
pPgHdr->pExtra = (void *)&pPgHdr[1];
- memset(pPgHdr->pExtra, 0, pCache->szExtra);
+ memset(pPgHdr->pExtra, 0, 8);
pPgHdr->pCache = pCache;
pPgHdr->pgno = pgno;
pPgHdr->flags = PGHDR_CLEAN;
@@ -44645,7 +45239,7 @@ static int pcache1InitBulk(PCache1 *pCache){
szBulk = -1024 * (i64)pcache1.nInitPage;
}
if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){
- szBulk = pCache->szAlloc*pCache->nMax;
+ szBulk = pCache->szAlloc*(i64)pCache->nMax;
}
zBulk = pCache->pBulk = sqlite3Malloc( szBulk );
sqlite3EndBenignMalloc();
@@ -46179,7 +46773,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
#ifdef SQLITE_OMIT_WAL
# define sqlite3WalOpen(x,y,z) 0
# define sqlite3WalLimit(x,y)
-# define sqlite3WalClose(w,x,y,z) 0
+# define sqlite3WalClose(v,w,x,y,z) 0
# define sqlite3WalBeginReadTransaction(y,z) 0
# define sqlite3WalEndReadTransaction(z)
# define sqlite3WalDbsize(y) 0
@@ -46189,7 +46783,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
# define sqlite3WalSavepoint(y,z)
# define sqlite3WalSavepointUndo(y,z) 0
# define sqlite3WalFrames(u,v,w,x,y,z) 0
-# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
+# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0
# define sqlite3WalCallback(z) 0
# define sqlite3WalExclusiveMode(y,z) 0
# define sqlite3WalHeapMemory(z) 0
@@ -46207,7 +46801,7 @@ typedef struct Wal Wal;
/* Open and close a connection to a write-ahead log. */
SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
-SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
+SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *);
/* Set the limiting size of a WAL file. */
SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
@@ -46250,6 +46844,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
/* Copy pages from the log to the database file */
SQLITE_PRIVATE int sqlite3WalCheckpoint(
Wal *pWal, /* Write-ahead log connection */
+ sqlite3 *db, /* Check this handle's interrupt flag */
int eMode, /* One of PASSIVE, FULL and RESTART */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
@@ -46281,6 +46876,7 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
#ifdef SQLITE_ENABLE_SNAPSHOT
SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot);
SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot);
+SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal);
#endif
#ifdef SQLITE_ENABLE_ZIPVFS
@@ -46970,6 +47566,7 @@ struct Pager {
int nRead; /* Database pages read */
#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 */
@@ -47090,13 +47687,20 @@ static const unsigned char aJournalMagic[] = {
#define isOpen(pFd) ((pFd)->pMethods!=0)
/*
-** Return true if this pager uses a write-ahead log instead of the usual
-** rollback journal. Otherwise false.
+** Return true if this pager uses a write-ahead log to read page pgno.
+** Return false if the pager reads pgno directly from the database.
*/
-#ifndef SQLITE_OMIT_WAL
-static int pagerUseWal(Pager *pPager){
- return (pPager->pWal!=0);
+#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
+SQLITE_PRIVATE int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
+ u32 iRead = 0;
+ int rc;
+ if( pPager->pWal==0 ) return 0;
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
+ return rc || iRead;
}
+#endif
+#ifndef SQLITE_OMIT_WAL
+# define pagerUseWal(x) ((x)->pWal!=0)
#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
@@ -47295,6 +47899,33 @@ static char *print_pager_state(Pager *p){
}
#endif
+/* Forward references to the various page getters */
+static int getPageNormal(Pager*,Pgno,DbPage**,int);
+static int getPageError(Pager*,Pgno,DbPage**,int);
+#if SQLITE_MAX_MMAP_SIZE>0
+static int getPageMMap(Pager*,Pgno,DbPage**,int);
+#endif
+
+/*
+** Set the Pager.xGet method for the appropriate routine used to fetch
+** content from the pager.
+*/
+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
+ ){
+ pPager->xGet = getPageMMap;
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+ }else{
+ pPager->xGet = getPageNormal;
+ }
+}
+
/*
** Return true if it is necessary to write page *pPg into the sub-journal.
** A page needs to be written into the sub-journal if there exists one
@@ -48109,6 +48740,7 @@ static void pager_unlock(Pager *pPager){
}
if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
pPager->errCode = SQLITE_OK;
+ setGetterMethod(pPager);
}
pPager->journalOff = 0;
@@ -48146,6 +48778,7 @@ static int pager_error(Pager *pPager, int rc){
if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
pPager->errCode = rc;
pPager->eState = PAGER_ERROR;
+ setGetterMethod(pPager);
}
return rc;
}
@@ -48314,7 +48947,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
pPager->pInJournal = 0;
pPager->nRec = 0;
if( rc==SQLITE_OK ){
- if( pagerFlushOnCommit(pPager, bCommit) ){
+ if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){
sqlite3PcacheCleanAll(pPager->pPCache);
}else{
sqlite3PcacheClearWritable(pPager->pPCache);
@@ -49713,6 +50346,7 @@ static void pagerFixMaplimit(Pager *pPager){
sqlite3_int64 sz;
sz = pPager->szMmap;
pPager->bUseFetch = (sz>0);
+ setGetterMethod(pPager);
sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
}
#endif
@@ -50209,6 +50843,7 @@ static int pagerSyncHotJournal(Pager *pPager){
return rc;
}
+#if SQLITE_MAX_MMAP_SIZE>0
/*
** Obtain a reference to a memory mapped page object for page number pgno.
** The new object will use the pointer pData, obtained from xFetch().
@@ -50231,7 +50866,8 @@ static int pagerAcquireMapPage(
*ppPage = p = pPager->pMmapFreelist;
pPager->pMmapFreelist = p->pDirty;
p->pDirty = 0;
- memset(p->pExtra, 0, pPager->nExtra);
+ assert( pPager->nExtra>=8 );
+ memset(p->pExtra, 0, 8);
}else{
*ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
if( p==0 ){
@@ -50256,6 +50892,7 @@ static int pagerAcquireMapPage(
return SQLITE_OK;
}
+#endif
/*
** Release a reference to page pPg. pPg must have been returned by an
@@ -50298,9 +50935,10 @@ static void pagerFreeMapHdrs(Pager *pPager){
** a hot journal may be left in the filesystem but no error is returned
** to the caller.
*/
-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
+SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
u8 *pTmp = (u8 *)pPager->pTmpSpace;
+ assert( db || pagerUseWal(pPager)==0 );
assert( assert_pager_state(pPager) );
disable_simulated_io_errors();
sqlite3BeginBenignMalloc();
@@ -50308,7 +50946,10 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
/* pPager->errCode = 0; */
pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
- sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
+ assert( db || pPager->pWal==0 );
+ sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize,
+ (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp)
+ );
pPager->pWal = 0;
#endif
pager_reset(pPager);
@@ -50827,7 +51468,9 @@ SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){
**
** The nExtra parameter specifies the number of bytes of space allocated
** along with each page reference. This space is available to the user
-** via the sqlite3PagerGetExtra() API.
+** via the sqlite3PagerGetExtra() API. When a new page is allocated, the
+** first 8 bytes of this space are zeroed but the remainder is uninitialized.
+** (The extra space is used by btree as the MemPage object.)
**
** The flags argument is used to specify properties that affect the
** operation of the pager. It should be passed some bitwise combination
@@ -51057,8 +51700,8 @@ act_like_temp_file:
/* Initialize the PCache object. */
if( rc==SQLITE_OK ){
- assert( nExtra<1000 );
nExtra = ROUND8(nExtra);
+ assert( nExtra>=8 && nExtra<1000 );
rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
!memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
}
@@ -51123,6 +51766,7 @@ act_like_temp_file:
/* pPager->xBusyHandler = 0; */
/* pPager->pBusyHandlerArg = 0; */
pPager->xReiniter = xReinit;
+ setGetterMethod(pPager);
/* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
/* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
@@ -51536,10 +52180,17 @@ static void pagerUnlockIfUnused(Pager *pPager){
}
/*
-** Acquire a reference to page number pgno in pager pPager (a page
-** reference has type DbPage*). If the requested reference is
+** The page getter methods each try to acquire a reference to a
+** page with page number pgno. If the requested reference is
** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
**
+** There are different implementations of the getter method depending
+** on the current state of the pager.
+**
+** getPageNormal() -- The normal getter
+** getPageError() -- Used if the pager is in an error state
+** getPageMmap() -- Used if memory-mapped I/O is enabled
+**
** If the requested page is already in the cache, it is returned.
** Otherwise, a new page object is allocated and populated with data
** read from the database file. In some cases, the pcache module may
@@ -51551,14 +52202,14 @@ static void pagerUnlockIfUnused(Pager *pPager){
** already in the cache when this function is called, then the extra
** data is left as it was when the page object was last used.
**
-** If the database image is smaller than the requested page or if a
-** non-zero value is passed as the noContent parameter and the
+** If the database image is smaller than the requested page or if
+** the flags parameter contains the PAGER_GET_NOCONTENT bit and the
** requested page is not already stored in the cache, then no
** actual disk read occurs. In this case the memory image of the
** page is initialized to all zeros.
**
-** If noContent is true, it means that we do not care about the contents
-** of the page. This occurs in two scenarios:
+** If PAGER_GET_NOCONTENT is true, it means that we do not care about
+** the contents of the page. This occurs in two scenarios:
**
** a) When reading a free-list leaf page from the database, and
**
@@ -51566,8 +52217,8 @@ static void pagerUnlockIfUnused(Pager *pPager){
** a new page into the cache to be filled with the data read
** from the savepoint journal.
**
-** If noContent is true, then the data returned is zeroed instead of
-** being read from the database. Additionally, the bits corresponding
+** If PAGER_GET_NOCONTENT is true, then the data returned is zeroed instead
+** of being read from the database. Additionally, the bits corresponding
** to pgno in Pager.pInJournal (bitvec of pages already written to the
** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
** savepoints are set. This means if the page is made writable at any
@@ -51585,106 +52236,39 @@ static void pagerUnlockIfUnused(Pager *pPager){
** Since Lookup() never goes to disk, it never has to deal with locks
** or journal files.
*/
-SQLITE_PRIVATE int sqlite3PagerGet(
+static int getPageNormal(
Pager *pPager, /* The pager open on the database file */
Pgno pgno, /* Page number to fetch */
DbPage **ppPage, /* Write a pointer to the page here */
int flags /* PAGER_GET_XXX flags */
){
int rc = SQLITE_OK;
- PgHdr *pPg = 0;
- u32 iFrame = 0; /* Frame to read from WAL file */
- const int noContent = (flags & PAGER_GET_NOCONTENT);
-
- /* It is acceptable to use a read-only (mmap) page for any page except
- ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
- ** flag was specified by the caller. And so long as the db is not a
- ** temporary or in-memory database. */
- const int bMmapOk = (pgno>1 && USEFETCH(pPager)
- && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
-#ifdef SQLITE_HAS_CODEC
- && pPager->xCodec==0
-#endif
- );
+ PgHdr *pPg;
+ u8 noContent; /* True if PAGER_GET_NOCONTENT is set */
+ sqlite3_pcache_page *pBase;
- /* Optimization note: Adding the "pgno<=1" term before "pgno==0" here
- ** allows the compiler optimizer to reuse the results of the "pgno>1"
- ** test in the previous statement, and avoid testing pgno==0 in the
- ** common case where pgno is large. */
- if( pgno<=1 && pgno==0 ){
- return SQLITE_CORRUPT_BKPT;
- }
+ assert( pPager->errCode==SQLITE_OK );
assert( pPager->eState>=PAGER_READER );
assert( assert_pager_state(pPager) );
- assert( noContent==0 || bMmapOk==0 );
-
assert( pPager->hasHeldSharedLock==1 );
- /* If the pager is in the error state, return an error immediately.
- ** Otherwise, request the page from the PCache layer. */
- if( pPager->errCode!=SQLITE_OK ){
- rc = pPager->errCode;
- }else{
- if( bMmapOk && pagerUseWal(pPager) ){
- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
- if( rc!=SQLITE_OK ) goto pager_acquire_err;
- }
-
- if( bMmapOk && iFrame==0 ){
- void *pData = 0;
-
- rc = sqlite3OsFetch(pPager->fd,
- (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
- );
-
- if( rc==SQLITE_OK && pData ){
- if( pPager->eState>PAGER_READER || pPager->tempFile ){
- pPg = sqlite3PagerLookup(pPager, pgno);
- }
- if( pPg==0 ){
- rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
- }else{
- sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
- }
- if( pPg ){
- assert( rc==SQLITE_OK );
- *ppPage = pPg;
- return SQLITE_OK;
- }
- }
- if( rc!=SQLITE_OK ){
- goto pager_acquire_err;
- }
- }
-
- {
- sqlite3_pcache_page *pBase;
- pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
- if( pBase==0 ){
- rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
- if( rc!=SQLITE_OK ) goto pager_acquire_err;
- if( pBase==0 ){
- pPg = *ppPage = 0;
- rc = SQLITE_NOMEM_BKPT;
- goto pager_acquire_err;
- }
- }
- pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
- assert( pPg!=0 );
- }
- }
-
- if( rc!=SQLITE_OK ){
- /* Either the call to sqlite3PcacheFetch() returned an error or the
- ** pager was already in the error-state when this function was called.
- ** Set pPg to 0 and jump to the exception handler. */
+ if( pgno==0 ) return SQLITE_CORRUPT_BKPT;
+ pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
+ if( pBase==0 ){
pPg = 0;
- goto pager_acquire_err;
+ rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
+ if( rc!=SQLITE_OK ) goto pager_acquire_err;
+ if( pBase==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ goto pager_acquire_err;
+ }
}
+ pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
assert( pPg==(*ppPage) );
assert( pPg->pgno==pgno );
assert( pPg->pPager==pPager || pPg->pPager==0 );
+ noContent = (flags & PAGER_GET_NOCONTENT)!=0;
if( pPg->pPager && !noContent ){
/* In this case the pcache already contains an initialized copy of
** the page. Return without further ado. */
@@ -51694,17 +52278,18 @@ SQLITE_PRIVATE int sqlite3PagerGet(
}else{
/* The pager cache has created a new page. Its content needs to
- ** be initialized. */
-
- pPg->pPager = pPager;
-
- /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
- ** number greater than this, or the unused locking-page, is requested. */
+ ** be initialized. But first some error checks:
+ **
+ ** (1) The maximum page number is 2^31
+ ** (2) Never try to fetch the locking page
+ */
if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
rc = SQLITE_CORRUPT_BKPT;
goto pager_acquire_err;
}
+ pPg->pPager = pPager;
+
assert( !isOpen(pPager->fd) || !MEMDB );
if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
if( pgno>pPager->mxPgno ){
@@ -51730,7 +52315,8 @@ SQLITE_PRIVATE int sqlite3PagerGet(
memset(pPg->pData, 0, pPager->pageSize);
IOTRACE(("ZERO %p %d\n", pPager, pgno));
}else{
- if( pagerUseWal(pPager) && bMmapOk==0 ){
+ u32 iFrame = 0; /* Frame to read from WAL file */
+ if( pagerUseWal(pPager) ){
rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
if( rc!=SQLITE_OK ) goto pager_acquire_err;
}
@@ -51743,7 +52329,6 @@ SQLITE_PRIVATE int sqlite3PagerGet(
}
pager_set_pagehash(pPg);
}
-
return SQLITE_OK;
pager_acquire_err:
@@ -51752,11 +52337,109 @@ pager_acquire_err:
sqlite3PcacheDrop(pPg);
}
pagerUnlockIfUnused(pPager);
-
*ppPage = 0;
return rc;
}
+#if SQLITE_MAX_MMAP_SIZE>0
+/* The page getter for when memory-mapped I/O is enabled */
+static int getPageMMap(
+ Pager *pPager, /* The pager open on the database file */
+ Pgno pgno, /* Page number to fetch */
+ DbPage **ppPage, /* Write a pointer to the page here */
+ int flags /* PAGER_GET_XXX flags */
+){
+ int rc = SQLITE_OK;
+ PgHdr *pPg = 0;
+ u32 iFrame = 0; /* Frame to read from WAL file */
+
+ /* It is acceptable to use a read-only (mmap) page for any page except
+ ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
+ ** flag was specified by the caller. And so long as the db is not a
+ ** temporary or in-memory database. */
+ const int bMmapOk = (pgno>1
+ && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
+ );
+
+ 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"
+ ** test in the previous statement, and avoid testing pgno==0 in the
+ ** common case where pgno is large. */
+ if( pgno<=1 && pgno==0 ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ assert( pPager->eState>=PAGER_READER );
+ assert( assert_pager_state(pPager) );
+ assert( pPager->hasHeldSharedLock==1 );
+ assert( pPager->errCode==SQLITE_OK );
+
+ if( bMmapOk && pagerUseWal(pPager) ){
+ rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+ if( rc!=SQLITE_OK ){
+ *ppPage = 0;
+ return rc;
+ }
+ }
+ if( bMmapOk && iFrame==0 ){
+ void *pData = 0;
+ rc = sqlite3OsFetch(pPager->fd,
+ (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
+ );
+ if( rc==SQLITE_OK && pData ){
+ if( pPager->eState>PAGER_READER || pPager->tempFile ){
+ pPg = sqlite3PagerLookup(pPager, pgno);
+ }
+ if( pPg==0 ){
+ rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
+ }else{
+ sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
+ }
+ if( pPg ){
+ assert( rc==SQLITE_OK );
+ *ppPage = pPg;
+ return SQLITE_OK;
+ }
+ }
+ if( rc!=SQLITE_OK ){
+ *ppPage = 0;
+ return rc;
+ }
+ }
+ return getPageNormal(pPager, pgno, ppPage, flags);
+}
+#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+
+/* The page getter method for when the pager is an error state */
+static int getPageError(
+ Pager *pPager, /* The pager open on the database file */
+ Pgno pgno, /* Page number to fetch */
+ DbPage **ppPage, /* Write a pointer to the page here */
+ int flags /* PAGER_GET_XXX flags */
+){
+ UNUSED_PARAMETER(pgno);
+ UNUSED_PARAMETER(flags);
+ assert( pPager->errCode!=SQLITE_OK );
+ *ppPage = 0;
+ return pPager->errCode;
+}
+
+
+/* Dispatch all page fetch requests to the appropriate getter method.
+*/
+SQLITE_PRIVATE int sqlite3PagerGet(
+ Pager *pPager, /* The pager open on the database file */
+ Pgno pgno, /* Page number to fetch */
+ DbPage **ppPage, /* Write a pointer to the page here */
+ int flags /* PAGER_GET_XXX flags */
+){
+ return pPager->xGet(pPager, pgno, ppPage, flags);
+}
+
/*
** Acquire a page if it is already in the in-memory cache. Do
** not read the page from disk. Return a pointer to the page,
@@ -52230,11 +52913,11 @@ SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
assert( (pPg->flags & PGHDR_MMAP)==0 );
assert( pPager->eState>=PAGER_WRITER_LOCKED );
assert( assert_pager_state(pPager) );
- if( pPager->errCode ){
- return pPager->errCode;
- }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){
+ if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){
if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
return SQLITE_OK;
+ }else if( pPager->errCode ){
+ return pPager->errCode;
}else if( pPager->sectorSize > (u32)pPager->pageSize ){
assert( pPager->tempFile==0 );
return pagerWriteLargeSector(pPg);
@@ -52729,6 +53412,7 @@ SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
*/
pPager->errCode = SQLITE_ABORT;
pPager->eState = PAGER_ERROR;
+ setGetterMethod(pPager);
return rc;
}
}else{
@@ -52933,7 +53617,11 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
** savepoint. If no errors occur, SQLITE_OK is returned.
*/
SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
- int rc = pPager->errCode; /* Return code */
+ int rc = pPager->errCode;
+
+#ifdef SQLITE_ENABLE_ZIPVFS
+ if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK;
+#endif
assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
@@ -52974,6 +53662,21 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
rc = pagerPlaybackSavepoint(pPager, pSavepoint);
assert(rc!=SQLITE_DONE);
}
+
+#ifdef SQLITE_ENABLE_ZIPVFS
+ /* If the cache has been modified but the savepoint cannot be rolled
+ ** back journal_mode=off, put the pager in the error state. This way,
+ ** if the VFS used by this pager includes ZipVFS, the entire transaction
+ ** can be rolled back at the ZipVFS level. */
+ else if(
+ pPager->journalMode==PAGER_JOURNALMODE_OFF
+ && pPager->eState>=PAGER_WRITER_CACHEMOD
+ ){
+ pPager->errCode = SQLITE_ABORT;
+ pPager->eState = PAGER_ERROR;
+ setGetterMethod(pPager);
+ }
+#endif
}
return rc;
@@ -53044,6 +53747,7 @@ SQLITE_PRIVATE void sqlite3PagerSetCodec(
pPager->xCodecSizeChng = xCodecSizeChng;
pPager->xCodecFree = xCodecFree;
pPager->pCodec = pCodec;
+ setGetterMethod(pPager);
pagerReportSize(pPager);
}
SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
@@ -53453,10 +54157,16 @@ SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
**
** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
*/
-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
+SQLITE_PRIVATE int sqlite3PagerCheckpoint(
+ Pager *pPager, /* Checkpoint on this pager */
+ sqlite3 *db, /* Db handle used to check for interrupts */
+ int eMode, /* Type of checkpoint */
+ int *pnLog, /* OUT: Final number of frames in log */
+ int *pnCkpt /* OUT: Final number of checkpointed frames */
+){
int rc = SQLITE_OK;
if( pPager->pWal ){
- rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
+ rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
pPager->pBusyHandlerArg,
pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
@@ -53588,7 +54298,7 @@ SQLITE_PRIVATE int sqlite3PagerOpenWal(
** error (SQLITE_BUSY) is returned and the log connection is not closed.
** If successful, the EXCLUSIVE lock is not released before returning.
*/
-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
+SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
int rc = SQLITE_OK;
assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
@@ -53616,7 +54326,7 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
if( rc==SQLITE_OK && pPager->pWal ){
rc = pagerExclusiveLock(pPager);
if( rc==SQLITE_OK ){
- rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
+ rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags,
pPager->pageSize, (u8*)pPager->pTmpSpace);
pPager->pWal = 0;
pagerFixMaplimit(pPager);
@@ -53653,6 +54363,20 @@ SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSn
}
return rc;
}
+
+/*
+** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this
+** is not a WAL database, return an error.
+*/
+SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){
+ int rc;
+ if( pPager->pWal ){
+ rc = sqlite3WalSnapshotRecover(pPager->pWal);
+ }else{
+ rc = SQLITE_ERROR;
+ }
+ return rc;
+}
#endif /* SQLITE_ENABLE_SNAPSHOT */
#endif /* !SQLITE_OMIT_WAL */
@@ -55399,6 +56123,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){
*/
static int walCheckpoint(
Wal *pWal, /* Wal connection */
+ sqlite3 *db, /* Check for interrupts on this handle */
int eMode, /* One of PASSIVE, FULL or RESTART */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
@@ -55493,6 +56218,10 @@ static int walCheckpoint(
while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
i64 iOffset;
assert( walFramePgno(pWal, iFrame)==iDbpage );
+ if( db->u1.isInterrupted ){
+ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
+ break;
+ }
if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
continue;
}
@@ -55597,6 +56326,7 @@ static void walLimitSize(Wal *pWal, i64 nMax){
*/
SQLITE_PRIVATE int sqlite3WalClose(
Wal *pWal, /* Wal to close */
+ sqlite3 *db, /* For interrupt flag */
int sync_flags, /* Flags to pass to OsSync() (or 0) */
int nBuf,
u8 *zBuf /* Buffer of at least nBuf bytes */
@@ -55613,13 +56343,14 @@ SQLITE_PRIVATE int sqlite3WalClose(
**
** The EXCLUSIVE lock is not released before returning.
*/
- rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
- if( rc==SQLITE_OK ){
+ if( zBuf!=0
+ && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE))
+ ){
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
}
- rc = sqlite3WalCheckpoint(
- pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
+ rc = sqlite3WalCheckpoint(pWal, db,
+ SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
);
if( rc==SQLITE_OK ){
int bPersist = -1;
@@ -56048,6 +56779,84 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
return rc;
}
+#ifdef SQLITE_ENABLE_SNAPSHOT
+/*
+** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted
+** variable so that older snapshots can be accessed. To do this, loop
+** through all wal frames from nBackfillAttempted to (nBackfill+1),
+** comparing their content to the corresponding page with the database
+** file, if any. Set nBackfillAttempted to the frame number of the
+** first frame for which the wal file content matches the db file.
+**
+** This is only really safe if the file-system is such that any page
+** writes made by earlier checkpointers were atomic operations, which
+** is not always true. It is also possible that nBackfillAttempted
+** may be left set to a value larger than expected, if a wal frame
+** contains content that duplicate of an earlier version of the same
+** page.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code if an
+** error occurs. It is not an error if nBackfillAttempted cannot be
+** decreased at all.
+*/
+SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){
+ int rc;
+
+ assert( pWal->readLock>=0 );
+ rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
+ if( rc==SQLITE_OK ){
+ volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+ int szPage = (int)pWal->szPage;
+ i64 szDb; /* Size of db file in bytes */
+
+ rc = sqlite3OsFileSize(pWal->pDbFd, &szDb);
+ if( rc==SQLITE_OK ){
+ void *pBuf1 = sqlite3_malloc(szPage);
+ void *pBuf2 = sqlite3_malloc(szPage);
+ if( pBuf1==0 || pBuf2==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ u32 i = pInfo->nBackfillAttempted;
+ for(i=pInfo->nBackfillAttempted; i>pInfo->nBackfill; i--){
+ volatile ht_slot *dummy;
+ volatile u32 *aPgno; /* Array of page numbers */
+ u32 iZero; /* Frame corresponding to aPgno[0] */
+ u32 pgno; /* Page number in db file */
+ i64 iDbOff; /* Offset of db file entry */
+ i64 iWalOff; /* Offset of wal file entry */
+
+ rc = walHashGet(pWal, walFramePage(i), &dummy, &aPgno, &iZero);
+ if( rc!=SQLITE_OK ) break;
+ pgno = aPgno[i-iZero];
+ iDbOff = (i64)(pgno-1) * szPage;
+
+ if( iDbOff+szPage<=szDb ){
+ iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
+ rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
+
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff);
+ }
+
+ if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){
+ break;
+ }
+ }
+
+ pInfo->nBackfillAttempted = i-1;
+ }
+ }
+
+ sqlite3_free(pBuf1);
+ sqlite3_free(pBuf2);
+ }
+ walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
+ }
+
+ return rc;
+}
+#endif /* SQLITE_ENABLE_SNAPSHOT */
+
/*
** Begin a read transaction on the database.
**
@@ -56110,7 +56919,11 @@ SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
** 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. */
+ ** 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 ){
@@ -56867,6 +57680,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
*/
SQLITE_PRIVATE int sqlite3WalCheckpoint(
Wal *pWal, /* Wal connection */
+ sqlite3 *db, /* Check this handle's interrupt flag */
int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */
int (*xBusy)(void*), /* Function to call when busy */
void *pBusyArg, /* Context argument for xBusyHandler */
@@ -56941,7 +57755,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
rc = SQLITE_CORRUPT_BKPT;
}else{
- rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
+ rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
}
/* If no error occurred, set the output variables. */
@@ -57061,9 +57875,14 @@ SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
int rc = SQLITE_OK;
WalIndexHdr *pRet;
+ static const u32 aZero[4] = { 0, 0, 0, 0 };
assert( pWal->readLock>=0 && pWal->writeLock==0 );
+ if( memcmp(&pWal->hdr.aFrameCksum[0],aZero,16)==0 ){
+ *ppSnapshot = 0;
+ return SQLITE_ERROR;
+ }
pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
if( pRet==0 ){
rc = SQLITE_NOMEM_BKPT;
@@ -57085,7 +57904,7 @@ SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapsho
** Return a +ve value if snapshot p1 is newer than p2. A -ve value if
** p1 is older than p2 and zero if p1 and p2 are the same snapshot.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
+SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){
WalIndexHdr *pHdr1 = (WalIndexHdr*)p1;
WalIndexHdr *pHdr2 = (WalIndexHdr*)p2;
@@ -57401,37 +58220,39 @@ typedef struct CellInfo CellInfo;
#define PTF_LEAF 0x08
/*
-** As each page of the file is loaded into memory, an instance of the following
-** structure is appended and initialized to zero. This structure stores
-** information about the page that is decoded from the raw file page.
+** An instance of this object stores information about each a single database
+** page that has been loaded into memory. The information in this object
+** is derived from the raw on-disk page content.
**
-** The pParent field points back to the parent page. This allows us to
-** walk up the BTree from any leaf to the root. Care must be taken to
-** unref() the parent page pointer when this page is no longer referenced.
-** The pageDestructor() routine handles that chore.
+** As each database page is loaded into memory, the pager allocats an
+** instance of this object and zeros the first 8 bytes. (This is the
+** "extra" information associated with each page of the pager.)
**
** Access to all fields of this structure is controlled by the mutex
** stored in MemPage.pBt->mutex.
*/
struct MemPage {
u8 isInit; /* True if previously initialized. MUST BE FIRST! */
- u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
+ u8 bBusy; /* Prevent endless loops on corrupt database files */
u8 intKey; /* True if table b-trees. False for index b-trees */
u8 intKeyLeaf; /* True if the leaf of an intKey table */
+ Pgno pgno; /* Page number for this page */
+ /* Only the first 8 bytes (above) are zeroed by pager.c when a new page
+ ** is allocated. All fields that follow must be initialized before use */
u8 leaf; /* True if a leaf page */
u8 hdrOffset; /* 100 for page 1. 0 otherwise */
u8 childPtrSize; /* 0 if leaf==1. 4 if leaf==0 */
u8 max1bytePayload; /* min(maxLocal,127) */
- u8 bBusy; /* Prevent endless loops on corrupt database files */
+ u8 nOverflow; /* Number of overflow cell bodies in aCell[] */
u16 maxLocal; /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
u16 minLocal; /* Copy of BtShared.minLocal or BtShared.minLeaf */
u16 cellOffset; /* Index in aData of first cell pointer */
u16 nFree; /* Number of free bytes on the page */
u16 nCell; /* Number of cells on this page, local and ovfl */
u16 maskPage; /* Mask for page offset */
- u16 aiOvfl[5]; /* Insert the i-th overflow cell before the aiOvfl-th
+ u16 aiOvfl[4]; /* Insert the i-th overflow cell before the aiOvfl-th
** non-overflow cell */
- u8 *apOvfl[5]; /* Pointers to the body of overflow cells */
+ u8 *apOvfl[4]; /* Pointers to the body of overflow cells */
BtShared *pBt; /* Pointer to BtShared that this page is part of */
u8 *aData; /* Pointer to disk image of the page data */
u8 *aDataEnd; /* One byte past the end of usable data */
@@ -57440,17 +58261,9 @@ struct MemPage {
DbPage *pDbPage; /* Pager page handle */
u16 (*xCellSize)(MemPage*,u8*); /* cellSizePtr method */
void (*xParseCell)(MemPage*,u8*,CellInfo*); /* btreeParseCell method */
- Pgno pgno; /* Page number for this page */
};
/*
-** The in-memory image of a disk page has the auxiliary information appended
-** to the end. EXTRA_SIZE is the number of bytes of space needed to hold
-** that extra information.
-*/
-#define EXTRA_SIZE sizeof(MemPage)
-
-/*
** A linked list of the following structures is stored at BtShared.pLock.
** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor
** is opened on the table with root page BtShared.iTable. Locks are removed
@@ -57840,11 +58653,9 @@ struct IntegrityCk {
*/
#if SQLITE_BYTEORDER==4321
# define get2byteAligned(x) (*(u16*)(x))
-#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
- && GCC_VERSION>=4008000
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4008000
# define get2byteAligned(x) __builtin_bswap16(*(u16*)(x))
-#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
- && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
# define get2byteAligned(x) _byteswap_ushort(*(u16*)(x))
#else
# define get2byteAligned(x) ((x)[0]<<8 | (x)[1])
@@ -58019,16 +58830,24 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){
** two or more btrees in common both try to lock all their btrees
** at the same instant.
*/
-SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
+static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){
int i;
+ int skipOk = 1;
Btree *p;
assert( sqlite3_mutex_held(db->mutex) );
for(i=0; i<db->nDb; i++){
p = db->aDb[i].pBt;
- if( p ) sqlite3BtreeEnter(p);
+ if( p && p->sharable ){
+ sqlite3BtreeEnter(p);
+ skipOk = 0;
+ }
}
+ db->skipBtreeMutex = skipOk;
}
-SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
+SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
+ if( db->skipBtreeMutex==0 ) btreeEnterAll(db);
+}
+static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){
int i;
Btree *p;
assert( sqlite3_mutex_held(db->mutex) );
@@ -58037,6 +58856,9 @@ SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
if( p ) sqlite3BtreeLeave(p);
}
}
+SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){
+ if( db->skipBtreeMutex==0 ) btreeLeaveAll(db);
+}
#ifndef NDEBUG
/*
@@ -58222,7 +59044,7 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
** The shared cache setting effects only future calls to
** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){
+SQLITE_API int sqlite3_enable_shared_cache(int enable){
sqlite3GlobalConfig.sharedCacheEnabled = enable;
return SQLITE_OK;
}
@@ -58768,7 +59590,7 @@ static int saveCursorKey(BtCursor *pCur){
pCur->nKey = sqlite3BtreePayloadSize(pCur);
pKey = sqlite3Malloc( pCur->nKey );
if( pKey ){
- rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
+ rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
if( rc==SQLITE_OK ){
pCur->pKey = pKey;
}else{
@@ -58899,26 +59721,23 @@ static int btreeMoveto(
){
int rc; /* Status code */
UnpackedRecord *pIdxKey; /* Unpacked index key */
- char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */
- char *pFree = 0;
if( pKey ){
assert( nKey==(i64)(int)nKey );
- pIdxKey = sqlite3VdbeAllocUnpackedRecord(
- pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
- );
+ pIdxKey = sqlite3VdbeAllocUnpackedRecord(pCur->pKeyInfo);
if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
if( pIdxKey->nField==0 ){
- sqlite3DbFree(pCur->pKeyInfo->db, pFree);
- return SQLITE_CORRUPT_BKPT;
+ rc = SQLITE_CORRUPT_BKPT;
+ goto moveto_done;
}
}else{
pIdxKey = 0;
}
rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes);
- if( pFree ){
- sqlite3DbFree(pCur->pKeyInfo->db, pFree);
+moveto_done:
+ if( pIdxKey ){
+ sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey);
}
return rc;
}
@@ -59456,17 +60275,18 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
/*
-** Defragment the page given. All Cells are moved to the
-** end of the page and all free space is collected into one
-** big FreeBlk that occurs in between the header and cell
-** pointer array and the cell content area.
+** Defragment the page given. This routine reorganizes cells within the
+** page so that there are no free-blocks on the free-block list.
+**
+** Parameter nMaxFrag is the maximum amount of fragmented space that may be
+** present in the page after this routine returns.
**
** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
** b-tree page so that there are no freeblocks or fragment bytes, all
** unused bytes are contained in the unallocated space region, and all
** cells are packed tightly at the end of the page.
*/
-static int defragmentPage(MemPage *pPage){
+static int defragmentPage(MemPage *pPage, int nMaxFrag){
int i; /* Loop counter */
int pc; /* Address of the i-th cell */
int hdr; /* Offset to the page header */
@@ -59481,7 +60301,6 @@ static int defragmentPage(MemPage *pPage){
int iCellFirst; /* First allowable cell index */
int iCellLast; /* Last possible cell index */
-
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( pPage->pBt!=0 );
assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
@@ -59493,9 +60312,56 @@ static int defragmentPage(MemPage *pPage){
cellOffset = pPage->cellOffset;
nCell = pPage->nCell;
assert( nCell==get2byte(&data[hdr+3]) );
+ iCellFirst = cellOffset + 2*nCell;
usableSize = pPage->pBt->usableSize;
+
+ /* This block handles pages with two or fewer free blocks and nMaxFrag
+ ** or fewer fragmented bytes. In this case it is faster to move the
+ ** two (or one) blocks of cells using memmove() and add the required
+ ** offsets to each pointer in the cell-pointer array than it is to
+ ** reconstruct the entire page. */
+ if( (int)data[hdr+7]<=nMaxFrag ){
+ int iFree = get2byte(&data[hdr+1]);
+ if( iFree ){
+ int iFree2 = get2byte(&data[iFree]);
+
+ /* pageFindSlot() has already verified that free blocks are sorted
+ ** in order of offset within the page, and that no block extends
+ ** past the end of the page. Provided the two free slots do not
+ ** overlap, this guarantees that the memmove() calls below will not
+ ** overwrite the usableSize byte buffer, even if the database page
+ ** is corrupt. */
+ assert( iFree2==0 || iFree2>iFree );
+ assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
+ assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
+
+ if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
+ u8 *pEnd = &data[cellOffset + nCell*2];
+ u8 *pAddr;
+ int sz2 = 0;
+ int sz = get2byte(&data[iFree+2]);
+ int top = get2byte(&data[hdr+5]);
+ if( iFree2 ){
+ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_BKPT;
+ sz2 = get2byte(&data[iFree2+2]);
+ assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
+ memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
+ sz += sz2;
+ }
+ cbrk = top+sz;
+ assert( cbrk+(iFree-top) <= usableSize );
+ memmove(&data[cbrk], &data[top], iFree-top);
+ for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
+ pc = get2byte(pAddr);
+ if( pc<iFree ){ put2byte(pAddr, pc+sz); }
+ else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
+ }
+ goto defragment_out;
+ }
+ }
+ }
+
cbrk = usableSize;
- iCellFirst = cellOffset + 2*nCell;
iCellLast = usableSize - 4;
for(i=0; i<nCell; i++){
u8 *pAddr; /* The i-th cell pointer */
@@ -59529,16 +60395,18 @@ static int defragmentPage(MemPage *pPage){
}
memcpy(&data[cbrk], &src[pc], size);
}
+ data[hdr+7] = 0;
+
+ defragment_out:
+ if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
+ return SQLITE_CORRUPT_BKPT;
+ }
assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk);
data[hdr+1] = 0;
data[hdr+2] = 0;
- data[hdr+7] = 0;
memset(&data[iCellFirst], 0, cbrk-iCellFirst);
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- if( cbrk-iCellFirst!=pPage->nFree ){
- return SQLITE_CORRUPT_BKPT;
- }
return SQLITE_OK;
}
@@ -59676,10 +60544,10 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){
assert( pPage->nCell>0 || CORRUPT_DB );
- rc = defragmentPage(pPage);
+ rc = defragmentPage(pPage, MIN(4, pPage->nFree - (2+nByte)));
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
- assert( gap+nByte<=top );
+ assert( gap+2+nByte<=top );
}
@@ -59741,8 +60609,11 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
if( data[iPtr+1]==0 && data[iPtr]==0 ){
iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */
}else{
- while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
- if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
+ while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
+ if( iFreeBlk<iPtr+4 ){
+ if( iFreeBlk==0 ) break;
+ return SQLITE_CORRUPT_BKPT;
+ }
iPtr = iFreeBlk;
}
if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
@@ -59876,7 +60747,7 @@ static int btreeInitPage(MemPage *pPage){
assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
if( !pPage->isInit ){
- u16 pc; /* Address of a freeblock within pPage->aData[] */
+ int pc; /* Address of a freeblock within pPage->aData[] */
u8 hdr; /* Offset to beginning of page header */
u8 *data; /* Equal to pPage->aData */
BtShared *pBt; /* The main btree structure */
@@ -59956,25 +60827,30 @@ static int btreeInitPage(MemPage *pPage){
** freeblocks. */
pc = get2byte(&data[hdr+1]);
nFree = data[hdr+7] + top; /* Init nFree to non-freeblock free space */
- while( pc>0 ){
- u16 next, size;
- if( pc<iCellFirst || pc>iCellLast ){
+ if( pc>0 ){
+ u32 next, size;
+ if( pc<iCellFirst ){
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
** always be at least one cell before the first freeblock.
- **
- ** Or, the freeblock is off the end of the page
*/
return SQLITE_CORRUPT_BKPT;
}
- next = get2byte(&data[pc]);
- size = get2byte(&data[pc+2]);
- if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){
- /* Free blocks must be in ascending order. And the last byte of
- ** the free-block must lie on the database page. */
- return SQLITE_CORRUPT_BKPT;
+ while( 1 ){
+ if( pc>iCellLast ){
+ return SQLITE_CORRUPT_BKPT; /* Freeblock off the end of the page */
+ }
+ next = get2byte(&data[pc]);
+ size = get2byte(&data[pc+2]);
+ nFree = nFree + size;
+ if( next<=pc+size+3 ) break;
+ pc = next;
+ }
+ if( next>0 ){
+ return SQLITE_CORRUPT_BKPT; /* Freeblock not in ascending order */
+ }
+ if( pc+size>(unsigned int)usableSize ){
+ return SQLITE_CORRUPT_BKPT; /* Last freeblock extends past page end */
}
- nFree = nFree + size;
- pc = next;
}
/* At this point, nFree contains the sum of the offset to the start
@@ -60415,7 +61291,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
goto btree_open_out;
}
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
- EXTRA_SIZE, flags, vfsFlags, pageReinit);
+ sizeof(MemPage), flags, vfsFlags, pageReinit);
if( rc==SQLITE_OK ){
sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap);
rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
@@ -60528,12 +61404,14 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
btree_open_out:
if( rc!=SQLITE_OK ){
if( pBt && pBt->pPager ){
- sqlite3PagerClose(pBt->pPager);
+ sqlite3PagerClose(pBt->pPager, 0);
}
sqlite3_free(pBt);
sqlite3_free(p);
*ppBtree = 0;
}else{
+ sqlite3_file *pFile;
+
/* If the B-Tree was successfully opened, set the pager-cache size to the
** default value. Except, when opening on an existing shared pager-cache,
** do not change the pager-cache size.
@@ -60541,6 +61419,11 @@ btree_open_out:
if( sqlite3BtreeSchema(p, 0, 0)==0 ){
sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE);
}
+
+ pFile = sqlite3PagerFile(pBt->pPager);
+ if( pFile->pMethods ){
+ sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db);
+ }
}
if( mutexOpen ){
assert( sqlite3_mutex_held(mutexOpen) );
@@ -60670,7 +61553,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
** Clean out and delete the BtShared object.
*/
assert( !pBt->pCursor );
- sqlite3PagerClose(pBt->pPager);
+ sqlite3PagerClose(pBt->pPager, p->db);
if( pBt->xFreeSchema && pBt->pSchema ){
pBt->xFreeSchema(pBt->pSchema);
}
@@ -60936,6 +61819,31 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){
#endif
}
+/*
+** If the user has not set the safety-level for this database connection
+** using "PRAGMA synchronous", and if the safety-level is not already
+** set to the value passed to this function as the second parameter,
+** set it so.
+*/
+#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
+static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
+ sqlite3 *db;
+ Db *pDb;
+ if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
+ while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
+ if( pDb->bSyncSet==0
+ && pDb->safety_level!=safety_level
+ && pDb!=&db->aDb[1]
+ ){
+ pDb->safety_level = safety_level;
+ sqlite3PagerSetFlags(pBt->pPager,
+ pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
+ }
+ }
+}
+#else
+# define setDefaultSyncFlag(pBt,safety_level)
+#endif
/*
** Get a reference to pPage1 of the database file. This will
@@ -61009,26 +61917,15 @@ static int lockBtree(BtShared *pBt){
if( rc!=SQLITE_OK ){
goto page1_init_failed;
}else{
-#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
- sqlite3 *db;
- Db *pDb;
- if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){
- while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; }
- if( pDb->bSyncSet==0
- && pDb->safety_level==SQLITE_DEFAULT_SYNCHRONOUS+1
- ){
- pDb->safety_level = SQLITE_DEFAULT_WAL_SYNCHRONOUS+1;
- sqlite3PagerSetFlags(pBt->pPager,
- pDb->safety_level | (db->flags & PAGER_FLAGS_MASK));
- }
- }
-#endif
+ setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
if( isOpen==0 ){
releasePage(pPage1);
return SQLITE_OK;
}
}
rc = SQLITE_NOTADB;
+ }else{
+ setDefaultSyncFlag(pBt, SQLITE_DEFAULT_SYNCHRONOUS+1);
}
#endif
@@ -61417,14 +62314,11 @@ static int setChildPtrmaps(MemPage *pPage){
int nCell; /* Number of cells in page pPage */
int rc; /* Return code */
BtShared *pBt = pPage->pBt;
- u8 isInitOrig = pPage->isInit;
Pgno pgno = pPage->pgno;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
rc = btreeInitPage(pPage);
- if( rc!=SQLITE_OK ){
- goto set_child_ptrmaps_out;
- }
+ if( rc!=SQLITE_OK ) return rc;
nCell = pPage->nCell;
for(i=0; i<nCell; i++){
@@ -61443,8 +62337,6 @@ static int setChildPtrmaps(MemPage *pPage){
ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc);
}
-set_child_ptrmaps_out:
- pPage->isInit = isInitOrig;
return rc;
}
@@ -61472,7 +62364,6 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
}
put4byte(pPage->aData, iTo);
}else{
- u8 isInitOrig = pPage->isInit;
int i;
int nCell;
int rc;
@@ -61486,12 +62377,14 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( eType==PTRMAP_OVERFLOW1 ){
CellInfo info;
pPage->xParseCell(pPage, pCell, &info);
- if( info.nLocal<info.nPayload
- && pCell+info.nSize-1<=pPage->aData+pPage->maskPage
- && iFrom==get4byte(pCell+info.nSize-4)
- ){
- put4byte(pCell+info.nSize-4, iTo);
- break;
+ if( info.nLocal<info.nPayload ){
+ if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ if( iFrom==get4byte(pCell+info.nSize-4) ){
+ put4byte(pCell+info.nSize-4, iTo);
+ break;
+ }
}
}else{
if( get4byte(pCell)==iFrom ){
@@ -61508,8 +62401,6 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
}
put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
}
-
- pPage->isInit = isInitOrig;
}
return SQLITE_OK;
}
@@ -62168,7 +63059,12 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) );
sqlite3BtreeEnter(p);
- rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
+ if( op==SAVEPOINT_ROLLBACK ){
+ rc = saveAllCursors(pBt, 0, 0);
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint);
+ }
if( rc==SQLITE_OK ){
if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){
pBt->nPage = 0;
@@ -62404,6 +63300,10 @@ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){
return pCur && pCur->eState==CURSOR_VALID;
}
#endif /* NDEBUG */
+SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){
+ assert( pCur!=0 );
+ return pCur->eState==CURSOR_VALID;
+}
/*
** Return the value of the integer key or "rowid" for a table btree.
@@ -62550,7 +63450,6 @@ static int copyPayload(
**
** 0: The operation is a read. Populate the overflow cache.
** 1: The operation is a write. Populate the overflow cache.
-** 2: The operation is a read. Do not populate the overflow cache.
**
** A total of "amt" bytes are read or written beginning at "offset".
** Data is read to or from the buffer pBuf.
@@ -62558,13 +63457,13 @@ static int copyPayload(
** The content being read or written might appear on the main page
** or be scattered out on multiple overflow pages.
**
-** If the current cursor entry uses one or more overflow pages and the
-** eOp argument is not 2, this function may allocate space for and lazily
-** populates the overflow page-list cache array (BtCursor.aOverflow).
+** If the current cursor entry uses one or more overflow pages
+** this function may allocate space for and lazily populate
+** the overflow page-list cache array (BtCursor.aOverflow).
** Subsequent calls use this cache to make seeking to the supplied offset
** more efficient.
**
-** Once an overflow page-list cache has been allocated, it may be
+** Once an overflow page-list cache has been allocated, it must be
** invalidated if some other cursor writes to the same table, or if
** the cursor is moved to a different row. Additionally, in auto-vacuum
** mode, the following events may invalidate an overflow page-list cache.
@@ -62586,21 +63485,17 @@ static int accessPayload(
MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
#ifdef SQLITE_DIRECT_OVERFLOW_READ
- unsigned char * const pBufStart = pBuf;
- int bEnd; /* True if reading to end of data */
+ unsigned char * const pBufStart = pBuf; /* Start of original out buffer */
#endif
assert( pPage );
+ assert( eOp==0 || eOp==1 );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
assert( cursorHoldsMutex(pCur) );
- assert( eOp!=2 || offset==0 ); /* Always start from beginning for eOp==2 */
getCellInfo(pCur);
aPayload = pCur->info.pPayload;
-#ifdef SQLITE_DIRECT_OVERFLOW_READ
- bEnd = offset+amt==pCur->info.nPayload;
-#endif
assert( offset+amt <= pCur->info.nPayload );
assert( aPayload > pPage->aData );
@@ -62619,7 +63514,7 @@ static int accessPayload(
if( a+offset>pCur->info.nLocal ){
a = pCur->info.nLocal - offset;
}
- rc = copyPayload(&aPayload[offset], pBuf, a, (eOp & 0x01), pPage->pDbPage);
+ rc = copyPayload(&aPayload[offset], pBuf, a, eOp, pPage->pDbPage);
offset = 0;
pBuf += a;
amt -= a;
@@ -62635,53 +63530,46 @@ static int accessPayload(
nextPage = get4byte(&aPayload[pCur->info.nLocal]);
/* If the BtCursor.aOverflow[] has not been allocated, allocate it now.
- ** Except, do not allocate aOverflow[] for eOp==2.
**
** The aOverflow[] array is sized at one entry for each overflow page
** in the overflow chain. The page number of the first overflow page is
** stored in aOverflow[0], etc. A value of 0 in the aOverflow[] array
** means "not yet known" (the cache is lazily populated).
*/
- if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
+ if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){
int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
if( nOvfl>pCur->nOvflAlloc ){
Pgno *aNew = (Pgno*)sqlite3Realloc(
pCur->aOverflow, nOvfl*2*sizeof(Pgno)
);
if( aNew==0 ){
- rc = SQLITE_NOMEM_BKPT;
+ return SQLITE_NOMEM_BKPT;
}else{
pCur->nOvflAlloc = nOvfl*2;
pCur->aOverflow = aNew;
}
}
- if( rc==SQLITE_OK ){
- memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
- pCur->curFlags |= BTCF_ValidOvfl;
+ memset(pCur->aOverflow, 0, nOvfl*sizeof(Pgno));
+ pCur->curFlags |= BTCF_ValidOvfl;
+ }else{
+ /* If the overflow page-list cache has been allocated and the
+ ** entry for the first required overflow page is valid, skip
+ ** directly to it.
+ */
+ if( pCur->aOverflow[offset/ovflSize] ){
+ iIdx = (offset/ovflSize);
+ nextPage = pCur->aOverflow[iIdx];
+ offset = (offset%ovflSize);
}
}
- /* If the overflow page-list cache has been allocated and the
- ** entry for the first required overflow page is valid, skip
- ** directly to it.
- */
- if( (pCur->curFlags & BTCF_ValidOvfl)!=0
- && pCur->aOverflow[offset/ovflSize]
- ){
- iIdx = (offset/ovflSize);
- nextPage = pCur->aOverflow[iIdx];
- offset = (offset%ovflSize);
- }
-
- for( ; rc==SQLITE_OK && amt>0 && nextPage; iIdx++){
-
+ assert( rc==SQLITE_OK && amt>0 );
+ while( nextPage ){
/* If required, populate the overflow page-list cache. */
- if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){
- assert( pCur->aOverflow[iIdx]==0
- || pCur->aOverflow[iIdx]==nextPage
- || CORRUPT_DB );
- pCur->aOverflow[iIdx] = nextPage;
- }
+ assert( pCur->aOverflow[iIdx]==0
+ || pCur->aOverflow[iIdx]==nextPage
+ || CORRUPT_DB );
+ pCur->aOverflow[iIdx] = nextPage;
if( offset>=ovflSize ){
/* The only reason to read this page is to obtain the page
@@ -62689,11 +63577,7 @@ static int accessPayload(
** data is not required. So first try to lookup the overflow
** page-list cache, if any, then fall back to the getOverflowPage()
** function.
- **
- ** Note that the aOverflow[] array must be allocated because eOp!=2
- ** here. If eOp==2, then offset==0 and this branch is never taken.
*/
- assert( eOp!=2 );
assert( pCur->curFlags & BTCF_ValidOvfl );
assert( pCur->pBtree->db==pBt->db );
if( pCur->aOverflow[iIdx+1] ){
@@ -62707,7 +63591,7 @@ static int accessPayload(
** range of data that is being read (eOp==0) or written (eOp!=0).
*/
#ifdef SQLITE_DIRECT_OVERFLOW_READ
- sqlite3_file *fd;
+ sqlite3_file *fd; /* File from which to do direct overflow read */
#endif
int a = amt;
if( a + offset > ovflSize ){
@@ -62719,27 +63603,25 @@ static int accessPayload(
**
** 1) this is a read operation, and
** 2) data is required from the start of this overflow page, and
- ** 3) the database is file-backed, and
- ** 4) there is no open write-transaction, and
- ** 5) the database is not a WAL database,
- ** 6) all data from the page is being read.
- ** 7) at least 4 bytes have already been read into the output buffer
+ ** 3) there is no open write-transaction, and
+ ** 4) the database is file-backed, and
+ ** 5) the page is not in the WAL file
+ ** 6) at least 4 bytes have already been read into the output buffer
**
** then data can be read directly from the database file into the
** output buffer, bypassing the page-cache altogether. This speeds
** up loading large records that span many overflow pages.
*/
- if( (eOp&0x01)==0 /* (1) */
+ if( eOp==0 /* (1) */
&& offset==0 /* (2) */
- && (bEnd || a==ovflSize) /* (6) */
- && pBt->inTransaction==TRANS_READ /* (4) */
- && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
- && pBt->pPage1->aData[19]==0x01 /* (5) */
- && &pBuf[-4]>=pBufStart /* (7) */
+ && pBt->inTransaction==TRANS_READ /* (3) */
+ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (4) */
+ && 0==sqlite3PagerUseWal(pBt->pPager, nextPage) /* (5) */
+ && &pBuf[-4]>=pBufStart /* (6) */
){
u8 aSave[4];
u8 *aWrite = &pBuf[-4];
- assert( aWrite>=pBufStart ); /* hence (7) */
+ assert( aWrite>=pBufStart ); /* due to (6) */
memcpy(aSave, aWrite, 4);
rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
nextPage = get4byte(aWrite);
@@ -62750,41 +63632,49 @@ static int accessPayload(
{
DbPage *pDbPage;
rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage,
- ((eOp&0x01)==0 ? PAGER_GET_READONLY : 0)
+ (eOp==0 ? PAGER_GET_READONLY : 0)
);
if( rc==SQLITE_OK ){
aPayload = sqlite3PagerGetData(pDbPage);
nextPage = get4byte(aPayload);
- rc = copyPayload(&aPayload[offset+4], pBuf, a, (eOp&0x01), pDbPage);
+ rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
sqlite3PagerUnref(pDbPage);
offset = 0;
}
}
amt -= a;
+ if( amt==0 ) return rc;
pBuf += a;
}
+ if( rc ) break;
+ iIdx++;
}
}
if( rc==SQLITE_OK && amt>0 ){
- return SQLITE_CORRUPT_BKPT;
+ return SQLITE_CORRUPT_BKPT; /* Overflow chain ends prematurely */
}
return rc;
}
/*
-** Read part of the key associated with cursor pCur. Exactly
-** "amt" bytes will be transferred into pBuf[]. The transfer
+** Read part of the payload for the row at which that cursor pCur is currently
+** pointing. "amt" bytes will be transferred into pBuf[]. The transfer
** begins at "offset".
**
-** The caller must ensure that pCur is pointing to a valid row
-** in the table.
+** pCur can be pointing to either a table or an index b-tree.
+** If pointing to a table btree, then the content section is read. If
+** pCur is pointing to an index b-tree then the key section is read.
+**
+** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing
+** to a valid row in the table. For sqlite3BtreePayloadChecked(), the
+** cursor might be invalid or might need to be restored before being read.
**
** Return SQLITE_OK on success or an error code if anything goes
** wrong. An error is returned if "offset+amt" is larger than
** the available payload.
*/
-SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
assert( cursorHoldsMutex(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
@@ -62793,33 +63683,34 @@ SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pB
}
/*
-** Read part of the data associated with cursor pCur. Exactly
-** "amt" bytes will be transfered into pBuf[]. The transfer
-** begins at "offset".
-**
-** Return SQLITE_OK on success or an error code if anything goes
-** wrong. An error is returned if "offset+amt" is larger than
-** the available payload.
+** This variant of sqlite3BtreePayload() works even if the cursor has not
+** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read()
+** interface.
*/
-SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
- int rc;
-
#ifndef SQLITE_OMIT_INCRBLOB
+static SQLITE_NOINLINE int accessPayloadChecked(
+ BtCursor *pCur,
+ u32 offset,
+ u32 amt,
+ void *pBuf
+){
+ int rc;
if ( pCur->eState==CURSOR_INVALID ){
return SQLITE_ABORT;
}
-#endif
-
assert( cursorOwnsBtShared(pCur) );
- rc = restoreCursorPosition(pCur);
- if( rc==SQLITE_OK ){
- assert( pCur->eState==CURSOR_VALID );
- assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] );
- assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
- rc = accessPayload(pCur, offset, amt, pBuf, 0);
+ rc = btreeRestoreCursorPosition(pCur);
+ return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0);
+}
+SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+ if( pCur->eState==CURSOR_VALID ){
+ assert( cursorOwnsBtShared(pCur) );
+ return accessPayload(pCur, offset, amt, pBuf, 0);
+ }else{
+ return accessPayloadChecked(pCur, offset, amt, pBuf);
}
- return rc;
}
+#endif /* SQLITE_OMIT_INCRBLOB */
/*
** Return a pointer to payload information from the entry that the
@@ -62906,7 +63797,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
pCur, pCur->curPagerFlags);
}
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** Page pParent is an internal (non-leaf) tree page. This function
** asserts that page number iChild is the left-child if the iIdx'th
@@ -62990,9 +63881,12 @@ static int moveToRoot(BtCursor *pCur){
}
if( pCur->iPage>=0 ){
- while( pCur->iPage ){
- assert( pCur->apPage[pCur->iPage]!=0 );
- releasePageNotNull(pCur->apPage[pCur->iPage--]);
+ if( pCur->iPage ){
+ do{
+ assert( pCur->apPage[pCur->iPage]!=0 );
+ releasePageNotNull(pCur->apPage[pCur->iPage--]);
+ }while( pCur->iPage);
+ goto skip_init;
}
}else if( pCur->pgnoRoot==0 ){
pCur->eState = CURSOR_INVALID;
@@ -63003,7 +63897,7 @@ static int moveToRoot(BtCursor *pCur){
0, pCur->curPagerFlags);
if( rc!=SQLITE_OK ){
pCur->eState = CURSOR_INVALID;
- return rc;
+ return rc;
}
pCur->iPage = 0;
pCur->curIntKey = pCur->apPage[0]->intKey;
@@ -63026,10 +63920,12 @@ static int moveToRoot(BtCursor *pCur){
return SQLITE_CORRUPT_BKPT;
}
+skip_init:
pCur->aiIdx[0] = 0;
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
+ pRoot = pCur->apPage[0];
if( pRoot->nCell>0 ){
pCur->eState = CURSOR_VALID;
}else if( !pRoot->leaf ){
@@ -63218,9 +64114,26 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
*pRes = 0;
return SQLITE_OK;
}
- if( (pCur->curFlags & BTCF_AtLast)!=0 && pCur->info.nKey<intKey ){
- *pRes = -1;
- return SQLITE_OK;
+ if( pCur->info.nKey<intKey ){
+ if( (pCur->curFlags & BTCF_AtLast)!=0 ){
+ *pRes = -1;
+ return SQLITE_OK;
+ }
+ /* If the requested key is one more than the previous key, then
+ ** try to get there using sqlite3BtreeNext() rather than a full
+ ** binary search. This is an optimization only. The correct answer
+ ** is still obtained without this ase, only a little more slowely */
+ if( pCur->info.nKey+1==intKey && !pCur->skipNext ){
+ *pRes = 0;
+ rc = sqlite3BtreeNext(pCur, pRes);
+ if( rc ) return rc;
+ if( *pRes==0 ){
+ getCellInfo(pCur);
+ if( pCur->info.nKey==intKey ){
+ return SQLITE_OK;
+ }
+ }
+ }
}
}
@@ -63286,16 +64199,16 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
if( lwr>upr ){ c = +1; break; }
}else{
assert( nCellKey==intKey );
- pCur->curFlags |= BTCF_ValidNKey;
- pCur->info.nKey = nCellKey;
pCur->aiIdx[pCur->iPage] = (u16)idx;
if( !pPage->leaf ){
lwr = idx;
goto moveto_next_layer;
}else{
+ pCur->curFlags |= BTCF_ValidNKey;
+ pCur->info.nKey = nCellKey;
+ pCur->info.nSize = 0;
*pRes = 0;
- rc = SQLITE_OK;
- goto moveto_finish;
+ return SQLITE_OK;
}
}
assert( lwr+upr>=0 );
@@ -63356,7 +64269,8 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
goto moveto_finish;
}
pCur->aiIdx[pCur->iPage] = (u16)idx;
- rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 2);
+ rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
+ pCur->curFlags &= ~BTCF_ValidOvfl;
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
@@ -63406,7 +64320,7 @@ moveto_next_layer:
}
moveto_finish:
pCur->info.nSize = 0;
- pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+ assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
return rc;
}
@@ -63427,6 +64341,30 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
}
/*
+** Return an estimate for the number of rows in the table that pCur is
+** pointing to. Return a negative number if no estimate is currently
+** available.
+*/
+SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
+ i64 n;
+ u8 i;
+
+ assert( cursorOwnsBtShared(pCur) );
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
+
+ /* Currently this interface is only called by the OP_IfSmaller
+ ** opcode, and it that case the cursor will always be valid and
+ ** will always point to a leaf node. */
+ if( NEVER(pCur->eState!=CURSOR_VALID) ) return -1;
+ if( NEVER(pCur->apPage[pCur->iPage]->leaf==0) ) return -1;
+
+ for(n=1, i=0; i<=pCur->iPage; i++){
+ n *= pCur->apPage[i]->nCell;
+ }
+ return n;
+}
+
+/*
** Advance the cursor to the next entry in the database. If
** successful then set *pRes=0. If the cursor
** was already pointing to the last entry in the database before
@@ -63604,7 +64542,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
moveToParent(pCur);
}
assert( pCur->info.nSize==0 );
- assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 );
+ assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
pCur->aiIdx[pCur->iPage]--;
pPage = pCur->apPage[pCur->iPage];
@@ -64120,30 +65058,28 @@ static void freePage(MemPage *pPage, int *pRC){
static int clearCell(
MemPage *pPage, /* The page that contains the Cell */
unsigned char *pCell, /* First byte of the Cell */
- u16 *pnSize /* Write the size of the Cell here */
+ CellInfo *pInfo /* Size information about the cell */
){
BtShared *pBt = pPage->pBt;
- CellInfo info;
Pgno ovflPgno;
int rc;
int nOvfl;
u32 ovflPageSize;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- pPage->xParseCell(pPage, pCell, &info);
- *pnSize = info.nSize;
- if( info.nLocal==info.nPayload ){
+ pPage->xParseCell(pPage, pCell, pInfo);
+ if( pInfo->nLocal==pInfo->nPayload ){
return SQLITE_OK; /* No overflow pages. Return without doing anything */
}
- if( pCell+info.nSize-1 > pPage->aData+pPage->maskPage ){
+ if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
return SQLITE_CORRUPT_BKPT; /* Cell extends past end of page */
}
- ovflPgno = get4byte(pCell + info.nSize - 4);
+ ovflPgno = get4byte(pCell + pInfo->nSize - 4);
assert( pBt->usableSize > 4 );
ovflPageSize = pBt->usableSize - 4;
- nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
+ nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize;
assert( nOvfl>0 ||
- (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize)
+ (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)<ovflPageSize)
);
while( nOvfl-- ){
Pgno iNext = 0;
@@ -64233,8 +65169,6 @@ static int fillInCell(
nHeader += putVarint32(&pCell[nHeader], nPayload);
nHeader += putVarint(&pCell[nHeader], *(u64*)&pX->nKey);
}else{
- assert( pX->nData==0 );
- assert( pX->nZero==0 );
assert( pX->nKey<=0x7fffffff && pX->pKey!=0 );
nSrc = nPayload = (int)pX->nKey;
pSrc = pX->pKey;
@@ -64274,7 +65208,7 @@ static int fillInCell(
** Use a call to btreeParseCellPtr() to verify that the values above
** were computed correctly.
*/
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
{
CellInfo info;
pPage->xParseCell(pPage, pCell, &info);
@@ -64385,7 +65319,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
if( *pRC ) return;
-
assert( idx>=0 && idx<pPage->nCell );
assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
@@ -64469,7 +65402,10 @@ static void insertCell(
put4byte(pCell, iChild);
}
j = pPage->nOverflow++;
- assert( j<(int)(sizeof(pPage->apOvfl)/sizeof(pPage->apOvfl[0])) );
+ /* Comparison against ArraySize-1 since we hold back one extra slot
+ ** as a contingency. In other words, never need more than 3 overflow
+ ** slots but 4 are allocated, just to be safe. */
+ assert( j < ArraySize(pPage->apOvfl)-1 );
pPage->apOvfl[j] = pCell;
pPage->aiOvfl[j] = (u16)i;
@@ -65209,7 +66145,7 @@ static int balance_nonroot(
nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow;
if( (i--)==0 ) break;
- if( i+nxDiv==pParent->aiOvfl[0] && pParent->nOverflow ){
+ if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){
apDiv[i] = pParent->apOvfl[0];
pgno = get4byte(apDiv[i]);
szNew[i] = pParent->xCellSize(pParent, apDiv[i]);
@@ -65401,7 +66337,6 @@ static int balance_nonroot(
for(i=0; i<nOld; i++){
MemPage *p = apOld[i];
szNew[i] = usableSpace - p->nFree;
- if( szNew[i]<0 ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; }
for(j=0; j<p->nOverflow; j++){
szNew[i] += 2 + p->xCellSize(p, p->apOvfl[j]);
}
@@ -65799,7 +66734,7 @@ static int balance_nonroot(
** free space needs to be up front.
*/
assert( nNew==1 || CORRUPT_DB );
- rc = defragmentPage(apNew[0]);
+ rc = defragmentPage(apNew[0], -1);
testcase( rc!=SQLITE_OK );
assert( apNew[0]->nFree ==
(get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
@@ -66063,22 +66998,24 @@ static int balance(BtCursor *pCur){
** pX.pData,nData,nZero fields must be zero.
**
** If the seekResult parameter is non-zero, then a successful call to
-** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
-** been performed. seekResult is the search result returned (a negative
-** number if pCur points at an entry that is smaller than (pKey, nKey), or
-** a positive value if pCur points at an entry that is larger than
-** (pKey, nKey)).
-**
-** If the seekResult parameter is non-zero, then the caller guarantees that
-** cursor pCur is pointing at the existing copy of a row that is to be
-** overwritten. If the seekResult parameter is 0, then cursor pCur may
-** point to any entry or to no entry at all and so this function has to seek
-** the cursor before the new key can be inserted.
+** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
+** been performed. In other words, if seekResult!=0 then the cursor
+** is currently pointing to a cell that will be adjacent to the cell
+** to be inserted. If seekResult<0 then pCur points to a cell that is
+** smaller then (pKey,nKey). If seekResult>0 then pCur points to a cell
+** that is larger than (pKey,nKey).
+**
+** If seekResult==0, that means pCur is pointing at some unknown location.
+** In that case, this routine must seek the cursor to the correct insertion
+** point for (pKey,nKey) before doing the insertion. For index btrees,
+** if pX->nMem is non-zero, then pX->aMem contains pointers to the unpacked
+** key values and pX->aMem can be used instead of pX->pKey to avoid having
+** to decode the key.
*/
SQLITE_PRIVATE int sqlite3BtreeInsert(
BtCursor *pCur, /* Insert data into the table of this cursor */
const BtreePayload *pX, /* Content of the row to be inserted */
- int appendBias, /* True if this is likely an append */
+ int flags, /* True if this is likely an append */
int seekResult /* Result of prior MovetoUnpacked() call */
){
int rc;
@@ -66091,6 +67028,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
unsigned char *oldCell;
unsigned char *newCell = 0;
+ assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND))==flags );
+
if( pCur->eState==CURSOR_FAULT ){
assert( pCur->skipNext!=SQLITE_OK );
return pCur->skipNext;
@@ -66131,18 +67070,38 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** cursors open on the row being replaced */
invalidateIncrblobCursors(p, pX->nKey, 0);
+ /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing
+ ** to a row with the same key as the new entry being inserted. */
+ assert( (flags & BTREE_SAVEPOSITION)==0 ||
+ ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) );
+
/* If the cursor is currently on the last row and we are appending a
** new row onto the end, set the "loc" to avoid an unnecessary
** btreeMoveto() call */
- if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0
- && pCur->info.nKey==pX->nKey-1 ){
- loc = -1;
+ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){
+ loc = 0;
+ }else if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey>0
+ && pCur->info.nKey==pX->nKey-1 ){
+ loc = -1;
}else if( loc==0 ){
- rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, appendBias, &loc);
+ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc);
if( rc ) return rc;
}
- }else if( loc==0 ){
- rc = btreeMoveto(pCur, pX->pKey, pX->nKey, appendBias, &loc);
+ }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){
+ if( pX->nMem ){
+ UnpackedRecord r;
+ r.pKeyInfo = pCur->pKeyInfo;
+ r.aMem = pX->aMem;
+ r.nField = pX->nMem;
+ r.default_rc = 0;
+ r.errCode = 0;
+ r.r1 = 0;
+ r.r2 = 0;
+ r.eqSeen = 0;
+ rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc);
+ }else{
+ rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc);
+ }
if( rc ) return rc;
}
assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
@@ -66163,7 +67122,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
assert( szNew <= MX_CELL_SIZE(pBt) );
idx = pCur->aiIdx[pCur->iPage];
if( loc==0 ){
- u16 szOld;
+ CellInfo info;
assert( idx<pPage->nCell );
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ){
@@ -66173,8 +67132,19 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
if( !pPage->leaf ){
memcpy(newCell, oldCell, 4);
}
- rc = clearCell(pPage, oldCell, &szOld);
- dropCell(pPage, idx, szOld, &rc);
+ rc = clearCell(pPage, oldCell, &info);
+ if( info.nSize==szNew && info.nLocal==info.nPayload ){
+ /* Overwrite the old cell with the new if they are the same size.
+ ** We could also try to do this if the old cell is smaller, then add
+ ** the leftover space to the free list. But experiments show that
+ ** doing that is no faster then skipping this optimization and just
+ ** calling dropCell() and insertCell(). */
+ assert( rc==SQLITE_OK ); /* clearCell never fails when nLocal==nPayload */
+ if( oldCell+szNew > pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
+ memcpy(oldCell, newCell, szNew);
+ return SQLITE_OK;
+ }
+ dropCell(pPage, idx, info.nSize, &rc);
if( rc ) goto end_insert;
}else if( loc<0 && pPage->nCell>0 ){
assert( pPage->leaf );
@@ -66218,6 +67188,20 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** from trying to save the current position of the cursor. */
pCur->apPage[pCur->iPage]->nOverflow = 0;
pCur->eState = CURSOR_INVALID;
+ if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){
+ rc = moveToRoot(pCur);
+ if( pCur->pKeyInfo ){
+ assert( pCur->pKey==0 );
+ pCur->pKey = sqlite3Malloc( pX->nKey );
+ if( pCur->pKey==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pCur->pKey, pX->pKey, pX->nKey);
+ }
+ }
+ pCur->eState = CURSOR_REQUIRESEEK;
+ pCur->nKey = pX->nKey;
+ }
}
assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
@@ -66250,7 +67234,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
unsigned char *pCell; /* Pointer to cell to delete */
int iCellIdx; /* Index of cell to delete */
int iCellDepth; /* Depth of node containing pCell */
- u16 szCell; /* Size of the cell being deleted */
+ CellInfo info; /* Size of the cell being deleted */
int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */
u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */
@@ -66322,8 +67306,8 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** itself from within the page. */
rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc ) return rc;
- rc = clearCell(pPage, pCell, &szCell);
- dropCell(pPage, iCellIdx, szCell, &rc);
+ rc = clearCell(pPage, pCell, &info);
+ dropCell(pPage, iCellIdx, info.nSize, &rc);
if( rc ) return rc;
/* If the cell deleted was not located on a leaf page, then the cursor
@@ -66573,7 +67557,7 @@ static int clearDatabasePage(
unsigned char *pCell;
int i;
int hdr;
- u16 szCell;
+ CellInfo info;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
@@ -66593,7 +67577,7 @@ static int clearDatabasePage(
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}
- rc = clearCell(pPage, pCell, &szCell);
+ rc = clearCell(pPage, pCell, &info);
if( rc ) goto cleardatabasepage_out;
}
if( !pPage->leaf ){
@@ -66684,27 +67668,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
assert( sqlite3BtreeHoldsMutex(p) );
assert( p->inTrans==TRANS_WRITE );
-
- /* It is illegal to drop a table if any cursors are open on the
- ** database. This is because in auto-vacuum mode the backend may
- ** need to move another root-page to fill a gap left by the deleted
- ** root page. If an open cursor was using this page a problem would
- ** occur.
- **
- ** This error is caught long before control reaches this point.
- */
- if( NEVER(pBt->pCursor) ){
- sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db);
- return SQLITE_LOCKED_SHAREDCACHE;
- }
-
- /*
- ** It is illegal to drop the sqlite_master table on page 1. But again,
- ** this error is caught long before reaching this point.
- */
- if( NEVER(iTable<2) ){
- return SQLITE_CORRUPT_BKPT;
- }
+ assert( iTable>=2 );
rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
if( rc ) return rc;
@@ -67612,7 +68576,7 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *
if( pBt->inTransaction!=TRANS_NONE ){
rc = SQLITE_LOCKED;
}else{
- rc = sqlite3PagerCheckpoint(pBt->pPager, eMode, pnLog, pnCkpt);
+ rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
}
sqlite3BtreeLeave(p);
}
@@ -67934,22 +68898,16 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
int i = sqlite3FindDbName(pDb, zDb);
if( i==1 ){
- Parse *pParse;
+ Parse sParse;
int rc = 0;
- pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
- if( pParse==0 ){
- sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
- rc = SQLITE_NOMEM_BKPT;
- }else{
- pParse->db = pDb;
- if( sqlite3OpenTempDatabase(pParse) ){
- sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
- rc = SQLITE_ERROR;
- }
- sqlite3DbFree(pErrorDb, pParse->zErrMsg);
- sqlite3ParserReset(pParse);
- sqlite3StackFree(pErrorDb, pParse);
+ memset(&sParse, 0, sizeof(sParse));
+ sParse.db = pDb;
+ if( sqlite3OpenTempDatabase(&sParse) ){
+ sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
+ rc = SQLITE_ERROR;
}
+ sqlite3DbFree(pErrorDb, sParse.zErrMsg);
+ sqlite3ParserReset(&sParse);
if( rc ){
return 0;
}
@@ -67995,7 +68953,7 @@ static int checkReadTransaction(sqlite3 *db, Btree *p){
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
*/
-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3* pDestDb, /* Database to write to */
const char *zDestDb, /* Name of database within pDestDb */
sqlite3* pSrcDb, /* Database connection to read from */
@@ -68047,7 +69005,6 @@ SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
p->isAttached = 0;
if( 0==p->pSrc || 0==p->pDest
- || setDestPgsz(p)==SQLITE_NOMEM
|| checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK
){
/* One (or both) of the named databases did not exist or an OOM
@@ -68203,7 +69160,7 @@ static void attachBackupObject(sqlite3_backup *p){
/*
** Copy nPage pages from the source b-tree to the destination.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
int rc;
int destMode; /* Destination journal mode */
int pgszSrc = 0; /* Source page size */
@@ -68235,14 +69192,6 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
rc = SQLITE_OK;
}
- /* Lock the destination database, if it is not locked already. */
- if( SQLITE_OK==rc && p->bDestLocked==0
- && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
- ){
- p->bDestLocked = 1;
- sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
- }
-
/* If there is no open read-transaction on the source database, open
** one now. If a transaction is opened here, then it will be closed
** before this function exits.
@@ -68252,6 +69201,24 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
bCloseTrans = 1;
}
+ /* If the destination database has not yet been locked (i.e. if this
+ ** is the first call to backup_step() for the current backup operation),
+ ** try to set its page size to the same as the source database. This
+ ** is especially important on ZipVFS systems, as in that case it is
+ ** not possible to create a database file that uses one page size by
+ ** writing to it with another. */
+ if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){
+ rc = SQLITE_NOMEM;
+ }
+
+ /* Lock the destination database, if it is not locked already. */
+ if( SQLITE_OK==rc && p->bDestLocked==0
+ && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
+ ){
+ p->bDestLocked = 1;
+ sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
+ }
+
/* Do not allow backup if the destination database is in WAL mode
** and the page sizes are different between source and destination */
pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
@@ -68447,7 +69414,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
sqlite3 *pSrcDb; /* Source database connection */
int rc; /* Value to return */
@@ -68499,7 +69466,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
@@ -68513,7 +69480,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
** Return the total number of pages in the source database as of the most
** recent call to sqlite3_backup_step().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
@@ -68840,18 +69807,18 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
- int f;
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
assert( (pMem->flags&MEM_RowSet)==0 );
- ExpandBlob(pMem);
- f = pMem->flags;
- if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
- if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
- return SQLITE_NOMEM_BKPT;
+ if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
+ if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
+ if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
+ if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
+ return SQLITE_NOMEM_BKPT;
+ }
+ pMem->z[pMem->n] = 0;
+ pMem->z[pMem->n+1] = 0;
+ pMem->flags |= MEM_Term;
}
- pMem->z[pMem->n] = 0;
- pMem->z[pMem->n+1] = 0;
- pMem->flags |= MEM_Term;
}
pMem->flags &= ~MEM_Ephem;
#ifdef SQLITE_DEBUG
@@ -68867,25 +69834,24 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
*/
#ifndef SQLITE_OMIT_INCRBLOB
SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
- if( pMem->flags & MEM_Zero ){
- int nByte;
- assert( pMem->flags&MEM_Blob );
- assert( (pMem->flags&MEM_RowSet)==0 );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-
- /* Set nByte to the number of bytes required to store the expanded blob. */
- nByte = pMem->n + pMem->u.nZero;
- if( nByte<=0 ){
- nByte = 1;
- }
- if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
- return SQLITE_NOMEM_BKPT;
- }
+ int nByte;
+ assert( pMem->flags & MEM_Zero );
+ assert( pMem->flags&MEM_Blob );
+ assert( (pMem->flags&MEM_RowSet)==0 );
+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
- pMem->n += pMem->u.nZero;
- pMem->flags &= ~(MEM_Zero|MEM_Term);
+ /* Set nByte to the number of bytes required to store the expanded blob. */
+ nByte = pMem->n + pMem->u.nZero;
+ if( nByte<=0 ){
+ nByte = 1;
+ }
+ if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
+ return SQLITE_NOMEM_BKPT;
}
+
+ memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
+ pMem->n += pMem->u.nZero;
+ pMem->flags &= ~(MEM_Zero|MEM_Term);
return SQLITE_OK;
}
#endif
@@ -68945,6 +69911,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
+ pMem->enc = 0;
return SQLITE_NOMEM_BKPT;
}
@@ -69226,7 +70193,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
- pMem->flags &= ~(MEM_Str|MEM_Blob);
+ pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero);
return SQLITE_OK;
}
@@ -69244,7 +70211,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
if( (pMem->flags & MEM_Blob)==0 ){
sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
- MemSetTypeFlag(pMem, MEM_Blob);
+ if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob);
}else{
pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
}
@@ -69585,10 +70552,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
/*
** Move data out of a btree key or data field and into a Mem structure.
-** The data or key is taken from the entry that pCur is currently pointing
+** The data is payload from the entry that pCur is currently pointing
** to. offset and amt determine what portion of the data or key to retrieve.
-** key is true to get the key or false to get data. The result is written
-** into the pMem element.
+** The result is written into the pMem element.
**
** The pMem object must have been initialized. This routine will use
** pMem->zMalloc to hold the content from the btree, if possible. New
@@ -69603,17 +70569,12 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
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. */
- int key, /* If true, retrieve from the btree key, not data. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
int rc;
pMem->flags = MEM_Null;
if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
- if( key ){
- rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
- }else{
- rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
- }
+ rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
if( rc==SQLITE_OK ){
pMem->z[amt] = 0;
pMem->z[amt+1] = 0;
@@ -69629,7 +70590,6 @@ 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. */
- int key, /* If true, retrieve from the btree key, not data. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
char *zData; /* Data from the btree layer */
@@ -69650,7 +70610,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
pMem->flags = MEM_Blob|MEM_Ephem;
pMem->n = (int)amt;
}else{
- rc = vdbeMemFromBtreeResize(pCur, offset, amt, key, pMem);
+ rc = vdbeMemFromBtreeResize(pCur, offset, amt, pMem);
}
return rc;
@@ -69668,10 +70628,8 @@ static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
assert( (pVal->flags & MEM_RowSet)==0 );
assert( (pVal->flags & (MEM_Null))==0 );
if( pVal->flags & (MEM_Blob|MEM_Str) ){
+ if( ExpandBlob(pVal) ) return 0;
pVal->flags |= MEM_Str;
- if( pVal->flags & MEM_Zero ){
- sqlite3VdbeMemExpandBlob(pVal);
- }
if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){
sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
}
@@ -69924,10 +70882,7 @@ static int valueFromExpr(
const char *zNeg = "";
int rc = SQLITE_OK;
- if( !pExpr ){
- *ppVal = 0;
- return SQLITE_OK;
- }
+ assert( pExpr!=0 );
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
@@ -69997,6 +70952,7 @@ static int valueFromExpr(
}else if( op==TK_NULL ){
pVal = valueNew(db, pCtx);
if( pVal==0 ) goto no_mem;
+ sqlite3VdbeMemNumerify(pVal);
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
@@ -70051,7 +71007,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
u8 affinity, /* Affinity to use */
sqlite3_value **ppVal /* Write the new value here */
){
- return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0);
+ return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
}
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -70171,9 +71127,9 @@ static int stat4ValueFromExpr(
** structures intended to be compared against sample index keys stored
** in the sqlite_stat4 table.
**
-** A single call to this function attempts to populates field iVal (leftmost
-** is 0 etc.) of the unpacked record with a value extracted from expression
-** pExpr. Extraction of values is possible if:
+** A single call to this function populates zero or more fields of the
+** record starting with field iVal (fields are numbered from left to
+** right starting with 0). A single field is populated if:
**
** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
**
@@ -70182,10 +71138,14 @@ static int stat4ValueFromExpr(
** * The sqlite3ValueFromExpr() function is able to extract a value
** from the expression (i.e. the expression is a literal value).
**
-** If a value can be extracted, the affinity passed as the 5th argument
-** is applied to it before it is copied into the UnpackedRecord. Output
-** parameter *pbOk is set to true if a value is extracted, or false
-** otherwise.
+** Or, if pExpr is a TK_VECTOR, one field is populated for each of the
+** vector components that match either of the two latter criteria listed
+** above.
+**
+** Before any value is appended to the record, the affinity of the
+** corresponding column within index pIdx is applied to it. Before
+** this function returns, output parameter *pnExtract is set to the
+** number of values appended to the record.
**
** When this function is called, *ppRec must either point to an object
** allocated by an earlier call to this function, or must be NULL. If it
@@ -70201,22 +71161,33 @@ SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
Index *pIdx, /* Index being probed */
UnpackedRecord **ppRec, /* IN/OUT: Probe record */
Expr *pExpr, /* The expression to extract a value from */
- u8 affinity, /* Affinity to use */
+ int nElem, /* Maximum number of values to append */
int iVal, /* Array element to populate */
- int *pbOk /* OUT: True if value was extracted */
+ int *pnExtract /* OUT: Values appended to the record */
){
- int rc;
- sqlite3_value *pVal = 0;
- struct ValueNewStat4Ctx alloc;
+ int rc = SQLITE_OK;
+ int nExtract = 0;
- alloc.pParse = pParse;
- alloc.pIdx = pIdx;
- alloc.ppRec = ppRec;
- alloc.iVal = iVal;
+ if( pExpr==0 || pExpr->op!=TK_SELECT ){
+ int i;
+ struct ValueNewStat4Ctx alloc;
+
+ alloc.pParse = pParse;
+ alloc.pIdx = pIdx;
+ alloc.ppRec = ppRec;
+
+ for(i=0; i<nElem; i++){
+ sqlite3_value *pVal = 0;
+ Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0);
+ u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i);
+ alloc.iVal = iVal+i;
+ rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal);
+ if( !pVal ) break;
+ nExtract++;
+ }
+ }
- rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal);
- assert( pVal==0 || pVal->db==pParse->db );
- *pbOk = (pVal!=0);
+ *pnExtract = nExtract;
return rc;
}
@@ -70379,8 +71350,9 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
sqlite3 *db = pParse->db;
Vdbe *p;
- p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
+ p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) );
if( p==0 ) return 0;
+ memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp));
p->db = db;
if( db->pVdbe ){
db->pVdbe->pPrev = p;
@@ -70414,6 +71386,7 @@ SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
assert( isPrepareV2==1 || isPrepareV2==0 );
if( p==0 ) return;
+ if( !isPrepareV2 ) p->expmask = 0;
#if defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_ENABLE_SQLLOG)
if( !isPrepareV2 ) return;
#endif
@@ -70442,6 +71415,7 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
pA->zSql = pB->zSql;
pB->zSql = zTmp;
pB->isPrepareV2 = pA->isPrepareV2;
+ pB->expmask = pA->expmask;
}
/*
@@ -70472,6 +71446,12 @@ static int growOpArray(Vdbe *v, int nOp){
UNUSED_PARAMETER(nOp);
#endif
+ /* Ensure that the size of a VDBE does not grow too large */
+ if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
+ sqlite3OomFault(p->db);
+ return SQLITE_NOMEM;
+ }
+
assert( nOp<=(1024/sizeof(Op)) );
assert( nNew>=(p->nOpAlloc+nOp) );
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
@@ -70542,9 +71522,8 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
if( p->db->flags & SQLITE_VdbeAddopTrace ){
int jj, kk;
Parse *pParse = p->pParse;
- for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
+ for(jj=kk=0; jj<pParse->nColCache; jj++){
struct yColCache *x = pParse->aColCache + jj;
- if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
kk++;
}
@@ -70671,7 +71650,11 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(
int p4 /* The P4 operand as an integer */
){
int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3);
- sqlite3VdbeChangeP4(p, addr, SQLITE_INT_TO_PTR(p4), P4_INT32);
+ if( p->db->mallocFailed==0 ){
+ VdbeOp *pOp = &p->aOp[addr];
+ pOp->p4type = P4_INT32;
+ pOp->p4.i = p4;
+ }
return addr;
}
@@ -70732,7 +71715,6 @@ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
if( p->aLabel ){
p->aLabel[j] = v->nOp;
}
- p->iFixedOp = v->nOp - 1;
}
/*
@@ -71004,6 +71986,22 @@ SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
#endif
/*
+** Verify that the VM passed as the only argument does not contain
+** an OP_ResultRow opcode. Fail an assert() if it does. This is used
+** by code in pragma.c to ensure that the implementation of certain
+** pragmas comports with the flags specified in the mkpragmatab.tcl
+** script.
+*/
+#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
+SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){
+ int i;
+ for(i=0; i<p->nOp; i++){
+ assert( p->aOp[i].opcode!=OP_ResultRow );
+ }
+}
+#endif
+
+/*
** This function returns a pointer to the array of opcodes associated with
** the Vdbe passed as the first argument. It is the callers responsibility
** to arrange for the returned array to be eventually freed using the
@@ -71122,8 +72120,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, u32 addr, int val){
SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, u32 addr, int val){
sqlite3VdbeGetOp(p,addr)->p3 = val;
}
-SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
- if( !p->db->mallocFailed ) p->aOp[p->nOp-1].p5 = p5;
+SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){
+ assert( p->nOp>0 || p->db->mallocFailed );
+ if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5;
}
/*
@@ -71131,7 +72130,6 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 p5){
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
- p->pParse->iFixedOp = p->nOp - 1;
sqlite3VdbeChangeP2(p, addr, p->nOp);
}
@@ -71183,10 +72181,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
break;
}
#endif
- case P4_MPRINTF: {
- if( db->pnBytesFreed==0 ) sqlite3_free(p4);
- break;
- }
case P4_FUNCDEF: {
freeEphemeralFunction(db, (FuncDef*)p4);
break;
@@ -71254,7 +72248,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
** then remove it. Return true if and only if an opcode was removed.
*/
SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
- if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
+ if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){
return sqlite3VdbeChangeToNoop(p, p->nOp-1);
}else{
return 0;
@@ -71332,15 +72326,41 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
}
/*
+** Change the P4 operand of the most recently coded instruction
+** to the value defined by the arguments. This is a high-speed
+** version of sqlite3VdbeChangeP4().
+**
+** The P4 operand must not have been previously defined. And the new
+** P4 must not be P4_INT32. Use sqlite3VdbeChangeP4() in either of
+** those cases.
+*/
+SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){
+ VdbeOp *pOp;
+ assert( n!=P4_INT32 && n!=P4_VTAB );
+ assert( n<=0 );
+ if( p->db->mallocFailed ){
+ freeP4(p->db, n, pP4);
+ }else{
+ assert( pP4!=0 );
+ assert( p->nOp>0 );
+ pOp = &p->aOp[p->nOp-1];
+ assert( pOp->p4type==P4_NOTUSED );
+ pOp->p4type = n;
+ pOp->p4.p = pP4;
+ }
+}
+
+/*
** Set the P4 on the most recently added opcode to the KeyInfo for the
** index given.
*/
SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){
Vdbe *v = pParse->pVdbe;
+ KeyInfo *pKeyInfo;
assert( v!=0 );
assert( pIdx!=0 );
- sqlite3VdbeChangeP4(v, -1, (char*)sqlite3KeyInfoOfIndex(pParse, pIdx),
- P4_KEYINFO);
+ pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx);
+ if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
}
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
@@ -71452,12 +72472,21 @@ static int displayComment(
const char *zSynopsis;
int nOpName;
int ii, jj;
+ char zAlt[50];
zOpName = sqlite3OpcodeName(pOp->opcode);
nOpName = sqlite3Strlen30(zOpName);
if( zOpName[nOpName+1] ){
int seenCom = 0;
char c;
zSynopsis = zOpName += nOpName + 1;
+ if( strncmp(zSynopsis,"IF ",3)==0 ){
+ if( pOp->p5 & SQLITE_STOREP2 ){
+ sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3);
+ }else{
+ sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
+ }
+ zSynopsis = zAlt;
+ }
for(ii=jj=0; jj<nTemp-1 && (c = zSynopsis[ii])!=0; ii++){
if( c=='P' ){
c = zSynopsis[++ii];
@@ -71621,7 +72650,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
break;
}
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
case P4_FUNCCTX: {
FuncDef *pDef = pOp->p4.pCtx->pFunc;
sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
@@ -71809,6 +72838,21 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
#endif
/*
+** Initialize an array of N Mem element.
+*/
+static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
+ while( (N--)>0 ){
+ p->db = db;
+ p->flags = flags;
+ p->szMalloc = 0;
+#ifdef SQLITE_DEBUG
+ p->pScopyFrom = 0;
+#endif
+ p++;
+ }
+}
+
+/*
** Release an array of N Mem elements
*/
static void releaseMemArray(Mem *p, int N){
@@ -72019,6 +73063,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
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);
}else{
assert( pMem->z!=0 );
@@ -72161,7 +73206,7 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
int i;
#endif
assert( p!=0 );
- assert( p->magic==VDBE_MAGIC_INIT );
+ assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET );
/* There should be at least one opcode.
*/
@@ -72218,7 +73263,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
int nMem; /* Number of VM memory registers */
int nCursor; /* Number of cursors required */
int nArg; /* Number of arguments in subprograms */
- int nOnce; /* Number of OP_Once instructions */
int n; /* Loop counter */
struct ReusableSpace x; /* Reusable bulk memory */
@@ -72233,8 +73277,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
nMem = pParse->nMem;
nCursor = pParse->nTab;
nArg = pParse->nMaxArg;
- nOnce = pParse->nOnce;
- if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
/* Each cursor uses a memory cell. The first cursor (cursor 0) can
** use aMem[0] which is not otherwise used by the VDBE program. Allocate
@@ -72253,10 +73295,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */
assert( x.nFree>=0 );
- if( x.nFree>0 ){
- memset(x.pSpace, 0, x.nFree);
- assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
- }
+ assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
@@ -72281,36 +73320,32 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
- p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
if( x.nNeeded==0 ) break;
- x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
+ x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
x.nFree = x.nNeeded;
}while( !db->mallocFailed );
- p->nCursor = nCursor;
- p->nOnceFlag = nOnce;
- if( p->aVar ){
+ p->pVList = pParse->pVList;
+ pParse->pVList = 0;
+ p->explain = pParse->explain;
+ if( db->mallocFailed ){
+ p->nVar = 0;
+ p->nCursor = 0;
+ p->nMem = 0;
+ }else{
+ p->nCursor = nCursor;
p->nVar = (ynVar)nVar;
- for(n=0; n<nVar; n++){
- p->aVar[n].flags = MEM_Null;
- p->aVar[n].db = db;
- }
- }
- p->nzVar = pParse->nzVar;
- p->azVar = pParse->azVar;
- pParse->nzVar = 0;
- pParse->azVar = 0;
- if( p->aMem ){
+ initMemArray(p->aVar, nVar, db, MEM_Null);
p->nMem = nMem;
- for(n=0; n<nMem; n++){
- p->aMem[n].flags = MEM_Undefined;
- p->aMem[n].db = db;
- }
+ initMemArray(p->aMem, nMem, db, MEM_Undefined);
+ memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+ memset(p->anExec, 0, p->nOp*sizeof(i64));
+#endif
}
- p->explain = pParse->explain;
sqlite3VdbeRewind(p);
}
@@ -72322,15 +73357,15 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
if( pCx==0 ){
return;
}
- assert( pCx->pBt==0 || pCx->eCurType==CURTYPE_BTREE );
+ assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE );
switch( pCx->eCurType ){
case CURTYPE_SORTER: {
sqlite3VdbeSorterClose(p->db, pCx);
break;
}
case CURTYPE_BTREE: {
- if( pCx->pBt ){
- sqlite3BtreeClose(pCx->pBt);
+ if( pCx->pBtx ){
+ sqlite3BtreeClose(pCx->pBtx);
/* The pCx->pCursor will be close automatically, if it exists, by
** the call above. */
}else{
@@ -72379,8 +73414,6 @@ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
v->anExec = pFrame->anExec;
#endif
- v->aOnceFlag = pFrame->aOnceFlag;
- v->nOnceFlag = pFrame->nOnceFlag;
v->aOp = pFrame->aOp;
v->nOp = pFrame->nOp;
v->aMem = pFrame->aMem;
@@ -72464,13 +73497,9 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
sqlite3DbFree(db, p->aColName);
n = nResColumn*COLNAME_N;
p->nResColumn = (u16)nResColumn;
- p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );
+ p->aColName = pColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n );
if( p->aColName==0 ) return;
- while( n-- > 0 ){
- pColName->flags = MEM_Null;
- pColName->db = p->db;
- pColName++;
- }
+ initMemArray(p->aColName, n, p->db, MEM_Null);
}
/*
@@ -72805,60 +73834,59 @@ static void checkActiveVdbeCnt(sqlite3 *db){
** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned.
** Otherwise SQLITE_OK.
*/
-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
+static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){
sqlite3 *const db = p->db;
int rc = SQLITE_OK;
+ int i;
+ const int iSavepoint = p->iStatement-1;
- /* If p->iStatement is greater than zero, then this Vdbe opened a
- ** statement transaction that should be closed here. The only exception
- ** is that an IO error may have occurred, causing an emergency rollback.
- ** In this case (db->nStatement==0), and there is nothing to do.
- */
- if( db->nStatement && p->iStatement ){
- int i;
- const int iSavepoint = p->iStatement-1;
-
- assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
- assert( db->nStatement>0 );
- assert( p->iStatement==(db->nStatement+db->nSavepoint) );
+ assert( eOp==SAVEPOINT_ROLLBACK || eOp==SAVEPOINT_RELEASE);
+ assert( db->nStatement>0 );
+ assert( p->iStatement==(db->nStatement+db->nSavepoint) );
- for(i=0; i<db->nDb; i++){
- int rc2 = SQLITE_OK;
- Btree *pBt = db->aDb[i].pBt;
- if( pBt ){
- if( eOp==SAVEPOINT_ROLLBACK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
- }
- if( rc2==SQLITE_OK ){
- rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
- }
- if( rc==SQLITE_OK ){
- rc = rc2;
- }
- }
- }
- db->nStatement--;
- p->iStatement = 0;
-
- if( rc==SQLITE_OK ){
+ for(i=0; i<db->nDb; i++){
+ int rc2 = SQLITE_OK;
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ){
if( eOp==SAVEPOINT_ROLLBACK ){
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
+ rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint);
+ }
+ if( rc2==SQLITE_OK ){
+ rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint);
}
if( rc==SQLITE_OK ){
- rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
+ rc = rc2;
}
}
+ }
+ db->nStatement--;
+ p->iStatement = 0;
- /* If the statement transaction is being rolled back, also restore the
- ** database handles deferred constraint counter to the value it had when
- ** the statement transaction was opened. */
+ if( rc==SQLITE_OK ){
if( eOp==SAVEPOINT_ROLLBACK ){
- db->nDeferredCons = p->nStmtDefCons;
- db->nDeferredImmCons = p->nStmtDefImmCons;
+ rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint);
}
+ if( rc==SQLITE_OK ){
+ rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint);
+ }
+ }
+
+ /* If the statement transaction is being rolled back, also restore the
+ ** database handles deferred constraint counter to the value it had when
+ ** the statement transaction was opened. */
+ if( eOp==SAVEPOINT_ROLLBACK ){
+ db->nDeferredCons = p->nStmtDefCons;
+ db->nDeferredImmCons = p->nStmtDefImmCons;
}
return rc;
}
+SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){
+ if( p->db->nStatement && p->iStatement ){
+ return vdbeCloseStatement(p, eOp);
+ }
+ return SQLITE_OK;
+}
+
/*
** This function is called when a transaction opened by the database
@@ -72918,14 +73946,13 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
** one, or the complete transaction if there is no statement transaction.
*/
+ if( p->magic!=VDBE_MAGIC_RUN ){
+ return SQLITE_OK;
+ }
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM_BKPT;
}
- if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
closeAllCursors(p);
- if( p->magic!=VDBE_MAGIC_RUN ){
- return SQLITE_OK;
- }
checkActiveVdbeCnt(db);
/* No commit or rollback needed if the program never started or if the
@@ -73233,7 +74260,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
}
#endif
p->iCurrentTime = 0;
- p->magic = VDBE_MAGIC_INIT;
+ p->magic = VDBE_MAGIC_RESET;
return p->rc & db->errMask;
}
@@ -73295,26 +74322,29 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp,
*/
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
SubProgram *pSub, *pNext;
- int i;
assert( p->db==0 || p->db==db );
- releaseMemArray(p->aVar, p->nVar);
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
for(pSub=p->pProgram; pSub; pSub=pNext){
pNext = pSub->pNext;
vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
sqlite3DbFree(db, pSub);
}
- for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
- sqlite3DbFree(db, p->azVar);
+ if( p->magic!=VDBE_MAGIC_INIT ){
+ releaseMemArray(p->aVar, p->nVar);
+ sqlite3DbFree(db, p->pVList);
+ sqlite3DbFree(db, p->pFree);
+ }
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
- sqlite3DbFree(db, p->pFree);
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
- for(i=0; i<p->nScan; i++){
- sqlite3DbFree(db, p->aScan[i].zName);
+ {
+ int i;
+ for(i=0; i<p->nScan; i++){
+ sqlite3DbFree(db, p->aScan[i].zName);
+ }
+ sqlite3DbFree(db, p->aScan);
}
- sqlite3DbFree(db, p->aScan);
#endif
}
@@ -73815,30 +74845,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
** If an OOM error occurs, NULL is returned.
*/
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
- KeyInfo *pKeyInfo, /* Description of the record */
- char *pSpace, /* Unaligned space available */
- int szSpace, /* Size of pSpace[] in bytes */
- char **ppFree /* OUT: Caller should free this pointer */
+ KeyInfo *pKeyInfo /* Description of the record */
){
UnpackedRecord *p; /* Unpacked record to return */
- int nOff; /* Increment pSpace by nOff to align it */
int nByte; /* Number of bytes required for *p */
-
- /* We want to shift the pointer pSpace up such that it is 8-byte aligned.
- ** Thus, we need to calculate a value, nOff, between 0 and 7, to shift
- ** it by. If pSpace is already 8-byte aligned, nOff should be zero.
- */
- nOff = (8 - (SQLITE_PTR_TO_INT(pSpace) & 7)) & 7;
nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
- if( nByte>szSpace+nOff ){
- p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
- *ppFree = (char *)p;
- if( !p ) return 0;
- }else{
- p = (UnpackedRecord*)&pSpace[nOff];
- *ppFree = 0;
- }
-
+ p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
+ if( !p ) return 0;
p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
assert( pKeyInfo->aSortOrder!=0 );
p->pKeyInfo = pKeyInfo;
@@ -73886,7 +74899,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
p->nField = u;
}
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** This function compares two index or table record keys in the same way
** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
@@ -73991,7 +75004,7 @@ debugCompareEnd:
}
#endif
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
/*
** Count the number of fields (a.k.a. columns) in the record given by
** pKey,nKey. The verify that this count is less than or equal to the
@@ -74066,14 +75079,48 @@ static int vdbeCompareMemString(
}
/*
+** The input pBlob is guaranteed to be a Blob that is not marked
+** with MEM_Zero. Return true if it could be a zero-blob.
+*/
+static int isAllZero(const char *z, int n){
+ int i;
+ for(i=0; i<n; i++){
+ if( z[i] ) return 0;
+ }
+ return 1;
+}
+
+/*
** Compare two blobs. Return negative, zero, or positive if the first
** is less than, equal to, or greater than the second, respectively.
** If one blob is a prefix of the other, then the shorter is the lessor.
*/
static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
- int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n);
+ int c;
+ int n1 = pB1->n;
+ int n2 = pB2->n;
+
+ /* It is possible to have a Blob value that has some non-zero content
+ ** followed by zero content. But that only comes up for Blobs formed
+ ** by the OP_MakeRecord opcode, and such Blobs never get passed into
+ ** sqlite3MemCompare(). */
+ assert( (pB1->flags & MEM_Zero)==0 || n1==0 );
+ assert( (pB2->flags & MEM_Zero)==0 || n2==0 );
+
+ if( (pB1->flags|pB2->flags) & MEM_Zero ){
+ if( pB1->flags & pB2->flags & MEM_Zero ){
+ return pB1->u.nZero - pB2->u.nZero;
+ }else if( pB1->flags & MEM_Zero ){
+ if( !isAllZero(pB2->z, pB2->n) ) return -1;
+ return pB1->u.nZero - n2;
+ }else{
+ if( !isAllZero(pB1->z, pB1->n) ) return +1;
+ return n1 - pB2->u.nZero;
+ }
+ }
+ c = memcmp(pB1->z, pB2->z, n1>n2 ? n2 : n1);
if( c ) return c;
- return pB1->n - pB2->n;
+ return n1 - n2;
}
/*
@@ -74379,6 +75426,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);
testcase( serial_type==12 );
if( serial_type<12 || (serial_type & 0x01) ){
@@ -74390,6 +75438,12 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
if( (d1+nStr) > (unsigned)nKey1 ){
pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
return 0; /* Corruption */
+ }else if( pRhs->flags & MEM_Zero ){
+ if( !isAllZero((const char*)&aKey1[d1],nStr) ){
+ rc = 1;
+ }else{
+ rc = nStr - pRhs->u.nZero;
+ }
}else{
int nCmp = MIN(nStr, pRhs->n);
rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
@@ -74460,7 +75514,7 @@ static int vdbeRecordCompareInt(
int res;
u32 y;
u64 x;
- i64 v = pPKey2->aMem[0].u.i;
+ i64 v;
i64 lhs;
vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
@@ -74519,6 +75573,7 @@ static int vdbeRecordCompareInt(
return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
}
+ v = pPKey2->aMem[0].u.i;
if( v>lhs ){
res = pPKey2->r1;
}else if( v<lhs ){
@@ -74670,7 +75725,7 @@ 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, 1, &m);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
if( rc ){
return rc;
}
@@ -74750,7 +75805,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
return SQLITE_CORRUPT_BKPT;
}
sqlite3VdbeMemInit(&m, db, 0);
- rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
+ rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m);
if( rc ){
return rc;
}
@@ -74832,8 +75887,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
*/
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){
assert( iVar>0 );
- if( iVar>32 ){
- v->expmask = 0xffffffff;
+ if( iVar>=32 ){
+ v->expmask |= 0x80000000;
}else{
v->expmask |= ((u32)1 << (iVar-1));
}
@@ -74866,10 +75921,10 @@ SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
** This function is used to free UnpackedRecord structures allocated by
** the vdbeUnpackRecord() function found in vdbeapi.c.
*/
-static void vdbeFreeUnpacked(sqlite3 *db, UnpackedRecord *p){
+static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
if( p ){
int i;
- for(i=0; i<p->nField; i++){
+ for(i=0; i<nField; i++){
Mem *pMem = &p->aMem[i];
if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
}
@@ -74902,10 +75957,15 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
assert( db->pPreUpdate==0 );
memset(&preupdate, 0, sizeof(PreUpdate));
- if( op==SQLITE_UPDATE ){
- iKey2 = v->aMem[iReg].u.i;
+ if( HasRowid(pTab)==0 ){
+ iKey1 = iKey2 = 0;
+ preupdate.pPk = sqlite3PrimaryKeyIndex(pTab);
}else{
- iKey2 = iKey1;
+ if( op==SQLITE_UPDATE ){
+ iKey2 = v->aMem[iReg].u.i;
+ }else{
+ iKey2 = iKey1;
+ }
}
assert( pCsr->nField==pTab->nCol
@@ -74922,14 +75982,14 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
preupdate.iKey1 = iKey1;
preupdate.iKey2 = iKey2;
- preupdate.iPKey = pTab->iPKey;
+ preupdate.pTab = pTab;
db->pPreUpdate = &preupdate;
db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
db->pPreUpdate = 0;
sqlite3DbFree(db, preupdate.aRecord);
- vdbeFreeUnpacked(db, preupdate.pUnpacked);
- vdbeFreeUnpacked(db, preupdate.pNewUnpacked);
+ vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked);
+ vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked);
if( preupdate.aNew ){
int i;
for(i=0; i<pCsr->nField; i++){
@@ -74969,7 +76029,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
** collating sequences are registered or if an authorizer function is
** added or changed.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p==0 || p->expired;
}
@@ -75038,7 +76098,7 @@ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
/* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
@@ -75065,7 +76125,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
@@ -75086,7 +76146,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int i;
int rc = SQLITE_OK;
Vdbe *p = (Vdbe*)pStmt;
@@ -75098,7 +76158,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
sqlite3VdbeMemRelease(&p->aVar[i]);
p->aVar[i].flags = MEM_Null;
}
- if( p->isPrepareV2 && p->expmask ){
+ assert( p->isPrepareV2 || p->expmask==0 );
+ if( p->expmask ){
p->expired = 1;
}
sqlite3_mutex_leave(mutex);
@@ -75110,10 +76171,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
** The following routines extract information from a Mem or sqlite3_value
** structure.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
- if( sqlite3VdbeMemExpandBlob(p)!=SQLITE_OK ){
+ if( ExpandBlob(p)!=SQLITE_OK ){
assert( p->flags==MEM_Null && p->z==0 );
return 0;
}
@@ -75123,36 +76184,36 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
return sqlite3_value_text(pVal);
}
}
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF8);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){
+SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
return sqlite3VdbeRealValue((Mem*)pVal);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
return (int)sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){
+SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
return sqlite3VdbeIntValue((Mem*)pVal);
}
-SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value *pVal){
+SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
Mem *pMem = (Mem*)pVal;
return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0);
}
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
}
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16BE);
}
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal){
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
return sqlite3ValueText(pVal, SQLITE_UTF16LE);
}
#endif /* SQLITE_OMIT_UTF16 */
@@ -75160,7 +76221,7 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal
** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
** point number string BLOB NULL
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){
+SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
static const u8 aType[] = {
SQLITE_BLOB, /* 0x00 */
SQLITE_NULL, /* 0x01 */
@@ -75200,7 +76261,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){
/* Make a copy of an sqlite3_value object
*/
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value *pOrig){
+SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
sqlite3_value *pNew;
if( pOrig==0 ) return 0;
pNew = sqlite3_malloc( sizeof(*pNew) );
@@ -75223,7 +76284,7 @@ SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value *
/* Destroy an sqlite3_value object previously obtained from
** sqlite3_value_dup().
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value *pOld){
+SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){
sqlite3ValueFree(pOld);
}
@@ -75266,7 +76327,7 @@ static int invokeValueDestructor(
if( pCtx ) sqlite3_result_error_toobig(pCtx);
return SQLITE_TOOBIG;
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(
+SQLITE_API void sqlite3_result_blob(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -75276,7 +76337,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, 0, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(
+SQLITE_API void sqlite3_result_blob64(
sqlite3_context *pCtx,
const void *z,
sqlite3_uint64 n,
@@ -75290,43 +76351,43 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(
setResultStrOrError(pCtx, z, (int)n, 0, xDel);
}
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_ERROR;
pCtx->fErrorOrAux = 1;
sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
+SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
Mem *pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
pOut->eSubtype = eSubtype & 0xff;
pOut->flags |= MEM_Subtype;
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
+SQLITE_API void sqlite3_result_text(
sqlite3_context *pCtx,
const char *z,
int n,
@@ -75335,7 +76396,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
+SQLITE_API void sqlite3_result_text64(
sqlite3_context *pCtx,
const char *z,
sqlite3_uint64 n,
@@ -75352,7 +76413,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
}
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
+SQLITE_API void sqlite3_result_text16(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -75361,7 +76422,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
+SQLITE_API void sqlite3_result_text16be(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -75370,7 +76431,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
+SQLITE_API void sqlite3_result_text16le(
sqlite3_context *pCtx,
const void *z,
int n,
@@ -75380,15 +76441,15 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemCopy(pCtx->pOut, pValue);
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
+SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
Mem *pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
@@ -75397,7 +76458,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context *pCtx, u
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
return SQLITE_OK;
}
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
pCtx->isError = errCode;
pCtx->fErrorOrAux = 1;
#ifdef SQLITE_DEBUG
@@ -75410,7 +76471,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx,
}
/* Force an SQLITE_TOOBIG error. */
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
pCtx->isError = SQLITE_TOOBIG;
pCtx->fErrorOrAux = 1;
@@ -75419,7 +76480,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx
}
/* An SQLITE_NOMEM error. */
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
pCtx->isError = SQLITE_NOMEM_BKPT;
@@ -75443,7 +76504,7 @@ static int doWalCallbacks(sqlite3 *db){
nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
- rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
+ rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
}
}
}
@@ -75591,7 +76652,7 @@ end_of_step:
** sqlite3Step() to do most of the work. If a schema error occurs,
** call sqlite3Reprepare() and try again.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
int rc = SQLITE_OK; /* Result from sqlite3Step() */
int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */
Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */
@@ -75642,7 +76703,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
+SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
assert( p && p->pFunc );
return p->pFunc->pUserData;
}
@@ -75657,7 +76718,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
** sqlite3_create_function16() routines that originally registered the
** application defined function.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
assert( p && p->pOut );
return p->pOut->db;
}
@@ -75733,7 +76794,7 @@ static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xFinalize );
assert( sqlite3_mutex_held(p->pOut->db->mutex) );
testcase( nByte<0 );
@@ -75748,7 +76809,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, in
** Return the auxiliary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
@@ -75769,7 +76830,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int i
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(
+SQLITE_API void sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
@@ -75824,7 +76885,7 @@ failed:
** implementations should keep their own counts within their aggregate
** context.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
+SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize );
return p->pMem->n;
}
@@ -75833,7 +76894,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
/*
** Return the number of columns in the result set for the statement pStmt.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
return pVm ? pVm->nResColumn : 0;
}
@@ -75842,7 +76903,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
** Return the number of values available from the current row of the
** currently executing statement pStmt.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
Vdbe *pVm = (Vdbe *)pStmt;
if( pVm==0 || pVm->pResultSet==0 ) return 0;
return pVm->nResColumn;
@@ -75896,14 +76957,13 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
Mem *pOut;
pVm = (Vdbe *)pStmt;
- if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
- sqlite3_mutex_enter(pVm->db->mutex);
+ if( pVm==0 ) return (Mem*)columnNullValue();
+ assert( pVm->db );
+ sqlite3_mutex_enter(pVm->db->mutex);
+ if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
pOut = &pVm->pResultSet[i];
}else{
- if( pVm && ALWAYS(pVm->db) ){
- sqlite3_mutex_enter(pVm->db->mutex);
- sqlite3Error(pVm->db, SQLITE_RANGE);
- }
+ sqlite3Error(pVm->db, SQLITE_RANGE);
pOut = (Mem*)columnNullValue();
}
return pOut;
@@ -75936,6 +76996,8 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
*/
Vdbe *p = (Vdbe *)pStmt;
if( p ){
+ assert( p->db!=0 );
+ assert( sqlite3_mutex_held(p->db->mutex) );
p->rc = sqlite3ApiExit(p->db, p->rc);
sqlite3_mutex_leave(p->db->mutex);
}
@@ -75945,7 +77007,7 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
** The following routines are used to access elements of the current row
** in the result set.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
const void *val;
val = sqlite3_value_blob( columnMem(pStmt,i) );
/* Even though there is no encoding conversion, value_blob() might
@@ -75955,37 +77017,37 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, i
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *pStmt, int i){
+SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
double val = sqlite3_value_double( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
int val = sqlite3_value_int( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *pStmt, int i){
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
Mem *pOut = columnMem(pStmt, i);
if( pOut->flags&MEM_Static ){
pOut->flags &= ~MEM_Static;
@@ -75995,13 +77057,13 @@ SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStm
return (sqlite3_value *)pOut;
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return val;
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
int iType = sqlite3_value_type( columnMem(pStmt,i) );
columnMallocFailure(pStmt);
return iType;
@@ -76065,12 +77127,12 @@ static const void *columnName(
** Return the name of the Nth column of the result set returned by SQL
** statement pStmt.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
}
@@ -76090,12 +77152,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt,
** Return the column declaration type (if applicable) of the 'i'th column
** of the result set of SQL statement pStmt.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
}
@@ -76108,12 +77170,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pS
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
}
@@ -76124,12 +77186,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stm
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
}
@@ -76140,12 +77202,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *
** NULL is returned if the result column is an expression or constant or
** anything else which is not an unambiguous reference to a database column.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
return columnName(
pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
}
@@ -76201,9 +77263,8 @@ static int vdbeUnbind(Vdbe *p, int i){
** as if there had been a schema change, on the first sqlite3_step() call
** following any change to the bindings of that parameter.
*/
- if( p->isPrepareV2 &&
- ((i<32 && p->expmask & ((u32)1 << i)) || p->expmask==0xffffffff)
- ){
+ assert( p->isPrepareV2 || p->expmask==0 );
+ if( p->expmask!=0 && (p->expmask & (i>=31 ? 0x80000000 : (u32)1<<i))!=0 ){
p->expired = 1;
}
return SQLITE_OK;
@@ -76246,7 +77307,7 @@ static int bindText(
/*
** Bind a blob value to an SQL statement variable.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
+SQLITE_API int sqlite3_bind_blob(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -76258,7 +77319,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
#endif
return bindText(pStmt, i, zData, nData, xDel, 0);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
+SQLITE_API int sqlite3_bind_blob64(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -76272,7 +77333,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
return bindText(pStmt, i, zData, (int)nData, xDel, 0);
}
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -76282,10 +77343,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, do
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
return sqlite3_bind_int64(p, i, (i64)iValue);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -76295,7 +77356,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sql
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
int rc;
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, i);
@@ -76304,7 +77365,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(
+SQLITE_API int sqlite3_bind_text(
sqlite3_stmt *pStmt,
int i,
const char *zData,
@@ -76313,7 +77374,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(
){
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(
+SQLITE_API int sqlite3_bind_text64(
sqlite3_stmt *pStmt,
int i,
const char *zData,
@@ -76330,7 +77391,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(
}
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
+SQLITE_API int sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
@@ -76340,7 +77401,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
switch( sqlite3_value_type((sqlite3_value*)pValue) ){
case SQLITE_INTEGER: {
@@ -76371,7 +77432,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, con
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
rc = vdbeUnbind(p, i);
@@ -76381,7 +77442,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i,
}
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
+SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
int rc;
Vdbe *p = (Vdbe *)pStmt;
sqlite3_mutex_enter(p->db->mutex);
@@ -76400,7 +77461,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i
** Return the number of wildcards that can be potentially bound to.
** This routine is added to support DBD::SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
return p ? p->nVar : 0;
}
@@ -76411,12 +77472,10 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
**
** The result is always UTF-8.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
Vdbe *p = (Vdbe*)pStmt;
- if( p==0 || i<1 || i>p->nzVar ){
- return 0;
- }
- return p->azVar[i-1];
+ if( p==0 ) return 0;
+ return sqlite3VListNumToName(p->pVList, i);
}
/*
@@ -76425,21 +77484,10 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *
** return 0.
*/
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){
- int i;
- if( p==0 ){
- return 0;
- }
- if( zName ){
- for(i=0; i<p->nzVar; i++){
- const char *z = p->azVar[i];
- if( z && strncmp(z,zName,nName)==0 && z[nName]==0 ){
- return i+1;
- }
- }
- }
- return 0;
+ if( p==0 || zName==0 ) return 0;
+ return sqlite3VListNameToNum(p->pVList, zName, nName);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
}
@@ -76473,16 +77521,18 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt
** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise
** SQLITE_OK is returned.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
+SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
Vdbe *pFrom = (Vdbe*)pFromStmt;
Vdbe *pTo = (Vdbe*)pToStmt;
if( pFrom->nVar!=pTo->nVar ){
return SQLITE_ERROR;
}
- if( pTo->isPrepareV2 && pTo->expmask ){
+ assert( pTo->isPrepareV2 || pTo->expmask==0 );
+ if( pTo->expmask ){
pTo->expired = 1;
}
- if( pFrom->isPrepareV2 && pFrom->expmask ){
+ assert( pFrom->isPrepareV2 || pFrom->expmask==0 );
+ if( pFrom->expmask ){
pFrom->expired = 1;
}
return sqlite3TransferBindings(pFromStmt, pToStmt);
@@ -76495,7 +77545,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt,
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->db : 0;
}
@@ -76503,16 +77553,16 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}
/*
** Return true if the prepared statement is in need of being reset.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
Vdbe *v = (Vdbe*)pStmt;
- return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
+ return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0;
}
/*
@@ -76521,7 +77571,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
** prepared statement for the database connection. Return NULL if there
** are no more.
*/
-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
sqlite3_stmt *pNext;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(pDb) ){
@@ -76542,7 +77592,7 @@ SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_
/*
** Return the value of a status counter for a prepared statement
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
Vdbe *pVdbe = (Vdbe*)pStmt;
u32 v;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -76559,7 +77609,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, i
/*
** Return the SQL associated with a prepared statement
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
return p ? p->zSql : 0;
}
@@ -76573,7 +77623,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
** expanded bound parameters.
*/
-SQLITE_API char *SQLITE_STDCALL sqlite3_expanded_sql(sqlite3_stmt *pStmt){
+SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
#ifdef SQLITE_OMIT_TRACE
return 0;
#else
@@ -76600,10 +77650,9 @@ static UnpackedRecord *vdbeUnpackRecord(
int nKey,
const void *pKey
){
- char *dummy; /* Dummy argument for AllocUnpackedRecord() */
UnpackedRecord *pRet; /* Return value */
- pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo, 0, 0, &dummy);
+ pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pRet ){
memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
@@ -76615,8 +77664,9 @@ static UnpackedRecord *vdbeUnpackRecord(
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or deleted.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p = db->pPreUpdate;
+ Mem *pMem;
int rc = SQLITE_OK;
/* Test that this call is being made from within an SQLITE_DELETE or
@@ -76625,6 +77675,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlit
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}
+ if( p->pPk ){
+ iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
+ }
if( iIdx>=p->pCsr->nField || iIdx<0 ){
rc = SQLITE_RANGE;
goto preupdate_old_out;
@@ -76638,7 +77691,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlit
nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
aRec = sqlite3DbMallocRaw(db, nRec);
if( !aRec ) goto preupdate_old_out;
- rc = sqlite3BtreeData(p->pCsr->uc.pCursor, 0, nRec, aRec);
+ rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
if( rc==SQLITE_OK ){
p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec);
if( !p->pUnpacked ) rc = SQLITE_NOMEM;
@@ -76650,12 +77703,14 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlit
p->aRecord = aRec;
}
- if( iIdx>=p->pUnpacked->nField ){
+ pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
+ if( iIdx==p->pTab->iPKey ){
+ sqlite3VdbeMemSetInt64(pMem, p->iKey1);
+ }else if( iIdx>=p->pUnpacked->nField ){
*ppValue = (sqlite3_value *)columnNullValue();
- }else{
- *ppValue = &p->pUnpacked->aMem[iIdx];
- if( iIdx==p->iPKey ){
- sqlite3VdbeMemSetInt64(*ppValue, p->iKey1);
+ }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){
+ if( pMem->flags & MEM_Int ){
+ sqlite3VdbeMemRealify(pMem);
}
}
@@ -76670,7 +77725,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlit
** This function is called from within a pre-update callback to retrieve
** the number of columns in the row being updated, deleted or inserted.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_count(sqlite3 *db){
+SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){
PreUpdate *p = db->pPreUpdate;
return (p ? p->keyinfo.nField : 0);
}
@@ -76688,7 +77743,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_count(sqlite3 *db){
** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL
** or SET DEFAULT action is considered a trigger.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_depth(sqlite3 *db){
+SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){
PreUpdate *p = db->pPreUpdate;
return (p ? p->v->nFrame : 0);
}
@@ -76699,7 +77754,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_depth(sqlite3 *db){
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or inserted.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
+SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p = db->pPreUpdate;
int rc = SQLITE_OK;
Mem *pMem;
@@ -76708,6 +77763,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlit
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
}
+ if( p->pPk && p->op!=SQLITE_UPDATE ){
+ iIdx = sqlite3ColumnOfIndex(p->pPk, iIdx);
+ }
if( iIdx>=p->pCsr->nField || iIdx<0 ){
rc = SQLITE_RANGE;
goto preupdate_new_out;
@@ -76719,7 +77777,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlit
UnpackedRecord *pUnpack = p->pNewUnpacked;
if( !pUnpack ){
Mem *pData = &p->v->aMem[p->iNewReg];
- rc = sqlite3VdbeMemExpandBlob(pData);
+ rc = ExpandBlob(pData);
if( rc!=SQLITE_OK ) goto preupdate_new_out;
pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
if( !pUnpack ){
@@ -76728,13 +77786,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlit
}
p->pNewUnpacked = pUnpack;
}
- if( iIdx>=pUnpack->nField ){
+ pMem = &pUnpack->aMem[iIdx];
+ if( iIdx==p->pTab->iPKey ){
+ sqlite3VdbeMemSetInt64(pMem, p->iKey2);
+ }else if( iIdx>=pUnpack->nField ){
pMem = (sqlite3_value *)columnNullValue();
- }else{
- pMem = &pUnpack->aMem[iIdx];
- if( iIdx==p->iPKey ){
- sqlite3VdbeMemSetInt64(pMem, p->iKey2);
- }
}
}else{
/* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
@@ -76753,7 +77809,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlit
assert( iIdx>=0 && iIdx<p->pCsr->nField );
pMem = &p->aNew[iIdx];
if( pMem->flags==0 ){
- if( iIdx==p->iPKey ){
+ if( iIdx==p->pTab->iPKey ){
sqlite3VdbeMemSetInt64(pMem, p->iKey2);
}else{
rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
@@ -76773,7 +77829,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlit
/*
** Return status data for a single loop within query pStmt.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement being queried */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Which metric to return */
@@ -76832,7 +77888,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
/*
** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
memset(p->anExec, 0, p->nOp * sizeof(i64));
}
@@ -77150,7 +78206,7 @@ SQLITE_API int sqlite3_found_count = 0;
** Test a register to see if it exceeds the current maximum blob size.
** If it does, record the new maximum blob size.
*/
-#if defined(SQLITE_TEST) && !defined(SQLITE_OMIT_BUILTIN_TEST)
+#if defined(SQLITE_TEST) && !defined(SQLITE_UNTESTABLE)
# define UPDATE_MAX_BLOBSIZE(P) updateMaxBlobsize(P)
#else
# define UPDATE_MAX_BLOBSIZE(P)
@@ -77260,7 +78316,7 @@ static VdbeCursor *allocateCursor(
}
if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
- memset(pCx, 0, sizeof(VdbeCursor));
+ memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
pCx->eCurType = eCurType;
pCx->iDb = iDb;
pCx->nField = nField;
@@ -77359,7 +78415,7 @@ static void applyAffinity(
** is appropriate. But only do the conversion if it is possible without
** loss of information and return the revised type of the argument.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
int eType = sqlite3_value_type(pVal);
if( eType==SQLITE_TEXT ){
Mem *pMem = (Mem*)pVal;
@@ -77442,9 +78498,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
}else{
c = 's';
}
-
- sqlite3_snprintf(100, zCsr, "%c", c);
- zCsr += sqlite3Strlen30(zCsr);
+ *(zCsr++) = c;
sqlite3_snprintf(100, zCsr, "%d[", pMem->n);
zCsr += sqlite3Strlen30(zCsr);
for(i=0; i<16 && i<pMem->n; i++){
@@ -77456,9 +78510,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
if( z<32 || z>126 ) *zCsr++ = '.';
else *zCsr++ = z;
}
-
- sqlite3_snprintf(100, zCsr, "]%s", encnames[pMem->enc]);
- zCsr += sqlite3Strlen30(zCsr);
+ *(zCsr++) = ']';
if( f & MEM_Zero ){
sqlite3_snprintf(100, zCsr,"+%dz",pMem->u.nZero);
zCsr += sqlite3Strlen30(zCsr);
@@ -77701,7 +78753,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
sqlite3 *db = p->db; /* The database */
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
u8 encoding = ENC(db); /* The database encoding */
- int iCompare = 0; /* Result of last OP_Compare operation */
+ int iCompare = 0; /* Result of last comparison */
unsigned nVmStep = 0; /* Number of virtual machine steps */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
@@ -77711,8 +78763,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
Mem *pIn2 = 0; /* 2nd input operand */
Mem *pIn3 = 0; /* 3rd input operand */
Mem *pOut = 0; /* Output operand */
- int *aPermute = 0; /* Permutation of columns for OP_Compare */
- i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
#endif
@@ -77727,7 +78777,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
}
assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
assert( p->bIsReader || p->readOnly!=0 );
- p->rc = SQLITE_OK;
p->iCurrentTime = 0;
assert( p->explain==0 );
p->pResultSet = 0;
@@ -78033,7 +79082,7 @@ case OP_Yield: { /* in1, jump */
}
/* Opcode: HaltIfNull P1 P2 P3 P4 P5
-** Synopsis: if r[P3]=null halt
+** Synopsis: if r[P3]=null halt
**
** Check the value in register P3. If it is NULL then Halt using
** parameter P1, P2, and P4 as if this were a Halt instruction. If the
@@ -78088,7 +79137,6 @@ case OP_Halt: {
p->nFrame--;
sqlite3VdbeSetChanges(db, p->nChange);
pcx = sqlite3VdbeFrameRestore(pFrame);
- lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
/* Instruction pcx is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
@@ -78105,7 +79153,7 @@ case OP_Halt: {
p->rc = pOp->p1;
p->errorAction = (u8)pOp->p2;
p->pc = pcx;
- assert( pOp->p5>=0 && pOp->p5<=4 );
+ assert( pOp->p5<=4 );
if( p->rc ){
if( pOp->p5 ){
static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
@@ -78246,7 +79294,7 @@ case OP_String: { /* out2 */
}
/* Opcode: Null P1 P2 P3 * *
-** Synopsis: r[P2..P3]=NULL
+** Synopsis: r[P2..P3]=NULL
**
** Write a NULL into registers P2. If P3 greater than P2, then also write
** NULL into register P3 and every register in between P2 and P3. If P3
@@ -78264,18 +79312,20 @@ case OP_Null: { /* out2 */
cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem+1 - p->nCursor) );
pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
+ pOut->n = 0;
while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
sqlite3VdbeMemSetNull(pOut);
pOut->flags = nullFlag;
+ pOut->n = 0;
cnt--;
}
break;
}
/* Opcode: SoftNull P1 * * * *
-** Synopsis: r[P1]=NULL
+** Synopsis: r[P1]=NULL
**
** Set register P1 to have the value NULL as seen by the OP_MakeRecord
** instruction, but do not free any string or blob memory associated with
@@ -78316,19 +79366,19 @@ case OP_Variable: { /* out2 */
Mem *pVar; /* Value being transferred */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
- assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
+ assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
pVar = &p->aVar[pOp->p1 - 1];
if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
- pOut = out2Prerelease(p, pOp);
+ pOut = &aMem[pOp->p2];
sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: Move P1 P2 P3 * *
-** Synopsis: r[P2@P3]=r[P1@P3]
+** Synopsis: r[P2@P3]=r[P1@P3]
**
** Move the P3 values in register P1..P1+P3-1 over into
** registers P2..P2+P3-1. Registers P1..P1+P3-1 are
@@ -78438,7 +79488,7 @@ case OP_IntCopy: { /* out2 */
}
/* Opcode: ResultRow P1 P2 * * *
-** Synopsis: output=r[P1@P2]
+** Synopsis: output=r[P1@P2]
**
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
@@ -78571,14 +79621,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
}
/* Opcode: Add P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]+r[P2]
+** Synopsis: r[P3]=r[P1]+r[P2]
**
** Add the value in register P1 to the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Multiply P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]*r[P2]
+** Synopsis: r[P3]=r[P1]*r[P2]
**
**
** Multiply the value in register P1 by the value in register P2
@@ -78586,14 +79636,14 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** If either input is NULL, the result is NULL.
*/
/* Opcode: Subtract P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]-r[P1]
+** Synopsis: r[P3]=r[P2]-r[P1]
**
** Subtract the value in register P1 from the value in register P2
** and store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: Divide P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]/r[P1]
+** Synopsis: r[P3]=r[P2]/r[P1]
**
** Divide the value in register P1 by the value in register P2
** and store the result in register P3 (P3=P2/P1). If the value in
@@ -78601,7 +79651,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
** NULL, the result is NULL.
*/
/* Opcode: Remainder P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]%r[P1]
+** Synopsis: r[P3]=r[P2]%r[P1]
**
** Compute the remainder after integer register P2 is divided by
** register P1 and store the result in register P3.
@@ -78799,23 +79849,21 @@ case OP_Function: {
for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
}
- memAboutToChange(p, pCtx->pOut);
+ memAboutToChange(p, pOut);
#ifdef SQLITE_DEBUG
for(i=0; i<pCtx->argc; i++){
assert( memIsValid(pCtx->argv[i]) );
REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
}
#endif
- MemSetTypeFlag(pCtx->pOut, MEM_Null);
+ MemSetTypeFlag(pOut, MEM_Null);
pCtx->fErrorOrAux = 0;
- db->lastRowid = lastRowid;
(*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
- lastRowid = db->lastRowid; /* Remember rowid changes made by xSFunc */
/* If the function returned an error, throw an exception */
if( pCtx->fErrorOrAux ){
if( pCtx->isError ){
- sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
rc = pCtx->isError;
}
sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
@@ -78824,31 +79872,31 @@ case OP_Function: {
/* Copy the result of the function into register P3 */
if( pOut->flags & (MEM_Str|MEM_Blob) ){
- sqlite3VdbeChangeEncoding(pCtx->pOut, encoding);
- if( sqlite3VdbeMemTooBig(pCtx->pOut) ) goto too_big;
+ sqlite3VdbeChangeEncoding(pOut, encoding);
+ if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
}
- REGISTER_TRACE(pOp->p3, pCtx->pOut);
- UPDATE_MAX_BLOBSIZE(pCtx->pOut);
+ REGISTER_TRACE(pOp->p3, pOut);
+ UPDATE_MAX_BLOBSIZE(pOut);
break;
}
/* Opcode: BitAnd P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]&r[P2]
+** Synopsis: r[P3]=r[P1]&r[P2]
**
** Take the bit-wise AND of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: BitOr P1 P2 P3 * *
-** Synopsis: r[P3]=r[P1]|r[P2]
+** Synopsis: r[P3]=r[P1]|r[P2]
**
** Take the bit-wise OR of the values in register P1 and P2 and
** store the result in register P3.
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftLeft P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]<<r[P1]
+** Synopsis: r[P3]=r[P2]<<r[P1]
**
** Shift the integer value in register P2 to the left by the
** number of bits specified by the integer in register P1.
@@ -78856,7 +79904,7 @@ case OP_Function: {
** If either input is NULL, the result is NULL.
*/
/* Opcode: ShiftRight P1 P2 P3 * *
-** Synopsis: r[P3]=r[P2]>>r[P1]
+** Synopsis: r[P3]=r[P2]>>r[P1]
**
** Shift the integer value in register P2 to the right by the
** number of bits specified by the integer in register P1.
@@ -78916,7 +79964,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
}
/* Opcode: AddImm P1 P2 * * *
-** Synopsis: r[P1]=r[P1]+P2
+** Synopsis: r[P1]=r[P1]+P2
**
** Add the constant P2 to the value in register P1.
** The result is always an integer.
@@ -79008,15 +80056,12 @@ case OP_Cast: { /* in1 */
}
#endif /* SQLITE_OMIT_CAST */
-/* Opcode: Lt P1 P2 P3 P4 P5
-** Synopsis: if r[P1]<r[P3] goto P2
-**
-** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
-** jump to address P2.
+/* Opcode: Eq P1 P2 P3 P4 P5
+** Synopsis: IF r[P3]==r[P1]
**
-** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
-** reg(P3) is NULL then take the jump. If the SQLITE_JUMPIFNULL
-** bit is clear then fall through if either operand is NULL.
+** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then
+** jump to address P2. Or if the SQLITE_STOREP2 flag is set in P5, then
+** store the result of comparison in register P2.
**
** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made
@@ -79030,61 +80075,78 @@ case OP_Cast: { /* in1 */
** the values are compared. If both values are blobs then memcmp() is
** used to determine the results of the comparison. If both values
** are text, then the appropriate collating function specified in
-** P4 is used to do the comparison. If P4 is not specified then
+** P4 is used to do the comparison. If P4 is not specified then
** memcmp() is used to compare text string. If both values are
** numeric, then a numeric comparison is used. If the two values
** are of different types, then numbers are considered less than
** strings and strings are considered less than blobs.
**
-** If the SQLITE_STOREP2 bit of P5 is set, then do not jump. Instead,
-** store a boolean result (either 0, or 1, or NULL) in register P2.
+** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
+** true or false and is never NULL. If both operands are NULL then the result
+** of comparison is true. If either operand is NULL then the result is false.
+** If neither operand is NULL the result is the same as it would be if
+** the SQLITE_NULLEQ flag were omitted from P5.
**
-** If the SQLITE_NULLEQ bit is set in P5, then NULL values are considered
-** equal to one another, provided that they do not have their MEM_Cleared
-** bit set.
+** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the
+** content of r[P2] is only changed if the new value is NULL or 0 (false).
+** In other words, a prior r[P2] value will not be overwritten by 1 (true).
*/
/* Opcode: Ne P1 P2 P3 P4 P5
-** Synopsis: if r[P1]!=r[P3] goto P2
+** Synopsis: IF r[P3]!=r[P1]
**
-** This works just like the Lt opcode except that the jump is taken if
-** the operands in registers P1 and P3 are not equal. See the Lt opcode for
+** This works just like the Eq opcode except that the jump is taken if
+** the operands in registers P1 and P3 are not equal. See the Eq opcode for
** additional information.
**
-** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
-** true or false and is never NULL. If both operands are NULL then the result
-** of comparison is false. If either operand is NULL then the result is true.
-** If neither operand is NULL the result is the same as it would be if
-** the SQLITE_NULLEQ flag were omitted from P5.
+** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the
+** content of r[P2] is only changed if the new value is NULL or 1 (true).
+** In other words, a prior r[P2] value will not be overwritten by 0 (false).
*/
-/* Opcode: Eq P1 P2 P3 P4 P5
-** Synopsis: if r[P1]==r[P3] goto P2
+/* Opcode: Lt P1 P2 P3 P4 P5
+** Synopsis: IF r[P3]<r[P1]
**
-** This works just like the Lt opcode except that the jump is taken if
-** the operands in registers P1 and P3 are equal.
-** See the Lt opcode for additional information.
+** Compare the values in register P1 and P3. If reg(P3)<reg(P1) then
+** jump to address P2. Or if the SQLITE_STOREP2 flag is set in P5 store
+** the result of comparison (0 or 1 or NULL) into register P2.
**
-** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either
-** true or false and is never NULL. If both operands are NULL then the result
-** of comparison is true. If either operand is NULL then the result is false.
-** If neither operand is NULL the result is the same as it would be if
-** the SQLITE_NULLEQ flag were omitted from P5.
+** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or
+** reg(P3) is NULL then the take the jump. If the SQLITE_JUMPIFNULL
+** bit is clear then fall through if either operand is NULL.
+**
+** The SQLITE_AFF_MASK portion of P5 must be an affinity character -
+** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made
+** to coerce both inputs according to this affinity before the
+** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric
+** affinity is used. Note that the affinity conversions are stored
+** back into the input registers P1 and P3. So this opcode can cause
+** persistent changes to registers P1 and P3.
+**
+** Once any conversions have taken place, and neither value is NULL,
+** the values are compared. If both values are blobs then memcmp() is
+** used to determine the results of the comparison. If both values
+** are text, then the appropriate collating function specified in
+** P4 is used to do the comparison. If P4 is not specified then
+** memcmp() is used to compare text string. If both values are
+** numeric, then a numeric comparison is used. If the two values
+** are of different types, then numbers are considered less than
+** strings and strings are considered less than blobs.
*/
/* Opcode: Le P1 P2 P3 P4 P5
-** Synopsis: if r[P1]<=r[P3] goto P2
+** Synopsis: IF r[P3]<=r[P1]
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is less than or equal to the content of
** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Gt P1 P2 P3 P4 P5
-** Synopsis: if r[P1]>r[P3] goto P2
+** Synopsis: IF r[P3]>r[P1]
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than the content of
** register P1. See the Lt opcode for additional information.
*/
/* Opcode: Ge P1 P2 P3 P4 P5
-** Synopsis: if r[P1]>=r[P3] goto P2
+** Synopsis: IF r[P3]>=r[P1]
**
** This works just like the Lt opcode except that the jump is taken if
** the content of register P3 is greater than or equal to the content of
@@ -79096,7 +80158,7 @@ case OP_Lt: /* same as TK_LT, jump, in1, in3 */
case OP_Le: /* same as TK_LE, jump, in1, in3 */
case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
- int res; /* Result of the comparison of pIn1 against pIn3 */
+ int res, res2; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
u16 flags1; /* Copy of initial value of pIn1->flags */
u16 flags3; /* Copy of initial value of pIn3->flags */
@@ -79115,13 +80177,12 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
assert( (flags1 & MEM_Cleared)==0 );
assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
- if( (flags1&MEM_Null)!=0
- && (flags3&MEM_Null)!=0
+ if( (flags1&flags3&MEM_Null)!=0
&& (flags3&MEM_Cleared)==0
){
- res = 0; /* Results are equal */
+ res = 0; /* Operands are equal */
}else{
- res = 1; /* Results are not equal */
+ res = 1; /* Operands are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
@@ -79130,6 +80191,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
*/
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
+ iCompare = 1; /* Operands are not equal */
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
@@ -79148,12 +80210,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
+ testcase( flags3!=pIn3->flags ); /* Possible if pIn1==pIn3 */
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn3,0);
}
}
+ /* Handle the common case of integer comparison here, as an
+ ** optimization, to avoid a call to sqlite3MemCompare() */
+ if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){
+ if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; }
+ if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; }
+ res = 0;
+ goto compare_op;
+ }
}else if( affinity==SQLITE_AFF_TEXT ){
if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn1->flags & MEM_Int );
@@ -79161,7 +80232,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);
- flags3 = pIn3->flags;
+ assert( pIn1!=pIn3 );
}
if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){
testcase( pIn3->flags & MEM_Int );
@@ -79172,23 +80243,16 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
}
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
- if( flags1 & MEM_Zero ){
- sqlite3VdbeMemExpandBlob(pIn1);
- flags1 &= ~MEM_Zero;
- }
- if( flags3 & MEM_Zero ){
- sqlite3VdbeMemExpandBlob(pIn3);
- flags3 &= ~MEM_Zero;
- }
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
+compare_op:
switch( pOp->opcode ){
- case OP_Eq: res = res==0; break;
- case OP_Ne: res = res!=0; break;
- case OP_Lt: res = res<0; break;
- case OP_Le: res = res<=0; break;
- case OP_Gt: res = res>0; break;
- default: res = res>=0; break;
+ case OP_Eq: res2 = res==0; break;
+ case OP_Ne: res2 = res; break;
+ case OP_Lt: res2 = res<0; break;
+ case OP_Le: res2 = res<=0; break;
+ case OP_Gt: res2 = res>0; break;
+ default: res2 = res>=0; break;
}
/* Undo any changes made by applyAffinity() to the input registers. */
@@ -79199,23 +80263,59 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
+ iCompare = res;
+ res2 = res2!=0; /* For this path res2 must be exactly 0 or 1 */
+ if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){
+ /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1
+ ** and prevents OP_Ne from overwriting NULL with 0. This flag
+ ** is only used in contexts where either:
+ ** (1) op==OP_Eq && (r[P2]==NULL || r[P2]==0)
+ ** (2) op==OP_Ne && (r[P2]==NULL || r[P2]==1)
+ ** Therefore it is not necessary to check the content of r[P2] for
+ ** NULL. */
+ assert( pOp->opcode==OP_Ne || pOp->opcode==OP_Eq );
+ assert( res2==0 || res2==1 );
+ testcase( res2==0 && pOp->opcode==OP_Eq );
+ testcase( res2==1 && pOp->opcode==OP_Eq );
+ testcase( res2==0 && pOp->opcode==OP_Ne );
+ testcase( res2==1 && pOp->opcode==OP_Ne );
+ if( (pOp->opcode==OP_Eq)==res2 ) break;
+ }
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = res;
+ pOut->u.i = res2;
REGISTER_TRACE(pOp->p2, pOut);
}else{
VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
- if( res ){
+ if( res2 ){
goto jump_to_p2;
}
}
break;
}
+/* 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.
+*/
+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 );
+ VdbeBranchTaken(iCompare!=0, 2);
+ if( iCompare!=0 ) goto jump_to_p2;
+ break;
+}
+
+
/* Opcode: Permutation * * * P4 *
**
-** Set the permutation used by the OP_Compare operator to be the array
-** of integers in P4.
+** Set the permutation used by the OP_Compare operator in the next
+** instruction. The permutation is stored in the P4 operand.
**
** The permutation is only valid until the next OP_Compare that has
** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
@@ -79227,7 +80327,8 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
case OP_Permutation: {
assert( pOp->p4type==P4_INTARRAY );
assert( pOp->p4.ai );
- aPermute = pOp->p4.ai + 1;
+ assert( pOp[1].opcode==OP_Compare );
+ assert( pOp[1].p5 & OPFLAG_PERMUTE );
break;
}
@@ -79260,15 +80361,24 @@ case OP_Compare: {
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
+ int *aPermute; /* The permutation */
- if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
+ if( (pOp->p5 & OPFLAG_PERMUTE)==0 ){
+ aPermute = 0;
+ }else{
+ assert( pOp>aOp );
+ assert( pOp[-1].opcode==OP_Permutation );
+ assert( pOp[-1].p4type==P4_INTARRAY );
+ aPermute = pOp[-1].p4.ai + 1;
+ assert( aPermute!=0 );
+ }
n = pOp->p3;
pKeyInfo = pOp->p4.pKeyInfo;
assert( n>0 );
assert( pKeyInfo!=0 );
p1 = pOp->p1;
p2 = pOp->p2;
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
@@ -79294,7 +80404,6 @@ case OP_Compare: {
break;
}
}
- aPermute = 0;
break;
}
@@ -79407,23 +80516,39 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
/* Opcode: Once P1 P2 * * *
**
-** Check the "once" flag number P1. If it is set, jump to instruction P2.
-** Otherwise, set the flag and fall through to the next instruction.
-** In other words, this opcode causes all following opcodes up through P2
-** (but not including P2) to run just once and to be skipped on subsequent
-** times through the loop.
+** Fall through to the next instruction the first time this opcode is
+** encountered on each invocation of the byte-code program. Jump to P2
+** on the second and all subsequent encounters during the same invocation.
**
-** All "once" flags are initially cleared whenever a prepared statement
-** first begins to run.
+** Top-level programs determine first invocation by comparing the P1
+** operand against the P1 operand on the OP_Init opcode at the beginning
+** of the program. If the P1 values differ, then fall through and make
+** the P1 of this opcode equal to the P1 of OP_Init. If P1 values are
+** the same then take the jump.
+**
+** For subprograms, there is a bitmask in the VdbeFrame that determines
+** whether or not the jump should be taken. The bitmask is necessary
+** because the self-altering code trick does not work for recursive
+** triggers.
*/
case OP_Once: { /* jump */
- assert( pOp->p1<p->nOnceFlag );
- VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
- if( p->aOnceFlag[pOp->p1] ){
- goto jump_to_p2;
+ u32 iAddr; /* Address of this instruction */
+ assert( p->aOp[0].opcode==OP_Init );
+ if( p->pFrame ){
+ iAddr = (int)(pOp - p->aOp);
+ if( (p->pFrame->aOnce[iAddr/8] & (1<<(iAddr & 7)))!=0 ){
+ VdbeBranchTaken(1, 2);
+ goto jump_to_p2;
+ }
+ p->pFrame->aOnce[iAddr/8] |= 1<<(iAddr & 7);
}else{
- p->aOnceFlag[pOp->p1] = 1;
+ if( p->aOp[0].p1==pOp->p1 ){
+ VdbeBranchTaken(1, 2);
+ goto jump_to_p2;
+ }
}
+ VdbeBranchTaken(0, 2);
+ pOp->p1 = p->aOp[0].p1;
break;
}
@@ -79461,7 +80586,7 @@ case OP_IfNot: { /* jump, in1 */
}
/* Opcode: IsNull P1 P2 * * *
-** Synopsis: if r[P1]==NULL goto P2
+** Synopsis: if r[P1]==NULL goto P2
**
** Jump to P2 if the value in register P1 is NULL.
*/
@@ -79489,7 +80614,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
}
/* Opcode: Column P1 P2 P3 P4 P5
-** Synopsis: r[P3]=PX
+** Synopsis: r[P3]=PX
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction. (See the MakeRecord opcode for additional
@@ -79548,7 +80673,6 @@ case OP_Column: {
assert( pC->eCurType!=CURTYPE_VTAB );
assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
assert( pC->eCurType!=CURTYPE_SORTER );
- pCrsr = pC->uc.pCursor;
if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
if( pC->nullRow ){
@@ -79564,6 +80688,7 @@ case OP_Column: {
goto op_column_out;
}
}else{
+ pCrsr = pC->uc.pCursor;
assert( pC->eCurType==CURTYPE_BTREE );
assert( pCrsr );
assert( sqlite3BtreeCursorIsValid(pCrsr) );
@@ -79627,7 +80752,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(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
+ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
zData = (u8*)sMem.z;
}else{
@@ -79736,12 +80861,16 @@ case OP_Column: {
** 2. the length(X) function if X is a blob, and
** 3. if the content length is zero.
** So we might as well use bogus content rather than reading
- ** content from disk. */
- static u8 aZero[8]; /* This is the bogus content */
+ ** content from disk.
+ **
+ ** 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.
+ */
+ static u8 aZero[16]; /* This is the bogus content */
sqlite3VdbeSerialGet(aZero, t, pDest);
}else{
- rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
- pDest);
+ rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
pDest->flags &= ~MEM_Ephem;
@@ -79856,6 +80985,20 @@ case OP_MakeRecord: {
}while( zAffinity[0] );
}
+#ifdef SQLITE_ENABLE_NULL_TRIM
+ /* NULLs can be safely trimmed from the end of the record, as long as
+ ** as the schema format is 2 or more and none of the omitted columns
+ ** have a non-NULL default value. Also, the record must be left with
+ ** at least one field. If P5>0 then it will be one more than the
+ ** index of the right-most column with a non-NULL default value */
+ if( pOp->p5 ){
+ while( (pLast->flags & MEM_Null)!=0 && nField>pOp->p5 ){
+ pLast--;
+ nField--;
+ }
+ }
+#endif
+
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
*/
@@ -80255,12 +81398,12 @@ case OP_Transaction: {
rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
testcase( rc==SQLITE_BUSY_SNAPSHOT );
testcase( rc==SQLITE_BUSY_RECOVERY );
- if( (rc&0xff)==SQLITE_BUSY ){
- p->pc = (int)(pOp - aOp);
- p->rc = rc;
- goto vdbe_return;
- }
if( rc!=SQLITE_OK ){
+ if( (rc&0xff)==SQLITE_BUSY ){
+ p->pc = (int)(pOp - aOp);
+ p->rc = rc;
+ goto vdbe_return;
+ }
goto abort_due_to_error;
}
@@ -80287,10 +81430,9 @@ case OP_Transaction: {
}
/* Gather the schema version number for checking:
- ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite
- ** each time a query is executed to ensure that the internal cache of the
- ** schema used when compiling the SQL query matches the schema of the
- ** database against which the compiled query is actually executed.
+ ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
+ ** version is checked to ensure that the schema has not changed since the
+ ** SQL statement was prepared.
*/
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
iGen = db->aDb[pOp->p1].pSchema->iGeneration;
@@ -80607,10 +81749,10 @@ case OP_OpenEphemeral: {
if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
pCx->isEphemeral = 1;
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt,
+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
+ rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
@@ -80618,21 +81760,20 @@ case OP_OpenEphemeral: {
** opening it. If a transient table is required, just use the
** automatically created table with root-page 1 (an BLOB_INTKEY table).
*/
- if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
+ if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
+ rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
assert( pKeyInfo->db==db );
assert( pKeyInfo->enc==ENC(db) );
- pCx->pKeyInfo = pKeyInfo;
- rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR,
+ rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR,
pKeyInfo, pCx->uc.pCursor);
}
pCx->isTable = 0;
}else{
- rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR,
+ rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
0, pCx->uc.pCursor);
pCx->isTable = 1;
}
@@ -80864,7 +82005,8 @@ case OP_SeekGT: { /* jump, in3 */
if( pC->isTable ){
/* The BTREE_SEEK_EQ flag is only set on index cursors */
- assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 );
+ assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0
+ || CORRUPT_DB );
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
@@ -80951,7 +82093,6 @@ case OP_SeekGT: { /* jump, in3 */
#ifdef SQLITE_DEBUG
{ int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
- ExpandBlob(r.aMem);
r.eqSeen = 0;
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, &r, 0, 0, &res);
if( rc!=SQLITE_OK ){
@@ -80999,7 +82140,6 @@ seek_not_found:
}
break;
}
-
/* Opcode: Found P1 P2 P3 P4 *
** Synopsis: key=r[P3@P4]
@@ -81068,10 +82208,9 @@ case OP_Found: { /* jump, in3 */
int ii;
VdbeCursor *pC;
int res;
- char *pFree;
+ UnpackedRecord *pFree;
UnpackedRecord *pIdxKey;
UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
#ifdef SQLITE_TEST
if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
@@ -81088,26 +82227,24 @@ case OP_Found: { /* jump, in3 */
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->uc.pCursor!=0 );
assert( pC->isTable==0 );
- pFree = 0;
if( pOp->p4.i>0 ){
r.pKeyInfo = pC->pKeyInfo;
r.nField = (u16)pOp->p4.i;
r.aMem = pIn3;
+#ifdef SQLITE_DEBUG
for(ii=0; ii<r.nField; ii++){
assert( memIsValid(&r.aMem[ii]) );
- ExpandBlob(&r.aMem[ii]);
-#ifdef SQLITE_DEBUG
+ assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 );
if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
-#endif
}
+#endif
pIdxKey = &r;
+ pFree = 0;
}else{
- pIdxKey = sqlite3VdbeAllocUnpackedRecord(
- pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
- );
+ pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
if( pIdxKey==0 ) goto no_mem;
assert( pIn3->flags & MEM_Blob );
- ExpandBlob(pIn3);
+ (void)ExpandBlob(pIn3);
sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
pIdxKey->default_rc = 0;
@@ -81124,7 +82261,7 @@ case OP_Found: { /* jump, in3 */
}
}
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
- sqlite3DbFree(db, pFree);
+ if( pFree ) sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
@@ -81351,7 +82488,7 @@ case OP_NewRowid: { /* out2 */
sqlite3VdbeMemIntegerify(pMem);
assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
- rc = SQLITE_FULL; /* IMP: R-12275-61338 */
+ rc = SQLITE_FULL; /* IMP: R-17817-00630 */
goto abort_due_to_error;
}
if( v<pMem->u.i+1 ){
@@ -81403,15 +82540,10 @@ case OP_NewRowid: { /* out2 */
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
**
-** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of
-** the last seek operation (OP_NotExists or OP_SeekRowid) was a success,
-** then this
-** operation will not attempt to find the appropriate row before doing
-** the insert but will instead overwrite the row that the cursor is
-** currently pointing to. Presumably, the prior OP_NotExists or
-** OP_SeekRowid opcode
-** has already positioned the cursor correctly. This is an optimization
-** that boosts performance by avoiding redundant seeks.
+** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
+** run faster by avoiding an unnecessary seek on cursor P1. However,
+** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
+** seeks on the cursor or if the most recent seek used a key equal to P3.
**
** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an
** UPDATE operation. Otherwise (if the flag is clear) then this opcode
@@ -81432,7 +82564,7 @@ case OP_NewRowid: { /* out2 */
** for indices is OP_IdxInsert.
*/
/* Opcode: InsertInt P1 P2 P3 P4 P5
-** Synopsis: intkey=P3 data=r[P2]
+** Synopsis: intkey=P3 data=r[P2]
**
** This works exactly like OP_Insert except that the key is the
** integer value P3, not the value of the integer stored in register P3.
@@ -81456,7 +82588,7 @@ case OP_InsertInt: {
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->uc.pCursor!=0 );
- assert( pC->isTable );
+ assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable );
assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC );
REGISTER_TRACE(pOp->p2, pData);
@@ -81472,14 +82604,13 @@ case OP_InsertInt: {
}
if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
- assert( pC->isTable );
assert( pC->iDb>=0 );
- zDb = db->aDb[pC->iDb].zName;
+ zDb = db->aDb[pC->iDb].zDbSName;
pTab = pOp->p4.pTab;
- assert( HasRowid(pTab) );
+ assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
}else{
- pTab = 0; /* Not needed. Silence a comiler warning. */
+ pTab = 0; /* Not needed. Silence a compiler warning. */
zDb = 0; /* Not needed. Silence a compiler warning. */
}
@@ -81491,10 +82622,11 @@ case OP_InsertInt: {
){
sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2);
}
+ if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = x.nKey;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
if( pData->flags & MEM_Null ){
x.pData = 0;
x.nData = 0;
@@ -81511,7 +82643,7 @@ case OP_InsertInt: {
}
x.pKey = 0;
rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
- (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
+ (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult
);
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
@@ -81548,7 +82680,7 @@ case OP_InsertInt: {
** P1 must not be pseudo-table. It has to be a real table with
** multiple rows.
**
-** If P4 is not NULL then it points to a Table struture. In this case either
+** If P4 is not NULL then it points to a Table object. In this case either
** the update or pre-update hook, or both, may be invoked. The P1 cursor must
** have been positioned using OP_NotFound prior to invoking this opcode in
** this case. Specifically, if one is configured, the pre-update hook is
@@ -81591,7 +82723,7 @@ case OP_Delete: {
if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
assert( pC->iDb>=0 );
assert( pOp->p4.pTab!=0 );
- zDb = db->aDb[pC->iDb].zName;
+ zDb = db->aDb[pC->iDb].zDbSName;
pTab = pOp->p4.pTab;
if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
@@ -81603,8 +82735,11 @@ case OP_Delete: {
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/* Invoke the pre-update-hook if required. */
- if( db->xPreUpdateCallback && pOp->p4.pTab && HasRowid(pTab) ){
- assert( !(opflags & OPFLAG_ISUPDATE) || (aMem[pOp->p3].flags & MEM_Int) );
+ if( db->xPreUpdateCallback && pOp->p4.pTab ){
+ assert( !(opflags & OPFLAG_ISUPDATE)
+ || HasRowid(pTab)==0
+ || (aMem[pOp->p3].flags & MEM_Int)
+ );
sqlite3VdbePreUpdateHook(p, pC,
(opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE,
zDb, pTab, pC->movetoTarget,
@@ -81635,6 +82770,7 @@ case OP_Delete: {
rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
pC->cacheStatus = CACHE_STALE;
+ pC->seekResult = 0;
if( rc ) goto abort_due_to_error;
/* Invoke the update-hook if required. */
@@ -81663,7 +82799,7 @@ case OP_ResetCount: {
}
/* Opcode: SorterCompare P1 P2 P3 P4
-** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2
+** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2
**
** P1 is a sorter cursor. This instruction compares a prefix of the
** record blob in register P3 against a prefix of the entry that
@@ -81721,50 +82857,51 @@ case OP_SorterData: {
break;
}
-/* Opcode: RowData P1 P2 * * *
+/* Opcode: RowData P1 P2 P3 * *
** Synopsis: r[P2]=data
**
-** Write into register P2 the complete row data for cursor P1.
+** Write into register P2 the complete row content for the row at
+** which cursor P1 is currently pointing.
** There is no interpretation of the data.
** It is just copied onto the P2 register exactly as
** it is found in the database file.
**
+** If cursor P1 is an index, then the content is the key of the row.
+** If cursor P2 is a table, then the content extracted is the data.
+**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
** of a real table, not a pseudo-table.
-*/
-/* Opcode: RowKey P1 P2 * * *
-** Synopsis: r[P2]=key
**
-** Write into register P2 the complete row key for cursor P1.
-** There is no interpretation of the data.
-** The key is copied onto the P2 register exactly as
-** it is found in the database file.
+** If P3!=0 then this opcode is allowed to make an ephermeral pointer
+** into the database page. That means that the content of the output
+** register will be invalidated as soon as the cursor moves - including
+** moves caused by other cursors that "save" the the current cursors
+** position in order that they can write to the same table. If P3==0
+** then a copy of the data is made into memory. P3!=0 is faster, but
+** P3==0 is safer.
**
-** If the P1 cursor must be pointing to a valid row (not a NULL row)
-** of a real table, not a pseudo-table.
+** If P3!=0 then the content of the P2 register is unsuitable for use
+** in OP_Result and any OP_Result will invalidate the P2 register content.
+** The P2 register content is invalidated by opcodes like OP_Function or
+** by any use of another cursor pointing to the same table.
*/
-case OP_RowKey:
case OP_RowData: {
VdbeCursor *pC;
BtCursor *pCrsr;
u32 n;
- pOut = &aMem[pOp->p2];
- memAboutToChange(p, pOut);
+ pOut = out2Prerelease(p, pOp);
- /* Note that RowKey and RowData are really exactly the same instruction */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
pC = p->apCsr[pOp->p1];
assert( pC!=0 );
assert( pC->eCurType==CURTYPE_BTREE );
assert( isSorter(pC)==0 );
- assert( pC->isTable || pOp->opcode!=OP_RowData );
- assert( pC->isTable==0 || pOp->opcode==OP_RowData );
assert( pC->nullRow==0 );
assert( pC->uc.pCursor!=0 );
pCrsr = pC->uc.pCursor;
- /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
+ /* The OP_RowData opcodes always follow OP_NotExists or
** OP_SeekRowid or OP_Rewind/Op_Next with no intervening instructions
** that might invalidate the cursor.
** If this where not the case, on of the following assert()s
@@ -81784,18 +82921,9 @@ case OP_RowData: {
goto too_big;
}
testcase( n==0 );
- if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
- goto no_mem;
- }
- pOut->n = n;
- MemSetTypeFlag(pOut, MEM_Blob);
- if( pC->isTable==0 ){
- rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
- }else{
- rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
- }
+ rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut);
if( rc ) goto abort_due_to_error;
- pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
+ if( !pOp->p3 ) Deephemeralize(pOut);
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
break;
@@ -81884,6 +83012,13 @@ case OP_NullRow: {
** This opcode leaves the cursor configured to move in reverse order,
** from the end toward the beginning. In other words, the cursor is
** configured to use Prev, not Next.
+**
+** If P3 is -1, then the cursor is positioned at the end of the btree
+** for the purpose of appending a new entry onto the btree. In that
+** case P2 must be 0. It is assumed that the cursor is used only for
+** appending and so if the cursor is valid, then the cursor must already
+** be pointing at the end of the btree and so no changes are made to
+** the cursor.
*/
case OP_Last: { /* jump */
VdbeCursor *pC;
@@ -81897,23 +83032,63 @@ case OP_Last: { /* jump */
pCrsr = pC->uc.pCursor;
res = 0;
assert( pCrsr!=0 );
- rc = sqlite3BtreeLast(pCrsr, &res);
- pC->nullRow = (u8)res;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
pC->seekResult = pOp->p3;
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
+ if( pOp->p3==0 || !sqlite3BtreeCursorIsValidNN(pCrsr) ){
+ rc = sqlite3BtreeLast(pCrsr, &res);
+ pC->nullRow = (u8)res;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
+ if( rc ) goto abort_due_to_error;
+ if( pOp->p2>0 ){
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
+ }
+ }else{
+ assert( pOp->p2==0 );
+ }
+ break;
+}
+
+/* Opcode: IfSmaller P1 P2 P3 * *
+**
+** Estimate the number of rows in the table P1. Jump to P2 if that
+** estimate is less than approximately 2**(0.1*P3).
+*/
+case OP_IfSmaller: { /* jump */
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ i64 sz;
+
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pCrsr = pC->uc.pCursor;
+ assert( pCrsr );
+ rc = sqlite3BtreeFirst(pCrsr, &res);
if( rc ) goto abort_due_to_error;
- if( pOp->p2>0 ){
- VdbeBranchTaken(res!=0,2);
- if( res ) goto jump_to_p2;
+ if( res==0 ){
+ sz = sqlite3BtreeRowCountEst(pCrsr);
+ if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)<pOp->p3 ) res = 1;
}
+ VdbeBranchTaken(res!=0,2);
+ if( res ) goto jump_to_p2;
break;
}
+/* Opcode: SorterSort P1 P2 * * *
+**
+** After all records have been inserted into the Sorter object
+** identified by P1, invoke this opcode to actually do the sorting.
+** Jump to P2 if there are no records to be sorted.
+**
+** This opcode is an alias for OP_Sort and OP_Rewind that is used
+** for Sorter objects.
+*/
/* Opcode: Sort P1 P2 * * *
**
** This opcode does exactly the same thing as OP_Rewind except that
@@ -82041,6 +83216,13 @@ case OP_Rewind: { /* jump */
** This opcode works just like Prev except that if cursor P1 is not
** open it behaves a no-op.
*/
+/* Opcode: SorterNext P1 P2 * * P5
+**
+** This opcode works just like OP_Next except that P1 must be a
+** sorter object for which the OP_SorterSort opcode has been
+** invoked. This opcode advances the cursor to the next sorted
+** record, or jumps to P2 if there are no more sorted records.
+*/
case OP_SorterNext: { /* jump */
VdbeCursor *pC;
int res;
@@ -82097,27 +83279,41 @@ next_tail:
goto check_for_interrupt;
}
-/* Opcode: IdxInsert P1 P2 P3 * P5
+/* Opcode: IdxInsert P1 P2 P3 P4 P5
** Synopsis: key=r[P2]
**
** Register P2 holds an SQL index key made using the
** MakeRecord instructions. This opcode writes that key
** into the index P1. Data for the entry is nil.
**
-** P3 is a flag that provides a hint to the b-tree layer that this
-** insert is likely to be an append.
+** If P4 is not zero, then it is the number of values in the unpacked
+** key of reg(P2). In that case, P3 is the index of the first register
+** for the unpacked key. The availability of the unpacked key can sometimes
+** be an optimization.
+**
+** If P5 has the OPFLAG_APPEND bit set, that is a hint to the b-tree layer
+** that this insert is likely to be an append.
**
** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is
** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear,
** then the change counter is unchanged.
**
-** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have
-** just done a seek to the spot where the new entry is to be inserted.
-** This flag avoids doing an extra seek.
+** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might
+** run faster by avoiding an unnecessary seek on cursor P1. However,
+** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior
+** seeks on the cursor or if the most recent seek used a key equivalent
+** to P2.
**
** This instruction only works for indices. The equivalent instruction
** for tables is OP_Insert.
*/
+/* Opcode: SorterInsert P1 P2 * * *
+** Synopsis: key=r[P2]
+**
+** Register P2 holds an SQL index key made using the
+** 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 */
VdbeCursor *pC;
@@ -82139,10 +83335,10 @@ case OP_IdxInsert: { /* in2 */
}else{
x.nKey = pIn2->n;
x.pKey = pIn2->z;
- x.nData = 0;
- x.nZero = 0;
- x.pData = 0;
- rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, pOp->p3,
+ 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 );
@@ -82186,11 +83382,12 @@ case OP_IdxDelete: {
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
+ pC->seekResult = 0;
break;
}
/* Opcode: Seek P1 * P3 P4 *
-** Synopsis: Move P3 to P1.rowid
+** Synopsis: Move P3 to P1.rowid
**
** P1 is an open index cursor and P3 is a cursor on the corresponding
** table. This opcode does a deferred seek of the P3 table cursor
@@ -82263,7 +83460,6 @@ case OP_IdxRowid: { /* out2 */
}else{
pOut = out2Prerelease(p, pOp);
pOut->u.i = rowid;
- pOut->flags = MEM_Int;
}
}else{
assert( pOp->opcode==OP_IdxRowid );
@@ -82527,6 +83723,18 @@ case OP_CreateTable: { /* out2 */
break;
}
+/* Opcode: SqlExec * * * P4 *
+**
+** Run the SQL statement or statements specified in the P4 string.
+*/
+case OP_SqlExec: {
+ db->nSqlExec++;
+ rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0);
+ db->nSqlExec--;
+ if( rc ) goto abort_due_to_error;
+ break;
+}
+
/* Opcode: ParseSchema P1 * * P4 *
**
** Read and parse all entries from the SQLITE_MASTER table of database P1
@@ -82555,13 +83763,13 @@ case OP_ParseSchema: {
assert( iDb>=0 && iDb<db->nDb );
assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
/* Used to be a conditional */ {
- zMaster = SCHEMA_TABLE(iDb);
+ zMaster = MASTER_NAME;
initData.db = db;
initData.iDb = pOp->p1;
initData.pzErrMsg = &p->zErrMsg;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
- db->aDb[iDb].zName, zMaster, pOp->p4.z);
+ db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
if( zSql==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
@@ -82647,7 +83855,7 @@ case OP_DropTrigger: {
** register P1 the text of an error message describing any problems.
** If no problems are found, store a NULL in register P1.
**
-** The register P3 contains the maximum number of allowed errors.
+** The register P3 contains one less than the maximum number of allowed errors.
** At most reg(P3) errors will be reported.
** In other words, the analysis stops as soon as reg(P1) errors are
** seen. Reg(P1) is updated with the number of errors remaining.
@@ -82680,14 +83888,14 @@ case OP_IntegrityCk: {
assert( pOp->p5<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p5) );
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
- (int)pnErr->u.i, &nErr);
- pnErr->u.i -= nErr;
+ (int)pnErr->u.i+1, &nErr);
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
assert( z==0 );
}else if( z==0 ){
goto no_mem;
}else{
+ pnErr->u.i -= nErr-1;
sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
@@ -82697,7 +83905,7 @@ case OP_IntegrityCk: {
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* Opcode: RowSetAdd P1 P2 * * *
-** Synopsis: rowset(P1)=r[P2]
+** Synopsis: rowset(P1)=r[P2]
**
** Insert the integer value held by register P2 into a boolean index
** held in register P1.
@@ -82717,7 +83925,7 @@ case OP_RowSetAdd: { /* in1, in2 */
}
/* Opcode: RowSetRead P1 P2 P3 * *
-** Synopsis: r[P3]=rowset(P1)
+** Synopsis: r[P3]=rowset(P1)
**
** Extract the smallest value from boolean index P1 and put that value into
** register P3. Or, if boolean index P1 is initially empty, leave P3
@@ -82866,8 +84074,8 @@ case OP_Program: { /* jump */
if( pProgram->nCsr==0 ) nMem++;
nByte = ROUND8(sizeof(VdbeFrame))
+ nMem * sizeof(Mem)
- + pProgram->nCsr * sizeof(VdbeCursor *)
- + pProgram->nOnce * sizeof(u8);
+ + pProgram->nCsr * sizeof(VdbeCursor*)
+ + (pProgram->nOp + 7)/8;
pFrame = sqlite3DbMallocZero(db, nByte);
if( !pFrame ){
goto no_mem;
@@ -82887,8 +84095,6 @@ case OP_Program: { /* jump */
pFrame->aOp = p->aOp;
pFrame->nOp = p->nOp;
pFrame->token = pProgram->token;
- pFrame->aOnceFlag = p->aOnceFlag;
- pFrame->nOnceFlag = p->nOnceFlag;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
pFrame->anExec = p->anExec;
#endif
@@ -82908,7 +84114,7 @@ case OP_Program: { /* jump */
p->nFrame++;
pFrame->pParent = p->pFrame;
- pFrame->lastRowid = lastRowid;
+ pFrame->lastRowid = db->lastRowid;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
assert( pFrame->pAuxData==0 );
@@ -82920,15 +84126,14 @@ case OP_Program: { /* jump */
p->nMem = pFrame->nChildMem;
p->nCursor = (u16)pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem];
+ pFrame->aOnce = (u8*)&p->apCsr[pProgram->nCsr];
+ memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8);
p->aOp = aOp = pProgram->aOp;
p->nOp = pProgram->nOp;
- p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
- p->nOnceFlag = pProgram->nOnce;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
p->anExec = 0;
#endif
pOp = &aOp[-1];
- memset(p->aOnceFlag, 0, p->nOnceFlag);
break;
}
@@ -83072,29 +84277,42 @@ case OP_IfPos: { /* jump, in1 */
** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
*/
case OP_OffsetLimit: { /* in1, out2, in3 */
+ i64 x;
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
pOut = out2Prerelease(p, pOp);
assert( pIn1->flags & MEM_Int );
assert( pIn3->flags & MEM_Int );
- pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0);
+ x = pIn1->u.i;
+ if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){
+ /* If the LIMIT is less than or equal to zero, loop forever. This
+ ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then
+ ** also loop forever. This is undocumented. In fact, one could argue
+ ** that the loop should terminate. But assuming 1 billion iterations
+ ** per second (far exceeding the capabilities of any current hardware)
+ ** it would take nearly 300 years to actually reach the limit. So
+ ** looping forever is a reasonable approximation. */
+ pOut->u.i = -1;
+ }else{
+ pOut->u.i = x;
+ }
break;
}
-/* Opcode: IfNotZero P1 P2 P3 * *
-** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2
+/* Opcode: IfNotZero P1 P2 * * *
+** Synopsis: if r[P1]!=0 then r[P1]--, goto P2
**
** Register P1 must contain an integer. If the content of register P1 is
-** initially nonzero, then subtract P3 from the value in register P1 and
-** jump to P2. If register P1 is initially zero, leave it unchanged
-** and fall through.
+** initially greater than zero, then decrement the value in register P1.
+** If it is non-zero (negative or positive) and then also jump to P2.
+** If register P1 is initially zero, leave it unchanged and fall through.
*/
case OP_IfNotZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i ){
- pIn1->u.i -= pOp->p3;
+ if( pIn1->u.i>0 ) pIn1->u.i--;
goto jump_to_p2;
}
break;
@@ -83103,13 +84321,13 @@ case OP_IfNotZero: { /* jump, in1 */
/* Opcode: DecrJumpZero P1 P2 * * *
** Synopsis: if (--r[P1])==0 goto P2
**
-** Register P1 must hold an integer. Decrement the value in register P1
-** then jump to P2 if the new value is exactly zero.
+** Register P1 must hold an integer. Decrement the value in P1
+** and jump to P2 if the new value is exactly zero.
*/
case OP_DecrJumpZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
- pIn1->u.i--;
+ if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--;
VdbeBranchTaken(pIn1->u.i==0, 2);
if( pIn1->u.i==0 ) goto jump_to_p2;
break;
@@ -83355,7 +84573,7 @@ case OP_JournalMode: { /* out2 */
** file. An EXCLUSIVE lock may still be held on the database file
** after a successful return.
*/
- rc = sqlite3PagerCloseWal(pPager);
+ rc = sqlite3PagerCloseWal(pPager, db);
if( rc==SQLITE_OK ){
sqlite3PagerSetJournalMode(pPager, eNew);
}
@@ -83390,15 +84608,14 @@ case OP_JournalMode: { /* out2 */
#endif /* SQLITE_OMIT_PRAGMA */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/* Opcode: Vacuum * * * * *
+/* Opcode: Vacuum P1 * * * *
**
-** Vacuum the entire database. This opcode will cause other virtual
-** machines to be created and run. It may not be called from within
-** a transaction.
+** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
+** for an attached database. The "temp" database may not be vacuumed.
*/
case OP_Vacuum: {
assert( p->readOnly==0 );
- rc = sqlite3RunVacuum(&p->zErrMsg, db);
+ rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1);
if( rc ) goto abort_due_to_error;
break;
}
@@ -83840,7 +85057,7 @@ case OP_VUpdate: {
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK && pOp->p1 ){
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
- db->lastRowid = lastRowid = rowid;
+ db->lastRowid = rowid;
}
if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
if( pOp->p5==OE_Ignore ){
@@ -83896,8 +85113,8 @@ case OP_MaxPgcnt: { /* out2 */
#endif
-/* Opcode: Init * P2 * P4 *
-** Synopsis: Start at P2
+/* Opcode: Init P1 P2 * P4 *
+** Synopsis: Start at P2
**
** Programs contain a single instance of this opcode as the very first
** opcode.
@@ -83907,9 +85124,13 @@ case OP_MaxPgcnt: { /* out2 */
** Or if P4 is blank, use the string returned by sqlite3_sql().
**
** If P2 is not zero, jump to instruction P2.
+**
+** Increment the value of P1 so that OP_Once opcodes will jump the
+** first time they are evaluated for this run.
*/
case OP_Init: { /* jump */
char *zTrace;
+ int i;
/* If the P4 argument is not NULL, then it must be an SQL comment string.
** The "--" string is broken up to prevent false-positives with srcck1.c.
@@ -83921,6 +85142,7 @@ case OP_Init: { /* jump */
** sqlite3_expanded_sql(P) otherwise.
*/
assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
+ assert( pOp==p->aOp ); /* Always instruction 0 */
#ifndef SQLITE_OMIT_TRACE
if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
@@ -83935,17 +85157,21 @@ case OP_Init: { /* jump */
sqlite3_free(z);
}else
#endif
- {
+ if( db->nVdbeExec>1 ){
+ char *z = sqlite3MPrintf(db, "-- %s", zTrace);
+ (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, z);
+ sqlite3DbFree(db, z);
+ }else{
(void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
}
}
#ifdef SQLITE_USE_FCNTL_TRACE
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
if( zTrace ){
- int i;
- for(i=0; i<db->nDb; i++){
- if( DbMaskTest(p->btreeMask, i)==0 ) continue;
- sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
+ int j;
+ for(j=0; j<db->nDb; j++){
+ if( DbMaskTest(p->btreeMask, j)==0 ) continue;
+ sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace);
}
}
#endif /* SQLITE_USE_FCNTL_TRACE */
@@ -83957,8 +85183,15 @@ case OP_Init: { /* jump */
}
#endif /* SQLITE_DEBUG */
#endif /* SQLITE_OMIT_TRACE */
- if( pOp->p2 ) goto jump_to_p2;
- break;
+ assert( pOp->p2>0 );
+ if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){
+ for(i=1; i<p->nOp; i++){
+ if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
+ }
+ pOp->p1 = 0;
+ }
+ pOp->p1++;
+ goto jump_to_p2;
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
@@ -84064,7 +85297,6 @@ abort_due_to_error:
** release the mutexes on btrees that were acquired at the
** top. */
vdbe_return:
- db->lastRowid = lastRowid;
testcase( nVmStep>0 );
p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
sqlite3VdbeLeave(p);
@@ -84128,10 +85360,9 @@ abort_due_to_interrupt:
*/
typedef struct Incrblob Incrblob;
struct Incrblob {
- int flags; /* Copy of "flags" passed to sqlite3_blob_open() */
int nByte; /* Size of open blob, in bytes */
int iOffset; /* Byte offset of blob in cursor data */
- int iCol; /* Table column this handle is open on */
+ u16 iCol; /* Table column this handle is open on */
BtCursor *pCsr; /* Cursor pointing at blob row */
sqlite3_stmt *pStmt; /* Statement holding cursor open */
sqlite3 *db; /* The associated database */
@@ -84162,17 +85393,27 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
char *zErr = 0; /* Error message */
Vdbe *v = (Vdbe *)p->pStmt;
- /* Set the value of the SQL statements only variable to integer iRow.
- ** This is done directly instead of using sqlite3_bind_int64() to avoid
- ** triggering asserts related to mutexes.
+ /* Set the value of register r[1] in the SQL statement to integer iRow.
+ ** This is done directly as a performance optimization
*/
- assert( v->aVar[0].flags&MEM_Int );
- v->aVar[0].u.i = iRow;
+ v->aMem[1].flags = MEM_Int;
+ v->aMem[1].u.i = iRow;
- rc = sqlite3_step(p->pStmt);
+ /* If the statement has been run before (and is paused at the OP_ResultRow)
+ ** then back it up to the point where it does the OP_SeekRowid. This could
+ ** have been down with an extra OP_Goto, but simply setting the program
+ ** counter is faster. */
+ if( v->pc>3 ){
+ v->pc = 3;
+ rc = sqlite3VdbeExec(v);
+ }else{
+ rc = sqlite3_step(p->pStmt);
+ }
if( rc==SQLITE_ROW ){
VdbeCursor *pC = v->apCsr[0];
- u32 type = pC->aType[p->iCol];
+ u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
+ testcase( pC->nHdrParsed==p->iCol );
+ testcase( pC->nHdrParsed==p->iCol+1 );
if( type<12 ){
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
type==0?"null": type==7?"real": "integer"
@@ -84211,13 +85452,13 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
/*
** Open a blob handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3* db, /* The database connection */
const char *zDb, /* The attached database containing the blob */
const char *zTable, /* The table containing the blob */
const char *zColumn, /* The column containing the blob */
sqlite_int64 iRow, /* The row containing the glob */
- int flags, /* True -> read/write access, false -> read-only */
+ int wrFlag, /* True -> read/write access, false -> read-only */
sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */
){
int nAttempt = 0;
@@ -84239,7 +85480,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
return SQLITE_MISUSE_BKPT;
}
#endif
- flags = !!flags; /* flags = (flags ? 1 : 0); */
+ wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */
sqlite3_mutex_enter(db->mutex);
@@ -84281,7 +85522,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
goto blob_open_out;
}
pBlob->pTab = pTab;
- pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zName;
+ pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
/* Now search pTab for the exact column. */
for(iCol=0; iCol<pTab->nCol; iCol++) {
@@ -84299,9 +85540,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
/* If the value is being opened for writing, check that the
** column is not indexed, and that it is not part of a foreign key.
- ** It is against the rules to open a column to which either of these
- ** descriptions applies for writing. */
- if( flags ){
+ */
+ if( wrFlag ){
const char *zFault = 0;
Index *pIdx;
#ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -84362,19 +85602,17 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
static const VdbeOpList openBlob[] = {
{OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */
{OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */
- {OP_Variable, 1, 1, 0}, /* 2: Move ?1 into reg[1] */
- {OP_NotExists, 0, 7, 1}, /* 3: Seek the cursor */
- {OP_Column, 0, 0, 1}, /* 4 */
- {OP_ResultRow, 1, 0, 0}, /* 5 */
- {OP_Goto, 0, 2, 0}, /* 6 */
- {OP_Close, 0, 0, 0}, /* 7 */
- {OP_Halt, 0, 0, 0}, /* 8 */
+ /* blobSeekToRow() will initialize r[1] to the desired rowid */
+ {OP_NotExists, 0, 5, 1}, /* 2: Seek the cursor to rowid=r[1] */
+ {OP_Column, 0, 0, 1}, /* 3 */
+ {OP_ResultRow, 1, 0, 0}, /* 4 */
+ {OP_Halt, 0, 0, 0}, /* 5 */
};
Vdbe *v = (Vdbe *)pBlob->pStmt;
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
VdbeOp *aOp;
- sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags,
+ sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag,
pTab->pSchema->schema_cookie,
pTab->pSchema->iGeneration);
sqlite3VdbeChangeP5(v, 1);
@@ -84391,7 +85629,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
#else
aOp[0].p1 = iDb;
aOp[0].p2 = pTab->tnum;
- aOp[0].p3 = flags;
+ aOp[0].p3 = wrFlag;
sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
}
if( db->mallocFailed==0 ){
@@ -84399,7 +85637,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
** parameter of the other to pTab->tnum. */
- if( flags ) aOp[1].opcode = OP_OpenWrite;
+ if( wrFlag ) aOp[1].opcode = OP_OpenWrite;
aOp[1].p2 = pTab->tnum;
aOp[1].p3 = iDb;
@@ -84412,23 +85650,21 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
*/
aOp[1].p4type = P4_INT32;
aOp[1].p4.i = pTab->nCol+1;
- aOp[4].p2 = pTab->nCol;
+ aOp[3].p2 = pTab->nCol;
- pParse->nVar = 1;
+ pParse->nVar = 0;
pParse->nMem = 1;
pParse->nTab = 1;
sqlite3VdbeMakeReady(v, pParse);
}
}
- pBlob->flags = flags;
pBlob->iCol = iCol;
pBlob->db = db;
sqlite3BtreeLeaveAll(db);
if( db->mallocFailed ){
goto blob_open_out;
}
- sqlite3_bind_int64(pBlob->pStmt, 1, iRow);
rc = blobSeekToRow(pBlob, iRow, &zErr);
} while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA );
@@ -84452,7 +85688,7 @@ blob_open_out:
** Close a blob handle that was previously created using
** sqlite3_blob_open().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
int rc;
sqlite3 *db;
@@ -84545,14 +85781,14 @@ static int blobReadWrite(
/*
** Read data from a blob handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
- return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
+SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
+ return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked);
}
/*
** Write data to a blob handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
}
@@ -84562,7 +85798,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void
** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
** so no mutex is required for access.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
return (p && p->pStmt) ? p->nByte : 0;
}
@@ -84577,7 +85813,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
** subsequent calls to sqlite3_blob_xxx() functions (except blob_close())
** immediately return SQLITE_ABORT.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
int rc;
Incrblob *p = (Incrblob *)pBlob;
sqlite3 *db;
@@ -85572,7 +86808,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
}
#endif
- assert( pCsr->pKeyInfo && pCsr->pBt==0 );
+ assert( pCsr->pKeyInfo && pCsr->pBtx==0 );
assert( pCsr->eCurType==CURTYPE_SORTER );
szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
@@ -85940,12 +87176,8 @@ static int vdbeSorterOpenTempFile(
*/
static int vdbeSortAllocUnpacked(SortSubtask *pTask){
if( pTask->pUnpacked==0 ){
- char *pFree;
- pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(
- pTask->pSorter->pKeyInfo, 0, 0, &pFree
- );
- assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
- if( pFree==0 ) return SQLITE_NOMEM_BKPT;
+ pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo);
+ if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT;
pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
pTask->pUnpacked->errCode = 0;
}
@@ -87346,9 +88578,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
r2 = pSorter->pUnpacked;
pKeyInfo = pCsr->pKeyInfo;
if( r2==0 ){
- char *p;
- r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
- assert( pSorter->pUnpacked==(UnpackedRecord*)p );
+ r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( r2==0 ) return SQLITE_NOMEM_BKPT;
r2->nField = nKeyCol;
}
@@ -87819,11 +89049,11 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
**
** WRC_Continue Continue descending down the tree.
**
-** WRC_Prune Do not descend into child nodes. But allow
+** WRC_Prune Do not descend into child nodes, but allow
** the walk to continue with sibling nodes.
**
** WRC_Abort Do no more callbacks. Unwind the stack and
-** return the top-level walk call.
+** return from the top-level walk call.
**
** The return value from this routine is WRC_Abort to abandon the tree walk
** and WRC_Continue to continue.
@@ -87833,17 +89063,17 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
- if( rc==WRC_Continue
- && !ExprHasProperty(pExpr,EP_TokenOnly) ){
- if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
- }else{
- if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
- }
+ if( rc || ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
+ return rc & WRC_Abort;
}
- return rc & WRC_Abort;
+ if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
+ if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
+ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
+ if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
+ }else if( pExpr->x.pList ){
+ if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
+ }
+ return WRC_Continue;
}
SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;
@@ -87971,8 +89201,6 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
** table and column.
*/
/* #include "sqliteInt.h" */
-/* #include <stdlib.h> */
-/* #include <string.h> */
/*
** Walk the expression tree pExpr and increase the aggregate function
@@ -88177,8 +89405,8 @@ static int lookupName(
zDb = 0;
}else{
for(i=0; i<db->nDb; i++){
- assert( db->aDb[i].zName );
- if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
+ assert( db->aDb[i].zDbSName );
+ if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){
pSchema = db->aDb[i].pSchema;
break;
}
@@ -88187,7 +89415,8 @@ static int lookupName(
}
/* Start at the inner-most context and move outward until a match is found */
- while( pNC && cnt==0 ){
+ assert( pNC && cnt==0 );
+ do{
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
@@ -88356,6 +89585,10 @@ static int lookupName(
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
+ if( sqlite3ExprVectorSize(pOrig)!=1 ){
+ sqlite3ErrorMsg(pParse, "row value misused");
+ return WRC_Abort;
+ }
resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
cnt = 1;
pMatch = 0;
@@ -88368,11 +89601,11 @@ static int lookupName(
/* Advance to the next name context. The loop will exit when either
** we have a match (cnt>0) or when we run out of name contexts.
*/
- if( cnt==0 ){
- pNC = pNC->pNext;
- nSubquery++;
- }
- }
+ if( cnt ) break;
+ pNC = pNC->pNext;
+ nSubquery++;
+ }while( pNC );
+
/*
** If X and Y are NULL (in other words if only the column name Z is
@@ -88562,34 +89795,38 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
&& !defined(SQLITE_OMIT_SUBQUERY) */
- /* A lone identifier is the name of a column.
- */
- case TK_ID: {
- return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
- }
-
- /* A table name and column name: ID.ID
+ /* A column name: ID
+ ** Or table name and column name: ID.ID
** Or a database, table and column: ID.ID.ID
+ **
+ ** The TK_ID and TK_OUT cases are combined so that there will only
+ ** be one call to lookupName(). Then the compiler will in-line
+ ** lookupName() for a size reduction and performance increase.
*/
+ case TK_ID:
case TK_DOT: {
const char *zColumn;
const char *zTable;
const char *zDb;
Expr *pRight;
- /* if( pSrcList==0 ) break; */
- notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
- /*notValid(pParse, pNC, "the \".\" operator", NC_PartIdx|NC_IsCheck, 1);*/
- pRight = pExpr->pRight;
- if( pRight->op==TK_ID ){
+ if( pExpr->op==TK_ID ){
zDb = 0;
- zTable = pExpr->pLeft->u.zToken;
- zColumn = pRight->u.zToken;
+ zTable = 0;
+ zColumn = pExpr->u.zToken;
}else{
- assert( pRight->op==TK_DOT );
- zDb = pExpr->pLeft->u.zToken;
- zTable = pRight->pLeft->u.zToken;
- zColumn = pRight->pRight->u.zToken;
+ notValid(pParse, pNC, "the \".\" operator", NC_IdxExpr);
+ pRight = pExpr->pRight;
+ if( pRight->op==TK_ID ){
+ zDb = 0;
+ zTable = pExpr->pLeft->u.zToken;
+ zColumn = pRight->u.zToken;
+ }else{
+ assert( pRight->op==TK_DOT );
+ zDb = pExpr->pLeft->u.zToken;
+ zTable = pRight->pLeft->u.zToken;
+ zColumn = pRight->pRight->u.zToken;
+ }
}
return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
}
@@ -88602,14 +89839,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
int no_such_func = 0; /* True if no such function exists */
int wrong_num_args = 0; /* True if wrong number of arguments */
int is_agg = 0; /* True if is an aggregate function */
- int auth; /* Authorization to use the function */
int nId; /* Number of characters in function name */
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- notValid(pParse, pNC, "functions", NC_PartIdx);
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
@@ -88646,15 +89881,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
- auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
- if( auth!=SQLITE_OK ){
- if( auth==SQLITE_DENY ){
- sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
- pDef->zName);
- pNC->nErr++;
+ {
+ int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0);
+ if( auth!=SQLITE_OK ){
+ if( auth==SQLITE_DENY ){
+ sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
+ pDef->zName);
+ pNC->nErr++;
+ }
+ pExpr->op = TK_NULL;
+ return WRC_Prune;
}
- pExpr->op = TK_NULL;
- return WRC_Prune;
}
#endif
if( pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG) ){
@@ -88667,7 +89904,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
/* 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);
+ notValid(pParse, pNC, "non-deterministic functions",
+ NC_IdxExpr|NC_PartIdx);
}
}
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
@@ -88732,6 +89970,42 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
break;
}
+ case TK_BETWEEN:
+ case TK_EQ:
+ case TK_NE:
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_IS:
+ case TK_ISNOT: {
+ int nLeft, nRight;
+ if( pParse->db->mallocFailed ) break;
+ assert( pExpr->pLeft!=0 );
+ nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
+ if( pExpr->op==TK_BETWEEN ){
+ nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
+ if( nRight==nLeft ){
+ nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
+ }
+ }else{
+ assert( pExpr->pRight!=0 );
+ nRight = sqlite3ExprVectorSize(pExpr->pRight);
+ }
+ if( nLeft!=nRight ){
+ 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 );
+ testcase( pExpr->op==TK_IS );
+ testcase( pExpr->op==TK_ISNOT );
+ testcase( pExpr->op==TK_BETWEEN );
+ sqlite3ErrorMsg(pParse, "row value misused");
+ }
+ break;
+ }
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}
@@ -89474,6 +90748,18 @@ SQLITE_PRIVATE void sqlite3ResolveSelfReference(
*/
/* #include "sqliteInt.h" */
+/* Forward declarations */
+static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
+static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);
+
+/*
+** Return the affinity character for a single column of a table.
+*/
+SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){
+ assert( iCol<pTab->nCol );
+ return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
+}
+
/*
** Return the 'affinity' of the expression pExpr if any.
**
@@ -89499,21 +90785,21 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
assert( pExpr->flags&EP_xIsSelect );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
+ if( op==TK_REGISTER ) op = pExpr->op2;
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
return sqlite3AffinityType(pExpr->u.zToken, 0);
}
#endif
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
- && pExpr->pTab!=0
- ){
- /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally
- ** a TK_COLUMN but was previously evaluated and cached in a register */
- int j = pExpr->iColumn;
- if( j<0 ) return SQLITE_AFF_INTEGER;
- assert( pExpr->pTab && j<pExpr->pTab->nCol );
- return pExpr->pTab->aCol[j].affinity;
+ if( op==TK_AGG_COLUMN || op==TK_COLUMN ){
+ return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+ }
+ if( op==TK_SELECT_COLUMN ){
+ assert( pExpr->pLeft->flags&EP_xIsSelect );
+ return sqlite3ExprAffinity(
+ pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
+ );
}
return pExpr->affinity;
}
@@ -89679,7 +90965,7 @@ static char comparisonAffinity(Expr *pExpr){
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
}else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
- }else if( !aff ){
+ }else if( aff==0 ){
aff = SQLITE_AFF_BLOB;
}
return aff;
@@ -89769,6 +91055,274 @@ static int codeCompare(
return addr;
}
+/*
+** Return true if expression pExpr is a vector, or false otherwise.
+**
+** A vector is defined as any expression that results in two or more
+** columns of result. Every TK_VECTOR node is an vector because the
+** parser will not generate a TK_VECTOR with fewer than two entries.
+** But a TK_SELECT might be either a vector or a scalar. It is only
+** considered a vector if it has two or more result columns.
+*/
+SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr){
+ return sqlite3ExprVectorSize(pExpr)>1;
+}
+
+/*
+** If the expression passed as the only argument is of type TK_VECTOR
+** return the number of expressions in the vector. Or, if the expression
+** is a sub-select, return the number of columns in the sub-select. For
+** any other type of expression, return 1.
+*/
+SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr){
+ u8 op = pExpr->op;
+ if( op==TK_REGISTER ) op = pExpr->op2;
+ if( op==TK_VECTOR ){
+ return pExpr->x.pList->nExpr;
+ }else if( op==TK_SELECT ){
+ return pExpr->x.pSelect->pEList->nExpr;
+ }else{
+ return 1;
+ }
+}
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** Return a pointer to a subexpression of pVector that is the i-th
+** column of the vector (numbered starting with 0). The caller must
+** ensure that i is within range.
+**
+** If pVector is really a scalar (and "scalar" here includes subqueries
+** that return a single column!) then return pVector unmodified.
+**
+** pVector retains ownership of the returned subexpression.
+**
+** If the vector is a (SELECT ...) then the expression returned is
+** just the expression for the i-th term of the result set, and may
+** not be ready for evaluation because the table cursor has not yet
+** been positioned.
+*/
+SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
+ assert( i<sqlite3ExprVectorSize(pVector) );
+ if( sqlite3ExprIsVector(pVector) ){
+ assert( pVector->op2==0 || pVector->op==TK_REGISTER );
+ if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
+ return pVector->x.pSelect->pEList->a[i].pExpr;
+ }else{
+ return pVector->x.pList->a[i].pExpr;
+ }
+ }
+ return pVector;
+}
+#endif /* !defined(SQLITE_OMIT_SUBQUERY) */
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** Compute and return a new Expr object which when passed to
+** sqlite3ExprCode() will generate all necessary code to compute
+** the iField-th column of the vector expression pVector.
+**
+** It is ok for pVector to be a scalar (as long as iField==0).
+** In that case, this routine works like sqlite3ExprDup().
+**
+** The caller owns the returned Expr object and is responsible for
+** ensuring that the returned value eventually gets freed.
+**
+** The caller retains ownership of pVector. If pVector is a TK_SELECT,
+** then the returned object will reference pVector and so pVector must remain
+** valid for the life of the returned object. If pVector is a TK_VECTOR
+** or a scalar expression, then it can be deleted as soon as this routine
+** returns.
+**
+** A trick to cause a TK_SELECT pVector to be deleted together with
+** the returned Expr object is to attach the pVector to the pRight field
+** of the returned TK_SELECT_COLUMN Expr object.
+*/
+SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(
+ Parse *pParse, /* Parsing context */
+ Expr *pVector, /* The vector. List of expressions or a sub-SELECT */
+ int iField /* Which column of the vector to return */
+){
+ Expr *pRet;
+ if( pVector->op==TK_SELECT ){
+ assert( pVector->flags & EP_xIsSelect );
+ /* The TK_SELECT_COLUMN Expr node:
+ **
+ ** pLeft: pVector containing TK_SELECT. Not deleted.
+ ** pRight: not used. But recursively deleted.
+ ** iColumn: Index of a column in pVector
+ ** iTable: 0 or the number of columns on the LHS of an assignment
+ ** pLeft->iTable: First in an array of register holding result, or 0
+ ** if the result is not yet computed.
+ **
+ ** sqlite3ExprDelete() specifically skips the recursive delete of
+ ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector
+ ** can be attached to pRight to cause this node to take ownership of
+ ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes
+ ** with the same pLeft pointer to the pVector, but only one of them
+ ** will own the pVector.
+ */
+ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0);
+ if( pRet ){
+ pRet->iColumn = iField;
+ pRet->pLeft = pVector;
+ }
+ assert( pRet==0 || pRet->iTable==0 );
+ }else{
+ if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;
+ pRet = sqlite3ExprDup(pParse->db, pVector, 0);
+ }
+ return pRet;
+}
+#endif /* !define(SQLITE_OMIT_SUBQUERY) */
+
+/*
+** If expression pExpr is of type TK_SELECT, generate code to evaluate
+** it. Return the register in which the result is stored (or, if the
+** sub-select returns more than one column, the first in an array
+** of registers in which the result is stored).
+**
+** If pExpr is not a TK_SELECT expression, return 0.
+*/
+static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
+ int reg = 0;
+#ifndef SQLITE_OMIT_SUBQUERY
+ if( pExpr->op==TK_SELECT ){
+ reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+ }
+#endif
+ return reg;
+}
+
+/*
+** Argument pVector points to a vector expression - either a TK_VECTOR
+** or TK_SELECT that returns more than one column. This function returns
+** the register number of a register that contains the value of
+** element iField of the vector.
+**
+** If pVector is a TK_SELECT expression, then code for it must have
+** already been generated using the exprCodeSubselect() routine. In this
+** case parameter regSelect should be the first in an array of registers
+** containing the results of the sub-select.
+**
+** If pVector is of type TK_VECTOR, then code for the requested field
+** is generated. In this case (*pRegFree) may be set to the number of
+** a temporary register to be freed by the caller before returning.
+**
+** Before returning, output parameter (*ppExpr) is set to point to the
+** Expr object corresponding to element iElem of the vector.
+*/
+static int exprVectorRegister(
+ Parse *pParse, /* Parse context */
+ Expr *pVector, /* Vector to extract element from */
+ int iField, /* Field to extract from pVector */
+ int regSelect, /* First in array of registers */
+ Expr **ppExpr, /* OUT: Expression element */
+ int *pRegFree /* OUT: Temp register to free */
+){
+ u8 op = pVector->op;
+ assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT );
+ if( op==TK_REGISTER ){
+ *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
+ return pVector->iTable+iField;
+ }
+ if( op==TK_SELECT ){
+ *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
+ return regSelect+iField;
+ }
+ *ppExpr = pVector->x.pList->a[iField].pExpr;
+ return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
+}
+
+/*
+** Expression pExpr is a comparison between two vector values. Compute
+** the result of the comparison (1, 0, or NULL) and write that
+** result into register dest.
+**
+** The caller must satisfy the following preconditions:
+**
+** if pExpr->op==TK_IS: op==TK_EQ and p5==SQLITE_NULLEQ
+** if pExpr->op==TK_ISNOT: op==TK_NE and p5==SQLITE_NULLEQ
+** otherwise: op==pExpr->op and p5==0
+*/
+static void codeVectorCompare(
+ Parse *pParse, /* Code generator context */
+ Expr *pExpr, /* The comparison operation */
+ int dest, /* Write results into this register */
+ u8 op, /* Comparison operator */
+ u8 p5 /* SQLITE_NULLEQ or zero */
+){
+ Vdbe *v = pParse->pVdbe;
+ Expr *pLeft = pExpr->pLeft;
+ Expr *pRight = pExpr->pRight;
+ int nLeft = sqlite3ExprVectorSize(pLeft);
+ int i;
+ int regLeft = 0;
+ int regRight = 0;
+ u8 opx = op;
+ int addrDone = sqlite3VdbeMakeLabel(v);
+
+ if( nLeft!=sqlite3ExprVectorSize(pRight) ){
+ sqlite3ErrorMsg(pParse, "row value misused");
+ return;
+ }
+ assert( pExpr->op==TK_EQ || pExpr->op==TK_NE
+ || pExpr->op==TK_IS || pExpr->op==TK_ISNOT
+ || pExpr->op==TK_LT || pExpr->op==TK_GT
+ || pExpr->op==TK_LE || pExpr->op==TK_GE
+ );
+ assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ)
+ || (pExpr->op==TK_ISNOT && op==TK_NE) );
+ assert( p5==0 || pExpr->op!=op );
+ assert( p5==SQLITE_NULLEQ || pExpr->op==op );
+
+ p5 |= SQLITE_STOREP2;
+ if( opx==TK_LE ) opx = TK_LT;
+ if( opx==TK_GE ) opx = TK_GT;
+
+ regLeft = exprCodeSubselect(pParse, pLeft);
+ regRight = exprCodeSubselect(pParse, pRight);
+
+ for(i=0; 1 /*Loop exits by "break"*/; i++){
+ int regFree1 = 0, regFree2 = 0;
+ Expr *pL, *pR;
+ int r1, r2;
+ assert( i>=0 && i<nLeft );
+ if( i>0 ) sqlite3ExprCachePush(pParse);
+ 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);
+ 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);
+ testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+ sqlite3ReleaseTempReg(pParse, regFree1);
+ sqlite3ReleaseTempReg(pParse, regFree2);
+ if( i>0 ) sqlite3ExprCachePop(pParse);
+ if( i==nLeft-1 ){
+ break;
+ }
+ if( opx==TK_EQ ){
+ sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v);
+ p5 |= SQLITE_KEEPNULL;
+ }else if( opx==TK_NE ){
+ sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v);
+ p5 |= SQLITE_KEEPNULL;
+ }else{
+ assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE );
+ sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone);
+ VdbeCoverageIf(v, op==TK_LT);
+ VdbeCoverageIf(v, op==TK_GT);
+ VdbeCoverageIf(v, op==TK_LE);
+ VdbeCoverageIf(v, op==TK_GE);
+ if( i==nLeft-2 ) opx = op;
+ }
+ }
+ sqlite3VdbeResolveLabel(v, addrDone);
+}
+
#if SQLITE_MAX_EXPR_DEPTH>0
/*
** Check that argument nHeight is less than or equal to the maximum
@@ -89904,7 +91458,7 @@ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
** is allocated to hold the integer text and the dequote flag is ignored.
*/
SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
- sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
+ sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */
int op, /* Expression opcode */
const Token *pToken, /* Token argument. Might be NULL */
int dequote /* True to dequote */
@@ -90003,15 +91557,19 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
Parse *pParse, /* Parsing context */
int op, /* Expression opcode */
Expr *pLeft, /* Left operand */
- Expr *pRight, /* Right operand */
- const Token *pToken /* Argument token */
+ Expr *pRight /* Right operand */
){
Expr *p;
if( op==TK_AND && pParse->nErr==0 ){
/* Take advantage of short-circuit false optimization for AND */
p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
}else{
- p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1);
+ p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
+ if( p ){
+ memset(p, 0, sizeof(Expr));
+ p->op = op & TKFLG_MASK;
+ p->iAgg = -1;
+ }
sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
}
if( p ) {
@@ -90114,7 +91672,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
** variable number.
**
** Wildcards of the form "?nnn" are assigned the number "nnn". We make
-** sure "nnn" is not too be to avoid a denial of service attack when
+** sure "nnn" is not too big to avoid a denial of service attack when
** the SQL statement comes from an external source.
**
** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
@@ -90122,28 +91680,34 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
** instance of the wildcard, the next sequential variable number is
** assigned.
*/
-SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
+SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
sqlite3 *db = pParse->db;
const char *z;
+ ynVar x;
if( pExpr==0 ) return;
assert( !ExprHasProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
z = pExpr->u.zToken;
assert( z!=0 );
assert( z[0]!=0 );
+ assert( n==sqlite3Strlen30(z) );
if( z[1]==0 ){
/* Wildcard of the form "?". Assign the next variable number */
assert( z[0]=='?' );
- pExpr->iColumn = (ynVar)(++pParse->nVar);
+ x = (ynVar)(++pParse->nVar);
}else{
- ynVar x = 0;
- u32 n = sqlite3Strlen30(z);
+ int doAdd = 0;
if( z[0]=='?' ){
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
** use it as the variable number */
i64 i;
- int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
- pExpr->iColumn = x = (ynVar)i;
+ int bOk;
+ if( n==2 ){ /*OPTIMIZATION-IF-TRUE*/
+ i = z[1]-'0'; /* The common case of ?N for a single digit N */
+ bOk = 1;
+ }else{
+ bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8);
+ }
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
@@ -90151,44 +91715,32 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]);
- x = 0;
+ return;
}
- if( i>pParse->nVar ){
- pParse->nVar = (int)i;
+ x = (ynVar)i;
+ if( x>pParse->nVar ){
+ pParse->nVar = (int)x;
+ doAdd = 1;
+ }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){
+ doAdd = 1;
}
}else{
/* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
** number as the prior appearance of the same name, or if the name
** has never appeared before, reuse the same variable number
*/
- ynVar i;
- for(i=0; i<pParse->nzVar; i++){
- if( pParse->azVar[i] && strcmp(pParse->azVar[i],z)==0 ){
- pExpr->iColumn = x = (ynVar)i+1;
- break;
- }
+ x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n);
+ if( x==0 ){
+ x = (ynVar)(++pParse->nVar);
+ doAdd = 1;
}
- if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar);
}
- if( x>0 ){
- if( x>pParse->nzVar ){
- char **a;
- a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0]));
- if( a==0 ){
- assert( db->mallocFailed ); /* Error reported through mallocFailed */
- return;
- }
- pParse->azVar = a;
- memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0]));
- pParse->nzVar = x;
- }
- if( z[0]!='?' || pParse->azVar[x-1]==0 ){
- sqlite3DbFree(db, pParse->azVar[x-1]);
- pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n);
- }
+ if( doAdd ){
+ pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x);
}
- }
- if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
+ }
+ pExpr->iColumn = x;
+ if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
sqlite3ErrorMsg(pParse, "too many SQL variables");
}
}
@@ -90200,18 +91752,25 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
- if( !ExprHasProperty(p, EP_TokenOnly) ){
+#ifdef SQLITE_DEBUG
+ if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
+ assert( p->pLeft==0 );
+ assert( p->pRight==0 );
+ assert( p->x.pSelect==0 );
+ }
+#endif
+ if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
/* The Expr.x union is never used at the same time as Expr.pRight */
assert( p->x.pList==0 || p->pRight==0 );
- sqlite3ExprDelete(db, p->pLeft);
+ if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
sqlite3ExprDelete(db, p->pRight);
- if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
sqlite3ExprListDelete(db, p->x.pList);
}
}
+ if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
if( !ExprHasProperty(p, EP_Static) ){
sqlite3DbFree(db, p);
}
@@ -90270,7 +91829,7 @@ static int dupedExprStructSize(Expr *p, int flags){
assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
assert( EXPR_FULLSIZE<=0xfff );
assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
- if( 0==flags ){
+ if( 0==flags || p->op==TK_SELECT_COLUMN ){
nSize = EXPR_FULLSIZE;
}else{
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
@@ -90388,7 +91947,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
memcpy(zToken, p->u.zToken, nToken);
}
- if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
+ if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
@@ -90400,7 +91959,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
/* Fill in pNew->pLeft and pNew->pRight. */
if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, dupFlags);
- if( ExprHasProperty(pNew, EP_Reduced) ){
+ if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){
pNew->pLeft = p->pLeft ?
exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0;
pNew->pRight = p->pRight ?
@@ -90410,8 +91969,14 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
*pzBuffer = zAlloc;
}
}else{
- if( !ExprHasProperty(p, EP_TokenOnly) ){
- pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
+ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
+ if( pNew->op==TK_SELECT_COLUMN ){
+ pNew->pLeft = p->pLeft;
+ assert( p->iColumn==0 || p->pRight==0 );
+ assert( p->pRight==0 || p->pRight==p->pLeft );
+ }else{
+ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
+ }
pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
}
}
@@ -90471,6 +92036,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
ExprList *pNew;
struct ExprList_item *pItem, *pOldItem;
int i;
+ Expr *pPriorSelectCol = 0;
assert( db!=0 );
if( p==0 ) return 0;
pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
@@ -90485,7 +92051,24 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
Expr *pOldExpr = pOldItem->pExpr;
+ Expr *pNewExpr;
pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
+ if( pOldExpr
+ && pOldExpr->op==TK_SELECT_COLUMN
+ && (pNewExpr = pItem->pExpr)!=0
+ ){
+ assert( pNewExpr->iColumn==0 || i>0 );
+ if( pNewExpr->iColumn==0 ){
+ assert( pOldExpr->pLeft==pOldExpr->pRight );
+ pPriorSelectCol = pNewExpr->pLeft = pNewExpr->pRight;
+ }else{
+ assert( i>0 );
+ assert( pItem[-1].pExpr!=0 );
+ assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 );
+ assert( pPriorSelectCol==pItem[-1].pExpr->pLeft );
+ pNewExpr->pLeft = pPriorSelectCol;
+ }
+ }
pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
pItem->sortOrder = pOldItem->sortOrder;
@@ -90536,7 +92119,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
}
pTab = pNewItem->pTab = pOldItem->pTab;
if( pTab ){
- pTab->nRef++;
+ pTab->nTabRef++;
}
pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
@@ -90569,33 +92152,41 @@ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
}
return pNew;
}
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
- Select *pNew, *pPrior;
+SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
+ Select *pRet = 0;
+ Select *pNext = 0;
+ Select **pp = &pRet;
+ Select *p;
+
assert( db!=0 );
- if( p==0 ) return 0;
- pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
- if( pNew==0 ) return 0;
- pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
- pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
- pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
- pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
- pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
- pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
- pNew->op = p->op;
- pNew->pPrior = pPrior = sqlite3SelectDup(db, p->pPrior, flags);
- if( pPrior ) pPrior->pNext = pNew;
- pNew->pNext = 0;
- pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
- pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
- pNew->iLimit = 0;
- pNew->iOffset = 0;
- pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
- pNew->addrOpenEphm[0] = -1;
- pNew->addrOpenEphm[1] = -1;
- pNew->nSelectRow = p->nSelectRow;
- pNew->pWith = withDup(db, p->pWith);
- sqlite3SelectSetName(pNew, p->zSelName);
- return pNew;
+ for(p=pDup; p; p=p->pPrior){
+ Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
+ if( pNew==0 ) break;
+ pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
+ pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
+ pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
+ pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
+ pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags);
+ pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags);
+ pNew->op = p->op;
+ pNew->pNext = pNext;
+ pNew->pPrior = 0;
+ pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags);
+ pNew->pOffset = sqlite3ExprDup(db, p->pOffset, flags);
+ pNew->iLimit = 0;
+ pNew->iOffset = 0;
+ pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
+ pNew->addrOpenEphm[0] = -1;
+ pNew->addrOpenEphm[1] = -1;
+ pNew->nSelectRow = p->nSelectRow;
+ pNew->pWith = withDup(db, p->pWith);
+ sqlite3SelectSetName(pNew, p->zSelName);
+ *pp = pNew;
+ pp = &pNew->pPrior;
+ pNext = pNew;
+ }
+
+ return pRet;
}
#else
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
@@ -90653,6 +92244,75 @@ no_mem:
}
/*
+** pColumns and pExpr form a vector assignment which is part of the SET
+** clause of an UPDATE statement. Like this:
+**
+** (a,b,c) = (expr1,expr2,expr3)
+** Or: (a,b,c) = (SELECT x,y,z FROM ....)
+**
+** For each term of the vector assignment, append new entries to the
+** expression list pList. In the case of a subquery on the RHS, append
+** TK_SELECT_COLUMN expressions.
+*/
+SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List to which to append. Might be NULL */
+ IdList *pColumns, /* List of names of LHS of the assignment */
+ Expr *pExpr /* Vector expression to be appended. Might be NULL */
+){
+ sqlite3 *db = pParse->db;
+ int n;
+ int i;
+ int iFirst = pList ? pList->nExpr : 0;
+ /* pColumns can only be NULL due to an OOM but an OOM will cause an
+ ** exit prior to this routine being invoked */
+ if( NEVER(pColumns==0) ) goto vector_append_error;
+ if( pExpr==0 ) goto vector_append_error;
+
+ /* If the RHS is a vector, then we can immediately check to see that
+ ** the size of the RHS and LHS match. But if the RHS is a SELECT,
+ ** wildcards ("*") in the result set of the SELECT must be expanded before
+ ** we can do the size check, so defer the size check until code generation.
+ */
+ if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){
+ sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
+ pColumns->nId, n);
+ goto vector_append_error;
+ }
+
+ for(i=0; i<pColumns->nId; i++){
+ Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i);
+ pList = sqlite3ExprListAppend(pParse, pList, pSubExpr);
+ if( pList ){
+ assert( pList->nExpr==iFirst+i+1 );
+ pList->a[pList->nExpr-1].zName = pColumns->a[i].zName;
+ pColumns->a[i].zName = 0;
+ }
+ }
+
+ if( pExpr->op==TK_SELECT ){
+ if( pList && pList->a[iFirst].pExpr ){
+ Expr *pFirst = pList->a[iFirst].pExpr;
+ assert( pFirst->op==TK_SELECT_COLUMN );
+
+ /* Store the SELECT statement in pRight so it will be deleted when
+ ** sqlite3ExprListDelete() is called */
+ pFirst->pRight = pExpr;
+ pExpr = 0;
+
+ /* Remember the size of the LHS in iTable so that we can check that
+ ** the RHS and LHS sizes match during code generation. */
+ pFirst->iTable = pColumns->nId;
+ }
+ }
+
+vector_append_error:
+ sqlite3ExprDelete(db, pExpr);
+ sqlite3IdListDelete(db, pColumns);
+ return pList;
+}
+
+/*
** Set the sort order for the last element on the given ExprList.
*/
SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){
@@ -90934,6 +92594,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
*/
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
+ if( p==0 ) return 0; /* Can only happen following on OOM */
/* If an expression is an integer literal that fits in a signed 32-bit
** integer, then the EP_IntValue flag will have already been set */
@@ -91059,8 +92720,8 @@ static Select *isCandidateForInOpt(Expr *pX){
Select *p;
SrcList *pSrc;
ExprList *pEList;
- Expr *pRes;
Table *pTab;
+ int i;
if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */
if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
p = pX->x.pSelect;
@@ -91083,23 +92744,18 @@ static Select *isCandidateForInOpt(Expr *pX){
assert( pTab->pSelect==0 ); /* FROM clause is not a view */
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
pEList = p->pEList;
- if( pEList->nExpr!=1 ) return 0; /* One column in the result set */
- pRes = pEList->a[0].pExpr;
- if( pRes->op!=TK_COLUMN ) return 0; /* Result is a column */
- assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */
+ assert( pEList!=0 );
+ /* All SELECT results must be columns. */
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *pRes = pEList->a[i].pExpr;
+ if( pRes->op!=TK_COLUMN ) return 0;
+ assert( pRes->iTable==pSrc->a[0].iCursor ); /* Not a correlated subquery */
+ }
return p;
}
#endif /* SQLITE_OMIT_SUBQUERY */
-/*
-** Code an OP_Once instruction and allocate space for its flag. Return the
-** address of the new instruction.
-*/
-SQLITE_PRIVATE int sqlite3CodeOnce(Parse *pParse){
- Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
- return sqlite3VdbeAddOp1(v, OP_Once, pParse->nOnce++);
-}
-
+#ifndef SQLITE_OMIT_SUBQUERY
/*
** Generate code that checks the left-most column of index table iCur to see if
** it contains any NULL entries. Cause the register at regHasNull to be set
@@ -91115,6 +92771,7 @@ static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
VdbeComment((v, "first_entry_in(%d)", iCur));
sqlite3VdbeJumpHere(v, addr1);
}
+#endif
#ifndef SQLITE_OMIT_SUBQUERY
@@ -91159,7 +92816,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** An existing b-tree might be used if the RHS expression pX is a simple
** subquery such as:
**
-** SELECT <column> FROM <table>
+** SELECT <column1>, <column2>... FROM <table>
**
** If the RHS of the IN operator is a list or a more complex subquery, then
** an ephemeral table might need to be generated from the RHS and then
@@ -91175,14 +92832,14 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
**
** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate
** through the set members) then the b-tree must not contain duplicates.
-** An epheremal table must be used unless the selected <column> is guaranteed
-** to be unique - either because it is an INTEGER PRIMARY KEY or it
-** has a UNIQUE constraint or UNIQUE index.
+** An epheremal table must be used unless the selected columns are guaranteed
+** to be unique - either because it is an INTEGER PRIMARY KEY or due to
+** a UNIQUE constraint or index.
**
** When IN_INDEX_MEMBERSHIP is used (and the b-tree will be used
** for fast set membership tests) then an epheremal table must
-** be used unless <column> is an INTEGER PRIMARY KEY or an index can
-** be found with <column> as its left-most column.
+** be used unless <columns> is a single INTEGER PRIMARY KEY column or an
+** index can be found with the specified <columns> as its left-most.
**
** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and
** if the RHS of the IN operator is a list (not a subquery) then this
@@ -91203,9 +92860,26 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** the value in that register will be NULL if the b-tree contains one or more
** NULL values, and it will be some non-NULL value if the b-tree contains no
** NULL values.
+**
+** If the aiMap parameter is not NULL, it must point to an array containing
+** one element for each column returned by the SELECT statement on the RHS
+** of the IN(...) operator. The i'th entry of the array is populated with the
+** offset of the index column that matches the i'th column returned by the
+** SELECT. For example, if the expression and selected index are:
+**
+** (?,?,?) IN (SELECT a, b, c FROM t1)
+** CREATE INDEX i1 ON t1(b, c, a);
+**
+** then aiMap[] is populated with {2, 0, 1}.
*/
#ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int *prRhsHasNull){
+SQLITE_PRIVATE int sqlite3FindInIndex(
+ Parse *pParse, /* Parsing context */
+ Expr *pX, /* The right-hand side (RHS) of the IN operator */
+ u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
+ int *prRhsHasNull, /* Register holding NULL status. See notes */
+ int *aiMap /* Mapping from Index fields to RHS fields */
+){
Select *p; /* SELECT to the right of IN operator */
int eType = 0; /* Type of RHS table. IN_INDEX_* */
int iTab = pParse->nTab++; /* Cursor of the RHS table */
@@ -91215,36 +92889,46 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
assert( pX->op==TK_IN );
mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
+ /* If the RHS of this IN(...) operator is a SELECT, and if it matters
+ ** whether or not the SELECT result contains NULL values, check whether
+ ** or not NULL is actually possible (it may not be, for example, due
+ ** to NOT NULL constraints in the schema). If no NULL values are possible,
+ ** set prRhsHasNull to 0 before continuing. */
+ if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){
+ int i;
+ ExprList *pEList = pX->x.pSelect->pEList;
+ for(i=0; i<pEList->nExpr; i++){
+ if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
+ }
+ if( i==pEList->nExpr ){
+ prRhsHasNull = 0;
+ }
+ }
+
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
- ** ephemeral table.
- */
+ ** ephemeral table. */
if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){
sqlite3 *db = pParse->db; /* Database connection */
Table *pTab; /* Table <table>. */
- Expr *pExpr; /* Expression <column> */
- i16 iCol; /* Index of column <column> */
i16 iDb; /* Database idx for pTab */
+ ExprList *pEList = p->pEList;
+ int nExpr = pEList->nExpr;
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
- pExpr = p->pEList->a[0].pExpr;
- iCol = (i16)pExpr->iColumn;
-
+
/* Code an OP_Transaction and OP_TableLock for <table>. */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
- /* This function is only called from two places. In both cases the vdbe
- ** has already been allocated. So assume sqlite3GetVdbe() is always
- ** successful here.
- */
- assert(v);
- if( iCol<0 ){
- int iAddr = sqlite3CodeOnce(pParse);
+ assert(v); /* sqlite3GetVdbe() has always been previously called */
+ if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){
+ /* The "x IN (SELECT rowid FROM table)" case */
+ int iAddr = sqlite3VdbeAddOp0(v, OP_Once);
VdbeCoverage(v);
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
@@ -91253,44 +92937,109 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
sqlite3VdbeJumpHere(v, iAddr);
}else{
Index *pIdx; /* Iterator variable */
+ int affinity_ok = 1;
+ int i;
- /* The collation sequence used by the comparison. If an index is to
- ** be used in place of a temp-table, it must be ordered according
- ** to this collation sequence. */
- CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);
-
- /* Check that the affinity that will be used to perform the
- ** comparison is the same as the affinity of the column. If
- ** it is not, it is not possible to use any index.
- */
- int affinity_ok = sqlite3IndexAffinityOk(pX, pTab->aCol[iCol].affinity);
-
- for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
- if( (pIdx->aiColumn[0]==iCol)
- && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
- && (!mustBeUnique || (pIdx->nKeyCol==1 && IsUniqueIndex(pIdx)))
- ){
- int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
- sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
- VdbeComment((v, "%s", pIdx->zName));
- assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
- eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
-
- if( prRhsHasNull && !pTab->aCol[iCol].notNull ){
+ /* Check that the affinity that will be used to perform each
+ ** comparison is the same as the affinity of each column in table
+ ** on the RHS of the IN operator. If it not, it is not possible to
+ ** use any index of the RHS table. */
+ for(i=0; i<nExpr && affinity_ok; i++){
+ Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
+ int iCol = pEList->a[i].pExpr->iColumn;
+ char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */
+ char cmpaff = sqlite3CompareAffinity(pLhs, idxaff);
+ testcase( cmpaff==SQLITE_AFF_BLOB );
+ testcase( cmpaff==SQLITE_AFF_TEXT );
+ switch( cmpaff ){
+ case SQLITE_AFF_BLOB:
+ break;
+ case SQLITE_AFF_TEXT:
+ /* sqlite3CompareAffinity() only returns TEXT if one side or the
+ ** other has no affinity and the other side is TEXT. Hence,
+ ** the only way for cmpaff to be TEXT is for idxaff to be TEXT
+ ** and for the term on the LHS of the IN to have no affinity. */
+ assert( idxaff==SQLITE_AFF_TEXT );
+ break;
+ default:
+ affinity_ok = sqlite3IsNumericAffinity(idxaff);
+ }
+ }
+
+ if( affinity_ok ){
+ /* Search for an existing index that will work for this IN operator */
+ for(pIdx=pTab->pIndex; pIdx && eType==0; pIdx=pIdx->pNext){
+ Bitmask colUsed; /* Columns of the index used */
+ Bitmask mCol; /* Mask for the current column */
+ if( pIdx->nColumn<nExpr ) continue;
+ /* Maximum nColumn is BMS-2, not BMS-1, so that we can compute
+ ** BITMASK(nExpr) without overflowing */
+ testcase( pIdx->nColumn==BMS-2 );
+ testcase( pIdx->nColumn==BMS-1 );
+ if( pIdx->nColumn>=BMS-1 ) continue;
+ if( mustBeUnique ){
+ if( pIdx->nKeyCol>nExpr
+ ||(pIdx->nColumn>nExpr && !IsUniqueIndex(pIdx))
+ ){
+ continue; /* This index is not unique over the IN RHS columns */
+ }
+ }
+
+ colUsed = 0; /* Columns of index used so far */
+ for(i=0; i<nExpr; i++){
+ Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
+ Expr *pRhs = pEList->a[i].pExpr;
+ CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
+ int j;
+
+ assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
+ for(j=0; j<nExpr; j++){
+ if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
+ assert( pIdx->azColl[j] );
+ if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
+ continue;
+ }
+ break;
+ }
+ if( j==nExpr ) break;
+ mCol = MASKBIT(j);
+ if( mCol & colUsed ) break; /* Each column used only once */
+ colUsed |= mCol;
+ if( aiMap ) aiMap[i] = j;
+ }
+
+ assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
+ if( colUsed==(MASKBIT(nExpr)-1) ){
+ /* If we reach this point, that means the index pIdx is usable */
+ int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+#ifndef SQLITE_OMIT_EXPLAIN
+ sqlite3VdbeAddOp4(v, OP_Explain, 0, 0, 0,
+ sqlite3MPrintf(db, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName),
+ P4_DYNAMIC);
+#endif
+ sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
+ sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
+ VdbeComment((v, "%s", pIdx->zName));
+ assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
+ eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
+
+ if( prRhsHasNull ){
#ifdef SQLITE_ENABLE_COLUMN_USED_MASK
- const i64 sOne = 1;
- sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed,
- iTab, 0, 0, (u8*)&sOne, P4_INT64);
+ i64 mask = (1<<nExpr)-1;
+ sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed,
+ iTab, 0, 0, (u8*)&mask, P4_INT64);
#endif
- *prRhsHasNull = ++pParse->nMem;
- sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
+ *prRhsHasNull = ++pParse->nMem;
+ if( nExpr==1 ){
+ sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull);
+ }
+ }
+ sqlite3VdbeJumpHere(v, iAddr);
}
- sqlite3VdbeJumpHere(v, iAddr);
- }
- }
- }
- }
+ } /* End loop over indexes */
+ } /* End if( affinity_ok ) */
+ } /* End if not an rowid index */
+ } /* End attempt to optimize using an index */
/* If no preexisting index is available for the IN clause
** and IN_INDEX_NOOP is an allowed reply
@@ -91306,7 +93055,6 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
){
eType = IN_INDEX_NOOP;
}
-
if( eType==0 ){
/* Could not find an existing table or index to use as the RHS b-tree.
@@ -91328,10 +93076,85 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
}else{
pX->iTable = iTab;
}
+
+ if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
+ int i, n;
+ n = sqlite3ExprVectorSize(pX->pLeft);
+ for(i=0; i<n; i++) aiMap[i] = i;
+ }
return eType;
}
#endif
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** Argument pExpr is an (?, ?...) IN(...) expression. This
+** function allocates and returns a nul-terminated string containing
+** the affinities to be used for each column of the comparison.
+**
+** It is the responsibility of the caller to ensure that the returned
+** string is eventually freed using sqlite3DbFree().
+*/
+static char *exprINAffinity(Parse *pParse, Expr *pExpr){
+ Expr *pLeft = pExpr->pLeft;
+ int nVal = sqlite3ExprVectorSize(pLeft);
+ Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0;
+ char *zRet;
+
+ assert( pExpr->op==TK_IN );
+ zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
+ if( zRet ){
+ int i;
+ for(i=0; i<nVal; i++){
+ Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
+ char a = sqlite3ExprAffinity(pA);
+ if( pSelect ){
+ zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
+ }else{
+ zRet[i] = a;
+ }
+ }
+ zRet[nVal] = '\0';
+ }
+ return zRet;
+}
+#endif
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
+** Load the Parse object passed as the first argument with an error
+** message of the form:
+**
+** "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);
+}
+#endif
+
+/*
+** Expression pExpr is a vector that has been used in a context where
+** it is not permitted. If pExpr is a sub-select vector, this routine
+** loads the Parse object with a message of the form:
+**
+** "sub-select returns N columns - expected 1"
+**
+** Or, if it is a regular scalar vector:
+**
+** "row value misused"
+*/
+SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
+#ifndef SQLITE_OMIT_SUBQUERY
+ if( pExpr->flags & EP_xIsSelect ){
+ sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
+ }else
+#endif
+ {
+ sqlite3ErrorMsg(pParse, "row value misused");
+ }
+}
+
/*
** Generate code for scalar subqueries used as a subquery expression, EXISTS,
** or IN operators. Examples:
@@ -91357,7 +93180,9 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
** value to non-NULL if the RHS is NULL-free.
**
** For a SELECT or EXISTS operator, return the register that holds the
-** result. For IN operators or if an error occurs, the return value is 0.
+** result. For a multi-column SELECT, the result is stored in a contiguous
+** array of registers and the return value is the register of the left-most
+** result column. Return 0 for IN operators or if an error occurs.
*/
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE int sqlite3CodeSubselect(
@@ -91372,8 +93197,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
if( NEVER(v==0) ) return 0;
sqlite3ExprCachePush(pParse);
- /* This code must be run in its entirety every time it is encountered
- ** if any of the following is true:
+ /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
+ ** is encountered if any of the following is true:
**
** * The right-hand side is a correlated subquery
** * The right-hand side is an expression list containing variables
@@ -91383,7 +93208,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** save the results, and reuse the same result on subsequent invocations.
*/
if( !ExprHasProperty(pExpr, EP_VarSelect) ){
- jmpIfDynamic = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
#ifndef SQLITE_OMIT_EXPLAIN
@@ -91399,17 +93224,18 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
switch( pExpr->op ){
case TK_IN: {
- char affinity; /* Affinity of the LHS of the IN */
int addr; /* Address of OP_OpenEphemeral instruction */
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
KeyInfo *pKeyInfo = 0; /* Key information */
-
- affinity = sqlite3ExprAffinity(pLeft);
+ int nVal; /* Size of vector pLeft */
+
+ nVal = sqlite3ExprVectorSize(pLeft);
+ assert( !isRowid || nVal==1 );
/* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
** expression it is handled the same way. An ephemeral table is
- ** filled with single-field index keys representing the results
- ** from the SELECT or the <exprlist>.
+ ** filled with index keys representing the results from the
+ ** SELECT or the <exprlist>.
**
** If the 'x' expression is a column value, or the SELECT...
** statement returns a column value, then the affinity of that
@@ -91420,8 +93246,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** is used.
*/
pExpr->iTable = pParse->nTab++;
- addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
- pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1);
+ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral,
+ pExpr->iTable, (isRowid?0:nVal));
+ pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* Case 1: expr IN (SELECT ...)
@@ -91430,27 +93257,36 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** table allocated and opened above.
*/
Select *pSelect = pExpr->x.pSelect;
- SelectDest dest;
- ExprList *pEList;
+ ExprList *pEList = pSelect->pEList;
assert( !isRowid );
- sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
- dest.affSdst = (u8)affinity;
- assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
- pSelect->iLimit = 0;
- testcase( pSelect->selFlags & SF_Distinct );
- testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
- if( sqlite3Select(pParse, pSelect, &dest) ){
- sqlite3KeyInfoUnref(pKeyInfo);
- return 0;
+ /* If the LHS and RHS of the IN operator do not match, that
+ ** error will have been caught long before we reach this point. */
+ if( ALWAYS(pEList->nExpr==nVal) ){
+ SelectDest dest;
+ int i;
+ sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
+ dest.zAffSdst = exprINAffinity(pParse, pExpr);
+ pSelect->iLimit = 0;
+ testcase( pSelect->selFlags & SF_Distinct );
+ testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
+ if( sqlite3Select(pParse, pSelect, &dest) ){
+ sqlite3DbFree(pParse->db, dest.zAffSdst);
+ sqlite3KeyInfoUnref(pKeyInfo);
+ return 0;
+ }
+ sqlite3DbFree(pParse->db, dest.zAffSdst);
+ assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
+ assert( pEList!=0 );
+ assert( pEList->nExpr>0 );
+ assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
+ for(i=0; i<nVal; i++){
+ Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
+ pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
+ pParse, p, pEList->a[i].pExpr
+ );
+ }
}
- pEList = pSelect->pEList;
- assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
- assert( pEList!=0 );
- assert( pEList->nExpr>0 );
- assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
- pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
- pEList->a[0].pExpr);
}else if( ALWAYS(pExpr->x.pList!=0) ){
/* Case 2: expr IN (exprlist)
**
@@ -91459,11 +93295,13 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** that columns affinity when building index keys. If <expr> is not
** a column, use numeric affinity.
*/
+ char affinity; /* Affinity of the LHS of the IN */
int i;
ExprList *pList = pExpr->x.pList;
struct ExprList_item *pItem;
int r1, r2, r3;
+ affinity = sqlite3ExprAffinity(pLeft);
if( !affinity ){
affinity = SQLITE_AFF_BLOB;
}
@@ -91503,7 +93341,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
sqlite3ExprCacheAffinityChange(pParse, r3, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
}
}
}
@@ -91519,26 +93357,37 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
case TK_EXISTS:
case TK_SELECT:
default: {
- /* If this has to be a scalar SELECT. Generate code to put the
- ** value of this select in a memory cell and record the number
- ** of the memory cell in iColumn. If this is an EXISTS, write
- ** an integer 0 (not exists) or 1 (exists) into a memory cell
- ** and record that memory cell in iColumn.
+ /* Case 3: (SELECT ... FROM ...)
+ ** or: EXISTS(SELECT ... FROM ...)
+ **
+ ** For a SELECT, generate code to put the values for all columns of
+ ** the first row into an array of registers and return the index of
+ ** the first register.
+ **
+ ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
+ ** into a register and return that register number.
+ **
+ ** In both cases, the query is augmented with "LIMIT 1". Any
+ ** preexisting limit is discarded in place of the new LIMIT 1.
*/
Select *pSel; /* SELECT statement to encode */
- SelectDest dest; /* How to deal with SELECt result */
+ SelectDest dest; /* How to deal with SELECT result */
+ int nReg; /* Registers to allocate */
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
-
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
+
pSel = pExpr->x.pSelect;
- sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
+ nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
+ sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
+ pParse->nMem += nReg;
if( pExpr->op==TK_SELECT ){
dest.eDest = SRT_Mem;
dest.iSdst = dest.iSDParm;
- sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
+ dest.nSdst = nReg;
+ sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
VdbeComment((v, "Init subquery result"));
}else{
dest.eDest = SRT_Exists;
@@ -91546,8 +93395,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
VdbeComment((v, "Init EXISTS result"));
}
sqlite3ExprDelete(pParse->db, pSel->pLimit);
- pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
- &sqlite3IntTokens[1]);
+ pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
+ &sqlite3IntTokens[1], 0);
pSel->iLimit = 0;
pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
@@ -91574,21 +93423,51 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
#ifndef SQLITE_OMIT_SUBQUERY
/*
+** Expr pIn is an IN(...) expression. This function checks that the
+** sub-select on the RHS of the IN() operator has the same number of
+** columns as the vector on the LHS. Or, if the RHS of the IN() is not
+** a sub-query, that the LHS is a vector of size 1.
+*/
+SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
+ int nVector = sqlite3ExprVectorSize(pIn->pLeft);
+ if( (pIn->flags & EP_xIsSelect) ){
+ if( nVector!=pIn->x.pSelect->pEList->nExpr ){
+ sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
+ return 1;
+ }
+ }else if( nVector!=1 ){
+ sqlite3VectorErrorMsg(pParse, pIn->pLeft);
+ return 1;
+ }
+ return 0;
+}
+#endif
+
+#ifndef SQLITE_OMIT_SUBQUERY
+/*
** Generate code for an IN expression.
**
** x IN (SELECT ...)
** x IN (value, value, ...)
**
-** The left-hand side (LHS) is a scalar expression. The right-hand side (RHS)
-** is an array of zero or more values. The expression is true if the LHS is
-** contained within the RHS. The value of the expression is unknown (NULL)
-** if the LHS is NULL or if the LHS is not contained within the RHS and the
-** RHS contains one or more NULL values.
+** The left-hand side (LHS) is a scalar or vector expression. The
+** right-hand side (RHS) is an array of zero or more scalar values, or a
+** subquery. If the RHS is a subquery, the number of result columns must
+** match the number of columns in the vector on the LHS. If the RHS is
+** a list of values, the LHS must be a scalar.
+**
+** The IN operator is true if the LHS value is contained within the RHS.
+** The result is false if the LHS is definitely not in the RHS. The
+** result is NULL if the presence of the LHS in the RHS cannot be
+** determined due to NULLs.
**
** This routine generates code that jumps to destIfFalse if the LHS is not
** contained within the RHS. If due to NULLs we cannot determine if the LHS
** is contained in the RHS then jump to destIfNull. If the LHS is contained
** within the RHS then fall through.
+**
+** See the separate in-operator.md documentation file in the canonical
+** SQLite source tree for additional information.
*/
static void sqlite3ExprCodeIN(
Parse *pParse, /* Parsing and code generating context */
@@ -91597,36 +93476,83 @@ static void sqlite3ExprCodeIN(
int destIfNull /* Jump here if the results are unknown due to NULLs */
){
int rRhsHasNull = 0; /* Register that is true if RHS contains NULL values */
- char affinity; /* Comparison affinity to use */
int eType; /* Type of the RHS */
- int r1; /* Temporary use register */
+ int rLhs; /* Register(s) holding the LHS values */
+ int rLhsOrig; /* LHS values prior to reordering by aiMap[] */
Vdbe *v; /* Statement under construction */
+ int *aiMap = 0; /* Map from vector field to index column */
+ char *zAff = 0; /* Affinity string for comparisons */
+ int nVector; /* Size of vectors for this IN operator */
+ int iDummy; /* Dummy parameter to exprCodeVector() */
+ Expr *pLeft; /* The LHS of the IN operator */
+ int i; /* loop counter */
+ int destStep2; /* Where to jump when NULLs seen in step 2 */
+ int destStep6 = 0; /* Start of code for Step 6 */
+ int addrTruthOp; /* Address of opcode that determines the IN is true */
+ int destNotNull; /* Jump here if a comparison is not true in step 6 */
+ int addrTop; /* Top of the step-6 loop */
+
+ pLeft = pExpr->pLeft;
+ if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
+ zAff = exprINAffinity(pParse, pExpr);
+ nVector = sqlite3ExprVectorSize(pExpr->pLeft);
+ aiMap = (int*)sqlite3DbMallocZero(
+ pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
+ );
+ if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;
- /* Compute the RHS. After this step, the table with cursor
- ** pExpr->iTable will contains the values that make up the RHS.
- */
+ /* Attempt to compute the RHS. After this step, if anything other than
+ ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable
+ ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
+ ** the RHS has not yet been coded. */
v = pParse->pVdbe;
assert( v!=0 ); /* OOM detected prior to this routine */
VdbeNoopComment((v, "begin IN expr"));
eType = sqlite3FindInIndex(pParse, pExpr,
IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
- destIfFalse==destIfNull ? 0 : &rRhsHasNull);
+ destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap);
- /* Figure out the affinity to use to create a key from the results
- ** of the expression. affinityStr stores a static string suitable for
- ** P4 of OP_MakeRecord.
- */
- affinity = comparisonAffinity(pExpr);
+ assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
+ || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC
+ );
+#ifdef SQLITE_DEBUG
+ /* Confirm that aiMap[] contains nVector integer values between 0 and
+ ** nVector-1. */
+ for(i=0; i<nVector; i++){
+ int j, cnt;
+ for(cnt=j=0; j<nVector; j++) if( aiMap[j]==i ) cnt++;
+ assert( cnt==1 );
+ }
+#endif
- /* Code the LHS, the <expr> from "<expr> IN (...)".
+ /* Code the LHS, the <expr> from "<expr> IN (...)". If the LHS is a
+ ** vector, then it is stored in an array of nVector registers starting
+ ** at r1.
+ **
+ ** sqlite3FindInIndex() might have reordered the fields of the LHS vector
+ ** 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.
*/
sqlite3ExprCachePush(pParse);
- r1 = sqlite3GetTempReg(pParse);
- sqlite3ExprCode(pParse, pExpr->pLeft, r1);
+ rLhsOrig = exprCodeVector(pParse, pLeft, &iDummy);
+ for(i=0; i<nVector && aiMap[i]==i; i++){} /* Are LHS fields reordered? */
+ if( i==nVector ){
+ /* LHS fields are not reordered */
+ rLhs = rLhsOrig;
+ }else{
+ /* Need to reorder the LHS fields according to aiMap */
+ rLhs = sqlite3GetTempRange(pParse, nVector);
+ for(i=0; i<nVector; i++){
+ sqlite3VdbeAddOp3(v, OP_Copy, rLhsOrig+i, rLhs+aiMap[i], 0);
+ }
+ }
/* If sqlite3FindInIndex() did not find or create an index that is
** suitable for evaluating the IN operator, then evaluate using a
** sequence of comparisons.
+ **
+ ** This is step (1) in the in-operator.md optimized algorithm.
*/
if( eType==IN_INDEX_NOOP ){
ExprList *pList = pExpr->x.pList;
@@ -91638,7 +93564,7 @@ static void sqlite3ExprCodeIN(
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( destIfNull!=destIfFalse ){
regCkNull = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull);
+ sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
}
for(ii=0; ii<pList->nExpr; ii++){
r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
@@ -91646,16 +93572,16 @@ static void sqlite3ExprCodeIN(
sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
}
if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){
- sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2,
+ sqlite3VdbeAddOp4(v, OP_Eq, rLhs, labelOk, r2,
(void*)pColl, P4_COLLSEQ);
VdbeCoverageIf(v, ii<pList->nExpr-1);
VdbeCoverageIf(v, ii==pList->nExpr-1);
- sqlite3VdbeChangeP5(v, affinity);
+ sqlite3VdbeChangeP5(v, zAff[0]);
}else{
assert( destIfNull==destIfFalse );
- sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2,
+ sqlite3VdbeAddOp4(v, OP_Ne, rLhs, destIfFalse, r2,
(void*)pColl, P4_COLLSEQ); VdbeCoverage(v);
- sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL);
+ sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL);
}
sqlite3ReleaseTempReg(pParse, regToFree);
}
@@ -91665,77 +93591,113 @@ static void sqlite3ExprCodeIN(
}
sqlite3VdbeResolveLabel(v, labelOk);
sqlite3ReleaseTempReg(pParse, regCkNull);
+ goto sqlite3ExprCodeIN_finished;
+ }
+
+ /* Step 2: Check to see if the LHS contains any NULL columns. If the
+ ** LHS does contain NULLs then the result must be either FALSE or NULL.
+ ** We will then skip the binary search of the RHS.
+ */
+ if( destIfNull==destIfFalse ){
+ destStep2 = destIfFalse;
}else{
-
- /* If the LHS is NULL, then the result is either false or NULL depending
- ** on whether the RHS is empty or not, respectively.
- */
- if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
- if( destIfNull==destIfFalse ){
- /* Shortcut for the common case where the false and NULL outcomes are
- ** the same. */
- sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
- }else{
- int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
- VdbeCoverage(v);
- sqlite3VdbeGoto(v, destIfNull);
- sqlite3VdbeJumpHere(v, addr1);
- }
- }
-
- if( eType==IN_INDEX_ROWID ){
- /* In this case, the RHS is the ROWID of table b-tree
- */
- sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, r1);
+ destStep2 = destStep6 = sqlite3VdbeMakeLabel(v);
+ }
+ for(i=0; i<nVector; i++){
+ Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
+ if( sqlite3ExprCanBeNull(p) ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
VdbeCoverage(v);
- }else{
- /* In this case, the RHS is an index b-tree.
- */
- sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);
-
- /* If the set membership test fails, then the result of the
- ** "x IN (...)" expression must be either 0 or NULL. If the set
- ** contains no NULL values, then the result is 0. If the set
- ** contains one or more NULL values, then the result of the
- ** expression is also NULL.
- */
- assert( destIfFalse!=destIfNull || rRhsHasNull==0 );
- if( rRhsHasNull==0 ){
- /* This branch runs if it is known at compile time that the RHS
- ** cannot contain NULL values. This happens as the result
- ** of a "NOT NULL" constraint in the database schema.
- **
- ** Also run this branch if NULL is equivalent to FALSE
- ** for this particular IN operator.
- */
- sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
- VdbeCoverage(v);
- }else{
- /* In this branch, the RHS of the IN might contain a NULL and
- ** the presence of a NULL on the RHS makes a difference in the
- ** outcome.
- */
- int addr1;
-
- /* First check to see if the LHS is contained in the RHS. If so,
- ** then the answer is TRUE the presence of NULLs in the RHS does
- ** not matter. If the LHS is not contained in the RHS, then the
- ** answer is NULL if the RHS contains NULLs and the answer is
- ** FALSE if the RHS is NULL-free.
- */
- addr1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
- VdbeCoverage(v);
- sqlite3VdbeGoto(v, destIfFalse);
- sqlite3VdbeJumpHere(v, addr1);
- }
}
}
- sqlite3ReleaseTempReg(pParse, r1);
+
+ /* Step 3. The LHS is now known to be non-NULL. Do the binary search
+ ** of the RHS using the LHS as a probe. If found, the result is
+ ** true.
+ */
+ if( eType==IN_INDEX_ROWID ){
+ /* In this case, the RHS is the ROWID of table b-tree and so we also
+ ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4
+ ** into a single opcode. */
+ sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs);
+ VdbeCoverage(v);
+ addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */
+ }else{
+ sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
+ if( destIfFalse==destIfNull ){
+ /* Combine Step 3 and Step 5 into a single opcode */
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse,
+ rLhs, nVector); VdbeCoverage(v);
+ goto sqlite3ExprCodeIN_finished;
+ }
+ /* Ordinary Step 3, for the case where FALSE and NULL are distinct */
+ addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0,
+ rLhs, nVector); VdbeCoverage(v);
+ }
+
+ /* Step 4. If the RHS is known to be non-NULL and we did not find
+ ** an match on the search above, then the result must be FALSE.
+ */
+ if( rRhsHasNull && nVector==1 ){
+ sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse);
+ VdbeCoverage(v);
+ }
+
+ /* Step 5. If we do not care about the difference between NULL and
+ ** FALSE, then just return false.
+ */
+ if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse);
+
+ /* Step 6: Loop through rows of the RHS. Compare each row to the LHS.
+ ** If any comparison is NULL, then the result is NULL. If all
+ ** comparisons are FALSE then the final result is FALSE.
+ **
+ ** For a scalar LHS, it is sufficient to check just the first row
+ ** of the RHS.
+ */
+ if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
+ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
+ VdbeCoverage(v);
+ if( nVector>1 ){
+ destNotNull = sqlite3VdbeMakeLabel(v);
+ }else{
+ /* For nVector==1, combine steps 6 and 7 by immediately returning
+ ** FALSE if the first comparison is not NULL */
+ destNotNull = destIfFalse;
+ }
+ for(i=0; i<nVector; i++){
+ Expr *p;
+ CollSeq *pColl;
+ int r3 = sqlite3GetTempReg(pParse);
+ p = sqlite3VectorFieldSubexpr(pLeft, i);
+ pColl = sqlite3ExprCollSeq(pParse, p);
+ sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, i, r3);
+ sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
+ (void*)pColl, P4_COLLSEQ);
+ VdbeCoverage(v);
+ sqlite3ReleaseTempReg(pParse, r3);
+ }
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
+ if( nVector>1 ){
+ sqlite3VdbeResolveLabel(v, destNotNull);
+ sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1);
+ VdbeCoverage(v);
+
+ /* Step 7: If we reach this point, we know that the result must
+ ** be false. */
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
+ }
+
+ /* Jumps here in order to return true. */
+ sqlite3VdbeJumpHere(v, addrTruthOp);
+
+sqlite3ExprCodeIN_finished:
+ if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs);
sqlite3ExprCachePop(pParse);
VdbeComment((v, "end IN expr"));
+sqlite3ExprCodeIN_oom_error:
+ sqlite3DbFree(pParse->db, aiMap);
+ sqlite3DbFree(pParse->db, zAff);
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -91779,52 +93741,39 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
const char *z = pExpr->u.zToken;
assert( z!=0 );
c = sqlite3DecOrHexToI64(z, &value);
- if( c==0 || (c==2 && negFlag) ){
- if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
- sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
- }else{
+ if( c==1 || (c==2 && !negFlag) || (negFlag && value==SMALLEST_INT64)){
#ifdef SQLITE_OMIT_FLOATING_POINT
sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else
#ifndef SQLITE_OMIT_HEX_INTEGER
if( sqlite3_strnicmp(z,"0x",2)==0 ){
- sqlite3ErrorMsg(pParse, "hex literal too big: %s", z);
+ sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z);
}else
#endif
{
codeReal(v, z, negFlag, iMem);
}
#endif
+ }else{
+ if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
+ sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
}
}
}
-#if defined(SQLITE_DEBUG)
/*
-** Verify the consistency of the column cache
+** Erase column-cache entry number i
*/
-static int cacheIsValid(Parse *pParse){
- int i, n;
- for(i=n=0; i<SQLITE_N_COLCACHE; i++){
- if( pParse->aColCache[i].iReg>0 ) n++;
- }
- return n==pParse->nColCache;
-}
-#endif
-
-/*
-** Clear a cache entry.
-*/
-static void cacheEntryClear(Parse *pParse, struct yColCache *p){
- if( p->tempReg ){
+static void cacheEntryClear(Parse *pParse, int i){
+ if( pParse->aColCache[i].tempReg ){
if( pParse->nTempReg<ArraySize(pParse->aTempReg) ){
- pParse->aTempReg[pParse->nTempReg++] = p->iReg;
+ pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
}
- p->tempReg = 0;
}
- p->iReg = 0;
pParse->nColCache--;
- assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
+ if( i<pParse->nColCache ){
+ pParse->aColCache[i] = pParse->aColCache[pParse->nColCache];
+ }
}
@@ -91854,46 +93803,33 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
** that the object will never already be in cache. Verify this guarantee.
*/
#ifndef NDEBUG
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- assert( p->iReg==0 || p->iTable!=iTab || p->iColumn!=iCol );
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+ assert( p->iTable!=iTab || p->iColumn!=iCol );
}
#endif
- /* Find an empty slot and replace it */
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg==0 ){
- p->iLevel = pParse->iCacheLevel;
- p->iTable = iTab;
- p->iColumn = iCol;
- p->iReg = iReg;
- p->tempReg = 0;
- p->lru = pParse->iCacheCnt++;
- pParse->nColCache++;
- assert( pParse->db->mallocFailed || cacheIsValid(pParse) );
- return;
- }
- }
-
- /* Replace the last recently used */
- minLru = 0x7fffffff;
- idxLru = -1;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->lru<minLru ){
- idxLru = i;
- minLru = p->lru;
+ /* If the cache is already full, delete the least recently used entry */
+ if( pParse->nColCache>=SQLITE_N_COLCACHE ){
+ minLru = 0x7fffffff;
+ idxLru = -1;
+ for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+ if( p->lru<minLru ){
+ idxLru = i;
+ minLru = p->lru;
+ }
}
- }
- if( ALWAYS(idxLru>=0) ){
p = &pParse->aColCache[idxLru];
- p->iLevel = pParse->iCacheLevel;
- p->iTable = iTab;
- p->iColumn = iCol;
- p->iReg = iReg;
- p->tempReg = 0;
- p->lru = pParse->iCacheCnt++;
- assert( cacheIsValid(pParse) );
- return;
+ }else{
+ p = &pParse->aColCache[pParse->nColCache++];
}
+
+ /* Add the new entry to the end of the cache */
+ p->iLevel = pParse->iCacheLevel;
+ p->iTable = iTab;
+ p->iColumn = iCol;
+ p->iReg = iReg;
+ p->tempReg = 0;
+ p->lru = pParse->iCacheCnt++;
}
/*
@@ -91901,13 +93837,14 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
** Purge the range of registers from the column cache.
*/
SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
- struct yColCache *p;
- if( iReg<=0 || pParse->nColCache==0 ) return;
- p = &pParse->aColCache[SQLITE_N_COLCACHE-1];
- while(1){
- if( p->iReg >= iReg && p->iReg < iReg+nReg ) cacheEntryClear(pParse, p);
- if( p==pParse->aColCache ) break;
- p--;
+ int i = 0;
+ while( i<pParse->nColCache ){
+ struct yColCache *p = &pParse->aColCache[i];
+ if( p->iReg >= iReg && p->iReg < iReg+nReg ){
+ cacheEntryClear(pParse, i);
+ }else{
+ i++;
+ }
}
}
@@ -91931,8 +93868,7 @@ SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
** the cache to the state it was in prior the most recent Push.
*/
SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
- int i;
- struct yColCache *p;
+ int i = 0;
assert( pParse->iCacheLevel>=1 );
pParse->iCacheLevel--;
#ifdef SQLITE_DEBUG
@@ -91940,9 +93876,11 @@ SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
printf("POP to %d\n", pParse->iCacheLevel);
}
#endif
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg && p->iLevel>pParse->iCacheLevel ){
- cacheEntryClear(pParse, p);
+ while( i<pParse->nColCache ){
+ if( pParse->aColCache[i].iLevel>pParse->iCacheLevel ){
+ cacheEntryClear(pParse, i);
+ }else{
+ i++;
}
}
}
@@ -91956,7 +93894,7 @@ SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse){
static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){
int i;
struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
if( p->iReg==iReg ){
p->tempReg = 0;
}
@@ -92034,8 +93972,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
int i;
struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn ){
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
+ if( p->iTable==iTable && p->iColumn==iColumn ){
p->lru = pParse->iCacheCnt++;
sqlite3ExprCachePinRegister(pParse, p->iReg);
return p->iReg;
@@ -92067,18 +94005,20 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnToReg(
*/
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
int i;
- struct yColCache *p;
-#if SQLITE_DEBUG
+#ifdef SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("CLEAR\n");
}
#endif
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
- if( p->iReg ){
- cacheEntryClear(pParse, p);
+ for(i=0; i<pParse->nColCache; i++){
+ if( pParse->aColCache[i].tempReg
+ && pParse->nTempReg<ArraySize(pParse->aTempReg)
+ ){
+ pParse->aTempReg[pParse->nTempReg++] = pParse->aColCache[i].iReg;
}
}
+ pParse->nColCache = 0;
}
/*
@@ -92110,7 +94050,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n
static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
int i;
struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
int r = p->iReg;
if( r>=iFrom && r<=iTo ) return 1; /*NO_TEST*/
}
@@ -92120,7 +94060,9 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
/*
-** Convert an expression node to a TK_REGISTER
+** Convert a scalar expression node to a TK_REGISTER referencing
+** register iReg. The caller must ensure that iReg already contains
+** the correct value for the expression.
*/
static void exprToRegister(Expr *p, int iReg){
p->op2 = p->op;
@@ -92130,6 +94072,38 @@ static void exprToRegister(Expr *p, int iReg){
}
/*
+** Evaluate an expression (either a vector or a scalar expression) and store
+** the result in continguous temporary registers. Return the index of
+** the first register used to store the result.
+**
+** If the returned result register is a temporary scalar, then also write
+** that register number into *piFreeable. If the returned result register
+** is not a temporary or if the expression is a vector set *piFreeable
+** to 0.
+*/
+static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){
+ int iResult;
+ int nResult = sqlite3ExprVectorSize(p);
+ if( nResult==1 ){
+ iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
+ }else{
+ *piFreeable = 0;
+ if( p->op==TK_SELECT ){
+ iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
+ }else{
+ int i;
+ iResult = pParse->nMem+1;
+ pParse->nMem += nResult;
+ for(i=0; i<nResult; i++){
+ sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
+ }
+ }
+ }
+ return iResult;
+}
+
+
+/*
** Generate code into the current Vdbe to evaluate the given
** expression. Attempt to store the results in register "target".
** Return the register where results are stored.
@@ -92146,9 +94120,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
int inReg = target; /* Results stored in register inReg */
int regFree1 = 0; /* If non-zero free this temporary register */
int regFree2 = 0; /* If non-zero free this temporary register */
- int r1, r2, r3, r4; /* Various register numbers */
- sqlite3 *db = pParse->db; /* The database connection */
+ int r1, r2; /* Various register numbers */
Expr tempX; /* Temporary expression node */
+ int p5 = 0;
assert( target>0 && target<=pParse->nMem );
if( v==0 ){
@@ -92167,12 +94141,11 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
struct AggInfo_col *pCol = &pAggInfo->aCol[pExpr->iAgg];
if( !pAggInfo->directMode ){
assert( pCol->iMem>0 );
- inReg = pCol->iMem;
- break;
+ return pCol->iMem;
}else if( pAggInfo->useSortingIdx ){
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
pCol->iSorterColumn, target);
- break;
+ return target;
}
/* Otherwise, fall thru into the TK_COLUMN case */
}
@@ -92181,38 +94154,36 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( iTab<0 ){
if( pParse->ckBase>0 ){
/* Generating CHECK constraints or inserting into partial index */
- inReg = pExpr->iColumn + pParse->ckBase;
- break;
+ return pExpr->iColumn + pParse->ckBase;
}else{
/* Coding an expression that is part of an index where column names
** in the index refer to the table to which the index belongs */
iTab = pParse->iSelfTab;
}
}
- inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
+ return sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
- break;
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
- break;
+ return target;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
case TK_FLOAT: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pExpr->u.zToken, 0, target);
- break;
+ return target;
}
#endif
case TK_STRING: {
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeLoadString(v, target, pExpr->u.zToken);
- break;
+ return target;
}
case TK_NULL: {
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
- break;
+ return target;
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case TK_BLOB: {
@@ -92227,7 +94198,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( z[n]=='\'' );
zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
- break;
+ return target;
}
#endif
case TK_VARIABLE: {
@@ -92236,15 +94207,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( pExpr->u.zToken[0]!=0 );
sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
if( pExpr->u.zToken[1]!=0 ){
- assert( pExpr->u.zToken[0]=='?'
- || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 );
- sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC);
+ const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn);
+ assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, z)==0 );
+ pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */
+ sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC);
}
- break;
+ return target;
}
case TK_REGISTER: {
- inReg = pExpr->iTable;
- break;
+ return pExpr->iTable;
}
#ifndef SQLITE_OMIT_CAST
case TK_CAST: {
@@ -92258,42 +94229,37 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
sqlite3AffinityType(pExpr->u.zToken, 0));
testcase( usedAsColumnCache(pParse, inReg, inReg) );
sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
- break;
+ return inReg;
}
#endif /* SQLITE_OMIT_CAST */
+ case TK_IS:
+ case TK_ISNOT:
+ op = (op==TK_IS) ? TK_EQ : TK_NE;
+ p5 = SQLITE_NULLEQ;
+ /* fall-through */
case TK_LT:
case TK_LE:
case TK_GT:
case TK_GE:
case TK_NE:
case TK_EQ: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, inReg, SQLITE_STOREP2);
- 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);
- assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
- assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
- assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- break;
- }
- case TK_IS:
- case TK_ISNOT: {
- testcase( op==TK_IS );
- testcase( op==TK_ISNOT );
- r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
- op = (op==TK_IS) ? TK_EQ : TK_NE;
- codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
- r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
- VdbeCoverageIf(v, op==TK_EQ);
- VdbeCoverageIf(v, op==TK_NE);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
+ Expr *pLeft = pExpr->pLeft;
+ if( sqlite3ExprIsVector(pLeft) ){
+ codeVectorCompare(pParse, pExpr, target, op, p5);
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
+ r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
+ codeCompare(pParse, pLeft, pExpr->pRight, op,
+ r1, r2, inReg, SQLITE_STOREP2 | p5);
+ 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);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
+ testcase( regFree1==0 );
+ testcase( regFree2==0 );
+ }
break;
}
case TK_AND:
@@ -92331,10 +94297,12 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( pLeft );
if( pLeft->op==TK_INTEGER ){
codeInteger(pParse, pLeft, 1, target);
+ return target;
#ifndef SQLITE_OMIT_FLOATING_POINT
}else if( pLeft->op==TK_FLOAT ){
assert( !ExprHasProperty(pExpr, EP_IntValue) );
codeReal(v, pLeft->u.zToken, 1, target);
+ return target;
#endif
}else{
tempX.op = TK_INTEGER;
@@ -92345,7 +94313,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target);
testcase( regFree2==0 );
}
- inReg = target;
break;
}
case TK_BITNOT:
@@ -92354,7 +94321,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( TK_NOT==OP_Not ); testcase( op==TK_NOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
testcase( regFree1==0 );
- inReg = target;
sqlite3VdbeAddOp2(v, op, r1, inReg);
break;
}
@@ -92379,7 +94345,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
- inReg = pInfo->aFunc[pExpr->iAgg].iMem;
+ return pInfo->aFunc[pExpr->iAgg].iMem;
}
break;
}
@@ -92390,9 +94356,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
const char *zId; /* The function name */
u32 constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
+ sqlite3 *db = pParse->db; /* The database connection */
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
+ 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);
+ }
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
if( ExprHasProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
@@ -92438,10 +94410,25 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
*/
if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
assert( nFarg>=1 );
- inReg = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target);
- break;
+ 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 ? azAff[aff-SQLITE_AFF_BLOB] : "none");
+ return target;
+ }
+#endif
+
for(i=0; i<nFarg; i++){
if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
testcase( i==31 );
@@ -92514,16 +94501,35 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( nFarg && constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
}
- break;
+ return target;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_EXISTS:
case TK_SELECT: {
+ int nCol;
testcase( op==TK_EXISTS );
testcase( op==TK_SELECT );
- inReg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+ if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
+ sqlite3SubselectError(pParse, nCol, 1);
+ }else{
+ return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
+ }
break;
}
+ case TK_SELECT_COLUMN: {
+ int n;
+ if( pExpr->pLeft->iTable==0 ){
+ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
+ }
+ assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
+ if( pExpr->iTable
+ && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft))
+ ){
+ sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
+ pExpr->iTable, n);
+ }
+ return pExpr->pLeft->iTable + pExpr->iColumn;
+ }
case TK_IN: {
int destIfFalse = sqlite3VdbeMakeLabel(v);
int destIfNull = sqlite3VdbeMakeLabel(v);
@@ -92533,7 +94539,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
sqlite3VdbeResolveLabel(v, destIfFalse);
sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
sqlite3VdbeResolveLabel(v, destIfNull);
- break;
+ return target;
}
#endif /* SQLITE_OMIT_SUBQUERY */
@@ -92550,35 +94556,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** Z is stored in pExpr->pList->a[1].pExpr.
*/
case TK_BETWEEN: {
- Expr *pLeft = pExpr->pLeft;
- struct ExprList_item *pLItem = pExpr->x.pList->a;
- Expr *pRight = pLItem->pExpr;
-
- r1 = sqlite3ExprCodeTemp(pParse, pLeft, &regFree1);
- r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
- testcase( regFree1==0 );
- testcase( regFree2==0 );
- r3 = sqlite3GetTempReg(pParse);
- r4 = sqlite3GetTempReg(pParse);
- codeCompare(pParse, pLeft, pRight, OP_Ge,
- r1, r2, r3, SQLITE_STOREP2); VdbeCoverage(v);
- pLItem++;
- pRight = pLItem->pExpr;
- sqlite3ReleaseTempReg(pParse, regFree2);
- r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
- testcase( regFree2==0 );
- codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
- VdbeCoverage(v);
- sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
- sqlite3ReleaseTempReg(pParse, r3);
- sqlite3ReleaseTempReg(pParse, r4);
- break;
+ exprCodeBetween(pParse, pExpr, target, 0, 0);
+ return target;
}
case TK_SPAN:
case TK_COLLATE:
case TK_UPLUS: {
- inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- break;
+ return sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
}
case TK_TRIGGER: {
@@ -92637,6 +94621,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
break;
}
+ case TK_VECTOR: {
+ sqlite3ErrorMsg(pParse, "row value misused");
+ break;
+ }
/*
** Form A:
@@ -92680,8 +94668,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( (pX = pExpr->pLeft)!=0 ){
tempX = *pX;
testcase( pX->op==TK_COLUMN );
- exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, &regFree1));
+ exprToRegister(&tempX, exprCodeVector(pParse, &tempX, &regFree1));
testcase( regFree1==0 );
+ memset(&opCompare, 0, sizeof(opCompare));
opCompare.op = TK_EQ;
opCompare.pLeft = &tempX;
pTest = &opCompare;
@@ -92715,7 +94704,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
}
- assert( db->mallocFailed || pParse->nErr>0
+ assert( pParse->db->mallocFailed || pParse->nErr>0
|| pParse->iCacheLevel==iCacheLevel );
sqlite3VdbeResolveLabel(v, endLabel);
break;
@@ -92756,24 +94745,40 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
/*
** Factor out the code of the given expression to initialization time.
+**
+** 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.
*/
-SQLITE_PRIVATE void sqlite3ExprCodeAtInit(
+SQLITE_PRIVATE int sqlite3ExprCodeAtInit(
Parse *pParse, /* Parsing context */
Expr *pExpr, /* The expression to code when the VDBE initializes */
- int regDest, /* Store the value in this register */
- u8 reusable /* True if this expression is reusable */
+ int regDest /* Store the value in this register */
){
ExprList *p;
assert( ConstFactorOk(pParse) );
p = pParse->pConstExpr;
+ if( regDest<0 && p ){
+ struct ExprList_item *pItem;
+ int i;
+ for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
+ if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
+ return pItem->u.iConstExprReg;
+ }
+ }
+ }
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;
- pItem->reusable = reusable;
}
pParse->pConstExpr = p;
+ return regDest;
}
/*
@@ -92796,19 +94801,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
&& pExpr->op!=TK_REGISTER
&& sqlite3ExprIsConstantNotJoin(pExpr)
){
- ExprList *p = pParse->pConstExpr;
- int i;
*pReg = 0;
- if( p ){
- struct ExprList_item *pItem;
- for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
- if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
- return pItem->u.iConstExprReg;
- }
- }
- }
- r2 = ++pParse->nMem;
- sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1);
+ r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1);
}else{
int r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
@@ -92862,7 +94856,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){
*/
SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
- sqlite3ExprCodeAtInit(pParse, pExpr, target, 0);
+ sqlite3ExprCodeAtInit(pParse, pExpr, target);
}else{
sqlite3ExprCode(pParse, pExpr, target);
}
@@ -92926,10 +94920,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR;
for(pItem=pList->a, i=0; i<n; i++, pItem++){
Expr *pExpr = pItem->pExpr;
- if( (flags & SQLITE_ECEL_REF)!=0 && (j = pList->a[i].u.x.iOrderByCol)>0 ){
- sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
+ if( (flags & SQLITE_ECEL_REF)!=0 && (j = pItem->u.x.iOrderByCol)>0 ){
+ if( flags & SQLITE_ECEL_OMITREF ){
+ i--;
+ n--;
+ }else{
+ sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
+ }
}else if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
- sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
+ sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
@@ -92960,20 +94959,33 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
**
** Code it as such, taking care to do the common subexpression
** elimination of x.
+**
+** The xJumpIf parameter determines details:
+**
+** NULL: Store the boolean result in reg[dest]
+** sqlite3ExprIfTrue: Jump to dest if true
+** sqlite3ExprIfFalse: Jump to dest if false
+**
+** The jumpIfNull parameter is ignored if xJumpIf is NULL.
*/
static void exprCodeBetween(
Parse *pParse, /* Parsing and code generating context */
Expr *pExpr, /* The BETWEEN expression */
- int dest, /* Jump here if the jump is taken */
- int jumpIfTrue, /* Take the jump if the BETWEEN is true */
+ int dest, /* Jump destination or storage location */
+ void (*xJump)(Parse*,Expr*,int,int), /* Action to take */
int jumpIfNull /* Take the jump if the BETWEEN is NULL */
){
- Expr exprAnd; /* The AND operator in x>=y AND x<=z */
+ Expr exprAnd; /* The AND operator in x>=y AND x<=z */
Expr compLeft; /* The x>=y term */
Expr compRight; /* The x<=z term */
Expr exprX; /* The x subexpression */
int regFree1 = 0; /* Temporary use register */
+
+ memset(&compLeft, 0, sizeof(Expr));
+ memset(&compRight, 0, sizeof(Expr));
+ memset(&exprAnd, 0, sizeof(Expr));
+
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
exprX = *pExpr->pLeft;
exprAnd.op = TK_AND;
@@ -92985,23 +94997,30 @@ static void exprCodeBetween(
compRight.op = TK_LE;
compRight.pLeft = &exprX;
compRight.pRight = pExpr->x.pList->a[1].pExpr;
- exprToRegister(&exprX, sqlite3ExprCodeTemp(pParse, &exprX, &regFree1));
- if( jumpIfTrue ){
- sqlite3ExprIfTrue(pParse, &exprAnd, dest, jumpIfNull);
- }else{
- sqlite3ExprIfFalse(pParse, &exprAnd, dest, jumpIfNull);
+ exprToRegister(&exprX, exprCodeVector(pParse, &exprX, &regFree1));
+ if( xJump ){
+ xJump(pParse, &exprAnd, dest, jumpIfNull);
+ }else{
+ /* Mark the expression is being from the ON or USING clause of a join
+ ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
+ ** it into the Parse.pConstExpr list. We should use a new bit for this,
+ ** for clarity, but we are out of bits in the Expr.flags field so we
+ ** have to reuse the EP_FromJoin bit. Bummer. */
+ exprX.flags |= EP_FromJoin;
+ sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
}
sqlite3ReleaseTempReg(pParse, regFree1);
/* Ensure adequate test coverage */
- testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1==0 );
- testcase( jumpIfTrue==0 && jumpIfNull==0 && regFree1!=0 );
- testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1==0 );
- testcase( jumpIfTrue==0 && jumpIfNull!=0 && regFree1!=0 );
- testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1==0 );
- testcase( jumpIfTrue!=0 && jumpIfNull==0 && regFree1!=0 );
- testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1==0 );
- testcase( jumpIfTrue!=0 && jumpIfNull!=0 && regFree1!=0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 );
+ testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 );
+ testcase( xJump==0 );
}
/*
@@ -93066,6 +95085,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
case TK_GE:
case TK_NE:
case TK_EQ: {
+ if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
@@ -93098,7 +95118,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
- exprCodeBetween(pParse, pExpr, dest, 1, jumpIfNull);
+ exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
@@ -93112,6 +95132,7 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
}
#endif
default: {
+ default_expr:
if( exprAlwaysTrue(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysFalse(pExpr) ){
@@ -93218,6 +95239,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
case TK_GE:
case TK_NE:
case TK_EQ: {
+ if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr;
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
@@ -93248,7 +95270,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
}
case TK_BETWEEN: {
testcase( jumpIfNull==0 );
- exprCodeBetween(pParse, pExpr, dest, 0, jumpIfNull);
+ exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull);
break;
}
#ifndef SQLITE_OMIT_SUBQUERY
@@ -93264,6 +95286,7 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
}
#endif
default: {
+ default_expr:
if( exprAlwaysFalse(pExpr) ){
sqlite3VdbeGoto(v, dest);
}else if( exprAlwaysTrue(pExpr) ){
@@ -93392,6 +95415,17 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
}
/*
+** Like sqlite3ExprCompare() except COLLATE operators at the top-level
+** are ignored.
+*/
+SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
+ return sqlite3ExprCompare(
+ sqlite3ExprSkipCollate(pA),
+ sqlite3ExprSkipCollate(pB),
+ iTab);
+}
+
+/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
** be false. Examples:
@@ -93421,11 +95455,10 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
){
return 1;
}
- if( pE2->op==TK_NOTNULL
- && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
- && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
- ){
- return 1;
+ if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){
+ Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft);
+ testcase( pX!=pE1->pLeft );
+ if( sqlite3ExprCompare(pX, pE2->pLeft, iTab)==0 ) return 1;
}
return 0;
}
@@ -93768,7 +95801,7 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
int i;
struct yColCache *p;
- for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
+ for(i=0, p=pParse->aColCache; i<pParse->nColCache; i++, p++){
if( p->iReg==iReg ){
p->tempReg = 1;
return;
@@ -93779,10 +95812,11 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
}
/*
-** Allocate or deallocate a block of nReg consecutive registers
+** Allocate or deallocate a block of nReg consecutive registers.
*/
SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
int i, n;
+ if( nReg==1 ) return sqlite3GetTempReg(pParse);
i = pParse->iRangeReg;
n = pParse->nRangeReg;
if( nReg<=n ){
@@ -93796,6 +95830,10 @@ SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){
return i;
}
SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){
+ if( nReg==1 ){
+ sqlite3ReleaseTempReg(pParse, iReg);
+ return;
+ }
sqlite3ExprCacheRemove(pParse, iReg, nReg);
if( nReg>pParse->nRangeReg ){
pParse->nRangeReg = nReg;
@@ -94251,7 +96289,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- zDb = db->aDb[iDb].zName;
+ zDb = db->aDb[iDb].zDbSName;
db->flags |= SQLITE_PreferBuiltin;
/* Get a NULL terminated version of the new table name. */
@@ -94342,7 +96380,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = sqlite_rename_parent(sql, %Q, %Q) "
- "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere);
+ "WHERE %s;", zDb, MASTER_NAME, zTabName, zName, zWhere);
sqlite3DbFree(db, zWhere);
}
}
@@ -94366,7 +96404,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
"ELSE name END "
"WHERE tbl_name=%Q COLLATE nocase AND "
"(type='table' OR type='index' OR type='trigger');",
- zDb, SCHEMA_TABLE(iDb), zName, zName, zName,
+ zDb, MASTER_NAME, zName, zName, zName,
#ifndef SQLITE_OMIT_TRIGGER
zName,
#endif
@@ -94449,7 +96487,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
assert( sqlite3BtreeHoldsAllMutexes(db) );
iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
- zDb = db->aDb[iDb].zName;
+ zDb = db->aDb[iDb].zDbSName;
zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */
pCol = &pNew->aCol[pNew->nCol-1];
pDflt = pCol->pDflt;
@@ -94527,7 +96565,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
"UPDATE \"%w\".%s SET "
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
"WHERE type = 'table' AND name = %Q",
- zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
+ zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1,
zTab
);
sqlite3DbFree(db, zCol);
@@ -94611,7 +96649,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
if( !pNew ) goto exit_begin_add_column;
pParse->pNewTable = pNew;
- pNew->nRef = 1;
+ pNew->nTabRef = 1;
pNew->nCol = pTab->nCol;
assert( pNew->nCol>0 );
nAlloc = (((pNew->nCol-1)/8)*8)+8;
@@ -94631,7 +96669,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
}
pNew->pSchema = db->aDb[iDb].pSchema;
pNew->addColOffset = pTab->addColOffset;
- pNew->nRef = 1;
+ pNew->nTabRef = 1;
/* Begin a transaction and increment the schema cookie. */
sqlite3BeginWriteOperation(pParse, 0, iDb);
@@ -94859,14 +96897,14 @@ static void openStatTable(
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
- if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
+ if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
if( aTable[i].zCols ){
/* 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
** because the OpenWrite opcode below will be needing it. */
sqlite3NestedParse(pParse,
- "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
+ "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
);
aRoot[i] = pParse->regRoot;
aCreateTbl[i] = OPFLAG_P2ISREG;
@@ -94881,7 +96919,7 @@ static void openStatTable(
if( zWhere ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
- pDb->zName, zTab, zWhereType, zWhere
+ pDb->zDbSName, zTab, zWhereType, zWhere
);
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
@@ -94939,6 +96977,7 @@ struct Stat4Accum {
Stat4Sample *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() */
@@ -95203,6 +97242,13 @@ static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){
assert( IsStat4 || nEqZero==0 );
#ifdef SQLITE_ENABLE_STAT4
+ /* Stat4Accum.nMaxEqZero is set to the maximum number of leading 0
+ ** values in the anEq[] array of any sample in Stat4Accum.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). */
+ if( nEqZero>p->nMaxEqZero ){
+ p->nMaxEqZero = nEqZero;
+ }
if( pNew->isPSample==0 ){
Stat4Sample *pUpgrade = 0;
assert( pNew->anEq[pNew->iCol]>0 );
@@ -95300,12 +97346,22 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){
}
}
- /* Update the anEq[] fields of any samples already collected. */
+ /* Check that no sample contains an anEq[] entry with an index of
+ ** p->nMaxEqZero or greater set to zero. */
for(i=p->nSample-1; i>=0; i--){
int j;
- for(j=iChng; j<p->nCol; j++){
- if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
+ for(j=p->nMaxEqZero; j<p->nCol; j++) assert( p->a[i].anEq[j]>0 );
+ }
+
+ /* Update the anEq[] fields of any samples already collected. */
+ if( iChng<p->nMaxEqZero ){
+ for(i=p->nSample-1; i>=0; i--){
+ int j;
+ for(j=iChng; j<p->nCol; j++){
+ if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j];
+ }
}
+ p->nMaxEqZero = iChng;
}
#endif
@@ -95446,6 +97502,12 @@ static const FuncDef statPushFuncdef = {
** 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
+** NULL.
+**
** If neither STAT3 nor STAT4 are enabled, then J is always
** STAT_GET_STAT1 and is hence omitted and this routine becomes
** a one-parameter function, stat_get(P), that always returns the
@@ -95643,7 +97705,7 @@ static void analyzeOneTable(
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
- db->aDb[iDb].zName ) ){
+ db->aDb[iDb].zDbSName ) ){
return;
}
#endif
@@ -95829,7 +97891,7 @@ static void analyzeOneTable(
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
for(j=0; j<pPk->nKeyCol; j++){
k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
- assert( k>=0 && k<pTab->nCol );
+ assert( k>=0 && k<pIdx->nColumn );
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
}
@@ -96013,27 +98075,14 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
if( i==1 ) continue; /* Do not analyze the TEMP database */
analyzeDatabase(pParse, i);
}
- }else if( pName2->n==0 ){
- /* Form 2: Analyze the database or table named */
- iDb = sqlite3FindDb(db, pName1);
- if( iDb>=0 ){
- analyzeDatabase(pParse, iDb);
- }else{
- z = sqlite3NameFromToken(db, pName1);
- if( z ){
- if( (pIdx = sqlite3FindIndex(db, z, 0))!=0 ){
- analyzeTable(pParse, pIdx->pTable, pIdx);
- }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){
- analyzeTable(pParse, pTab, 0);
- }
- sqlite3DbFree(db, z);
- }
- }
+ }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){
+ /* Analyze the schema named as the argument */
+ analyzeDatabase(pParse, iDb);
}else{
- /* Form 3: Analyze the fully qualified table name */
+ /* Form 3: Analyze the table or index named as an argument */
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
if( iDb>=0 ){
- zDb = db->aDb[iDb].zName;
+ zDb = pName2->n ? db->aDb[iDb].zDbSName : 0;
z = sqlite3NameFromToken(db, pTableName);
if( z ){
if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
@@ -96043,10 +98092,11 @@ SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){
}
sqlite3DbFree(db, z);
}
- }
+ }
+ }
+ if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){
+ sqlite3VdbeAddOp0(v, OP_Expire);
}
- v = sqlite3GetVdbe(pParse);
- if( v ) sqlite3VdbeAddOp0(v, OP_Expire);
}
/*
@@ -96175,7 +98225,11 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
#endif
pIndex->bUnordered = 0;
decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
- if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
+ pIndex->hasStat1 = 1;
+ if( pIndex->pPartIdxWhere==0 ){
+ pTable->nRowLogEst = pIndex->aiRowLogEst[0];
+ pTable->tabFlags |= TF_HasStat1;
+ }
}else{
Index fakeIdx;
fakeIdx.szIdxRow = pTable->szTabRow;
@@ -96184,6 +98238,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
#endif
decodeIntArray((char*)z, 1, 0, &pTable->nRowLogEst, &fakeIdx);
pTable->szTabRow = fakeIdx.szIdxRow;
+ pTable->tabFlags |= TF_HasStat1;
}
return 0;
@@ -96264,7 +98319,7 @@ static void initAvgEq(Index *pIdx){
}
}
- if( nDist100>nSum100 ){
+ if( nDist100>nSum100 && sumEq<nRow ){
avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
}
if( avgEq==0 ) avgEq = 1;
@@ -96415,7 +98470,9 @@ static int loadStatTbl(
sqlite3_finalize(pStmt);
return SQLITE_NOMEM_BKPT;
}
- memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
+ if( pSample->n ){
+ memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
+ }
pIdx->nSample++;
}
rc = sqlite3_finalize(pStmt);
@@ -96476,15 +98533,20 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
HashElem *i;
char *zSql;
int rc = SQLITE_OK;
+ Schema *pSchema = db->aDb[iDb].pSchema;
assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 );
/* Clear any prior statistics */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ pTab->tabFlags &= ~TF_HasStat1;
+ }
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
- pIdx->aiRowLogEst[0] = 0;
+ pIdx->hasStat1 = 0;
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
@@ -96493,7 +98555,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Load new statistics out of the sqlite_stat1 table */
sInfo.db = db;
- sInfo.zDatabase = db->aDb[iDb].zName;
+ sInfo.zDatabase = db->aDb[iDb].zDbSName;
if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
zSql = sqlite3MPrintf(db,
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
@@ -96507,9 +98569,9 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
/* Set appropriate defaults on all indexes not in the sqlite_stat1 table */
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
- if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx);
+ if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx);
}
/* Load the statistics from the sqlite_stat4 table. */
@@ -96519,7 +98581,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
rc = loadStat4(db, sInfo.zDatabase);
db->lookaside.bDisable--;
}
- for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+ for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){
Index *pIdx = sqliteHashData(i);
sqlite3_free(pIdx->aiRowEst);
pIdx->aiRowEst = 0;
@@ -96636,7 +98698,7 @@ static void attachFunc(
goto attach_error;
}
for(i=0; i<db->nDb; i++){
- char *z = db->aDb[i].zName;
+ char *z = db->aDb[i].zDbSName;
assert( z && zName );
if( sqlite3StrICmp(z, zName)==0 ){
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
@@ -96676,6 +98738,7 @@ static void attachFunc(
rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags);
sqlite3_free( zPath );
db->nDb++;
+ db->skipBtreeMutex = 0;
if( rc==SQLITE_CONSTRAINT ){
rc = SQLITE_ERROR;
zErrDyn = sqlite3MPrintf(db, "database is already attached");
@@ -96701,8 +98764,8 @@ static void attachFunc(
sqlite3BtreeLeave(aNew->pBt);
}
aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- aNew->zName = sqlite3DbStrDup(db, zName);
- if( rc==SQLITE_OK && aNew->zName==0 ){
+ aNew->zDbSName = sqlite3DbStrDup(db, zName);
+ if( rc==SQLITE_OK && aNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
@@ -96731,7 +98794,7 @@ static void attachFunc(
case SQLITE_NULL:
/* No key specified. Use the key from the main database */
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
- if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
+ if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
}
break;
@@ -96814,7 +98877,7 @@ static void detachFunc(
for(i=0; i<db->nDb; i++){
pDb = &db->aDb[i];
if( pDb->pBt==0 ) continue;
- if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
+ if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
}
if( i>=db->nDb ){
@@ -96864,6 +98927,7 @@ static void codeAttach(
sqlite3* db = pParse->db;
int regArgs;
+ if( pParse->nErr ) goto attach_end;
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
@@ -96972,7 +99036,7 @@ SQLITE_PRIVATE void sqlite3FixInit(
db = pParse->db;
assert( db->nDb>iDb );
pFix->pParse = pParse;
- pFix->zDb = db->aDb[iDb].zName;
+ pFix->zDb = db->aDb[iDb].zDbSName;
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
@@ -97069,7 +99133,7 @@ SQLITE_PRIVATE int sqlite3FixExpr(
return 1;
}
}
- if( ExprHasProperty(pExpr, EP_TokenOnly) ) break;
+ if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
@@ -97190,7 +99254,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(
** Setting the auth function to NULL disables this hook. The default
** setting of the auth function is NULL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3 *db,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
@@ -97230,9 +99294,9 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(
const char *zCol, /* Column name */
int iDb /* Index of containing database. */
){
- sqlite3 *db = pParse->db; /* Database handle */
- char *zDb = db->aDb[iDb].zName; /* Name of attached database */
- int rc; /* Auth callback return code */
+ sqlite3 *db = pParse->db; /* Database handle */
+ char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */
+ int rc; /* Auth callback return code */
if( db->init.busy ) return SQLITE_OK;
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
@@ -97417,10 +99481,10 @@ SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){
** codeTableLocks() functions.
*/
struct TableLock {
- int iDb; /* The database containing the table to be locked */
- int iTab; /* The root page of the table to be locked */
- u8 isWriteLock; /* True for write lock. False for a read lock */
- const char *zName; /* Name of the table */
+ int iDb; /* The database containing the table to be locked */
+ int iTab; /* The root page of the table to be locked */
+ u8 isWriteLock; /* True for write lock. False for a read lock */
+ const char *zLockName; /* Name of the table */
};
/*
@@ -97446,6 +99510,8 @@ SQLITE_PRIVATE void sqlite3TableLock(
TableLock *p;
assert( iDb>=0 );
+ if( iDb==1 ) return;
+ if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return;
for(i=0; i<pToplevel->nTableLock; i++){
p = &pToplevel->aTableLock[i];
if( p->iDb==iDb && p->iTab==iTab ){
@@ -97462,7 +99528,7 @@ SQLITE_PRIVATE void sqlite3TableLock(
p->iDb = iDb;
p->iTab = iTab;
p->isWriteLock = isWriteLock;
- p->zName = zName;
+ p->zLockName = zName;
}else{
pToplevel->nTableLock = 0;
sqlite3OomFault(pToplevel->db);
@@ -97484,7 +99550,7 @@ static void codeTableLocks(Parse *pParse){
TableLock *p = &pParse->aTableLock[i];
int p1 = p->iDb;
sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock,
- p->zName, P4_STATIC);
+ p->zLockName, P4_STATIC);
}
}
#else
@@ -97533,15 +99599,14 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
assert( !pParse->isMultiWrite
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
- while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
sqlite3VdbeAddOp0(v, OP_Halt);
#if SQLITE_USER_AUTHENTICATION
if( pParse->nTableLock>0 && db->init.busy==0 ){
sqlite3UserAuthInit(db);
if( db->auth.authLevel<UAUTH_User ){
- pParse->rc = SQLITE_AUTH_USER;
sqlite3ErrorMsg(pParse, "user not authenticated");
+ pParse->rc = SQLITE_AUTH_USER;
return;
}
}
@@ -97560,14 +99625,16 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
sqlite3VdbeJumpHere(v, 0);
for(iDb=0; iDb<db->nDb; iDb++){
+ Schema *pSchema;
if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
sqlite3VdbeUsesBtree(v, iDb);
+ pSchema = db->aDb[iDb].pSchema;
sqlite3VdbeAddOp4Int(v,
OP_Transaction, /* Opcode */
iDb, /* P1 */
DbMaskTest(pParse->writeMask,iDb), /* P2 */
- pParse->cookieValue[iDb], /* P3 */
- db->aDb[iDb].pSchema->iGeneration /* P4 */
+ pSchema->schema_cookie, /* P3 */
+ pSchema->iGeneration /* P4 */
);
if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
VdbeComment((v,
@@ -97618,16 +99685,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
}else{
pParse->rc = SQLITE_ERROR;
}
-
- /* We are done with this Parse object. There is no need to de-initialize it */
-#if 0
- pParse->colNamesSet = 0;
- pParse->nTab = 0;
- pParse->nMem = 0;
- pParse->nSet = 0;
- pParse->nVar = 0;
- DbMaskZero(pParse->cookieMask);
-#endif
}
/*
@@ -97647,8 +99704,7 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
char *zSql;
char *zErrMsg = 0;
sqlite3 *db = pParse->db;
-# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar))
- char saveBuf[SAVE_SZ];
+ char saveBuf[PARSE_TAIL_SZ];
if( pParse->nErr ) return;
assert( pParse->nested<10 ); /* Nesting should only be of limited depth */
@@ -97659,12 +99715,12 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
return; /* A malloc must have failed */
}
pParse->nested++;
- memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
- memset(&pParse->nVar, 0, SAVE_SZ);
+ memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
+ memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
sqlite3RunParser(pParse, zSql, &zErrMsg);
sqlite3DbFree(db, zErrMsg);
sqlite3DbFree(db, zSql);
- memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
+ memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
pParse->nested--;
}
@@ -97703,14 +99759,22 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha
return 0;
}
#endif
- 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].zName) ) continue;
- assert( sqlite3SchemaMutexHeld(db, j, 0) );
- p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
- if( p ) break;
+ 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;
+ }
+ }
+ /* 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;
}
- return p;
+ return 0;
}
/*
@@ -97746,6 +99810,9 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
Module *pMod = (Module*)sqlite3HashFind(&pParse->db->aModule, zName);
+ if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
+ pMod = sqlite3PragmaVtabRegister(pParse->db, zName);
+ }
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
return pMod->pEpoTab;
}
@@ -97782,7 +99849,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(
assert( p->pSchema==0 || p->zDatabase==0 );
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
- zDb = pParse->db->aDb[iDb].zName;
+ zDb = pParse->db->aDb[iDb].zDbSName;
}else{
zDb = p->zDatabase;
}
@@ -97810,7 +99877,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].zName) ) continue;
+ if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&pSchema->idxHash, zName);
if( p ) break;
@@ -97879,8 +99946,8 @@ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
- sqlite3DbFree(db, pDb->zName);
- pDb->zName = 0;
+ sqlite3DbFree(db, pDb->zDbSName);
+ pDb->zDbSName = 0;
continue;
}
if( j<i ){
@@ -98028,7 +100095,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
/* Do not delete the table until the reference count reaches zero. */
if( !pTable ) return;
- if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
+ if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return;
deleteTable(db, pTable);
}
@@ -98082,7 +100149,7 @@ SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
*/
SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){
Vdbe *v = sqlite3GetVdbe(p);
- sqlite3TableLock(p, iDb, MASTER_ROOT, 1, SCHEMA_TABLE(iDb));
+ sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME);
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
if( p->nTab==0 ){
p->nTab = 1;
@@ -98100,7 +100167,10 @@ SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
if( zName ){
Db *pDb;
for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
- if( 0==sqlite3StrICmp(pDb->zName, zName) ) break;
+ if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break;
+ /* "main" is always an acceptable alias for the primary database
+ ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */
+ if( i==0 && 0==sqlite3_stricmp("main", zName) ) break;
}
}
return i;
@@ -98159,7 +100229,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
return -1;
}
}else{
- assert( db->init.iDb==0 || db->init.busy );
+ assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
iDb = db->init.iDb;
*pUnqual = pName1;
}
@@ -98270,7 +100340,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
SQLITE_CREATE_VIEW,
SQLITE_CREATE_TEMP_VIEW
};
- char *zDb = db->aDb[iDb].zName;
+ char *zDb = db->aDb[iDb].zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
goto begin_table_error;
}
@@ -98289,7 +100359,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
** collisions.
*/
if( !IN_DECLARE_VTAB ){
- char *zDb = db->aDb[iDb].zName;
+ char *zDb = db->aDb[iDb].zDbSName;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto begin_table_error;
}
@@ -98319,7 +100389,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
pTable->zName = zName;
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
- pTable->nRef = 1;
+ pTable->nTabRef = 1;
pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
@@ -98496,6 +100566,7 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
p = pParse->pNewTable;
if( p==0 || NEVER(p->nCol<1) ) return;
p->aCol[p->nCol-1].notNull = (u8)onError;
+ p->tabFlags |= TF_HasNotNull;
}
/*
@@ -98844,6 +100915,9 @@ SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
** set back to prior value. But schema changes are infrequent
** and the probability of hitting the same cookie value is only
** 1 chance in 2^32. So we're safe enough.
+**
+** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments
+** the schema-version whenever the schema changes.
*/
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
sqlite3 *db = pParse->db;
@@ -99382,7 +101456,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
"UPDATE %Q.%s "
"SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
"WHERE rowid=#%d",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
+ db->aDb[iDb].zDbSName, MASTER_NAME,
zType,
p->zName,
p->zName,
@@ -99397,13 +101471,13 @@ SQLITE_PRIVATE void sqlite3EndTable(
/* Check to see if we need to create an sqlite_sequence table for
** keeping track of autoincrement keys.
*/
- if( p->tabFlags & TF_Autoincrement ){
+ if( (p->tabFlags & TF_Autoincrement)!=0 ){
Db *pDb = &db->aDb[iDb];
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( pDb->pSchema->pSeqTab==0 ){
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.sqlite_sequence(name,seq)",
- pDb->zName
+ pDb->zDbSName
);
}
}
@@ -99527,7 +101601,9 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
int nErr = 0; /* Number of errors encountered */
int n; /* Temporarily holds the number of cursors assigned */
sqlite3 *db = pParse->db; /* Database connection for malloc errors */
+#ifndef SQLITE_OMIT_AUTHORIZATION
sqlite3_xauth xAuth; /* Saved xAuth pointer */
+#endif
assert( pTable );
@@ -99717,7 +101793,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
- pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable, r1, r1);
+ pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1);
#endif
sqlite3ReleaseTempReg(pParse, r1);
}
@@ -99793,7 +101869,7 @@ static void sqlite3ClearStatTables(
const char *zName /* Name of index or table */
){
int i;
- const char *zDbName = pParse->db->aDb[iDb].zName;
+ const char *zDbName = pParse->db->aDb[iDb].zDbSName;
for(i=1; i<=4; i++){
char zTab[24];
sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
@@ -99846,7 +101922,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in
if( pTab->tabFlags & TF_Autoincrement ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
- pDb->zName, pTab->zName
+ pDb->zDbSName, pTab->zName
);
}
#endif
@@ -99860,7 +101936,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in
*/
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
- pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
+ pDb->zDbSName, MASTER_NAME, pTab->zName);
if( !isView && !IsVirtual(pTab) ){
destroyTable(pParse, pTab);
}
@@ -99914,7 +101990,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
{
int code;
const char *zTab = SCHEMA_TABLE(iDb);
- const char *zDb = db->aDb[iDb].zName;
+ const char *zDb = db->aDb[iDb].zDbSName;
const char *zArg2 = 0;
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
goto exit_drop_table;
@@ -100155,7 +102231,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
- db->aDb[iDb].zName ) ){
+ db->aDb[iDb].zDbSName ) ){
return;
}
#endif
@@ -100207,7 +102283,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
@@ -100407,7 +102483,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
goto exit_create_index;
}
}
- if( sqlite3FindIndex(db, zName, pDb->zName)!=0 ){
+ if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
if( !ifNotExist ){
sqlite3ErrorMsg(pParse, "index %s already exists", zName);
}else{
@@ -100437,7 +102513,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
{
- const char *zDb = pDb->zName;
+ const char *zDb = pDb->zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
goto exit_create_index;
}
@@ -100752,7 +102828,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
+ db->aDb[iDb].zDbSName, MASTER_NAME,
pIndex->zName,
pTab->zName,
iMem,
@@ -100830,6 +102906,9 @@ SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
int nCopy = MIN(ArraySize(aVal), pIdx->nKeyCol);
int i;
+ /* Indexes with default row estimates should not have stat1 data */
+ assert( !pIdx->hasStat1 );
+
/* Set the first entry (number of rows in the index) to the estimated
** number of rows in the table, or half the number of rows in the table
** for a partial index. But do not let the estimate drop below 10. */
@@ -100886,7 +102965,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists
{
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
- const char *zDb = db->aDb[iDb].zName;
+ const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
goto exit_drop_index;
@@ -100904,7 +102983,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists
sqlite3BeginWriteOperation(pParse, 1, iDb);
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName
+ db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName
);
sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
sqlite3ChangeCookie(pParse, iDb);
@@ -101047,7 +103126,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
/* Allocate additional space if needed */
if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
- int nAlloc = pSrc->nSrc+nExtra;
+ int nAlloc = pSrc->nSrc*2+nExtra;
int nGot;
pNew = sqlite3DbRealloc(db, pSrc,
sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) );
@@ -101125,9 +103204,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) );
if( pList==0 ) return 0;
pList->nAlloc = 1;
- pList->nSrc = 0;
+ pList->nSrc = 1;
+ memset(&pList->a[0], 0, sizeof(pList->a[0]));
+ pList->a[0].iCursor = -1;
+ }else{
+ pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
}
- pList = sqlite3SrcListEnlarge(db, pList, 1, pList->nSrc);
if( db->mallocFailed ){
sqlite3SrcListDelete(db, pList);
return 0;
@@ -101425,15 +103507,13 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
*/
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
- sqlite3 *db = pToplevel->db;
- assert( iDb>=0 && iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 || iDb==1 );
+ assert( iDb>=0 && iDb<pParse->db->nDb );
+ assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<SQLITE_MAX_ATTACHED+2 );
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) );
if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
DbMaskSet(pToplevel->cookieMask, iDb);
- pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
if( !OMIT_TEMPDB && iDb==1 ){
sqlite3OpenTempDatabase(pToplevel);
}
@@ -101449,7 +103529,7 @@ SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb)
int i;
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
- if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zName)) ){
+ if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){
sqlite3CodeVerifySchema(pParse, i);
}
}
@@ -101696,7 +103776,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
if( iDb<0 ) return;
z = sqlite3NameFromToken(db, pObjName);
if( z==0 ) return;
- zDb = db->aDb[iDb].zName;
+ zDb = db->aDb[iDb].zDbSName;
pTab = sqlite3FindTable(db, z, zDb);
if( pTab ){
reindexTable(pParse, pTab, 0);
@@ -102344,7 +104424,7 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
sqlite3DeleteTable(pParse->db, pItem->pTab);
pItem->pTab = pTab;
if( pTab ){
- pTab->nRef++;
+ pTab->nTabRef++;
}
if( sqlite3IndexedByLookup(pParse, pItem) ){
pTab = 0;
@@ -102410,7 +104490,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
- pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
+ pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}
@@ -102472,7 +104552,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
** );
*/
- pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
+ pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
if( pSelectRowid == 0 ) goto limit_where_cleanup;
pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
if( pEList == 0 ) goto limit_where_cleanup;
@@ -102491,8 +104571,8 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
if( pSelect == 0 ) return 0;
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
- pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0) : 0;
+ pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+ pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0;
sqlite3PExprAddSelect(pParse, pInClause, pSelect);
return pInClause;
@@ -102520,7 +104600,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
){
Vdbe *v; /* The virtual database engine */
Table *pTab; /* The table from which records will be deleted */
- const char *zDb; /* Name of database holding pTab */
int i; /* Loop counter */
WhereInfo *pWInfo; /* Information about the WHERE clause */
Index *pIdx; /* For looping over indices of the table */
@@ -102597,8 +104676,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
- zDb = db->aDb[iDb].zName;
- rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
+ rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0,
+ db->aDb[iDb].zDbSName);
assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
if( rcauth==SQLITE_DENY ){
goto delete_from_cleanup;
@@ -102758,7 +104837,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
nKey = 0; /* Zero tells OP_Found to use a composite key */
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
sqlite3IndexAffinityStr(pParse->db, pPk), nPk);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk);
}else{
/* Add the rowid of the row to be deleted to the RowSet */
nKey = 1; /* OP_Seek always uses a single rowid */
@@ -102782,7 +104861,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
if( !isView ){
int iAddrOnce = 0;
if( eOnePass==ONEPASS_MULTI ){
- iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
testcase( IsVirtual(pTab) );
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
@@ -102804,7 +104883,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
}else if( pPk ){
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
+ sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
assert( nKey==0 ); /* OP_Found will use a composite key */
}else{
addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
@@ -102828,12 +104907,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
#endif
{
int count = (pParse->nested==0); /* True to count changes */
- int iIdxNoSeek = -1;
- if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){
- iIdxNoSeek = aiCurOnePass[1];
- }
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
- iKey, nKey, count, OE_Default, eOnePass, iIdxNoSeek);
+ iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]);
}
/* End of the loop over all rowids/primary-keys. */
@@ -102847,14 +104922,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
sqlite3VdbeGoto(v, addrLoop);
sqlite3VdbeJumpHere(v, addrLoop);
}
-
- /* Close the cursors open on the table and its indexes. */
- if( !isView && !IsVirtual(pTab) ){
- if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
- for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
- sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i);
- }
- }
} /* End non-truncate path */
/* Update the sqlite_sequence table by storing the content of the
@@ -102921,15 +104988,17 @@ delete_from_cleanup:
**
** If eMode is ONEPASS_MULTI, then this call is being made as part
** of a ONEPASS delete that affects multiple rows. In this case, if
-** iIdxNoSeek is a valid cursor number (>=0), then its position should
-** be preserved following the delete operation. Or, if iIdxNoSeek is not
-** a valid cursor number, the position of iDataCur should be preserved
-** instead.
+** iIdxNoSeek is a valid cursor number (>=0) and is not the same as
+** iDataCur, then its position should be preserved following the delete
+** operation. Or, if iIdxNoSeek is not a valid cursor number, the
+** position of iDataCur should be preserved instead.
**
** iIdxNoSeek:
-** If iIdxNoSeek is a valid cursor number (>=0), then it identifies an
-** index cursor (from within array of cursors starting at iIdxCur) that
-** already points to the index entry to be deleted.
+** If iIdxNoSeek is a valid cursor number (>=0) not equal to iDataCur,
+** then it identifies an index cursor (from within array of cursors
+** starting at iIdxCur) that already points to the index entry to be deleted.
+** Except, this optimization is disabled if there are BEFORE triggers since
+** the trigger body might have moved the cursor.
*/
SQLITE_PRIVATE void sqlite3GenerateRowDelete(
Parse *pParse, /* Parsing context */
@@ -103000,13 +105069,18 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
/* If any BEFORE triggers were coded, then seek the cursor to the
** row to be deleted again. It may be that the BEFORE triggers moved
- ** the cursor or of already deleted the row that the cursor was
+ ** the cursor or already deleted the row that the cursor was
** pointing to.
+ **
+ ** Also disable the iIdxNoSeek optimization since the BEFORE trigger
+ ** may have moved that cursor.
*/
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
VdbeCoverageIf(v, opSeek==OP_NotExists);
VdbeCoverageIf(v, opSeek==OP_NotFound);
+ testcase( iIdxNoSeek>=0 );
+ iIdxNoSeek = -1;
}
/* Do FK processing. This call checks that any FK constraints that
@@ -103029,11 +105103,13 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
u8 p5 = 0;
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
- sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE);
+ if( pParse->nested==0 ){
+ sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
+ }
if( eMode!=ONEPASS_OFF ){
sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
}
- if( iIdxNoSeek>=0 ){
+ if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){
sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
}
if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;
@@ -103187,6 +105263,10 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
}
if( regOut ){
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
+ if( pIdx->pTable->pSelect ){
+ const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx);
+ sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
+ }
}
sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
@@ -103408,23 +105488,26 @@ static void instrFunc(
if( typeHaystack==SQLITE_NULL || typeNeedle==SQLITE_NULL ) return;
nHaystack = sqlite3_value_bytes(argv[0]);
nNeedle = sqlite3_value_bytes(argv[1]);
- if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
- zHaystack = sqlite3_value_blob(argv[0]);
- zNeedle = sqlite3_value_blob(argv[1]);
- isText = 0;
- }else{
- zHaystack = sqlite3_value_text(argv[0]);
- zNeedle = sqlite3_value_text(argv[1]);
- isText = 1;
- }
- while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
- N++;
- do{
- nHaystack--;
- zHaystack++;
- }while( isText && (zHaystack[0]&0xc0)==0x80 );
+ if( nNeedle>0 ){
+ if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){
+ zHaystack = sqlite3_value_blob(argv[0]);
+ zNeedle = sqlite3_value_blob(argv[1]);
+ isText = 0;
+ }else{
+ zHaystack = sqlite3_value_text(argv[0]);
+ zNeedle = sqlite3_value_text(argv[1]);
+ isText = 1;
+ }
+ if( zNeedle==0 || (nHaystack && zHaystack==0) ) return;
+ while( nNeedle<=nHaystack && memcmp(zHaystack, zNeedle, nNeedle)!=0 ){
+ N++;
+ do{
+ nHaystack--;
+ zHaystack++;
+ }while( isText && (zHaystack[0]&0xc0)==0x80 );
+ }
+ if( nNeedle>nHaystack ) N = 0;
}
- if( nNeedle>nHaystack ) N = 0;
sqlite3_result_int(context, N);
}
@@ -103804,9 +105887,19 @@ static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 };
static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
/*
-** Compare two UTF-8 strings for equality where the first string can
-** potentially be a "glob" or "like" expression. Return true (1) if they
-** are the same and false (0) if they are different.
+** Possible error returns from patternMatch()
+*/
+#define SQLITE_MATCH 0
+#define SQLITE_NOMATCH 1
+#define SQLITE_NOWILDCARDMATCH 2
+
+/*
+** Compare two UTF-8 strings for equality where the first string is
+** a GLOB or LIKE expression. Return values:
+**
+** SQLITE_MATCH: Match
+** SQLITE_NOMATCH: No match
+** SQLITE_NOWILDCARDMATCH: No match in spite of having * or % wildcards.
**
** Globbing rules:
**
@@ -103857,30 +105950,31 @@ static int patternCompare(
** single character of the input string for each "?" skipped */
while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
- return 0;
+ return SQLITE_NOWILDCARDMATCH;
}
}
if( c==0 ){
- return 1; /* "*" at the end of the pattern matches */
+ return SQLITE_MATCH; /* "*" at the end of the pattern matches */
}else if( c==matchOther ){
if( pInfo->matchSet==0 ){
c = sqlite3Utf8Read(&zPattern);
- if( c==0 ) return 0;
+ if( c==0 ) return SQLITE_NOWILDCARDMATCH;
}else{
/* "[...]" immediately follows the "*". We have to do a slow
** recursive search in this case, but it is an unusual case. */
assert( matchOther<0x80 ); /* '[' is a single-byte character */
- while( *zString
- && patternCompare(&zPattern[-1],zString,pInfo,matchOther)==0 ){
+ while( *zString ){
+ int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
SQLITE_SKIP_UTF8(zString);
}
- return *zString!=0;
+ return SQLITE_NOWILDCARDMATCH;
}
}
/* At this point variable c contains the first character of the
** pattern string past the "*". Search in the input string for the
- ** first matching character and recursively contine the match from
+ ** first matching character and recursively continue the match from
** that point.
**
** For a case-insensitive search, set variable cx to be the same as
@@ -103889,6 +105983,7 @@ static int patternCompare(
*/
if( c<=0x80 ){
u32 cx;
+ int bMatch;
if( noCase ){
cx = sqlite3Toupper(c);
c = sqlite3Tolower(c);
@@ -103897,27 +105992,30 @@ static int patternCompare(
}
while( (c2 = *(zString++))!=0 ){
if( c2!=c && c2!=cx ) continue;
- if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
+ bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
}
}else{
+ int bMatch;
while( (c2 = Utf8Read(zString))!=0 ){
if( c2!=c ) continue;
- if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
+ bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+ if( bMatch!=SQLITE_NOMATCH ) return bMatch;
}
}
- return 0;
+ return SQLITE_NOWILDCARDMATCH;
}
if( c==matchOther ){
if( pInfo->matchSet==0 ){
c = sqlite3Utf8Read(&zPattern);
- if( c==0 ) return 0;
+ if( c==0 ) return SQLITE_NOMATCH;
zEscaped = zPattern;
}else{
u32 prior_c = 0;
int seen = 0;
int invert = 0;
c = sqlite3Utf8Read(&zString);
- if( c==0 ) return 0;
+ if( c==0 ) return SQLITE_NOMATCH;
c2 = sqlite3Utf8Read(&zPattern);
if( c2=='^' ){
invert = 1;
@@ -103941,7 +106039,7 @@ static int patternCompare(
c2 = sqlite3Utf8Read(&zPattern);
}
if( c2==0 || (seen ^ invert)==0 ){
- return 0;
+ return SQLITE_NOMATCH;
}
continue;
}
@@ -103952,23 +106050,25 @@ static int patternCompare(
continue;
}
if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
- return 0;
+ return SQLITE_NOMATCH;
}
- return *zString==0;
+ return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH;
}
/*
-** The sqlite3_strglob() interface.
+** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and
+** non-zero if there is no match.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){
- return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[')==0;
+SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){
+ return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[');
}
/*
-** The sqlite3_strlike() interface.
+** The sqlite3_strlike() interface. Return 0 on a match and non-zero for
+** a miss - like strcmp().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
- return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0;
+SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
+ return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc);
}
/*
@@ -104049,7 +106149,7 @@ static void likeFunc(
#ifdef SQLITE_TEST
sqlite3_like_count++;
#endif
- sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape));
+ sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
}
}
@@ -104820,7 +106920,7 @@ static void groupConcatStep(
zSep = ",";
nSep = 1;
}
- if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
+ if( zSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
}
zVal = (char*)sqlite3_value_text(argv[0]);
nVal = sqlite3_value_bytes(argv[0]);
@@ -104961,6 +107061,9 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+#ifdef SQLITE_DEBUG
+ FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY),
+#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
@@ -105283,7 +107386,7 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex(
}
for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) ){
+ if( pIdx->nKeyCol==nCol && IsUniqueIndex(pIdx) && pIdx->pPartIdxWhere==0 ){
/* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number
** of columns. If each indexed column corresponds to a foreign key
** column of pFKey, then this index is a winner. */
@@ -105642,7 +107745,7 @@ static void fkScanChildren(
assert( iCol>=0 );
zCol = pFKey->pFrom->aCol[iCol].zName;
pRight = sqlite3Expr(db, TK_ID, zCol);
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
}
@@ -105664,7 +107767,7 @@ static void fkScanChildren(
if( HasRowid(pTab) ){
pLeft = exprTableRegister(pParse, pTab, regData, -1);
pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
- pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
+ pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
}else{
Expr *pEq, *pAll = 0;
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
@@ -105674,10 +107777,10 @@ static void fkScanChildren(
assert( iCol>=0 );
pLeft = exprTableRegister(pParse, pTab, regData, iCol);
pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
- pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
pAll = sqlite3ExprAnd(db, pAll, pEq);
}
- pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0);
+ pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
}
pWhere = sqlite3ExprAnd(db, pWhere, pNe);
}
@@ -105929,7 +108032,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- zDb = db->aDb[iDb].zName;
+ zDb = db->aDb[iDb].zDbSName;
/* Loop through all the foreign key constraints for which pTab is the
** child table (the table that the foreign key definition is part of). */
@@ -106065,7 +108168,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
struct SrcList_item *pItem = pSrc->a;
pItem->pTab = pFKey->pFrom;
pItem->zName = pFKey->pFrom->zName;
- pItem->pTab->nRef++;
+ pItem->pTab->nTabRef++;
pItem->iCursor = pParse->nTab++;
if( regNew!=0 ){
@@ -106263,10 +108366,9 @@ static Trigger *fkActionTrigger(
pEq = sqlite3PExpr(pParse, TK_EQ,
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
- , 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
- , 0);
+ );
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
/* For ON UPDATE, construct the next term of the WHEN clause.
@@ -106278,13 +108380,11 @@ static Trigger *fkActionTrigger(
pEq = sqlite3PExpr(pParse, TK_IS,
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
- 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)),
sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
- 0),
- 0);
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0))
+ );
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
}
@@ -106293,17 +108393,16 @@ static Trigger *fkActionTrigger(
if( action==OE_Cascade ){
pNew = sqlite3PExpr(pParse, TK_DOT,
sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
- sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
- , 0);
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0));
}else if( action==OE_SetDflt ){
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
if( pDflt ){
pNew = sqlite3ExprDup(db, pDflt, 0);
}else{
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
}
}else{
- pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
+ pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0);
}
pList = sqlite3ExprListAppend(pParse, pList, pNew);
sqlite3ExprListSetName(pParse, pList, &tFromCol, 0);
@@ -106350,7 +108449,7 @@ static Trigger *fkActionTrigger(
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
if( pWhen ){
- pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0);
+ pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0);
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
}
}
@@ -106669,7 +108768,9 @@ static int readsTable(Parse *p, int iDb, Table *pTab){
/*
** Locate or create an AutoincInfo structure associated with table pTab
** which is in database iDb. Return the register number for the register
-** that holds the maximum rowid.
+** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT
+** table. (Also return zero when doing a VACUUM since we do not want to
+** update the AUTOINCREMENT counters during a VACUUM.)
**
** There is at most one AutoincInfo structure per table even if the
** same table is autoincremented multiple times due to inserts within
@@ -106692,7 +108793,9 @@ static int autoIncBegin(
Table *pTab /* The table we are writing to */
){
int memId = 0; /* Register holding maximum rowid */
- if( pTab->tabFlags & TF_Autoincrement ){
+ if( (pTab->tabFlags & TF_Autoincrement)!=0
+ && (pParse->db->flags & SQLITE_Vacuum)==0
+ ){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
AutoincInfo *pInfo;
@@ -106950,8 +109053,7 @@ SQLITE_PRIVATE void sqlite3Insert(
sqlite3 *db; /* The main database structure */
Table *pTab; /* The table to insert into. aka TABLE */
char *zTab; /* Name of the table into which we are inserting */
- const char *zDb; /* Name of the database holding this table */
- int i, j, idx; /* Loop counters */
+ int i, j; /* Loop counters */
Vdbe *v; /* Generate code into this virtual machine */
Index *pIdx; /* For looping over indices of the table */
int nColumn; /* Number of columns in the data */
@@ -106965,7 +109067,6 @@ SQLITE_PRIVATE void sqlite3Insert(
int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
SelectDest dest; /* Destination for SELECT on rhs of INSERT */
int iDb; /* Index of database holding TABLE */
- Db *pDb; /* The database containing table being inserted into */
u8 useTempTable = 0; /* Store SELECT results in intermediate table */
u8 appendFlag = 0; /* True if the insert is likely to be an append */
u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
@@ -107015,9 +109116,8 @@ SQLITE_PRIVATE void sqlite3Insert(
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
- pDb = &db->aDb[iDb];
- zDb = pDb->zName;
- if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
+ if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0,
+ db->aDb[iDb].zDbSName) ){
goto insert_cleanup;
}
withoutRowid = !HasRowid(pTab);
@@ -107260,8 +109360,10 @@ SQLITE_PRIVATE void sqlite3Insert(
if( aRegIdx==0 ){
goto insert_cleanup;
}
- for(i=0; i<nIdx; i++){
+ for(i=0, pIdx=pTab->pIndex; i<nIdx; pIdx=pIdx->pNext, i++){
+ assert( pIdx );
aRegIdx[i] = ++pParse->nMem;
+ pParse->nMem += pIdx->nColumn;
}
}
@@ -107463,12 +109565,26 @@ SQLITE_PRIVATE void sqlite3Insert(
#endif
{
int isReplace; /* Set to true if constraints may cause a replace */
+ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */
sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
);
sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
+
+ /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE
+ ** constraints or (b) there are no triggers and this table is not a
+ ** parent table in a foreign key constraint. It is safe to set the
+ ** flag in the second case as if any REPLACE constraint is hit, an
+ ** OP_Delete or OP_IdxDelete instruction will be executed on each
+ ** cursor that is disturbed. And these instructions both clear the
+ ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT
+ ** functionality. */
+ bUseSeek = (isReplace==0 || (pTrigger==0 &&
+ ((db->flags & SQLITE_ForeignKeys)==0 || sqlite3FkReferences(pTab)==0)
+ ));
sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
- regIns, aRegIdx, 0, appendFlag, isReplace==0);
+ regIns, aRegIdx, 0, appendFlag, bUseSeek
+ );
}
}
@@ -107497,14 +109613,6 @@ SQLITE_PRIVATE void sqlite3Insert(
sqlite3VdbeJumpHere(v, addrInsTop);
}
- if( !IsVirtual(pTab) && !isView ){
- /* Close all tables opened */
- if( iDataCur<iIdxCur ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur);
- for(idx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
- sqlite3VdbeAddOp1(v, OP_Close, idx+iIdxCur);
- }
- }
-
insert_end:
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
@@ -107711,7 +109819,6 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
int ipkBottom = 0; /* Bottom of the rowid change constraint check */
u8 isUpdate; /* True if this is an UPDATE operation */
u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */
- int regRowid = -1; /* Register holding ROWID value */
isUpdate = regOldData!=0;
db = pParse->db;
@@ -107766,8 +109873,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
case OE_Fail: {
char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
pTab->aCol[i].zName);
- sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
- regNewData+1+i, zMsg, P4_DYNAMIC);
+ sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
+ regNewData+1+i);
+ sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
VdbeCoverage(v);
break;
@@ -107831,7 +109939,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
if( isUpdate ){
- /* pkChng!=0 does not mean that the rowid has change, only that
+ /* pkChng!=0 does not mean that the rowid has changed, only that
** it might have changed. Skip the conflict logic below if the rowid
** is unchanged. */
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
@@ -107909,7 +110017,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** OP_Insert replace the existing entry than it is to delete the
** existing entry and then insert a new one. */
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP);
- sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE);
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
if( pTab->pIndex ){
@@ -107966,7 +110074,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* Create a record for this index entry as it should appear after
** the insert or update. Store that record in the aRegIdx[ix] register
*/
- regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
+ regIdx = aRegIdx[ix]+1;
for(i=0; i<pIdx->nColumn; i++){
int iField = pIdx->aiColumn[i];
int x;
@@ -107977,9 +110085,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
VdbeComment((v, "%s column %d", pIdx->zName, i));
}else{
if( iField==XN_ROWID || iField==pTab->iPKey ){
- if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
x = regNewData;
- regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
}else{
x = iField + regNewData + 1;
}
@@ -107989,7 +110095,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
VdbeComment((v, "for %s", pIdx->zName));
- sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
+#ifdef SQLITE_ENABLE_NULL_TRIM
+ if( pIdx->idxType==2 ) sqlite3SetMakeRecordP5(v, pIdx->pTable);
+#endif
/* In an UPDATE operation, if this index is the PRIMARY KEY index
** of a WITHOUT ROWID table and there has been no change the
@@ -108003,7 +110111,6 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* Find out what action to take in case there is a uniqueness conflict */
onError = pIdx->onError;
if( onError==OE_None ){
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
sqlite3VdbeResolveLabel(v, addrUniqueOk);
continue; /* pIdx is not a UNIQUE index */
}
@@ -108012,7 +110119,26 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}else if( onError==OE_Default ){
onError = OE_Abort;
}
-
+
+ /* Collision detection may be omitted if all of the following are true:
+ ** (1) The conflict resolution algorithm is REPLACE
+ ** (2) The table is a WITHOUT ROWID table
+ ** (3) There are no secondary indexes on the table
+ ** (4) No delete triggers need to be fired if there is a conflict
+ ** (5) No FK constraint counters need to be updated if a conflict occurs.
+ */
+ if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
+ && pPk==pIdx /* Condition 2 */
+ && onError==OE_Replace /* Condition 1 */
+ && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */
+ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0))
+ && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */
+ (0==pTab->pFKey && 0==sqlite3FkReferences(pTab)))
+ ){
+ sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ continue;
+ }
+
/* Check to see if the new index entry will be unique */
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
regIdx, pIdx->nKeyCol); VdbeCoverage(v);
@@ -108096,13 +110222,12 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur,
regR, nPkField, 0, OE_Replace,
- (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), -1);
+ (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur);
seenReplace = 1;
break;
}
}
sqlite3VdbeResolveLabel(v, addrUniqueOk);
- sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn);
if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
}
if( ipkTop ){
@@ -108114,6 +110239,28 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace));
}
+#ifdef SQLITE_ENABLE_NULL_TRIM
+/*
+** Change the P5 operand on the last opcode (which should be an OP_MakeRecord)
+** to be the number of columns in table pTab that must not be NULL-trimmed.
+**
+** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero.
+*/
+SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){
+ u16 i;
+
+ /* Records with omitted columns are only allowed for schema format
+ ** version 2 and later (SQLite version 3.1.4, 2005-02-20). */
+ if( pTab->pSchema->file_format<2 ) return;
+
+ for(i=pTab->nCol-1; i>0; i--){
+ if( pTab->aCol[i].pDflt!=0 ) break;
+ if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break;
+ }
+ sqlite3VdbeChangeP5(v, i+1);
+}
+#endif
+
/*
** This routine generates code to finish the INSERT or UPDATE operation
** that was started by a prior call to sqlite3GenerateConstraintChecks.
@@ -108130,7 +110277,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
int iIdxCur, /* First index cursor */
int regNewData, /* Range of content */
int *aRegIdx, /* Register used by each index. 0 for unused indices */
- int isUpdate, /* True for UPDATE, False for INSERT */
+ int update_flags, /* True for UPDATE, False for INSERT */
int appendBias, /* True if this is likely to be an append */
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
@@ -108142,6 +110289,11 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
int i; /* Loop counter */
u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
+ assert( update_flags==0
+ || update_flags==OPFLAG_ISUPDATE
+ || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION)
+ );
+
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
@@ -108152,26 +110304,39 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
}
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
- pik_flags = 0;
- if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT;
+ pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0);
if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
assert( pParse->nested==0 );
pik_flags |= OPFLAG_NCHANGE;
+ pik_flags |= (update_flags & OPFLAG_SAVEPOSITION);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ if( update_flags==0 ){
+ sqlite3VdbeAddOp4(v, OP_InsertInt,
+ iIdxCur+i, aRegIdx[i], 0, (char*)pTab, P4_TABLE
+ );
+ sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP);
+ }
+#endif
}
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i],
+ aRegIdx[i]+1,
+ pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn);
sqlite3VdbeChangeP5(v, pik_flags);
}
if( !HasRowid(pTab) ) return;
regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
- if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0);
- sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
+ sqlite3SetMakeRecordP5(v, pTab);
+ if( !bAffinityDone ){
+ sqlite3TableAffinity(v, pTab, 0);
+ sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
+ }
if( pParse->nested ){
pik_flags = 0;
}else{
pik_flags = OPFLAG_NCHANGE;
- pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
+ pik_flags |= (update_flags?update_flags:OPFLAG_LASTROWID);
}
if( appendBias ){
pik_flags |= OPFLAG_APPEND;
@@ -108181,7 +110346,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
}
sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData);
if( !pParse->nested ){
- sqlite3VdbeChangeP4(v, -1, (char *)pTab, P4_TABLE);
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
sqlite3VdbeChangeP5(v, pik_flags);
}
@@ -108246,15 +110411,15 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
int iIdxCur = iBase++;
assert( pIdx->pSchema==pTab->pSchema );
+ if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
+ if( piDataCur ) *piDataCur = iIdxCur;
+ p5 = 0;
+ }
if( aToOpen==0 || aToOpen[i+1] ){
sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
- VdbeComment((v, "%s", pIdx->zName));
- }
- if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
- if( piDataCur ) *piDataCur = iIdxCur;
- }else{
sqlite3VdbeChangeP5(v, p5);
+ VdbeComment((v, "%s", pIdx->zName));
}
}
if( iBase>pParse->nTab ) pParse->nTab = iBase;
@@ -108382,7 +110547,7 @@ static int xferOptimization(
return 0; /* tab1 must not have triggers */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pDest->tabFlags & TF_Virtual ){
+ if( IsVirtual(pDest) ){
return 0; /* tab1 must not be a virtual table */
}
#endif
@@ -108444,7 +110609,7 @@ static int xferOptimization(
return 0; /* source and destination must both be WITHOUT ROWID or not */
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( pSrc->tabFlags & TF_Virtual ){
+ if( IsVirtual(pSrc) ){
return 0; /* tab2 must not be a virtual table */
}
#endif
@@ -108564,6 +110729,7 @@ static int xferOptimization(
sqlite3VdbeJumpHere(v, addr1);
}
if( HasRowid(pSrc) ){
+ u8 insFlags;
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
if( pDest->iPKey>=0 ){
@@ -108579,10 +110745,17 @@ static int xferOptimization(
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
assert( (pDest->tabFlags & TF_Autoincrement)==0 );
}
- sqlite3VdbeAddOp2(v, OP_RowData, iSrc, regData);
+ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
+ if( db->flags & SQLITE_Vacuum ){
+ sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
+ OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
+ }else{
+ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND;
+ }
sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid,
(char*)pDest, P4_TABLE);
- sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
+ sqlite3VdbeChangeP5(v, insFlags);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
@@ -108604,7 +110777,7 @@ static int xferOptimization(
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
+ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
if( db->flags & SQLITE_Vacuum ){
/* This INSERT command is part of a VACUUM operation, which guarantees
** that the destination table is empty. If all indexed columns use
@@ -108622,8 +110795,6 @@ static int xferOptimization(
** sorted order. */
for(i=0; i<pSrcIdx->nColumn; i++){
const char *zColl = pSrcIdx->azColl[i];
- assert( sqlite3_stricmp(sqlite3StrBINARY, zColl)!=0
- || sqlite3StrBINARY==zColl );
if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break;
}
if( i==pSrcIdx->nColumn ){
@@ -108634,8 +110805,8 @@ static int xferOptimization(
if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
idxInsFlags |= OPFLAG_NCHANGE;
}
- sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
- sqlite3VdbeChangeP5(v, idxInsFlags);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
+ sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -108645,6 +110816,7 @@ static int xferOptimization(
sqlite3ReleaseTempReg(pParse, regRowid);
sqlite3ReleaseTempReg(pParse, regData);
if( emptyDestTest ){
+ sqlite3AutoincrementEnd(pParse);
sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0);
sqlite3VdbeJumpHere(v, emptyDestTest);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
@@ -108686,7 +110858,7 @@ static int xferOptimization(
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite3_callback xCallback, /* Invoke this callback routine */
@@ -108732,7 +110904,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
(SQLITE_DONE==rc && !callbackIsInit
&& db->flags&SQLITE_NullCallback)) ){
if( !callbackIsInit ){
- azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
+ azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*));
if( azCols==0 ){
goto exec_out;
}
@@ -108753,6 +110925,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
goto exec_out;
}
}
+ azVals[i] = 0;
}
if( xCallback(pArg, nCol, azVals, azCols) ){
/* EVIDENCE-OF: R-38229-40159 If the callback function to
@@ -109108,6 +111281,8 @@ struct sqlite3_api_routines {
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
+ /* Version 3.18.0 and later */
+ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
};
/*
@@ -109366,6 +111541,8 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
+/* Version 3.18.0 and later */
+#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -109388,7 +111565,6 @@ typedef int (*sqlite3_loadext_entry)(
/************** End of sqlite3ext.h ******************************************/
/************** Continuing where we left off in loadext.c ********************/
/* #include "sqliteInt.h" */
-/* #include <string.h> */
#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
@@ -109792,7 +111968,9 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_system_errno,
/* Version 3.14.0 and later */
sqlite3_trace_v2,
- sqlite3_expanded_sql
+ sqlite3_expanded_sql,
+ /* Version 3.18.0 and later */
+ sqlite3_set_last_insert_rowid
};
/*
@@ -109948,7 +112126,7 @@ static int sqlite3LoadExtension(
db->aExtension[db->nExtension++] = handle;
return SQLITE_OK;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
@@ -109979,7 +112157,7 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
** Enable or disable extension loading. Extension loading is disabled by
** default so as not to open security holes in older applications.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
if( onoff ){
db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc;
@@ -109990,18 +112168,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int ono
return SQLITE_OK;
}
-#endif /* SQLITE_OMIT_LOAD_EXTENSION */
-
-/*
-** The auto-extension code added regardless of whether or not extension
-** loading is supported. We need a dummy sqlite3Apis pointer for that
-** code if regular extension loading is not available. This is that
-** dummy pointer.
-*/
-#ifdef SQLITE_OMIT_LOAD_EXTENSION
-static const sqlite3_api_routines sqlite3Apis = { 0 };
-#endif
-
+#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) */
/*
** The following object holds the list of automatically loaded
@@ -110036,7 +112203,7 @@ static SQLITE_WSD struct sqlite3AutoExtList {
** Register a statically linked extension that is automatically
** loaded by every new database connection.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(
+SQLITE_API int sqlite3_auto_extension(
void (*xInit)(void)
){
int rc = SQLITE_OK;
@@ -110083,7 +112250,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(
** Return 1 if xInit was found on the list and removed. Return 0 if xInit
** was not on the list.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(
+SQLITE_API int sqlite3_cancel_auto_extension(
void (*xInit)(void)
){
#if SQLITE_THREADSAFE
@@ -110108,7 +112275,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(
/*
** Reset the automatic extension loading mechanism.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){
+SQLITE_API void sqlite3_reset_auto_extension(void){
#ifndef SQLITE_OMIT_AUTOINIT
if( sqlite3_initialize()==SQLITE_OK )
#endif
@@ -110146,6 +112313,11 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
+#ifdef SQLITE_OMIT_LOAD_EXTENSION
+ const sqlite3_api_routines *pThunk = 0;
+#else
+ const sqlite3_api_routines *pThunk = &sqlite3Apis;
+#endif
sqlite3_mutex_enter(mutex);
if( i>=wsdAutoext.nExt ){
xInit = 0;
@@ -110155,7 +112327,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
}
sqlite3_mutex_leave(mutex);
zErrmsg = 0;
- if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
+ if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){
sqlite3ErrorWithMsg(db, rc,
"automatic extension loading failed: %s", zErrmsg);
go = 0;
@@ -110203,6 +112375,8 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
** ../tool/mkpragmatab.tcl. To update the set of pragmas, edit
** that script and rerun it.
*/
+
+/* The various pragma types */
#define PragTyp_HEADER_VALUE 0
#define PragTyp_AUTO_VACUUM 1
#define PragTyp_FLAG 2
@@ -110228,11 +112402,11 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_LOCKING_MODE 22
#define PragTyp_PAGE_COUNT 23
#define PragTyp_MMAP_SIZE 24
-#define PragTyp_PAGE_SIZE 25
-#define PragTyp_SECURE_DELETE 26
-#define PragTyp_SHRINK_MEMORY 27
-#define PragTyp_SOFT_HEAP_LIMIT 28
-#define PragTyp_STATS 29
+#define PragTyp_OPTIMIZE 25
+#define PragTyp_PAGE_SIZE 26
+#define PragTyp_SECURE_DELETE 27
+#define PragTyp_SHRINK_MEMORY 28
+#define PragTyp_SOFT_HEAP_LIMIT 29
#define PragTyp_SYNCHRONOUS 30
#define PragTyp_TABLE_INFO 31
#define PragTyp_TEMP_STORE 32
@@ -110246,422 +112420,572 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
#define PragTyp_REKEY 40
#define PragTyp_LOCK_STATUS 41
#define PragTyp_PARSER_TRACE 42
-#define PragFlag_NeedSchema 0x01
-#define PragFlag_ReadOnly 0x02
-static const struct sPragmaNames {
- const char *const zName; /* Name of pragma */
- u8 ePragTyp; /* PragTyp_XXX value */
- u8 mPragFlag; /* Zero or more PragFlag_XXX values */
- u32 iArg; /* Extra argument */
-} aPragmaNames[] = {
+#define PragTyp_STATS 43
+
+/* Property flags associated with various pragma. */
+#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
+#define PragFlg_NoColumns 0x02 /* OP_ResultRow called with zero columns */
+#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
+#define PragFlg_ReadOnly 0x08 /* Read-only HEADER_VALUE */
+#define PragFlg_Result0 0x10 /* Acts as query when no argument */
+#define PragFlg_Result1 0x20 /* Acts as query when has one argument */
+#define PragFlg_SchemaOpt 0x40 /* Schema restricts name search if present */
+#define PragFlg_SchemaReq 0x80 /* Schema required - "main" is default */
+
+/* Names of columns for pragmas that return multi-column result
+** or that return single-column results where the name of the
+** result column is different from the name of the pragma
+*/
+static const char *const pragCName[] = {
+ /* 0 */ "cache_size", /* Used by: default_cache_size */
+ /* 1 */ "cid", /* Used by: table_info */
+ /* 2 */ "name",
+ /* 3 */ "type",
+ /* 4 */ "notnull",
+ /* 5 */ "dflt_value",
+ /* 6 */ "pk",
+ /* 7 */ "tbl", /* Used by: stats */
+ /* 8 */ "idx",
+ /* 9 */ "wdth",
+ /* 10 */ "hght",
+ /* 11 */ "flgs",
+ /* 12 */ "seqno", /* Used by: index_info */
+ /* 13 */ "cid",
+ /* 14 */ "name",
+ /* 15 */ "seqno", /* Used by: index_xinfo */
+ /* 16 */ "cid",
+ /* 17 */ "name",
+ /* 18 */ "desc",
+ /* 19 */ "coll",
+ /* 20 */ "key",
+ /* 21 */ "seq", /* Used by: index_list */
+ /* 22 */ "name",
+ /* 23 */ "unique",
+ /* 24 */ "origin",
+ /* 25 */ "partial",
+ /* 26 */ "seq", /* Used by: database_list */
+ /* 27 */ "name",
+ /* 28 */ "file",
+ /* 29 */ "seq", /* Used by: collation_list */
+ /* 30 */ "name",
+ /* 31 */ "id", /* Used by: foreign_key_list */
+ /* 32 */ "seq",
+ /* 33 */ "table",
+ /* 34 */ "from",
+ /* 35 */ "to",
+ /* 36 */ "on_update",
+ /* 37 */ "on_delete",
+ /* 38 */ "match",
+ /* 39 */ "table", /* Used by: foreign_key_check */
+ /* 40 */ "rowid",
+ /* 41 */ "parent",
+ /* 42 */ "fkid",
+ /* 43 */ "busy", /* Used by: wal_checkpoint */
+ /* 44 */ "log",
+ /* 45 */ "checkpointed",
+ /* 46 */ "timeout", /* Used by: busy_timeout */
+ /* 47 */ "database", /* Used by: lock_status */
+ /* 48 */ "status",
+};
+
+/* Definitions of all built-in pragmas */
+typedef struct PragmaName {
+ const char *const zName; /* Name of pragma */
+ u8 ePragTyp; /* PragTyp_XXX value */
+ u8 mPragFlg; /* Zero or more PragFlg_XXX values */
+ u8 iPragCName; /* Start of column names in pragCName[] */
+ u8 nPragCName; /* Num of col names. 0 means use pragma name */
+ u32 iArg; /* Extra argument */
+} PragmaName;
+static const PragmaName aPragmaName[] = {
#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
- { /* zName: */ "activate_extensions",
- /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "activate_extensions",
+ /* ePragTyp: */ PragTyp_ACTIVATE_EXTENSIONS,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- { /* zName: */ "application_id",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlag: */ 0,
- /* iArg: */ BTREE_APPLICATION_ID },
+ {/* zName: */ "application_id",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_APPLICATION_ID },
#endif
#if !defined(SQLITE_OMIT_AUTOVACUUM)
- { /* zName: */ "auto_vacuum",
- /* ePragTyp: */ PragTyp_AUTO_VACUUM,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "auto_vacuum",
+ /* ePragTyp: */ PragTyp_AUTO_VACUUM,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
- { /* zName: */ "automatic_index",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_AutoIndex },
-#endif
-#endif
- { /* zName: */ "busy_timeout",
- /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "automatic_index",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_AutoIndex },
+#endif
+#endif
+ {/* zName: */ "busy_timeout",
+ /* ePragTyp: */ PragTyp_BUSY_TIMEOUT,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 46, 1,
+ /* iArg: */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- { /* zName: */ "cache_size",
- /* ePragTyp: */ PragTyp_CACHE_SIZE,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "cache_size",
+ /* ePragTyp: */ PragTyp_CACHE_SIZE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "cache_spill",
- /* ePragTyp: */ PragTyp_CACHE_SPILL,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
-#endif
- { /* zName: */ "case_sensitive_like",
- /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
- { /* zName: */ "cell_size_check",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_CellSizeCk },
+ {/* zName: */ "cache_spill",
+ /* ePragTyp: */ PragTyp_CACHE_SPILL,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+ {/* zName: */ "case_sensitive_like",
+ /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
+ /* ePragFlg: */ PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "cell_size_check",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CellSizeCk },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "checkpoint_fullfsync",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_CkptFullFSync },
+ {/* zName: */ "checkpoint_fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CkptFullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- { /* zName: */ "collation_list",
- /* ePragTyp: */ PragTyp_COLLATION_LIST,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "collation_list",
+ /* ePragTyp: */ PragTyp_COLLATION_LIST,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 29, 2,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
- { /* zName: */ "compile_options",
- /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "compile_options",
+ /* ePragTyp: */ PragTyp_COMPILE_OPTIONS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "count_changes",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_CountRows },
+ {/* zName: */ "count_changes",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_CountRows },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
- { /* zName: */ "data_store_directory",
- /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "data_store_directory",
+ /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- { /* zName: */ "data_version",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlag: */ PragFlag_ReadOnly,
- /* iArg: */ BTREE_DATA_VERSION },
+ {/* zName: */ "data_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_DATA_VERSION },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- { /* zName: */ "database_list",
- /* ePragTyp: */ PragTyp_DATABASE_LIST,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "database_list",
+ /* ePragTyp: */ PragTyp_DATABASE_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0,
+ /* ColNames: */ 26, 3,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
- { /* zName: */ "default_cache_size",
- /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "default_cache_size",
+ /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 1,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- { /* zName: */ "defer_foreign_keys",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_DeferFKs },
+ {/* zName: */ "defer_foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_DeferFKs },
#endif
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "empty_result_callbacks",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_NullCallback },
+ {/* zName: */ "empty_result_callbacks",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_NullCallback },
#endif
#if !defined(SQLITE_OMIT_UTF16)
- { /* zName: */ "encoding",
- /* ePragTyp: */ PragTyp_ENCODING,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "encoding",
+ /* ePragTyp: */ PragTyp_ENCODING,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- { /* zName: */ "foreign_key_check",
- /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "foreign_key_check",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 39, 4,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
- { /* zName: */ "foreign_key_list",
- /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "foreign_key_list",
+ /* ePragTyp: */ PragTyp_FOREIGN_KEY_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 31, 8,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
- { /* zName: */ "foreign_keys",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_ForeignKeys },
+ {/* zName: */ "foreign_keys",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ForeignKeys },
#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- { /* zName: */ "freelist_count",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlag: */ PragFlag_ReadOnly,
- /* iArg: */ BTREE_FREE_PAGE_COUNT },
+ {/* zName: */ "freelist_count",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_ReadOnly|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_FREE_PAGE_COUNT },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "full_column_names",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_FullColNames },
- { /* zName: */ "fullfsync",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_FullFSync },
+ {/* zName: */ "full_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_FullColNames },
+ {/* zName: */ "fullfsync",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_FullFSync },
#endif
#if defined(SQLITE_HAS_CODEC)
- { /* zName: */ "hexkey",
- /* ePragTyp: */ PragTyp_HEXKEY,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
- { /* zName: */ "hexrekey",
- /* ePragTyp: */ PragTyp_HEXKEY,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "hexkey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "hexrekey",
+ /* ePragTyp: */ PragTyp_HEXKEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_CHECK)
- { /* zName: */ "ignore_check_constraints",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_IgnoreChecks },
+ {/* zName: */ "ignore_check_constraints",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_IgnoreChecks },
#endif
#endif
#if !defined(SQLITE_OMIT_AUTOVACUUM)
- { /* zName: */ "incremental_vacuum",
- /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "incremental_vacuum",
+ /* ePragTyp: */ PragTyp_INCREMENTAL_VACUUM,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- { /* zName: */ "index_info",
- /* ePragTyp: */ PragTyp_INDEX_INFO,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
- { /* zName: */ "index_list",
- /* ePragTyp: */ PragTyp_INDEX_LIST,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
- { /* zName: */ "index_xinfo",
- /* ePragTyp: */ PragTyp_INDEX_INFO,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 1 },
+ {/* zName: */ "index_info",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 12, 3,
+ /* iArg: */ 0 },
+ {/* zName: */ "index_list",
+ /* ePragTyp: */ PragTyp_INDEX_LIST,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 21, 5,
+ /* iArg: */ 0 },
+ {/* zName: */ "index_xinfo",
+ /* ePragTyp: */ PragTyp_INDEX_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 15, 6,
+ /* iArg: */ 1 },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
- { /* zName: */ "integrity_check",
- /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "integrity_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- { /* zName: */ "journal_mode",
- /* ePragTyp: */ PragTyp_JOURNAL_MODE,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
- { /* zName: */ "journal_size_limit",
- /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "journal_mode",
+ /* ePragTyp: */ PragTyp_JOURNAL_MODE,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "journal_size_limit",
+ /* ePragTyp: */ PragTyp_JOURNAL_SIZE_LIMIT,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if defined(SQLITE_HAS_CODEC)
- { /* zName: */ "key",
- /* ePragTyp: */ PragTyp_KEY,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "key",
+ /* ePragTyp: */ PragTyp_KEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "legacy_file_format",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_LegacyFileFmt },
+ {/* zName: */ "legacy_file_format",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_LegacyFileFmt },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
- { /* zName: */ "lock_proxy_file",
- /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "lock_proxy_file",
+ /* ePragTyp: */ PragTyp_LOCK_PROXY_FILE,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
- { /* zName: */ "lock_status",
- /* ePragTyp: */ PragTyp_LOCK_STATUS,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "lock_status",
+ /* ePragTyp: */ PragTyp_LOCK_STATUS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 47, 2,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- { /* zName: */ "locking_mode",
- /* ePragTyp: */ PragTyp_LOCKING_MODE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
- { /* zName: */ "max_page_count",
- /* ePragTyp: */ PragTyp_PAGE_COUNT,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
- { /* zName: */ "mmap_size",
- /* ePragTyp: */ PragTyp_MMAP_SIZE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
- { /* zName: */ "page_count",
- /* ePragTyp: */ PragTyp_PAGE_COUNT,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
- { /* zName: */ "page_size",
- /* ePragTyp: */ PragTyp_PAGE_SIZE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "locking_mode",
+ /* ePragTyp: */ PragTyp_LOCKING_MODE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "max_page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "mmap_size",
+ /* ePragTyp: */ PragTyp_MMAP_SIZE,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+ {/* zName: */ "optimize",
+ /* ePragTyp: */ PragTyp_OPTIMIZE,
+ /* ePragFlg: */ PragFlg_Result1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
+ {/* zName: */ "page_count",
+ /* ePragTyp: */ PragTyp_PAGE_COUNT,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "page_size",
+ /* ePragTyp: */ PragTyp_PAGE_SIZE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
- { /* zName: */ "parser_trace",
- /* ePragTyp: */ PragTyp_PARSER_TRACE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "parser_trace",
+ /* ePragTyp: */ PragTyp_PARSER_TRACE,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "query_only",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_QueryOnly },
+ {/* zName: */ "query_only",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_QueryOnly },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
- { /* zName: */ "quick_check",
- /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "quick_check",
+ /* ePragTyp: */ PragTyp_INTEGRITY_CHECK,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "read_uncommitted",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_ReadUncommitted },
- { /* zName: */ "recursive_triggers",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_RecTriggers },
+ {/* zName: */ "read_uncommitted",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ReadUncommitted },
+ {/* zName: */ "recursive_triggers",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_RecTriggers },
#endif
#if defined(SQLITE_HAS_CODEC)
- { /* zName: */ "rekey",
- /* ePragTyp: */ PragTyp_REKEY,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "rekey",
+ /* ePragTyp: */ PragTyp_REKEY,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "reverse_unordered_selects",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_ReverseOrder },
+ {/* zName: */ "reverse_unordered_selects",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ReverseOrder },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- { /* zName: */ "schema_version",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlag: */ 0,
- /* iArg: */ BTREE_SCHEMA_VERSION },
+ {/* zName: */ "schema_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_SCHEMA_VERSION },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- { /* zName: */ "secure_delete",
- /* ePragTyp: */ PragTyp_SECURE_DELETE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "secure_delete",
+ /* ePragTyp: */ PragTyp_SECURE_DELETE,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "short_column_names",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_ShortColNames },
-#endif
- { /* zName: */ "shrink_memory",
- /* ePragTyp: */ PragTyp_SHRINK_MEMORY,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
- { /* zName: */ "soft_heap_limit",
- /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "short_column_names",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_ShortColNames },
+#endif
+ {/* zName: */ "shrink_memory",
+ /* ePragTyp: */ PragTyp_SHRINK_MEMORY,
+ /* ePragFlg: */ PragFlg_NoColumns,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "soft_heap_limit",
+ /* ePragTyp: */ PragTyp_SOFT_HEAP_LIMIT,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if defined(SQLITE_DEBUG)
- { /* zName: */ "sql_trace",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_SqlTrace },
+ {/* zName: */ "sql_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_SqlTrace },
#endif
#endif
-#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- { /* zName: */ "stats",
- /* ePragTyp: */ PragTyp_STATS,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
+ {/* zName: */ "stats",
+ /* ePragTyp: */ PragTyp_STATS,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
+ /* ColNames: */ 7, 5,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- { /* zName: */ "synchronous",
- /* ePragTyp: */ PragTyp_SYNCHRONOUS,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "synchronous",
+ /* ePragTyp: */ PragTyp_SYNCHRONOUS,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
- { /* zName: */ "table_info",
- /* ePragTyp: */ PragTyp_TABLE_INFO,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "table_info",
+ /* ePragTyp: */ PragTyp_TABLE_INFO,
+ /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
+ /* ColNames: */ 1, 6,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
- { /* zName: */ "temp_store",
- /* ePragTyp: */ PragTyp_TEMP_STORE,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
- { /* zName: */ "temp_store_directory",
- /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
-#endif
- { /* zName: */ "threads",
- /* ePragTyp: */ PragTyp_THREADS,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
+ {/* zName: */ "temp_store",
+ /* ePragTyp: */ PragTyp_TEMP_STORE,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "temp_store_directory",
+ /* ePragTyp: */ PragTyp_TEMP_STORE_DIRECTORY,
+ /* ePragFlg: */ PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+#endif
+ {/* zName: */ "threads",
+ /* ePragTyp: */ PragTyp_THREADS,
+ /* ePragFlg: */ PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
- { /* zName: */ "user_version",
- /* ePragTyp: */ PragTyp_HEADER_VALUE,
- /* ePragFlag: */ 0,
- /* iArg: */ BTREE_USER_VERSION },
+ {/* zName: */ "user_version",
+ /* ePragTyp: */ PragTyp_HEADER_VALUE,
+ /* ePragFlg: */ PragFlg_NoColumns1|PragFlg_Result0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ BTREE_USER_VERSION },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if defined(SQLITE_DEBUG)
- { /* zName: */ "vdbe_addoptrace",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_VdbeAddopTrace },
- { /* zName: */ "vdbe_debug",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
- { /* zName: */ "vdbe_eqp",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_VdbeEQP },
- { /* zName: */ "vdbe_listing",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_VdbeListing },
- { /* zName: */ "vdbe_trace",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_VdbeTrace },
+ {/* zName: */ "vdbe_addoptrace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeAddopTrace },
+ {/* zName: */ "vdbe_debug",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace },
+ {/* zName: */ "vdbe_eqp",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeEQP },
+ {/* zName: */ "vdbe_listing",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeListing },
+ {/* zName: */ "vdbe_trace",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_VdbeTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_WAL)
- { /* zName: */ "wal_autocheckpoint",
- /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
- /* ePragFlag: */ 0,
- /* iArg: */ 0 },
- { /* zName: */ "wal_checkpoint",
- /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
- /* ePragFlag: */ PragFlag_NeedSchema,
- /* iArg: */ 0 },
+ {/* zName: */ "wal_autocheckpoint",
+ /* ePragTyp: */ PragTyp_WAL_AUTOCHECKPOINT,
+ /* ePragFlg: */ 0,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ 0 },
+ {/* zName: */ "wal_checkpoint",
+ /* ePragTyp: */ PragTyp_WAL_CHECKPOINT,
+ /* ePragFlg: */ PragFlg_NeedSchema,
+ /* ColNames: */ 43, 3,
+ /* iArg: */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
- { /* zName: */ "writable_schema",
- /* ePragTyp: */ PragTyp_FLAG,
- /* ePragFlag: */ 0,
- /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
+ {/* zName: */ "writable_schema",
+ /* ePragTyp: */ PragTyp_FLAG,
+ /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1,
+ /* ColNames: */ 0, 0,
+ /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
#endif
};
-/* Number of pragmas: 60 on by default, 73 total. */
+/* Number of pragmas: 60 on by default, 74 total. */
/************** End of pragma.h **********************************************/
/************** Continuing where we left off in pragma.c *********************/
@@ -110799,29 +113123,29 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
#endif /* SQLITE_PAGER_PRAGMAS */
/*
-** Set the names of the first N columns to the values in azCol[]
+** Set result column names for a pragma.
*/
-static void setAllColumnNames(
- Vdbe *v, /* The query under construction */
- int N, /* Number of columns */
- const char **azCol /* Names of columns */
+static void setPragmaResultColumnNames(
+ Vdbe *v, /* The query under construction */
+ const PragmaName *pPragma /* The pragma */
){
- int i;
- sqlite3VdbeSetNumCols(v, N);
- for(i=0; i<N; i++){
- sqlite3VdbeSetColName(v, i, COLNAME_NAME, azCol[i], SQLITE_STATIC);
+ u8 n = pPragma->nPragCName;
+ sqlite3VdbeSetNumCols(v, n==0 ? 1 : n);
+ if( n==0 ){
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC);
+ }else{
+ int i, j;
+ for(i=0, j=pPragma->iPragCName; i<n; i++, j++){
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, pragCName[j], SQLITE_STATIC);
+ }
}
}
-static void setOneColumnName(Vdbe *v, const char *z){
- setAllColumnNames(v, 1, &z);
-}
/*
** Generate code to return a single integer value.
*/
-static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){
+static void returnSingleInt(Vdbe *v, i64 value){
sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, 1, 0, (const u8*)&value, P4_INT64);
- setOneColumnName(v, zLabel);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
@@ -110830,12 +113154,10 @@ static void returnSingleInt(Vdbe *v, const char *zLabel, i64 value){
*/
static void returnSingleText(
Vdbe *v, /* Prepared statement under construction */
- const char *zLabel, /* Name of the result column */
const char *zValue /* Value to be returned */
){
if( zValue ){
sqlite3VdbeLoadString(v, 1, (const char*)zValue);
- setOneColumnName(v, zLabel);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}
@@ -110914,6 +113236,42 @@ SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){
}
/*
+** Locate a pragma in the aPragmaName[] array.
+*/
+static const PragmaName *pragmaLocate(const char *zName){
+ int upr, lwr, mid = 0, rc;
+ lwr = 0;
+ upr = ArraySize(aPragmaName)-1;
+ while( lwr<=upr ){
+ mid = (lwr+upr)/2;
+ rc = sqlite3_stricmp(zName, aPragmaName[mid].zName);
+ if( rc==0 ) break;
+ if( rc<0 ){
+ upr = mid - 1;
+ }else{
+ lwr = mid + 1;
+ }
+ }
+ return lwr>upr ? 0 : &aPragmaName[mid];
+}
+
+/*
+** Helper subroutine for PRAGMA integrity_check:
+**
+** Generate code to output a single-column result row with the result
+** held in register regResult. Decrement the result count and halt if
+** the maximum number of result rows have been issued.
+*/
+static int integrityCheckResultRow(Vdbe *v, int regResult){
+ int addr;
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
+ addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+ return addr;
+}
+
+/*
** Process a pragma statement.
**
** Pragmas are of this form:
@@ -110941,12 +113299,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
Token *pId; /* Pointer to <id> token */
char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */
int iDb; /* Database index for <database> */
- int lwr, upr, mid = 0; /* Binary search bounds */
int rc; /* return value form SQLITE_FCNTL_PRAGMA */
sqlite3 *db = pParse->db; /* The database connection */
Db *pDb; /* The specific database being pragmaed */
Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */
- const struct sPragmaNames *pPragma;
+ const PragmaName *pPragma; /* The pragma */
if( v==0 ) return;
sqlite3VdbeRunOnlyOnce(v);
@@ -110974,7 +113331,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
assert( pId2 );
- zDb = pId2->n>0 ? pDb->zName : 0;
+ zDb = pId2->n>0 ? pDb->zDbSName : 0;
if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
goto pragma_out;
}
@@ -111001,7 +113358,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
db->busyHandler.nBusy = 0;
rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
if( rc==SQLITE_OK ){
- returnSingleText(v, "result", aFcntl[0]);
+ sqlite3VdbeSetNumCols(v, 1);
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT);
+ returnSingleText(v, aFcntl[0]);
sqlite3_free(aFcntl[0]);
goto pragma_out;
}
@@ -111016,26 +113375,21 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/* Locate the pragma in the lookup table */
- lwr = 0;
- upr = ArraySize(aPragmaNames)-1;
- while( lwr<=upr ){
- mid = (lwr+upr)/2;
- rc = sqlite3_stricmp(zLeft, aPragmaNames[mid].zName);
- if( rc==0 ) break;
- if( rc<0 ){
- upr = mid - 1;
- }else{
- lwr = mid + 1;
- }
- }
- if( lwr>upr ) goto pragma_out;
- pPragma = &aPragmaNames[mid];
+ pPragma = pragmaLocate(zLeft);
+ if( pPragma==0 ) goto pragma_out;
/* Make sure the database schema is loaded if the pragma requires that */
- if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
+ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
}
+ /* Register the result column names for pragmas that return results */
+ if( (pPragma->mPragFlg & PragFlg_NoColumns)==0
+ && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0)
+ ){
+ setPragmaResultColumnNames(v, pPragma);
+ }
+
/* Jump to the appropriate pragma handler */
switch( pPragma->ePragTyp ){
@@ -111072,7 +113426,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
VdbeOp *aOp;
sqlite3VdbeUsesBtree(v, iDb);
if( !zRight ){
- setOneColumnName(v, "cache_size");
pParse->nMem += 2;
sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize));
aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn);
@@ -111107,7 +113460,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( pBt!=0 );
if( !zRight ){
int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0;
- returnSingleInt(v, "page_size", size);
+ returnSingleInt(v, size);
}else{
/* Malloc may fail when setting the page-size, as there is an internal
** buffer that the pager module resizes using sqlite3_realloc().
@@ -111142,7 +113495,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
}
b = sqlite3BtreeSecureDelete(pBt, b);
- returnSingleInt(v, "secure_delete", b);
+ returnSingleInt(v, b);
break;
}
@@ -111174,8 +113527,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3AbsInt32(sqlite3Atoi(zRight)));
}
sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
break;
}
@@ -111221,7 +113572,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( eMode==PAGER_LOCKINGMODE_EXCLUSIVE ){
zRet = "exclusive";
}
- returnSingleText(v, "locking_mode", zRet);
+ returnSingleText(v, zRet);
break;
}
@@ -111234,7 +113585,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
int ii; /* Loop counter */
- setOneColumnName(v, "journal_mode");
if( zRight==0 ){
/* If there is no "=MODE" part of the pragma, do a query for the
** current mode */
@@ -111280,7 +113630,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( iLimit<-1 ) iLimit = -1;
}
iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
- returnSingleInt(v, "journal_size_limit", iLimit);
+ returnSingleInt(v, iLimit);
break;
}
@@ -111298,7 +113648,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
Btree *pBt = pDb->pBt;
assert( pBt!=0 );
if( !zRight ){
- returnSingleInt(v, "auto_vacuum", sqlite3BtreeGetAutoVacuum(pBt));
+ returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt));
}else{
int eAuto = getAutoVacuum(zRight);
assert( eAuto>=0 && eAuto<=2 );
@@ -111377,7 +113727,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
case PragTyp_CACHE_SIZE: {
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( !zRight ){
- returnSingleInt(v, "cache_size", pDb->pSchema->cache_size);
+ returnSingleInt(v, pDb->pSchema->cache_size);
}else{
int size = sqlite3Atoi(zRight);
pDb->pSchema->cache_size = size;
@@ -111411,7 +113761,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
case PragTyp_CACHE_SPILL: {
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( !zRight ){
- returnSingleInt(v, "cache_spill",
+ returnSingleInt(v,
(db->flags & SQLITE_CacheSpill)==0 ? 0 :
sqlite3BtreeSetSpillSize(pDb->pBt,0));
}else{
@@ -111465,7 +113815,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
rc = SQLITE_OK;
#endif
if( rc==SQLITE_OK ){
- returnSingleInt(v, "mmap_size", sz);
+ returnSingleInt(v, sz);
}else if( rc!=SQLITE_NOTFOUND ){
pParse->nErr++;
pParse->rc = rc;
@@ -111486,7 +113836,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_TEMP_STORE: {
if( !zRight ){
- returnSingleInt(v, "temp_store", db->temp_store);
+ returnSingleInt(v, db->temp_store);
}else{
changeTempStorage(pParse, zRight);
}
@@ -111505,7 +113855,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_TEMP_STORE_DIRECTORY: {
if( !zRight ){
- returnSingleText(v, "temp_store_directory", sqlite3_temp_directory);
+ returnSingleText(v, sqlite3_temp_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
@@ -111549,7 +113899,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_DATA_STORE_DIRECTORY: {
if( !zRight ){
- returnSingleText(v, "data_store_directory", sqlite3_data_directory);
+ returnSingleText(v, sqlite3_data_directory);
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
@@ -111588,7 +113938,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3_file *pFile = sqlite3PagerFile(pPager);
sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE,
&proxy_file_path);
- returnSingleText(v, "lock_proxy_file", proxy_file_path);
+ returnSingleText(v, proxy_file_path);
}else{
Pager *pPager = sqlite3BtreePager(pDb->pBt);
sqlite3_file *pFile = sqlite3PagerFile(pPager);
@@ -111620,12 +113970,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
case PragTyp_SYNCHRONOUS: {
if( !zRight ){
- returnSingleInt(v, "synchronous", pDb->safety_level-1);
+ returnSingleInt(v, pDb->safety_level-1);
}else{
if( !db->autoCommit ){
sqlite3ErrorMsg(pParse,
"Safety level may not be changed inside a transaction");
- }else{
+ }else if( iDb!=1 ){
int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
if( iLevel==0 ) iLevel = 1;
pDb->safety_level = iLevel;
@@ -111640,7 +113990,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
#ifndef SQLITE_OMIT_FLAG_PRAGMAS
case PragTyp_FLAG: {
if( zRight==0 ){
- returnSingleInt(v, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
+ setPragmaResultColumnNames(v, pPragma);
+ returnSingleInt(v, (db->flags & pPragma->iArg)!=0 );
}else{
int mask = pPragma->iArg; /* Mask of bits to set or clear. */
if( db->autoCommit==0 ){
@@ -111690,16 +114041,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
Table *pTab;
pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb);
if( pTab ){
- static const char *azCol[] = {
- "cid", "name", "type", "notnull", "dflt_value", "pk"
- };
int i, k;
int nHidden = 0;
Column *pCol;
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
pParse->nMem = 6;
sqlite3CodeVerifySchema(pParse, iDb);
- setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
if( IsHiddenColumn(pCol) ){
@@ -111727,41 +114074,39 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
break;
+#ifdef SQLITE_DEBUG
case PragTyp_STATS: {
- static const char *azCol[] = { "table", "index", "width", "height" };
Index *pIdx;
HashElem *i;
- v = sqlite3GetVdbe(pParse);
- pParse->nMem = 4;
+ pParse->nMem = 5;
sqlite3CodeVerifySchema(pParse, iDb);
- setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
Table *pTab = sqliteHashData(i);
- sqlite3VdbeMultiLoad(v, 1, "ssii",
+ sqlite3VdbeMultiLoad(v, 1, "ssiii",
pTab->zName,
0,
pTab->szTabRow,
- pTab->nRowLogEst);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ pTab->nRowLogEst,
+ pTab->tabFlags);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- sqlite3VdbeMultiLoad(v, 2, "sii",
+ sqlite3VdbeMultiLoad(v, 2, "siii",
pIdx->zName,
pIdx->szIdxRow,
- pIdx->aiRowLogEst[0]);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+ pIdx->aiRowLogEst[0],
+ pIdx->hasStat1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
}
}
}
break;
+#endif
case PragTyp_INDEX_INFO: if( zRight ){
Index *pIdx;
Table *pTab;
pIdx = sqlite3FindIndex(db, zRight, zDb);
if( pIdx ){
- static const char *azCol[] = {
- "seqno", "cid", "name", "desc", "coll", "key"
- };
int i;
int mx;
if( pPragma->iArg ){
@@ -111775,8 +114120,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
pTab = pIdx->pTable;
sqlite3CodeVerifySchema(pParse, iDb);
- assert( pParse->nMem<=ArraySize(azCol) );
- setAllColumnNames(v, pParse->nMem, azCol);
+ assert( pParse->nMem<=pPragma->nPragCName );
for(i=0; i<mx; i++){
i16 cnum = pIdx->aiColumn[i];
sqlite3VdbeMultiLoad(v, 1, "iis", i, cnum,
@@ -111799,13 +114143,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
int i;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
- static const char *azCol[] = {
- "seq", "name", "unique", "origin", "partial"
- };
- v = sqlite3GetVdbe(pParse);
pParse->nMem = 5;
sqlite3CodeVerifySchema(pParse, iDb);
- setAllColumnNames(v, 5, azCol); assert( 5==ArraySize(azCol) );
for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
const char *azOrigin[] = { "c", "u", "pk" };
sqlite3VdbeMultiLoad(v, 1, "isisi",
@@ -111821,16 +114160,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
break;
case PragTyp_DATABASE_LIST: {
- static const char *azCol[] = { "seq", "name", "file" };
int i;
pParse->nMem = 3;
- setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt==0 ) continue;
- assert( db->aDb[i].zName!=0 );
+ assert( db->aDb[i].zDbSName!=0 );
sqlite3VdbeMultiLoad(v, 1, "iss",
i,
- db->aDb[i].zName,
+ db->aDb[i].zDbSName,
sqlite3BtreeGetFilename(db->aDb[i].pBt));
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
@@ -111838,11 +114175,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
break;
case PragTyp_COLLATION_LIST: {
- static const char *azCol[] = { "seq", "name" };
int i = 0;
HashElem *p;
pParse->nMem = 2;
- setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){
CollSeq *pColl = (CollSeq *)sqliteHashData(p);
sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName);
@@ -111858,17 +114193,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
Table *pTab;
pTab = sqlite3FindTable(db, zRight, zDb);
if( pTab ){
- v = sqlite3GetVdbe(pParse);
pFK = pTab->pFKey;
if( pFK ){
- static const char *azCol[] = {
- "id", "seq", "table", "from", "to", "on_update", "on_delete",
- "match"
- };
int i = 0;
pParse->nMem = 8;
sqlite3CodeVerifySchema(pParse, iDb);
- setAllColumnNames(v, 8, azCol); assert( 8==ArraySize(azCol) );
while(pFK){
int j;
for(j=0; j<pFK->nCol; j++){
@@ -111909,14 +114238,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
int addrTop; /* Top of a loop checking foreign keys */
int addrOk; /* Jump here if the key is OK */
int *aiCols; /* child to parent column mapping */
- static const char *azCol[] = { "table", "rowid", "parent", "fkid" };
regResult = pParse->nMem+1;
pParse->nMem += 4;
regKey = ++pParse->nMem;
regRow = ++pParse->nMem;
- v = sqlite3GetVdbe(pParse);
- setAllColumnNames(v, 4, azCol); assert( 4==ArraySize(azCol) );
sqlite3CodeVerifySchema(pParse, iDb);
k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
while( k ){
@@ -112031,9 +114357,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
- /* Pragma "quick_check" is reduced version of
+ /* PRAGMA integrity_check
+ ** PRAGMA integrity_check(N)
+ ** PRAGMA quick_check
+ ** PRAGMA quick_check(N)
+ **
+ ** Verify the integrity of the database.
+ **
+ ** The "quick_check" is reduced version of
** integrity_check designed to detect most database corruption
- ** without most of the overhead of a full integrity-check.
+ ** without the overhead of cross-checking indexes. Quick_check
+ ** is linear time wherease integrity_check is O(NlogN).
*/
case PragTyp_INTEGRITY_CHECK: {
int i, j, addr, mxErr;
@@ -112055,7 +114389,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Initialize the VDBE program */
pParse->nMem = 6;
- setOneColumnName(v, "integrity_check");
/* Set the maximum error count */
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
@@ -112065,7 +114398,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX;
}
}
- sqlite3VdbeAddOp2(v, OP_Integer, mxErr, 1); /* reg[1] holds errors left */
+ sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */
/* Do an integrity check on each database file */
for(i=0; i<db->nDb; i++){
@@ -112080,10 +114413,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( iDb>=0 && i!=iDb ) continue;
sqlite3CodeVerifySchema(pParse, i);
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
/* Do an integrity check of the B-Tree
**
@@ -112119,16 +114448,16 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
- sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
+ sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
+ integrityCheckResultRow(v, 2);
sqlite3VdbeJumpHere(v, addr);
/* Make sure all the indices are constructed correctly.
*/
- for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
+ for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx, *pPk;
Index *pPrior = 0;
@@ -112136,12 +114465,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
int iDataCur, iIdxCur;
int r1 = -1;
- if( pTab->pIndex==0 ) continue;
+ if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */
+ if( pTab->pCheck==0
+ && (pTab->tabFlags & TF_HasNotNull)==0
+ && (pTab->pIndex==0 || isQuick)
+ ){
+ continue; /* No additional checks needed for this table */
+ }
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
- VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeJumpHere(v, addr);
sqlite3ExprCacheClear(pParse);
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
1, 0, &iDataCur, &iIdxCur);
@@ -112156,24 +114487,42 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Verify that all NOT NULL columns really are NOT NULL */
for(j=0; j<pTab->nCol; j++){
char *zErr;
- int jmp2, jmp3;
+ int jmp2;
if( j==pTab->iPKey ) continue;
if( pTab->aCol[j].notNull==0 ) continue;
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pTab->aCol[j].zName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
- jmp3 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
- sqlite3VdbeAddOp0(v, OP_Halt);
+ integrityCheckResultRow(v, 3);
sqlite3VdbeJumpHere(v, jmp2);
- sqlite3VdbeJumpHere(v, jmp3);
+ }
+ /* Verify CHECK constraints */
+ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
+ int addrCkFault = sqlite3VdbeMakeLabel(v);
+ int addrCkOk = sqlite3VdbeMakeLabel(v);
+ ExprList *pCheck = pTab->pCheck;
+ char *zErr;
+ int k;
+ pParse->iSelfTab = iDataCur;
+ sqlite3ExprCachePush(pParse);
+ for(k=pCheck->nExpr-1; k>0; k--){
+ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
+ }
+ sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk,
+ SQLITE_JUMPIFNULL);
+ sqlite3VdbeResolveLabel(v, addrCkFault);
+ zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
+ pTab->zName);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
+ integrityCheckResultRow(v, 3);
+ sqlite3VdbeResolveLabel(v, addrCkOk);
+ sqlite3ExprCachePop(pParse);
}
/* Validate index entries for the current row */
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4, jmp5;
int ckUniq = sqlite3VdbeMakeLabel(v);
if( pPk==pIdx ) continue;
@@ -112184,16 +114533,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Verify that an index entry exists for the current table row */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
pIdx->nColumn); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeLoadString(v, 3, "row ");
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
sqlite3VdbeLoadString(v, 4, " missing from index ");
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
- jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
- sqlite3VdbeAddOp0(v, OP_Halt);
+ jmp4 = integrityCheckResultRow(v, 3);
sqlite3VdbeJumpHere(v, jmp2);
/* For UNIQUE indexes, verify that only one entry exists with the
** current key. The entry is unique if (1) any column is NULL
@@ -112214,7 +114560,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeJumpHere(v, jmp6);
sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
pIdx->nKeyCol); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
sqlite3VdbeGoto(v, jmp5);
sqlite3VdbeResolveLabel(v, uniqOk);
@@ -112225,19 +114570,18 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
- sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
- for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
- if( pPk==pIdx ) continue;
- addr = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
- sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
- sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
- sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
- sqlite3VdbeLoadString(v, 3, pIdx->zName);
- sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
+ if( !isQuick ){
+ sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( pPk==pIdx ) continue;
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
+ addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ sqlite3VdbeLoadString(v, 3, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
+ integrityCheckResultRow(v, 7);
+ sqlite3VdbeJumpHere(v, addr);
+ }
}
#endif /* SQLITE_OMIT_BTREECOUNT */
}
@@ -112246,7 +114590,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
- { OP_If, 1, 4, 0}, /* 1 */
+ { OP_IfNotZero, 1, 4, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0}, /* 3 */
};
@@ -112254,7 +114598,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
if( aOp ){
- aOp[0].p2 = -mxErr;
+ aOp[0].p2 = 1-mxErr;
aOp[2].p4type = P4_STATIC;
aOp[2].p4.z = "ok";
}
@@ -112307,7 +114651,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 );
assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE );
assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE );
- returnSingleText(v, "encoding", encnames[ENC(pParse->db)].zName);
+ returnSingleText(v, encnames[ENC(pParse->db)].zName);
}else{ /* "PRAGMA encoding = XXX" */
/* Only change the value of sqlite.enc if the database handle is not
** initialized. If the main database exists, the new sqlite.enc value
@@ -112370,7 +114714,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
case PragTyp_HEADER_VALUE: {
int iCookie = pPragma->iArg; /* Which cookie to read or write */
sqlite3VdbeUsesBtree(v, iDb);
- if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
+ if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){
/* Write the specified cookie value */
static const VdbeOpList setCookie[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
@@ -112398,8 +114742,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
aOp[0].p1 = iDb;
aOp[1].p1 = iDb;
aOp[1].p3 = iCookie;
- sqlite3VdbeSetNumCols(v, 1);
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
sqlite3VdbeReusable(v);
}
}
@@ -112417,7 +114759,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
int i = 0;
const char *zOpt;
pParse->nMem = 1;
- setOneColumnName(v, "compile_option");
while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){
sqlite3VdbeLoadString(v, 1, zOpt);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
@@ -112434,7 +114775,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
** Checkpoint the database.
*/
case PragTyp_WAL_CHECKPOINT: {
- static const char *azCol[] = { "busy", "log", "checkpointed" };
int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED);
int eMode = SQLITE_CHECKPOINT_PASSIVE;
if( zRight ){
@@ -112446,7 +114786,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
eMode = SQLITE_CHECKPOINT_TRUNCATE;
}
}
- setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
pParse->nMem = 3;
sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
@@ -112465,7 +114804,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( zRight ){
sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight));
}
- returnSingleInt(v, "wal_autocheckpoint",
+ returnSingleInt(v,
db->xWalCallback==sqlite3WalDefaultHook ?
SQLITE_PTR_TO_INT(db->pWalArg) : 0);
}
@@ -112485,6 +114824,118 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
/*
+ ** PRAGMA optimize
+ ** PRAGMA optimize(MASK)
+ ** PRAGMA schema.optimize
+ ** PRAGMA schema.optimize(MASK)
+ **
+ ** Attempt to optimize the database. All schemas are optimized in the first
+ ** two forms, and only the specified schema is optimized in the latter two.
+ **
+ ** The details of optimizations performed by this pragma are expected
+ ** to change and improve over time. Applications should anticipate that
+ ** this pragma will perform new optimizations in future releases.
+ **
+ ** The optional argument is a bitmask of optimizations to perform:
+ **
+ ** 0x0001 Debugging mode. Do not actually perform any optimizations
+ ** but instead return one line of text for each optimization
+ ** that would have been done. Off by default.
+ **
+ ** 0x0002 Run ANALYZE on tables that might benefit. On by default.
+ ** See below for additional information.
+ **
+ ** 0x0004 (Not yet implemented) Record usage and performance
+ ** information from the current session in the
+ ** database file so that it will be available to "optimize"
+ ** pragmas run by future database connections.
+ **
+ ** 0x0008 (Not yet implemented) Create indexes that might have
+ ** been helpful to recent queries
+ **
+ ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all ** of the optimizations listed above except Debug Mode, including new
+ ** optimizations that have not yet been invented. If new optimizations are
+ ** ever added that should be off by default, those off-by-default
+ ** optimizations will have bitmasks of 0x10000 or larger.
+ **
+ ** DETERMINATION OF WHEN TO RUN ANALYZE
+ **
+ ** In the current implementation, a table is analyzed if only if all of
+ ** the following are true:
+ **
+ ** (1) MASK bit 0x02 is set.
+ **
+ ** (2) The query planner used sqlite_stat1-style statistics for one or
+ ** more indexes of the table at some point during the lifetime of
+ ** the current connection.
+ **
+ ** (3) One or more indexes of the table are currently unanalyzed OR
+ ** the number of rows in the table has increased by 25 times or more
+ ** since the last time ANALYZE was run.
+ **
+ ** The rules for when tables are analyzed are likely to change in
+ ** future releases.
+ */
+ case PragTyp_OPTIMIZE: {
+ int iDbLast; /* Loop termination point for the schema loop */
+ int iTabCur; /* Cursor for a table whose size needs checking */
+ HashElem *k; /* Loop over tables of a schema */
+ Schema *pSchema; /* The current schema */
+ Table *pTab; /* A table in the schema */
+ Index *pIdx; /* An index of the table */
+ LogEst szThreshold; /* Size threshold above which reanalysis is needd */
+ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */
+ u32 opMask; /* Mask of operations to perform */
+
+ if( zRight ){
+ opMask = (u32)sqlite3Atoi(zRight);
+ if( (opMask & 0x02)==0 ) break;
+ }else{
+ opMask = 0xfffe;
+ }
+ iTabCur = pParse->nTab++;
+ for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){
+ if( iDb==1 ) continue;
+ sqlite3CodeVerifySchema(pParse, iDb);
+ pSchema = db->aDb[iDb].pSchema;
+ for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
+ pTab = (Table*)sqliteHashData(k);
+
+ /* If table pTab has not been used in a way that would benefit from
+ ** having analysis statistics during the current session, then skip it.
+ ** This also has the effect of skipping virtual tables and views */
+ if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue;
+
+ /* Reanalyze if the table is 25 times larger than the last analysis */
+ szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 );
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( !pIdx->hasStat1 ){
+ szThreshold = 0; /* Always analyze if any index lacks statistics */
+ break;
+ }
+ }
+ if( szThreshold ){
+ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
+ sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur,
+ sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold);
+ VdbeCoverage(v);
+ }
+ zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"",
+ db->aDb[iDb].zDbSName, pTab->zName);
+ if( opMask & 0x01 ){
+ int r1 = sqlite3GetTempReg(pParse);
+ sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1);
+ }else{
+ sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC);
+ }
+ }
+ }
+ sqlite3VdbeAddOp0(v, OP_Expire);
+ break;
+ }
+
+ /*
** PRAGMA busy_timeout
** PRAGMA busy_timeout = N
**
@@ -112498,7 +114949,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( zRight ){
sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
}
- returnSingleInt(v, "timeout", db->busyTimeout);
+ returnSingleInt(v, db->busyTimeout);
break;
}
@@ -112518,7 +114969,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){
sqlite3_soft_heap_limit64(N);
}
- returnSingleInt(v, "soft_heap_limit", sqlite3_soft_heap_limit64(-1));
+ returnSingleInt(v, sqlite3_soft_heap_limit64(-1));
break;
}
@@ -112537,8 +114988,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
){
sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
}
- returnSingleInt(v, "threads",
- sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
+ returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
break;
}
@@ -112550,23 +115000,21 @@ SQLITE_PRIVATE void sqlite3Pragma(
static const char *const azLockName[] = {
"unlocked", "shared", "reserved", "pending", "exclusive"
};
- static const char *azCol[] = { "database", "status" };
int i;
- setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
pParse->nMem = 2;
for(i=0; i<db->nDb; i++){
Btree *pBt;
const char *zState = "unknown";
int j;
- if( db->aDb[i].zName==0 ) continue;
+ if( db->aDb[i].zDbSName==0 ) continue;
pBt = db->aDb[i].pBt;
if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
zState = "closed";
- }else if( sqlite3_file_control(db, i ? db->aDb[i].zName : 0,
+ }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0,
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
zState = azLockName[j];
}
- sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zName, zState);
+ sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
break;
@@ -112618,10 +115066,325 @@ SQLITE_PRIVATE void sqlite3Pragma(
} /* End of the PRAGMA switch */
+ /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only
+ ** purpose is to execute assert() statements to verify that if the
+ ** PragFlg_NoColumns1 flag is set and the caller specified an argument
+ ** to the PRAGMA, the implementation has not added any OP_ResultRow
+ ** instructions to the VM. */
+ if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){
+ sqlite3VdbeVerifyNoResultRow(v);
+ }
+
pragma_out:
sqlite3DbFree(db, zLeft);
sqlite3DbFree(db, zRight);
}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+/*****************************************************************************
+** Implementation of an eponymous virtual table that runs a pragma.
+**
+*/
+typedef struct PragmaVtab PragmaVtab;
+typedef struct PragmaVtabCursor PragmaVtabCursor;
+struct PragmaVtab {
+ sqlite3_vtab base; /* Base class. Must be first */
+ sqlite3 *db; /* The database connection to which it belongs */
+ const PragmaName *pName; /* Name of the pragma */
+ u8 nHidden; /* Number of hidden columns */
+ u8 iHidden; /* Index of the first hidden column */
+};
+struct PragmaVtabCursor {
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
+ sqlite3_stmt *pPragma; /* The pragma statement to run */
+ sqlite_int64 iRowid; /* Current rowid */
+ char *azArg[2]; /* Value of the argument and schema */
+};
+
+/*
+** Pragma virtual table module xConnect method.
+*/
+static int pragmaVtabConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ const PragmaName *pPragma = (const PragmaName*)pAux;
+ PragmaVtab *pTab = 0;
+ int rc;
+ int i, j;
+ char cSep = '(';
+ StrAccum acc;
+ char zBuf[200];
+
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+ sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+ sqlite3StrAccumAppendAll(&acc, "CREATE TABLE x");
+ for(i=0, j=pPragma->iPragCName; i<pPragma->nPragCName; i++, j++){
+ sqlite3XPrintf(&acc, "%c\"%s\"", cSep, pragCName[j]);
+ cSep = ',';
+ }
+ if( i==0 ){
+ sqlite3XPrintf(&acc, "(\"%s\"", pPragma->zName);
+ cSep = ',';
+ i++;
+ }
+ j = 0;
+ if( pPragma->mPragFlg & PragFlg_Result1 ){
+ sqlite3StrAccumAppendAll(&acc, ",arg HIDDEN");
+ j++;
+ }
+ if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){
+ sqlite3StrAccumAppendAll(&acc, ",schema HIDDEN");
+ j++;
+ }
+ sqlite3StrAccumAppend(&acc, ")", 1);
+ sqlite3StrAccumFinish(&acc);
+ assert( strlen(zBuf) < sizeof(zBuf)-1 );
+ rc = sqlite3_declare_vtab(db, zBuf);
+ if( rc==SQLITE_OK ){
+ pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab));
+ if( pTab==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ memset(pTab, 0, sizeof(PragmaVtab));
+ pTab->pName = pPragma;
+ pTab->db = db;
+ pTab->iHidden = i;
+ pTab->nHidden = j;
+ }
+ }else{
+ *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+ }
+
+ *ppVtab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** Pragma virtual table module xDisconnect method.
+*/
+static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){
+ PragmaVtab *pTab = (PragmaVtab*)pVtab;
+ sqlite3_free(pTab);
+ return SQLITE_OK;
+}
+
+/* Figure out the best index to use to search a pragma virtual table.
+**
+** There are not really any index choices. But we want to encourage the
+** query planner to give == constraints on as many hidden parameters as
+** possible, and especially on the first hidden parameter. So return a
+** high cost if hidden parameters are unconstrained.
+*/
+static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ PragmaVtab *pTab = (PragmaVtab*)tab;
+ const struct sqlite3_index_constraint *pConstraint;
+ int i, j;
+ int seen[2];
+
+ pIdxInfo->estimatedCost = (double)1;
+ if( pTab->nHidden==0 ){ return SQLITE_OK; }
+ pConstraint = pIdxInfo->aConstraint;
+ seen[0] = 0;
+ seen[1] = 0;
+ for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+ if( pConstraint->usable==0 ) continue;
+ if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( pConstraint->iColumn < pTab->iHidden ) continue;
+ j = pConstraint->iColumn - pTab->iHidden;
+ assert( j < 2 );
+ seen[j] = i+1;
+ }
+ if( seen[0]==0 ){
+ pIdxInfo->estimatedCost = (double)2147483647;
+ pIdxInfo->estimatedRows = 2147483647;
+ return SQLITE_OK;
+ }
+ j = seen[0]-1;
+ pIdxInfo->aConstraintUsage[j].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[j].omit = 1;
+ if( seen[1]==0 ) return SQLITE_OK;
+ pIdxInfo->estimatedCost = (double)20;
+ pIdxInfo->estimatedRows = 20;
+ j = seen[1]-1;
+ pIdxInfo->aConstraintUsage[j].argvIndex = 2;
+ pIdxInfo->aConstraintUsage[j].omit = 1;
+ return SQLITE_OK;
+}
+
+/* Create a new cursor for the pragma virtual table */
+static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
+ PragmaVtabCursor *pCsr;
+ pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr));
+ if( pCsr==0 ) return SQLITE_NOMEM;
+ memset(pCsr, 0, sizeof(PragmaVtabCursor));
+ pCsr->base.pVtab = pVtab;
+ *ppCursor = &pCsr->base;
+ return SQLITE_OK;
+}
+
+/* Clear all content from pragma virtual table cursor. */
+static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){
+ int i;
+ sqlite3_finalize(pCsr->pPragma);
+ pCsr->pPragma = 0;
+ for(i=0; i<ArraySize(pCsr->azArg); i++){
+ sqlite3_free(pCsr->azArg[i]);
+ pCsr->azArg[i] = 0;
+ }
+}
+
+/* Close a pragma virtual table cursor */
+static int pragmaVtabClose(sqlite3_vtab_cursor *cur){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur;
+ pragmaVtabCursorClear(pCsr);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/* Advance the pragma virtual table cursor to the next row */
+static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ int rc = SQLITE_OK;
+
+ /* Increment the xRowid value */
+ pCsr->iRowid++;
+ assert( pCsr->pPragma );
+ if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){
+ rc = sqlite3_finalize(pCsr->pPragma);
+ pCsr->pPragma = 0;
+ pragmaVtabCursorClear(pCsr);
+ }
+ return rc;
+}
+
+/*
+** Pragma virtual table module xFilter method.
+*/
+static int pragmaVtabFilter(
+ sqlite3_vtab_cursor *pVtabCursor,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
+ int rc;
+ int i, j;
+ StrAccum acc;
+ char *zSql;
+
+ UNUSED_PARAMETER(idxNum);
+ UNUSED_PARAMETER(idxStr);
+ pragmaVtabCursorClear(pCsr);
+ j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1;
+ for(i=0; i<argc; i++, j++){
+ assert( j<ArraySize(pCsr->azArg) );
+ pCsr->azArg[j] = sqlite3_mprintf("%s", sqlite3_value_text(argv[i]));
+ if( pCsr->azArg[j]==0 ){
+ return SQLITE_NOMEM;
+ }
+ }
+ sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]);
+ sqlite3StrAccumAppendAll(&acc, "PRAGMA ");
+ if( pCsr->azArg[1] ){
+ sqlite3XPrintf(&acc, "%Q.", pCsr->azArg[1]);
+ }
+ sqlite3StrAccumAppendAll(&acc, pTab->pName->zName);
+ if( pCsr->azArg[0] ){
+ sqlite3XPrintf(&acc, "=%Q", pCsr->azArg[0]);
+ }
+ zSql = sqlite3StrAccumFinish(&acc);
+ if( zSql==0 ) return SQLITE_NOMEM;
+ rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0);
+ sqlite3_free(zSql);
+ if( rc!=SQLITE_OK ){
+ pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
+ return rc;
+ }
+ return pragmaVtabNext(pVtabCursor);
+}
+
+/*
+** Pragma virtual table module xEof method.
+*/
+static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ return (pCsr->pPragma==0);
+}
+
+/* The xColumn method simply returns the corresponding column from
+** the PRAGMA.
+*/
+static int pragmaVtabColumn(
+ sqlite3_vtab_cursor *pVtabCursor,
+ sqlite3_context *ctx,
+ int i
+){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab);
+ if( i<pTab->iHidden ){
+ sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i));
+ }else{
+ sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT);
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Pragma virtual table module xRowid method.
+*/
+static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){
+ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor;
+ *p = pCsr->iRowid;
+ return SQLITE_OK;
+}
+
+/* The pragma virtual table object */
+static const sqlite3_module pragmaVtabModule = {
+ 0, /* iVersion */
+ 0, /* xCreate - create a table */
+ pragmaVtabConnect, /* xConnect - connect to an existing table */
+ pragmaVtabBestIndex, /* xBestIndex - Determine search strategy */
+ pragmaVtabDisconnect, /* xDisconnect - Disconnect from a table */
+ 0, /* xDestroy - Drop a table */
+ pragmaVtabOpen, /* xOpen - open a cursor */
+ pragmaVtabClose, /* xClose - close a cursor */
+ pragmaVtabFilter, /* xFilter - configure scan constraints */
+ pragmaVtabNext, /* xNext - advance a cursor */
+ pragmaVtabEof, /* xEof */
+ pragmaVtabColumn, /* xColumn - read data */
+ pragmaVtabRowid, /* xRowid - read data */
+ 0, /* xUpdate - write data */
+ 0, /* xBegin - begin transaction */
+ 0, /* xSync - sync transaction */
+ 0, /* xCommit - commit transaction */
+ 0, /* xRollback - rollback transaction */
+ 0, /* xFindFunction - function overloading */
+ 0, /* xRename - rename the table */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0 /* xRollbackTo */
+};
+
+/*
+** Check to see if zTabName is really the name of a pragma. If it is,
+** then register an eponymous virtual table for that pragma and return
+** a pointer to the Module object for the new virtual table.
+*/
+SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){
+ const PragmaName *pName;
+ assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 );
+ pName = pragmaLocate(zName+7);
+ if( pName==0 ) return 0;
+ if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0;
+ assert( sqlite3HashFind(&db->aModule, zName)==0 );
+ return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0);
+}
+
+#endif /* SQLITE_OMIT_VIRTUALTABLE */
#endif /* SQLITE_OMIT_PRAGMA */
@@ -112702,6 +115465,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
** structures that describe the table, index, or view.
*/
int rc;
+ u8 saved_iDb = db->init.iDb;
sqlite3_stmt *pStmt;
TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
@@ -112712,7 +115476,8 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
- db->init.iDb = 0;
+ db->init.iDb = saved_iDb;
+ assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
assert( iDb==1 );
@@ -112736,7 +115501,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
** to do here is record the root page number for that index.
*/
Index *pIndex;
- pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
+ pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
if( pIndex==0 ){
/* This can occur if there exists an index on a TEMP table which
** has the same name as another index on a permanent index. Since
@@ -112915,7 +115680,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
char *zSql;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
- db->aDb[iDb].zName, zMasterName);
+ db->aDb[iDb].zDbSName, zMasterName);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
sqlite3_xauth xAuth;
@@ -113145,18 +115910,14 @@ static int sqlite3Prepare(
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
- Parse *pParse; /* Parsing context */
char *zErrMsg = 0; /* Error message */
int rc = SQLITE_OK; /* Result code */
int i; /* Loop counter */
+ Parse sParse; /* Parsing context */
- /* Allocate the parsing context */
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
- if( pParse==0 ){
- rc = SQLITE_NOMEM_BKPT;
- goto end_prepare;
- }
- pParse->pReprepare = pReprepare;
+ memset(&sParse, 0, PARSE_HDR_SZ);
+ memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ);
+ sParse.pReprepare = pReprepare;
assert( ppStmt && *ppStmt==0 );
/* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
assert( sqlite3_mutex_held(db->mutex) );
@@ -113190,7 +115951,7 @@ static int sqlite3Prepare(
assert( sqlite3BtreeHoldsMutex(pBt) );
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
- const char *zDb = db->aDb[i].zName;
+ const char *zDb = db->aDb[i].zDbSName;
sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
testcase( db->flags & SQLITE_ReadUncommitted );
goto end_prepare;
@@ -113200,8 +115961,7 @@ static int sqlite3Prepare(
sqlite3VtabUnlockList(db);
- pParse->db = db;
- pParse->nQueryLoop = 0; /* Logarithmic, so 0 really means 1 */
+ sParse.db = db;
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
char *zSqlCopy;
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -113214,61 +115974,61 @@ static int sqlite3Prepare(
}
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
if( zSqlCopy ){
- sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
- pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
+ sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
+ sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
sqlite3DbFree(db, zSqlCopy);
}else{
- pParse->zTail = &zSql[nBytes];
+ sParse.zTail = &zSql[nBytes];
}
}else{
- sqlite3RunParser(pParse, zSql, &zErrMsg);
+ sqlite3RunParser(&sParse, zSql, &zErrMsg);
}
- assert( 0==pParse->nQueryLoop );
+ assert( 0==sParse.nQueryLoop );
- if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
- if( pParse->checkSchema ){
- schemaIsValid(pParse);
+ if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
+ if( sParse.checkSchema ){
+ schemaIsValid(&sParse);
}
if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM_BKPT;
+ sParse.rc = SQLITE_NOMEM_BKPT;
}
if( pzTail ){
- *pzTail = pParse->zTail;
+ *pzTail = sParse.zTail;
}
- rc = pParse->rc;
+ rc = sParse.rc;
#ifndef SQLITE_OMIT_EXPLAIN
- if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
+ if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
static const char * const azColName[] = {
"addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
"selectid", "order", "from", "detail"
};
int iFirst, mx;
- if( pParse->explain==2 ){
- sqlite3VdbeSetNumCols(pParse->pVdbe, 4);
+ if( sParse.explain==2 ){
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 4);
iFirst = 8;
mx = 12;
}else{
- sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
+ sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
iFirst = 0;
mx = 8;
}
for(i=iFirst; i<mx; i++){
- sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
+ sqlite3VdbeSetColName(sParse.pVdbe, i-iFirst, COLNAME_NAME,
azColName[i], SQLITE_STATIC);
}
}
#endif
if( db->init.busy==0 ){
- Vdbe *pVdbe = pParse->pVdbe;
- sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
+ Vdbe *pVdbe = sParse.pVdbe;
+ sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
}
- if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
- sqlite3VdbeFinalize(pParse->pVdbe);
+ if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
+ sqlite3VdbeFinalize(sParse.pVdbe);
assert(!(*ppStmt));
}else{
- *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
+ *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
}
if( zErrMsg ){
@@ -113279,16 +116039,15 @@ static int sqlite3Prepare(
}
/* Delete any TriggerPrg structures allocated while parsing this statement. */
- while( pParse->pTriggerPrg ){
- TriggerPrg *pT = pParse->pTriggerPrg;
- pParse->pTriggerPrg = pT->pNext;
+ while( sParse.pTriggerPrg ){
+ TriggerPrg *pT = sParse.pTriggerPrg;
+ sParse.pTriggerPrg = pT->pNext;
sqlite3DbFree(db, pT);
}
end_prepare:
- sqlite3ParserReset(pParse);
- sqlite3StackFree(db, pParse);
+ sqlite3ParserReset(&sParse);
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
return rc;
@@ -113369,7 +116128,7 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
+SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -113381,7 +116140,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -113457,7 +116216,7 @@ static int sqlite3Prepare16(
** and the statement is automatically recompiled if an schema change
** occurs.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
+SQLITE_API int sqlite3_prepare16(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -113469,7 +116228,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-16 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
@@ -113576,7 +116335,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){
pDest->eDest = (u8)eDest;
pDest->iSDParm = iParm;
- pDest->affSdst = 0;
+ pDest->zAffSdst = 0;
pDest->iSdst = 0;
pDest->nSdst = 0;
}
@@ -113822,7 +116581,7 @@ static void addWhereTerm(
pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
- pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2, 0);
+ pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
if( pEq && isOuterJoin ){
ExprSetProperty(pEq, EP_FromJoin);
assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
@@ -114009,7 +116768,7 @@ static void pushOntoSorter(
int iLimit; /* LIMIT counter */
assert( bSeq==0 || bSeq==1 );
- assert( nData==1 || regData==regOrigData );
+ assert( nData==1 || regData==regOrigData || regOrigData==0 );
if( nPrefixReg ){
assert( nPrefixReg==nExpr+bSeq );
regBase = regData - nExpr - bSeq;
@@ -114021,11 +116780,11 @@ static void pushOntoSorter(
iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
pSort->labelDone = sqlite3VdbeMakeLabel(v);
sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
- SQLITE_ECEL_DUP|SQLITE_ECEL_REF);
+ SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
if( bSeq ){
sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
}
- if( nPrefixReg==0 ){
+ if( nPrefixReg==0 && nData>0 ){
sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
@@ -114075,7 +116834,8 @@ static void pushOntoSorter(
}else{
op = OP_IdxInsert;
}
- sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
+ sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord,
+ regBase+nOBSat, nBase-nOBSat);
if( iLimit ){
int addr;
int r1 = 0;
@@ -114083,7 +116843,7 @@ static void pushOntoSorter(
** register is initialized with value of LIMIT+OFFSET.) After the sorter
** fills up, delete the least entry in the sorter after each insert.
** Thus we never hold more than the LIMIT+OFFSET rows in memory at once */
- addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v);
+ addr = sqlite3VdbeAddOp1(v, OP_IfNotZero, iLimit); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
if( pSort->bOrderedInnerLoop ){
r1 = ++pParse->nMem;
@@ -114143,34 +116903,11 @@ static void codeDistinct(
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N);
+ sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, r1);
}
-#ifndef SQLITE_OMIT_SUBQUERY
-/*
-** Generate an error message when a SELECT is used within a subexpression
-** (example: "a IN (SELECT * FROM table)") but it has more than 1 result
-** column. We do this in a subroutine because the error used to occur
-** in multiple places. (The error only occurs in one place now, but we
-** retain the subroutine to minimize code disruption.)
-*/
-static int checkForMultiColumnSelectError(
- Parse *pParse, /* Parse context. */
- SelectDest *pDest, /* Destination of SELECT results */
- int nExpr /* Number of result columns returned by SELECT */
-){
- int eDest = pDest->eDest;
- if( nExpr>1 && (eDest==SRT_Mem || eDest==SRT_Set) ){
- sqlite3ErrorMsg(pParse, "only a single result allowed for "
- "a SELECT that is part of an expression");
- return 1;
- }else{
- return 0;
- }
-}
-#endif
-
/*
** This routine generates the code for the inside of the inner loop
** of a SELECT.
@@ -114178,7 +116915,7 @@ static int checkForMultiColumnSelectError(
** If srcTab is negative, then the pEList expressions
** are evaluated in order to get the data for this row. If srcTab is
** zero or more, then data is pulled from srcTab and pEList is used only
-** to get number columns and the datatype for each column.
+** to get the number of columns and the collation sequence for each column.
*/
static void selectInnerLoop(
Parse *pParse, /* The parser context */
@@ -114193,13 +116930,20 @@ static void selectInnerLoop(
){
Vdbe *v = pParse->pVdbe;
int i;
- int hasDistinct; /* True if the DISTINCT keyword is present */
- int regResult; /* Start of memory holding result set */
+ int hasDistinct; /* True if the DISTINCT keyword is present */
int eDest = pDest->eDest; /* How to dispose of results */
int iParm = pDest->iSDParm; /* First argument to disposal method */
int nResultCol; /* Number of result columns */
int nPrefixReg = 0; /* Number of extra registers before regResult */
+ /* Usually, regResult is the first cell in an array of memory cells
+ ** containing the current result row. In this case regOrig is set to the
+ ** same value. However, if the results are being sent to the sorter, the
+ ** values for any expressions that are also part of the sort-key are omitted
+ ** from this array. In this case regOrig is set to zero. */
+ int regResult; /* Start of memory holding current results */
+ int regOrig; /* Start of memory holding full result (or 0) */
+
assert( v );
assert( pEList!=0 );
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
@@ -114230,7 +116974,7 @@ static void selectInnerLoop(
pParse->nMem += nResultCol;
}
pDest->nSdst = nResultCol;
- regResult = pDest->iSdst;
+ regOrig = regResult = pDest->iSdst;
if( srcTab>=0 ){
for(i=0; i<nResultCol; i++){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
@@ -114246,7 +116990,25 @@ static void selectInnerLoop(
}else{
ecelFlags = 0;
}
- sqlite3ExprCodeExprList(pParse, pEList, regResult, 0, ecelFlags);
+ if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
+ /* For each expression in pEList that is a copy of an expression in
+ ** the ORDER BY clause (pSort->pOrderBy), set the associated
+ ** iOrderByCol value to one more than the index of the ORDER BY
+ ** expression within the sort-key that pushOntoSorter() will generate.
+ ** This allows the pEList field to be omitted from the sorted record,
+ ** saving space and CPU cycles. */
+ ecelFlags |= (SQLITE_ECEL_OMITREF|SQLITE_ECEL_REF);
+ for(i=pSort->nOBSat; i<pSort->pOrderBy->nExpr; i++){
+ int j;
+ if( (j = pSort->pOrderBy->a[i].u.x.iOrderByCol)>0 ){
+ pEList->a[j-1].u.x.iOrderByCol = i+1-pSort->nOBSat;
+ }
+ }
+ regOrig = 0;
+ assert( eDest==SRT_Set || eDest==SRT_Mem
+ || eDest==SRT_Coroutine || eDest==SRT_Output );
+ }
+ nResultCol = sqlite3ExprCodeExprList(pParse,pEList,regResult,0,ecelFlags);
}
/* If the DISTINCT keyword was present on the SELECT statement
@@ -114320,7 +117082,7 @@ static void selectInnerLoop(
int r1;
r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
sqlite3ReleaseTempReg(pParse, r1);
break;
}
@@ -114357,7 +117119,7 @@ static void selectInnerLoop(
int addr = sqlite3VdbeCurrentAddr(v) + 4;
sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0);
VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol);
assert( pSort==0 );
}
#endif
@@ -114380,20 +117142,20 @@ static void selectInnerLoop(
** item into the set table with bogus data.
*/
case SRT_Set: {
- assert( nResultCol==1 );
- pDest->affSdst =
- sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
if( pSort ){
/* At first glance you would think we could optimize out the
** ORDER BY in this case since the order of entries in the set
** does not matter. But there might be a LIMIT clause, in which
** case the order does matter */
- pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg);
+ pushOntoSorter(
+ pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
}else{
int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
- sqlite3ExprCacheAffinityChange(pParse, regResult, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
+ assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol );
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol,
+ r1, pDest->zAffSdst, nResultCol);
+ sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol);
sqlite3ReleaseTempReg(pParse, r1);
}
break;
@@ -114408,14 +117170,16 @@ static void selectInnerLoop(
}
/* If this is a scalar select that is part of an expression, then
- ** store the results in the appropriate memory cell and break out
- ** of the scan loop.
+ ** store the results in the appropriate memory cell or array of
+ ** memory cells and break out of the scan loop.
*/
case SRT_Mem: {
- assert( nResultCol==1 );
if( pSort ){
- pushOntoSorter(pParse, pSort, p, regResult, regResult, 1, nPrefixReg);
+ assert( nResultCol<=pDest->nSdst );
+ pushOntoSorter(
+ pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg);
}else{
+ assert( nResultCol==pDest->nSdst );
assert( regResult==iParm );
/* The LIMIT clause will jump out of the loop for us */
}
@@ -114428,7 +117192,7 @@ static void selectInnerLoop(
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pSort ){
- pushOntoSorter(pParse, pSort, p, regResult, regResult, nResultCol,
+ pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol,
nPrefixReg);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
@@ -114478,7 +117242,7 @@ static void selectInnerLoop(
}
sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey);
sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2);
if( addrTest ) sqlite3VdbeJumpHere(v, addrTest);
sqlite3ReleaseTempReg(pParse, r1);
sqlite3ReleaseTempRange(pParse, r2, nKey+2);
@@ -114516,7 +117280,7 @@ static void selectInnerLoop(
*/
SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
int nExtra = (N+X)*(sizeof(CollSeq*)+1);
- KeyInfo *p = sqlite3DbMallocRaw(db, sizeof(KeyInfo) + nExtra);
+ KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
if( p ){
p->aSortOrder = (u8*)&p->aColl[N+X];
p->nField = (u16)N;
@@ -114713,14 +117477,13 @@ static void generateSortTail(
int iParm = pDest->iSDParm;
int regRow;
int regRowid;
+ int iCol;
int nKey;
int iSortTab; /* Sorter cursor to read from */
int nSortData; /* Trailing values to read from sorter */
int i;
int bSeq; /* True if sorter record includes seq. no. */
-#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
struct ExprList_item *aOutEx = p->pEList->a;
-#endif
assert( addrBreak<0 );
if( pSort->labelBkOut ){
@@ -114729,21 +117492,21 @@ static void generateSortTail(
sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
}
iTab = pSort->iECursor;
- if( eDest==SRT_Output || eDest==SRT_Coroutine ){
+ if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){
regRowid = 0;
regRow = pDest->iSdst;
nSortData = nColumn;
}else{
regRowid = sqlite3GetTempReg(pParse);
- regRow = sqlite3GetTempReg(pParse);
- nSortData = 1;
+ regRow = sqlite3GetTempRange(pParse, nColumn);
+ nSortData = nColumn;
}
nKey = pOrderBy->nExpr - pSort->nOBSat;
if( pSort->sortFlags & SORTFLAG_UseSorter ){
int regSortOut = ++pParse->nMem;
iSortTab = pParse->nTab++;
if( pSort->labelBkOut ){
- addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
}
sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
@@ -114758,11 +117521,18 @@ static void generateSortTail(
iSortTab = iTab;
bSeq = 1;
}
- for(i=0; i<nSortData; i++){
- sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
+ for(i=0, iCol=nKey+bSeq; i<nSortData; i++){
+ int iRead;
+ if( aOutEx[i].u.x.iOrderByCol ){
+ iRead = aOutEx[i].u.x.iOrderByCol-1;
+ }else{
+ iRead = iCol++;
+ }
+ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i);
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
}
switch( eDest ){
+ case SRT_Table:
case SRT_EphemTab: {
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
@@ -114771,16 +117541,14 @@ static void generateSortTail(
}
#ifndef SQLITE_OMIT_SUBQUERY
case SRT_Set: {
- assert( nColumn==1 );
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid,
- &pDest->affSdst, 1);
- sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
+ assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) );
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid,
+ pDest->zAffSdst, nColumn);
+ sqlite3ExprCacheAffinityChange(pParse, regRow, nColumn);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn);
break;
}
case SRT_Mem: {
- assert( nColumn==1 );
- sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
/* The LIMIT clause will terminate the loop for us */
break;
}
@@ -114799,7 +117567,11 @@ static void generateSortTail(
}
}
if( regRowid ){
- sqlite3ReleaseTempReg(pParse, regRow);
+ if( eDest==SRT_Set ){
+ sqlite3ReleaseTempRange(pParse, regRow, nColumn);
+ }else{
+ sqlite3ReleaseTempReg(pParse, regRow);
+ }
sqlite3ReleaseTempReg(pParse, regRowid);
}
/* The bottom of the loop
@@ -114946,7 +117718,7 @@ static const char *columnTypeImpl(
zOrigTab = pTab->zName;
if( pNC->pParse ){
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
- zOrigDb = pNC->pParse->db->aDb[iDb].zName;
+ zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
}
#else
if( iCol<0 ){
@@ -115282,7 +118054,7 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
/* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
** is disabled */
assert( db->lookaside.bDisable );
- pTab->nRef = 1;
+ pTab->nTabRef = 1;
pTab->zName = 0;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
@@ -115301,7 +118073,7 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
*/
static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
- if( v ) sqlite3VdbeAddOp0(v, OP_Init);
+ if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1);
if( pParse->pToplevel==0
&& OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
){
@@ -115513,6 +118285,7 @@ static void generateWithRecursiveQuery(
/* Process the LIMIT and OFFSET clauses, if they exist */
addrBreak = sqlite3VdbeMakeLabel(v);
+ p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, addrBreak);
pLimit = p->pLimit;
pOffset = p->pOffset;
@@ -115982,7 +118755,7 @@ static int multiSelect(
computeLimitRegisters(pParse, p, iBreak);
sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
r1 = sqlite3GetTempReg(pParse);
- iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
+ iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, r1);
selectInnerLoop(pParse, p, p->pEList, tab1,
@@ -116140,19 +118913,17 @@ static int generateOutputSubroutine(
}
#ifndef SQLITE_OMIT_SUBQUERY
- /* If we are creating a set for an "expr IN (SELECT ...)" construct,
- ** then there should be a single item on the stack. Write this
- ** item into the set table with bogus data.
+ /* If we are creating a set for an "expr IN (SELECT ...)".
*/
case SRT_Set: {
int r1;
- assert( pIn->nSdst==1 || pParse->nErr>0 );
- pDest->affSdst =
- sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
+ testcase( pIn->nSdst>1 );
r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &pDest->affSdst,1);
- sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst,
+ r1, pDest->zAffSdst, pIn->nSdst);
+ sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1,
+ pIn->iSdst, pIn->nSdst);
sqlite3ReleaseTempReg(pParse, r1);
break;
}
@@ -116611,8 +119382,8 @@ static int multiSelectOrderBy(
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/* Forward Declarations */
-static void substExprList(sqlite3*, ExprList*, int, ExprList*);
-static void substSelect(sqlite3*, Select *, int, ExprList*, int);
+static void substExprList(Parse*, ExprList*, int, ExprList*);
+static void substSelect(Parse*, Select *, int, ExprList*, int);
/*
** Scan through the expression pExpr. Replace every reference to
@@ -116628,36 +119399,46 @@ static void substSelect(sqlite3*, Select *, int, ExprList*, int);
** of the subquery rather the result set of the subquery.
*/
static Expr *substExpr(
- sqlite3 *db, /* Report malloc errors to this connection */
+ Parse *pParse, /* Report errors here */
Expr *pExpr, /* Expr in which substitution occurs */
int iTable, /* Table to be substituted */
ExprList *pEList /* Substitute expressions */
){
+ sqlite3 *db = pParse->db;
if( pExpr==0 ) return 0;
if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
}else{
Expr *pNew;
+ Expr *pCopy = pEList->a[pExpr->iColumn].pExpr;
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
- sqlite3ExprDelete(db, pExpr);
- pExpr = pNew;
+ if( sqlite3ExprIsVector(pCopy) ){
+ sqlite3VectorErrorMsg(pParse, pCopy);
+ }else{
+ pNew = sqlite3ExprDup(db, pCopy, 0);
+ if( pNew && (pExpr->flags & EP_FromJoin) ){
+ pNew->iRightJoinTable = pExpr->iRightJoinTable;
+ pNew->flags |= EP_FromJoin;
+ }
+ sqlite3ExprDelete(db, pExpr);
+ pExpr = pNew;
+ }
}
}else{
- pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
- pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
+ pExpr->pLeft = substExpr(pParse, pExpr->pLeft, iTable, pEList);
+ pExpr->pRight = substExpr(pParse, pExpr->pRight, iTable, pEList);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
- substSelect(db, pExpr->x.pSelect, iTable, pEList, 1);
+ substSelect(pParse, pExpr->x.pSelect, iTable, pEList, 1);
}else{
- substExprList(db, pExpr->x.pList, iTable, pEList);
+ substExprList(pParse, pExpr->x.pList, iTable, pEList);
}
}
return pExpr;
}
static void substExprList(
- sqlite3 *db, /* Report malloc errors here */
+ Parse *pParse, /* Report errors here */
ExprList *pList, /* List to scan and in which to make substitutes */
int iTable, /* Table to be substituted */
ExprList *pEList /* Substitute values */
@@ -116665,11 +119446,11 @@ static void substExprList(
int i;
if( pList==0 ) return;
for(i=0; i<pList->nExpr; i++){
- pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
+ pList->a[i].pExpr = substExpr(pParse, pList->a[i].pExpr, iTable, pEList);
}
}
static void substSelect(
- sqlite3 *db, /* Report malloc errors here */
+ Parse *pParse, /* Report errors here */
Select *p, /* SELECT statement in which to make substitutions */
int iTable, /* Table to be replaced */
ExprList *pEList, /* Substitute values */
@@ -116680,17 +119461,17 @@ static void substSelect(
int i;
if( !p ) return;
do{
- substExprList(db, p->pEList, iTable, pEList);
- substExprList(db, p->pGroupBy, iTable, pEList);
- substExprList(db, p->pOrderBy, iTable, pEList);
- p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
- p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
+ substExprList(pParse, p->pEList, iTable, pEList);
+ substExprList(pParse, p->pGroupBy, iTable, pEList);
+ substExprList(pParse, p->pOrderBy, iTable, pEList);
+ p->pHaving = substExpr(pParse, p->pHaving, iTable, pEList);
+ p->pWhere = substExpr(pParse, p->pWhere, iTable, pEList);
pSrc = p->pSrc;
assert( pSrc!=0 );
for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- substSelect(db, pItem->pSelect, iTable, pEList, 1);
+ substSelect(pParse, pItem->pSelect, iTable, pEList, 1);
if( pItem->fg.isTabFunc ){
- substExprList(db, pItem->u1.pFuncArg, iTable, pEList);
+ substExprList(pParse, pItem->u1.pFuncArg, iTable, pEList);
}
}
}while( doPrior && (p = p->pPrior)!=0 );
@@ -117087,12 +119868,12 @@ static int flattenSubquery(
*/
if( ALWAYS(pSubitem->pTab!=0) ){
Table *pTabToDel = pSubitem->pTab;
- if( pTabToDel->nRef==1 ){
+ if( pTabToDel->nTabRef==1 ){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
pTabToDel->pNextZombie = pToplevel->pZombieTab;
pToplevel->pZombieTab = pTabToDel;
}else{
- pTabToDel->nRef--;
+ pTabToDel->nTabRef--;
}
pSubitem->pTab = 0;
}
@@ -117207,14 +119988,17 @@ static int flattenSubquery(
assert( pParent->pHaving==0 );
pParent->pHaving = pParent->pWhere;
pParent->pWhere = pWhere;
- pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
- sqlite3ExprDup(db, pSub->pHaving, 0));
+ pParent->pHaving = sqlite3ExprAnd(db,
+ sqlite3ExprDup(db, pSub->pHaving, 0), pParent->pHaving
+ );
assert( pParent->pGroupBy==0 );
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
}else{
- pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
+ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
+ }
+ if( db->mallocFailed==0 ){
+ substSelect(pParse, pParent, iParent, pSub->pEList, 0);
}
- substSelect(db, pParent, iParent, pSub->pEList, 0);
/* The flattened query is distinct if either the inner or the
** outer query is distinct.
@@ -117288,7 +120072,7 @@ static int flattenSubquery(
** terms are duplicated into the subquery.
*/
static int pushDownWhereTerms(
- sqlite3 *db, /* The database connection (for malloc()) */
+ Parse *pParse, /* Parse context (for malloc() and error reporting) */
Select *pSubq, /* The subquery whose WHERE clause is to be augmented */
Expr *pWhere, /* The WHERE clause of the outer query */
int iCursor /* Cursor number of the subquery */
@@ -117309,16 +120093,16 @@ static int pushDownWhereTerms(
return 0; /* restriction (3) */
}
while( pWhere->op==TK_AND ){
- nChng += pushDownWhereTerms(db, pSubq, pWhere->pRight, iCursor);
+ nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor);
pWhere = pWhere->pLeft;
}
if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
nChng++;
while( pSubq ){
- pNew = sqlite3ExprDup(db, pWhere, 0);
- pNew = substExpr(db, pNew, iCursor, pSubq->pEList);
- pSubq->pWhere = sqlite3ExprAnd(db, pSubq->pWhere, pNew);
+ pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
+ pNew = substExpr(pParse, pNew, iCursor, pSubq->pEList);
+ pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
pSubq = pSubq->pPrior;
}
}
@@ -117610,7 +120394,7 @@ static int withExpand(
assert( pFrom->pTab==0 );
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
- pTab->nRef = 1;
+ pTab->nTabRef = 1;
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
pTab->iPKey = -1;
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
@@ -117633,25 +120417,33 @@ static int withExpand(
){
pItem->pTab = pTab;
pItem->fg.isRecursive = 1;
- pTab->nRef++;
+ pTab->nTabRef++;
pSel->selFlags |= SF_Recursive;
}
}
}
/* Only one recursive reference is permitted. */
- if( pTab->nRef>2 ){
+ if( pTab->nTabRef>2 ){
sqlite3ErrorMsg(
pParse, "multiple references to recursive table: %s", pCte->zName
);
return SQLITE_ERROR;
}
- assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 ));
+ assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
pCte->zCteErr = "circular reference: %s";
pSavedWith = pParse->pWith;
pParse->pWith = pWith;
- sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel);
+ if( bMayRecursive ){
+ Select *pPrior = pSel->pPrior;
+ assert( pPrior->pWith==0 );
+ pPrior->pWith = pSel->pWith;
+ sqlite3WalkSelect(pWalker, pPrior);
+ pPrior->pWith = 0;
+ }else{
+ sqlite3WalkSelect(pWalker, pSel);
+ }
pParse->pWith = pWith;
for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
@@ -117695,10 +120487,12 @@ static int withExpand(
*/
static void selectPopWith(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
- With *pWith = findRightmost(p)->pWith;
- if( pWith!=0 ){
- assert( pParse->pWith==pWith );
- pParse->pWith = pWith->pOuter;
+ if( pParse->pWith && p->pPrior==0 ){
+ With *pWith = findRightmost(p)->pWith;
+ if( pWith!=0 ){
+ assert( pParse->pWith==pWith );
+ pParse->pWith = pWith->pOuter;
+ }
}
}
#else
@@ -117748,8 +120542,8 @@ static int selectExpander(Walker *pWalker, Select *p){
}
pTabList = p->pSrc;
pEList = p->pEList;
- if( pWalker->xSelectCallback2==selectPopWith ){
- sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
+ if( p->pWith ){
+ sqlite3WithPush(pParse, p->pWith, 0);
}
/* Make sure cursor numbers have been assigned to all entries in
@@ -117779,7 +120573,7 @@ static int selectExpander(Walker *pWalker, Select *p){
if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
- pTab->nRef = 1;
+ pTab->nTabRef = 1;
pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
while( pSel->pPrior ){ pSel = pSel->pPrior; }
sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
@@ -117792,13 +120586,13 @@ static int selectExpander(Walker *pWalker, Select *p){
assert( pFrom->pTab==0 );
pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
if( pTab==0 ) return WRC_Abort;
- if( pTab->nRef==0xffff ){
+ if( pTab->nTabRef>=0xffff ){
sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
pTab->zName);
pFrom->pTab = 0;
return WRC_Abort;
}
- pTab->nRef++;
+ pTab->nTabRef++;
if( !IsVirtual(pTab) && cannotBeFunction(pParse, pFrom) ){
return WRC_Abort;
}
@@ -117902,7 +120696,7 @@ static int selectExpander(Walker *pWalker, Select *p){
continue;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- zSchemaName = iDb>=0 ? db->aDb[iDb].zName : "*";
+ zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
}
for(j=0; j<pTab->nCol; j++){
char *zName = pTab->aCol[j].zName;
@@ -117948,10 +120742,10 @@ static int selectExpander(Walker *pWalker, Select *p){
if( longNames || pTabList->nSrc>1 ){
Expr *pLeft;
pLeft = sqlite3Expr(db, TK_ID, zTabName);
- pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
if( zSchemaName ){
pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
- pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr, 0);
+ pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
}
if( longNames ){
zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
@@ -118036,9 +120830,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
- if( (pSelect->selFlags & SF_MultiValue)==0 ){
- w.xSelectCallback2 = selectPopWith;
- }
+ w.xSelectCallback2 = selectPopWith;
sqlite3WalkSelect(&w, pSelect);
}
@@ -118188,8 +120980,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
ExprList *pList = pF->pExpr->x.pList;
assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) );
- sqlite3VdbeAddOp4(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0, 0,
- (void*)pF->pFunc, P4_FUNCDEF);
+ sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
+ sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
}
}
@@ -118240,8 +121032,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
}
- sqlite3VdbeAddOp4(v, OP_AggStep0, 0, regAgg, pF->iMem,
- (void*)pF->pFunc, P4_FUNCDEF);
+ sqlite3VdbeAddOp3(v, OP_AggStep0, 0, regAgg, pF->iMem);
+ sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u8)nArg);
sqlite3ExprCacheAffinityChange(pParse, regAgg, nArg);
sqlite3ReleaseTempRange(pParse, regAgg, nArg);
@@ -118385,16 +121177,6 @@ SQLITE_PRIVATE int sqlite3Select(
}
#endif
-
- /* If writing to memory or generating a set
- ** only a single column may be output.
- */
-#ifndef SQLITE_OMIT_SUBQUERY
- if( checkForMultiColumnSelectError(pParse, pDest, p->pEList->nExpr) ){
- goto select_end;
- }
-#endif
-
/* Try to flatten subqueries in the FROM clause up into the main query
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
@@ -118485,7 +121267,7 @@ SQLITE_PRIVATE int sqlite3Select(
** inside the subquery. This can help the subquery to run more efficiently.
*/
if( (pItem->fg.jointype & JT_OUTER)==0
- && pushDownWhereTerms(db, pSub, p->pWhere, pItem->iCursor)
+ && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor)
){
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x100 ){
@@ -118549,7 +121331,7 @@ SQLITE_PRIVATE int sqlite3Select(
/* If the subquery is not correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
- onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
}else{
VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
@@ -118647,7 +121429,9 @@ SQLITE_PRIVATE int sqlite3Select(
/* Set the limiter.
*/
iEnd = sqlite3VdbeMakeLabel(v);
- p->nSelectRow = 320; /* 4 billion rows */
+ if( (p->selFlags & SF_FixedLimit)==0 ){
+ p->nSelectRow = 320; /* 4 billion rows */
+ }
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
@@ -119125,7 +121909,7 @@ SQLITE_PRIVATE int sqlite3Select(
** of output.
*/
resetAccumulator(pParse, &sAggInfo);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax,0,flag,0);
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0);
if( pWInfo==0 ){
sqlite3ExprListDelete(db, pDel);
goto select_end;
@@ -119214,8 +121998,6 @@ select_end:
** if they are not used.
*/
/* #include "sqliteInt.h" */
-/* #include <stdlib.h> */
-/* #include <string.h> */
#ifndef SQLITE_OMIT_GET_TABLE
@@ -119312,7 +122094,7 @@ malloc_failed:
** Instead, the entire table should be passed to sqlite3_free_table() when
** the calling procedure is finished using it.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
char ***pazResult, /* Write the result table here */
@@ -119381,7 +122163,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
/*
** This routine frees the space the sqlite3_get_table() malloced.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(
+SQLITE_API void sqlite3_free_table(
char **azResult /* Result returned from sqlite3_get_table() */
){
if( azResult ){
@@ -119496,7 +122278,6 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
int iDb; /* The database to store the trigger in */
Token *pName; /* The unqualified db name */
DbFixer sFix; /* State vector for the DB fixer */
- int iTabDb; /* Index of the database holding pTab */
assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */
assert( pName2!=0 );
@@ -119609,13 +122390,13 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
" trigger on table: %S", pTableName, 0);
goto trigger_cleanup;
}
- iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
+ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int code = SQLITE_CREATE_TRIGGER;
- const char *zDb = db->aDb[iTabDb].zName;
- const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
+ const char *zDb = db->aDb[iTabDb].zDbSName;
+ const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb;
if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
goto trigger_cleanup;
@@ -119709,7 +122490,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb), zName,
+ db->aDb[iDb].zDbSName, MASTER_NAME, zName,
pTrig->table, z);
sqlite3DbFree(db, z);
sqlite3ChangeCookie(pParse, iDb);
@@ -119898,7 +122679,7 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr)
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
- if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
+ if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
@@ -119944,7 +122725,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_TRIGGER;
- const char *zDb = db->aDb[iDb].zName;
+ const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
@@ -119960,7 +122741,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
if( (v = sqlite3GetVdbe(pParse))!=0 ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pTrigger->zName
+ db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName
);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
@@ -120063,8 +122844,10 @@ static SrcList *targetSrcList(
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
+ const char *zDb;
assert( iDb<db->nDb );
- pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
+ zDb = db->aDb[iDb].zDbSName;
+ pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, zDb);
}
}
return pSrc;
@@ -120278,7 +123061,6 @@ static TriggerPrg *codeRowTrigger(
}
pProgram->nMem = pSubParse->nMem;
pProgram->nCsr = pSubParse->nTab;
- pProgram->nOnce = pSubParse->nOnce;
pProgram->token = (void *)pTrigger;
pPrg->aColmask[0] = pSubParse->oldmask;
pPrg->aColmask[1] = pSubParse->newmask;
@@ -120571,14 +123353,14 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc,
pCol->affinity, &pValue);
if( pValue ){
- sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
+ sqlite3VdbeAppendP4(v, pValue, P4_MEM);
}
+ }
#ifndef SQLITE_OMIT_FLOATING_POINT
- if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
- sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
- }
-#endif
+ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
+ sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
+#endif
}
/*
@@ -120607,7 +123389,7 @@ SQLITE_PRIVATE void sqlite3Update(
int iDataCur; /* Cursor for the canonical data btree */
int iIdxCur; /* Cursor for the first index */
sqlite3 *db; /* The database structure */
- int *aRegIdx = 0; /* One register assigned to each index to be updated */
+ int *aRegIdx = 0; /* First register in array assigned to each index */
int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
** an expression for the i-th column of the table.
** aXRef[i]==-1 if the i-th column is not changed. */
@@ -120619,10 +123401,11 @@ SQLITE_PRIVATE void sqlite3Update(
AuthContext sContext; /* The authorization context */
NameContext sNC; /* The name-context to resolve expressions in */
int iDb; /* Database containing the table being updated */
- int okOnePass; /* True for one-pass algorithm without the FIFO */
+ int eOnePass; /* ONEPASS_XXX value from where.c */
int hasFK; /* True if foreign key processing is required */
int labelBreak; /* Jump here to break out of UPDATE loop */
int labelContinue; /* Jump here to continue next step of UPDATE loop */
+ int flags; /* Flags for sqlite3WhereBegin() */
#ifndef SQLITE_OMIT_TRIGGER
int isView; /* True when updating a view (INSTEAD OF trigger) */
@@ -120633,6 +123416,10 @@ SQLITE_PRIVATE void sqlite3Update(
int iEph = 0; /* Ephemeral table holding all primary key values */
int nKey = 0; /* Number of elements in regKey for WITHOUT ROWID */
int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */
+ int addrOpen = 0; /* Address of OP_OpenEphemeral */
+ int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */
+ i16 nPk = 0; /* Number of components of the PRIMARY KEY */
+ int bReplace = 0; /* True if REPLACE conflict resolution might happen */
/* Register Allocations */
int regRowCount = 0; /* A count of rows changed */
@@ -120751,7 +123538,7 @@ SQLITE_PRIVATE void sqlite3Update(
int rc;
rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
j<0 ? "ROWID" : pTab->aCol[j].zName,
- db->aDb[iDb].zName);
+ db->aDb[iDb].zDbSName);
if( rc==SQLITE_DENY ){
goto update_cleanup;
}else if( rc==SQLITE_IGNORE ){
@@ -120784,12 +123571,19 @@ SQLITE_PRIVATE void sqlite3Update(
int reg;
if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){
reg = ++pParse->nMem;
+ pParse->nMem += pIdx->nColumn;
}else{
reg = 0;
for(i=0; i<pIdx->nKeyCol; i++){
i16 iIdxCol = pIdx->aiColumn[i];
if( iIdxCol<0 || aXRef[iIdxCol]>=0 ){
reg = ++pParse->nMem;
+ pParse->nMem += pIdx->nColumn;
+ if( (onError==OE_Replace)
+ || (onError==OE_Default && pIdx->onError==OE_Replace)
+ ){
+ bReplace = 1;
+ }
break;
}
}
@@ -120797,6 +123591,11 @@ SQLITE_PRIVATE void sqlite3Update(
if( reg==0 ) aToOpen[j+1] = 0;
aRegIdx[j] = reg;
}
+ if( bReplace ){
+ /* If REPLACE conflict resolution might be invoked, open cursors on all
+ ** indexes in case they are needed to delete records. */
+ memset(aToOpen, 1, nIdx+1);
+ }
/* Begin generating code. */
v = sqlite3GetVdbe(pParse);
@@ -120849,110 +123648,130 @@ SQLITE_PRIVATE void sqlite3Update(
}
#endif
- /* Begin the database scan
- */
+ /* Initialize the count of updated rows */
+ if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
+ regRowCount = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+ }
+
if( HasRowid(pTab) ){
sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
- pWInfo = sqlite3WhereBegin(
- pParse, pTabList, pWhere, 0, 0,
- WHERE_ONEPASS_DESIRED | WHERE_SEEK_TABLE, iIdxCur
- );
- if( pWInfo==0 ) goto update_cleanup;
- okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
-
- /* Remember the rowid of every item to be updated.
- */
- sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
- if( !okOnePass ){
- sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
- }
-
- /* End the database scan loop.
- */
- sqlite3WhereEnd(pWInfo);
}else{
- int iPk; /* First of nPk memory cells holding PRIMARY KEY value */
- i16 nPk; /* Number of components of the PRIMARY KEY */
- int addrOpen; /* Address of the OpenEphemeral instruction */
-
assert( pPk!=0 );
nPk = pPk->nKeyCol;
iPk = pParse->nMem+1;
pParse->nMem += nPk;
regKey = ++pParse->nMem;
iEph = pParse->nTab++;
+
sqlite3VdbeAddOp2(v, OP_Null, 0, iPk);
addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
sqlite3VdbeSetP4KeyInfo(pParse, pPk);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,
- WHERE_ONEPASS_DESIRED, iIdxCur);
- if( pWInfo==0 ) goto update_cleanup;
- okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ }
+
+ /* Begin the database scan.
+ **
+ ** Do not consider a single-pass strategy for a multi-row update if
+ ** there are any triggers or foreign keys to process, or rows may
+ ** be deleted as a result of REPLACE conflict handling. Any of these
+ ** things might disturb a cursor being used to scan through the table
+ ** or index, causing a single-pass approach to malfunction. */
+ flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE;
+ if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
+ flags |= WHERE_ONEPASS_MULTIROW;
+ }
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur);
+ if( pWInfo==0 ) goto update_cleanup;
+
+ /* A one-pass strategy that might update more than one row may not
+ ** be used if any column of the index used for the scan is being
+ ** updated. Otherwise, if there is an index on "b", statements like
+ ** the following could create an infinite loop:
+ **
+ ** UPDATE t1 SET b=b+1 WHERE b>?
+ **
+ ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI
+ ** strategy that uses an index for which one or more columns are being
+ ** updated. */
+ eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ if( eOnePass==ONEPASS_MULTI ){
+ int iCur = aiCurOnePass[1];
+ if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){
+ eOnePass = ONEPASS_OFF;
+ }
+ assert( iCur!=iDataCur || !HasRowid(pTab) );
+ }
+
+ if( HasRowid(pTab) ){
+ /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF
+ ** mode, write the rowid into the FIFO. In either of the one-pass modes,
+ ** leave it in register regOldRowid. */
+ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid);
+ if( eOnePass==ONEPASS_OFF ){
+ sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid);
+ }
+ }else{
+ /* Read the PK of the current row into an array of registers. In
+ ** ONEPASS_OFF mode, serialize the array into a record and store it in
+ ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change
+ ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table
+ ** is not required) and leave the PK fields in the array of registers. */
for(i=0; i<nPk; i++){
assert( pPk->aiColumn[i]>=0 );
- sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
- iPk+i);
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur,pPk->aiColumn[i],iPk+i);
}
- if( okOnePass ){
+ if( eOnePass ){
sqlite3VdbeChangeToNoop(v, addrOpen);
nKey = nPk;
regKey = iPk;
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
sqlite3IndexAffinityStr(db, pPk), nPk);
- sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk);
}
- sqlite3WhereEnd(pWInfo);
}
- /* Initialize the count of updated rows
- */
- if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){
- regRowCount = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount);
+ if( eOnePass!=ONEPASS_MULTI ){
+ sqlite3WhereEnd(pWInfo);
}
labelBreak = sqlite3VdbeMakeLabel(v);
if( !isView ){
- /*
- ** Open every index that needs updating. Note that if any
- ** index could potentially invoke a REPLACE conflict resolution
- ** action, then we need to open all indices because we might need
- ** to be deleting some records.
- */
- if( onError==OE_Replace ){
- memset(aToOpen, 1, nIdx+1);
- }else{
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- if( pIdx->onError==OE_Replace ){
- memset(aToOpen, 1, nIdx+1);
- break;
- }
- }
- }
- if( okOnePass ){
+ int addrOnce = 0;
+
+ /* Open every index that needs updating. */
+ if( eOnePass!=ONEPASS_OFF ){
if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0;
if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0;
}
+
+ if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
+ }
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen,
0, 0);
+ if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
}
/* Top of the update loop */
- if( okOnePass ){
- if( aToOpen[iDataCur-iBaseCur] && !isView ){
+ if( eOnePass!=ONEPASS_OFF ){
+ if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
assert( pPk );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
VdbeCoverageNeverTaken(v);
}
- labelContinue = labelBreak;
+ if( eOnePass==ONEPASS_SINGLE ){
+ labelContinue = labelBreak;
+ }else{
+ labelContinue = sqlite3VdbeMakeLabel(v);
+ }
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
VdbeCoverageIf(v, pPk==0);
VdbeCoverageIf(v, pPk!=0);
}else if( pPk ){
labelContinue = sqlite3VdbeMakeLabel(v);
sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
- addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
+ addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
VdbeCoverage(v);
}else{
@@ -121070,7 +123889,6 @@ SQLITE_PRIVATE void sqlite3Update(
if( !isView ){
int addr1 = 0; /* Address of jump instruction */
- int bReplace = 0; /* True if REPLACE conflict resolution might happen */
/* Do constraint checks. */
assert( regOldRowid>0 );
@@ -121106,14 +123924,18 @@ SQLITE_PRIVATE void sqlite3Update(
assert( regNew==regNewRowid+1 );
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
sqlite3VdbeAddOp3(v, OP_Delete, iDataCur,
- OPFLAG_ISUPDATE | ((hasFK || chngKey || pPk!=0) ? 0 : OPFLAG_ISNOOP),
+ OPFLAG_ISUPDATE | ((hasFK || chngKey) ? 0 : OPFLAG_ISNOOP),
regNewRowid
);
+ if( eOnePass==ONEPASS_MULTI ){
+ assert( hasFK==0 && chngKey==0 );
+ sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
+ }
if( !pParse->nested ){
- sqlite3VdbeChangeP4(v, -1, (char*)pTab, P4_TABLE);
+ sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
}
#else
- if( hasFK || chngKey || pPk!=0 ){
+ if( hasFK || chngKey ){
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
}
#endif
@@ -121126,8 +123948,11 @@ SQLITE_PRIVATE void sqlite3Update(
}
/* Insert the new index entries and the new record. */
- sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
- regNewRowid, aRegIdx, 1, 0, 0);
+ sqlite3CompleteInsertion(
+ pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx,
+ OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0),
+ 0, 0
+ );
/* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
** handle rows (possibly in other tables) that refer via a foreign key
@@ -121149,8 +123974,11 @@ SQLITE_PRIVATE void sqlite3Update(
/* Repeat the above with the next record to be updated, until
** all record selected by the WHERE clause have been updated.
*/
- if( okOnePass ){
+ if( eOnePass==ONEPASS_SINGLE ){
/* Nothing to do at end-of-loop for a single-pass */
+ }else if( eOnePass==ONEPASS_MULTI ){
+ sqlite3VdbeResolveLabel(v, labelContinue);
+ sqlite3WhereEnd(pWInfo);
}else if( pPk ){
sqlite3VdbeResolveLabel(v, labelContinue);
sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
@@ -121159,15 +123987,6 @@ SQLITE_PRIVATE void sqlite3Update(
}
sqlite3VdbeResolveLabel(v, labelBreak);
- /* Close all tables */
- for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
- assert( aRegIdx );
- if( aToOpen[i+1] ){
- sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0);
- }
- }
- if( iDataCur<iIdxCur ) sqlite3VdbeAddOp2(v, OP_Close, iDataCur, 0);
-
/* Update the sqlite_sequence table by storing the content of the
** maximum rowid counter values recorded while inserting into
** autoincrement tables.
@@ -121353,57 +124172,52 @@ static void updateVirtualTable(
/* #include "vdbeInt.h" */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
-/*
-** Finalize a prepared statement. If there was an error, store the
-** text of the error message in *pzErrMsg. Return the result code.
-*/
-static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
- int rc;
- rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
- if( rc ){
- sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
- }
- return rc;
-}
/*
-** Execute zSql on database db. Return an error code.
+** Execute zSql on database db.
+**
+** If zSql returns rows, then each row will have exactly one
+** column. (This will only happen if zSql begins with "SELECT".)
+** Take each row of result and call execSql() again recursively.
+**
+** The execSqlF() routine does the same thing, except it accepts
+** a format string as its third argument
*/
static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
sqlite3_stmt *pStmt;
- VVA_ONLY( int rc; )
- if( !zSql ){
- return SQLITE_NOMEM_BKPT;
- }
- if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
- sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
- return sqlite3_errcode(db);
- }
- VVA_ONLY( rc = ) sqlite3_step(pStmt);
- assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) );
- return vacuumFinalize(db, pStmt, pzErrMsg);
-}
-
-/*
-** Execute zSql on database db. The statement returns exactly
-** one column. Execute this as SQL on the same database.
-*/
-static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
- sqlite3_stmt *pStmt;
int rc;
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+ /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
+ rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( rc!=SQLITE_OK ) return rc;
-
- while( SQLITE_ROW==sqlite3_step(pStmt) ){
- rc = execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
- if( rc!=SQLITE_OK ){
- vacuumFinalize(db, pStmt, pzErrMsg);
- return rc;
+ while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
+ const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
+ assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
+ if( zSubSql ){
+ assert( zSubSql[0]!='S' );
+ rc = execSql(db, pzErrMsg, zSubSql);
+ if( rc!=SQLITE_OK ) break;
}
}
-
- return vacuumFinalize(db, pStmt, pzErrMsg);
+ assert( rc!=SQLITE_ROW );
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
+ if( rc ){
+ sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
+ }
+ (void)sqlite3_finalize(pStmt);
+ return rc;
+}
+static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
+ char *z;
+ va_list ap;
+ int rc;
+ va_start(ap, zSql);
+ z = sqlite3VMPrintf(db, zSql, ap);
+ va_end(ap);
+ if( z==0 ) return SQLITE_NOMEM;
+ rc = execSql(db, pzErrMsg, z);
+ sqlite3DbFree(db, z);
+ return rc;
}
/*
@@ -121436,11 +124250,29 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
** transient would cause the database file to appear to be deleted
** following reboot.
*/
-SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
+SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
Vdbe *v = sqlite3GetVdbe(pParse);
- if( v ){
- sqlite3VdbeAddOp2(v, OP_Vacuum, 0, 0);
- sqlite3VdbeUsesBtree(v, 0);
+ int iDb = 0;
+ if( v==0 ) return;
+ if( pNm ){
+#ifndef SQLITE_BUG_COMPATIBLE_20160819
+ /* Default behavior: Report an error if the argument to VACUUM is
+ ** not recognized */
+ iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm);
+ if( iDb<0 ) return;
+#else
+ /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments
+ ** to VACUUM are silently ignored. This is a back-out of a bug fix that
+ ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270).
+ ** The buggy behavior is required for binary compatibility with some
+ ** legacy applications. */
+ iDb = sqlite3FindDb(pParse->db, pNm);
+ if( iDb<0 ) iDb = 0;
+#endif
+ }
+ if( iDb!=1 ){
+ sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
+ sqlite3VdbeUsesBtree(v, iDb);
}
return;
}
@@ -121448,11 +124280,10 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
/*
** This routine implements the OP_Vacuum opcode of the VDBE.
*/
-SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
+SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
Btree *pTemp; /* The temporary database we vacuum into */
- char *zSql = 0; /* SQL statements */
int saved_flags; /* Saved value of the db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
@@ -121461,6 +124292,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
int isMemDb; /* True if vacuuming a :memory: database */
int nRes; /* Bytes of reserved space at the end of each page */
int nDb; /* Number of attached databases */
+ const char *zDbMain; /* Schema name of database to vacuum */
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
@@ -121478,11 +124310,13 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_mTrace = db->mTrace;
- db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
- db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
+ db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
+ | SQLITE_PreferBuiltin | SQLITE_Vacuum);
+ db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
db->mTrace = 0;
- pMain = db->aDb[0].pBt;
+ zDbMain = db->aDb[iDb].zDbSName;
+ pMain = db->aDb[iDb].pBt;
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
@@ -121500,18 +124334,12 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
** to write the journal header file.
*/
nDb = db->nDb;
- if( sqlite3TempInMemory(db) ){
- zSql = "ATTACH ':memory:' AS vacuum_db;";
- }else{
- zSql = "ATTACH '' AS vacuum_db;";
- }
- rc = execSql(db, pzErrMsg, zSql);
- if( db->nDb>nDb ){
- pDb = &db->aDb[db->nDb-1];
- assert( strcmp(pDb->zName,"vacuum_db")==0 );
- }
+ rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- pTemp = db->aDb[db->nDb-1].pBt;
+ assert( (db->nDb-1)==nDb );
+ pDb = &db->aDb[nDb];
+ assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
+ pTemp = pDb->pBt;
/* The call to execSql() to attach the temp database has left the file
** locked (as there was more than one active statement when the transaction
@@ -121532,16 +124360,15 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
}
#endif
- sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size);
+ sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
- rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL);
/* Begin a transaction and take an exclusive lock on the main database
** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
** to ensure that we do not try to change the page-size on a WAL database.
*/
- rc = execSql(db, pzErrMsg, "BEGIN;");
+ rc = execSql(db, pzErrMsg, "BEGIN");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = sqlite3BtreeBeginTrans(pMain, 2);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
@@ -121568,64 +124395,48 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
/* Query the schema of the main database. Create a mirror schema
** in the temporary database.
*/
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14) "
- " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
- " AND coalesce(rootpage,1)>0"
+ db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
+ rc = execSqlF(db, pzErrMsg,
+ "SELECT sql FROM \"%w\".sqlite_master"
+ " WHERE type='table'AND name<>'sqlite_sequence'"
+ " AND coalesce(rootpage,1)>0",
+ zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14)"
- " FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %' ");
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21) "
- " FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
+ rc = execSqlF(db, pzErrMsg,
+ "SELECT sql FROM \"%w\".sqlite_master"
+ " WHERE type='index' AND length(sql)>10",
+ zDbMain
+ );
if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ db->init.iDb = 0;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
- assert( (db->flags & SQLITE_Vacuum)==0 );
- db->flags |= SQLITE_Vacuum;
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
- "|| ' SELECT * FROM main.' || quote(name) || ';'"
- "FROM main.sqlite_master "
- "WHERE type = 'table' AND name!='sqlite_sequence' "
- " AND coalesce(rootpage,1)>0"
+ rc = execSqlF(db, pzErrMsg,
+ "SELECT'INSERT INTO vacuum_db.'||quote(name)"
+ "||' SELECT*FROM\"%w\".'||quote(name)"
+ "FROM vacuum_db.sqlite_master "
+ "WHERE type='table'AND coalesce(rootpage,1)>0",
+ zDbMain
);
assert( (db->flags & SQLITE_Vacuum)!=0 );
db->flags &= ~SQLITE_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- /* Copy over the sequence table
- */
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'DELETE FROM vacuum_db.' || quote(name) || ';' "
- "FROM vacuum_db.sqlite_master WHERE name='sqlite_sequence' "
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db, pzErrMsg,
- "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
- "|| ' SELECT * FROM main.' || quote(name) || ';' "
- "FROM vacuum_db.sqlite_master WHERE name=='sqlite_sequence';"
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
-
-
/* Copy the triggers, views, and virtual tables from the main database
** over to the temporary database. None of these objects has any
** associated storage, so all we have to do is copy their entries
** from the SQLITE_MASTER table.
*/
- rc = execSql(db, pzErrMsg,
- "INSERT INTO vacuum_db.sqlite_master "
- " SELECT type, name, tbl_name, rootpage, sql"
- " FROM main.sqlite_master"
- " WHERE type='view' OR type='trigger'"
- " OR (type='table' AND rootpage=0)"
+ rc = execSqlF(db, pzErrMsg,
+ "INSERT INTO vacuum_db.sqlite_master"
+ " SELECT*FROM \"%w\".sqlite_master"
+ " WHERE type IN('view','trigger')"
+ " OR(type='table'AND rootpage=0)",
+ zDbMain
);
if( rc ) goto end_of_vacuum;
@@ -121679,6 +124490,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
end_of_vacuum:
/* Restore the original value of db->flags */
+ db->init.iDb = 0;
db->flags = saved_flags;
db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange;
@@ -121742,6 +124554,41 @@ struct VtabCtx {
};
/*
+** Construct and install a Module object for a virtual table. When this
+** routine is called, it is guaranteed that all appropriate locks are held
+** and the module is not already part of the connection.
+*/
+SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
+ sqlite3 *db, /* Database in which module is registered */
+ const char *zName, /* Name assigned to this module */
+ const sqlite3_module *pModule, /* The definition of the module */
+ void *pAux, /* Context pointer for xCreate/xConnect */
+ void (*xDestroy)(void *) /* Module destructor function */
+){
+ Module *pMod;
+ int nName = sqlite3Strlen30(zName);
+ pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
+ if( pMod ){
+ Module *pDel;
+ char *zCopy = (char *)(&pMod[1]);
+ memcpy(zCopy, zName, nName+1);
+ pMod->zName = zCopy;
+ pMod->pModule = pModule;
+ pMod->pAux = pAux;
+ pMod->xDestroy = xDestroy;
+ pMod->pEpoTab = 0;
+ pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
+ assert( pDel==0 || pDel==pMod );
+ if( pDel ){
+ sqlite3OomFault(db);
+ sqlite3DbFree(db, pDel);
+ pMod = 0;
+ }
+ }
+ return pMod;
+}
+
+/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
@@ -121754,35 +124601,15 @@ static int createModule(
void (*xDestroy)(void *) /* Module destructor function */
){
int rc = SQLITE_OK;
- int nName;
sqlite3_mutex_enter(db->mutex);
- nName = sqlite3Strlen30(zName);
if( sqlite3HashFind(&db->aModule, zName) ){
rc = SQLITE_MISUSE_BKPT;
}else{
- Module *pMod;
- pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
- if( pMod ){
- Module *pDel;
- char *zCopy = (char *)(&pMod[1]);
- memcpy(zCopy, zName, nName+1);
- pMod->zName = zCopy;
- pMod->pModule = pModule;
- pMod->pAux = pAux;
- pMod->xDestroy = xDestroy;
- pMod->pEpoTab = 0;
- pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
- assert( pDel==0 || pDel==pMod );
- if( pDel ){
- sqlite3OomFault(db);
- sqlite3DbFree(db, pDel);
- }
- }
+ (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy);
}
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
-
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -121791,7 +124618,7 @@ static int createModule(
/*
** External API function used to create a new virtual-table module.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
@@ -121806,7 +124633,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
/*
** External API function used to create a new virtual-table module.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
@@ -122037,8 +124864,7 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
iDb = sqlite3SchemaToIndex(db, pTable->pSchema);
assert( iDb>=0 );
- pTable->tabFlags |= TF_Virtual;
- pTable->nModuleArg = 0;
+ assert( pTable->nModuleArg==0 );
addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
addModuleArgument(db, pTable, 0);
addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
@@ -122057,7 +124883,7 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
*/
if( pTable->azModuleArg ){
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
- pTable->azModuleArg[0], pParse->db->aDb[iDb].zName);
+ pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
}
#endif
}
@@ -122121,7 +124947,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
"UPDATE %Q.%s "
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
"WHERE rowid=#%d",
- db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
+ db->aDb[iDb].zDbSName, MASTER_NAME,
pTab->zName,
pTab->zName,
zStmt,
@@ -122231,7 +125057,7 @@ static int vtabCallConstructor(
pVTable->pMod = pMod;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- pTab->azModuleArg[1] = db->aDb[iDb].zName;
+ pTab->azModuleArg[1] = db->aDb[iDb].zDbSName;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
@@ -122326,7 +125152,7 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
int rc;
assert( pTab );
- if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){
+ if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
return SQLITE_OK;
}
@@ -122385,7 +125211,7 @@ static void addToVTrans(sqlite3 *db, VTable *pVTab){
** This function is invoked by the vdbe to call the xCreate method
** of the virtual table named zTab in database iDb.
**
-** If an error occurs, *pzErr is set to point an an English language
+** If an error occurs, *pzErr is set to point to an English language
** description of the error and an SQLITE_XXX error code is returned.
** In this case the caller must call sqlite3DbFree(db, ) on *pzErr.
*/
@@ -122395,8 +125221,8 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
Module *pMod;
const char *zMod;
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
- assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
+ pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
+ assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
@@ -122430,7 +125256,7 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
** valid to call this function from within the xCreate() or xConnect() of a
** virtual table module.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
VtabCtx *pCtx;
Parse *pParse;
int rc = SQLITE_OK;
@@ -122450,7 +125276,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCre
return SQLITE_MISUSE_BKPT;
}
pTab = pCtx->pTab;
- assert( (pTab->tabFlags & TF_Virtual)!=0 );
+ assert( IsVirtual(pTab) );
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
@@ -122464,7 +125290,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCre
&& pParse->pNewTable
&& !db->mallocFailed
&& !pParse->pNewTable->pSelect
- && (pParse->pNewTable->tabFlags & TF_Virtual)==0
+ && !IsVirtual(pParse->pNewTable)
){
if( !pTab->aCol ){
Table *pNew = pParse->pNewTable;
@@ -122519,7 +125345,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
int rc = SQLITE_OK;
Table *pTab;
- pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
+ pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){
VTable *p;
int (*xDestroy)(sqlite3_vtab *);
@@ -122753,7 +125579,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
if( pExpr->op!=TK_COLUMN ) return pDef;
pTab = pExpr->pTab;
if( NEVER(pTab==0) ) return pDef;
- if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
+ if( !IsVirtual(pTab) ) return pDef;
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
assert( pVtab!=0 );
assert( pVtab->pModule!=0 );
@@ -122846,10 +125672,9 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){
return 0;
}
pMod->pEpoTab = pTab;
- pTab->nRef = 1;
+ pTab->nTabRef = 1;
pTab->pSchema = db->aDb[0].pSchema;
- pTab->tabFlags |= TF_Virtual;
- pTab->nModuleArg = 0;
+ assert( pTab->nModuleArg==0 );
pTab->iPKey = -1;
addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(db, pTab, 0);
@@ -122887,7 +125712,7 @@ SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
** The results of this routine are undefined unless it is called from
** within an xUpdate method.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
static const unsigned char aMap[] = {
SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE
};
@@ -122905,7 +125730,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
** the SQLite core with additional information about the behavior
** of the virtual table being implemented.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){
+SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
va_list ap;
int rc = SQLITE_OK;
@@ -122920,7 +125745,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){
if( !p ){
rc = SQLITE_MISUSE_BKPT;
}else{
- assert( p->pTab==0 || (p->pTab->tabFlags & TF_Virtual)!=0 );
+ assert( p->pTab==0 || IsVirtual(p->pTab) );
p->pVTable->bConstraint = (u8)va_arg(ap, int);
}
break;
@@ -123086,6 +125911,8 @@ struct WhereLoop {
union {
struct { /* Information for internal btree tables */
u16 nEq; /* Number of equality constraints */
+ u16 nBtm; /* Size of BTM vector */
+ u16 nTop; /* Size of TOP vector */
Index *pIndex; /* Index used, or NULL */
} btree;
struct { /* Information for virtual tables */
@@ -123208,19 +126035,20 @@ struct WherePath {
*/
struct WhereTerm {
Expr *pExpr; /* Pointer to the subexpression that is this term */
+ WhereClause *pWC; /* The clause this term is part of */
+ LogEst truthProb; /* Probability of truth for this expression */
+ u16 wtFlags; /* TERM_xxx bit flags. See below */
+ u16 eOperator; /* A WO_xx value describing <op> */
+ u8 nChild; /* Number of children that must disable us */
+ u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
int iParent; /* Disable pWC->a[iParent] when this term disabled */
int leftCursor; /* Cursor number of X in "X <op> <expr>" */
+ int iField; /* Field in (?,?,?) IN (SELECT...) vector */
union {
int leftColumn; /* Column number of X in "X <op> <expr>" */
WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */
WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */
} u;
- LogEst truthProb; /* Probability of truth for this expression */
- u16 eOperator; /* A WO_xx value describing <op> */
- u16 wtFlags; /* TERM_xxx bit flags. See below */
- u8 nChild; /* Number of children that must disable us */
- u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */
- WhereClause *pWC; /* The clause this term is part of */
Bitmask prereqRight; /* Bitmask of tables used by pExpr->pRight */
Bitmask prereqAll; /* Bitmask of tables referenced by pExpr */
};
@@ -123356,8 +126184,13 @@ struct WhereLoopBuilder {
UnpackedRecord *pRec; /* Probe for stat4 (if required) */
int nRecValid; /* Number of valid fields currently in pRec */
#endif
+ unsigned int bldFlags; /* SQLITE_BLDF_* flags */
};
+/* Allowed values for WhereLoopBuider.bldFlags */
+#define SQLITE_BLDF_INDEXED 0x0001 /* An index is used */
+#define SQLITE_BLDF_UNIQUE 0x0002 /* All keys of a UNIQUE index used */
+
/*
** The WHERE clause processing routine has two halves. The
** first part does the start of the WHERE loop and the second
@@ -123372,26 +126205,26 @@ struct WhereInfo {
Parse *pParse; /* Parsing and code generating context */
SrcList *pTabList; /* List of tables in the join */
ExprList *pOrderBy; /* The ORDER BY clause or NULL */
- ExprList *pDistinctSet; /* DISTINCT over all these values */
- WhereLoop *pLoops; /* List of all WhereLoop objects */
- Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
- LogEst nRowOut; /* Estimated number of output rows */
+ ExprList *pResultSet; /* Result set of the query */
LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
+ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
+ int iContinue; /* Jump here to continue with next record */
+ int iBreak; /* Jump here to break out of the loop */
+ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
+ u8 nLevel; /* Number of nested loop */
i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
u8 sorted; /* True if really sorted (not just grouped) */
u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */
u8 untestedTerms; /* Not all WHERE terms resolved by outer loop */
u8 eDistinct; /* One of the WHERE_DISTINCT_* values */
- u8 nLevel; /* Number of nested loop */
u8 bOrderedInnerLoop; /* True if only the inner-most loop is ordered */
int iTop; /* The very beginning of the WHERE loop */
- int iContinue; /* Jump here to continue with next record */
- int iBreak; /* Jump here to break out of the loop */
- int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */
- int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */
- WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
+ WhereLoop *pLoops; /* List of all WhereLoop objects */
+ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
+ LogEst nRowOut; /* Estimated number of output rows */
WhereClause sWC; /* Decomposition of the WHERE clause */
+ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */
WhereLevel a[1]; /* Information about each nest loop in WHERE */
};
@@ -123515,6 +126348,17 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
/************** Continuing where we left off in wherecode.c ******************/
#ifndef SQLITE_OMIT_EXPLAIN
+
+/*
+** Return the name of the i-th column of the pIdx index.
+*/
+static const char *explainIndexColumnName(Index *pIdx, int i){
+ i = pIdx->aiColumn[i];
+ if( i==XN_EXPR ) return "<expr>";
+ if( i==XN_ROWID ) return "rowid";
+ return pIdx->pTable->aCol[i].zName;
+}
+
/*
** This routine is a helper for explainIndexRange() below
**
@@ -123525,24 +126369,32 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
*/
static void explainAppendTerm(
StrAccum *pStr, /* The text expression being built */
- int iTerm, /* Index of this term. First is zero */
- const char *zColumn, /* Name of the column */
+ Index *pIdx, /* Index to read column names from */
+ int nTerm, /* Number of terms */
+ int iTerm, /* Zero-based index of first term. */
+ int bAnd, /* Non-zero to append " AND " */
const char *zOp /* Name of the operator */
){
- if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5);
- sqlite3StrAccumAppendAll(pStr, zColumn);
+ int i;
+
+ assert( nTerm>=1 );
+ if( bAnd ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+
+ if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
+ for(i=0; i<nTerm; i++){
+ if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
+ sqlite3StrAccumAppendAll(pStr, explainIndexColumnName(pIdx, iTerm+i));
+ }
+ if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
+
sqlite3StrAccumAppend(pStr, zOp, 1);
- sqlite3StrAccumAppend(pStr, "?", 1);
-}
-/*
-** Return the name of the i-th column of the pIdx index.
-*/
-static const char *explainIndexColumnName(Index *pIdx, int i){
- i = pIdx->aiColumn[i];
- if( i==XN_EXPR ) return "<expr>";
- if( i==XN_ROWID ) return "rowid";
- return pIdx->pTable->aCol[i].zName;
+ if( nTerm>1 ) sqlite3StrAccumAppend(pStr, "(", 1);
+ for(i=0; i<nTerm; i++){
+ if( i ) sqlite3StrAccumAppend(pStr, ",", 1);
+ sqlite3StrAccumAppend(pStr, "?", 1);
+ }
+ if( nTerm>1 ) sqlite3StrAccumAppend(pStr, ")", 1);
}
/*
@@ -123575,12 +126427,11 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){
j = i;
if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
- const char *z = explainIndexColumnName(pIndex, i);
- explainAppendTerm(pStr, i++, z, ">");
+ explainAppendTerm(pStr, pIndex, pLoop->u.btree.nBtm, j, i, ">");
+ i = 1;
}
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
- const char *z = explainIndexColumnName(pIndex, j);
- explainAppendTerm(pStr, i, z, "<");
+ explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<");
}
sqlite3StrAccumAppend(pStr, ")", 1);
}
@@ -123770,7 +126621,7 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
int nLoop = 0;
- while( pTerm
+ while( ALWAYS(pTerm!=0)
&& (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
&& (pLevel->notReady & pTerm->prereqAll)==0
@@ -123826,16 +126677,45 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){
}
}
+/*
+** Expression pRight, which is the RHS of a comparison operation, is
+** either a vector of n elements or, if n==1, a scalar expression.
+** Before the comparison operation, affinity zAff is to be applied
+** to the pRight values. This function modifies characters within the
+** affinity string to SQLITE_AFF_BLOB if either:
+**
+** * the comparison will be performed with no affinity, or
+** * the affinity change in zAff is guaranteed not to change the value.
+*/
+static void updateRangeAffinityStr(
+ Expr *pRight, /* RHS of comparison */
+ int n, /* Number of vector elements in comparison */
+ char *zAff /* Affinity string to modify */
+){
+ int i;
+ for(i=0; i<n; i++){
+ Expr *p = sqlite3VectorFieldSubexpr(pRight, i);
+ if( sqlite3CompareAffinity(p, zAff[i])==SQLITE_AFF_BLOB
+ || sqlite3ExprNeedsNoAffinityChange(p, zAff[i])
+ ){
+ zAff[i] = SQLITE_AFF_BLOB;
+ }
+ }
+}
/*
** Generate code for a single equality term of the WHERE clause. An equality
** term can be either X=expr or X IN (...). pTerm is the term to be
** coded.
**
-** The current value for the constraint is left in register iReg.
+** The current value for the constraint is left in a register, the index
+** of which is returned. An attempt is made store the result in iTarget but
+** this is only guaranteed for TK_ISNULL and TK_IN constraints. If the
+** constraint is a TK_EQ or TK_IS, then the current value might be left in
+** some other register and it is the caller's responsibility to compensate.
**
-** For a constraint of the form X=expr, the expression is evaluated and its
-** result is left on the stack. For constraints of the form X IN (...)
+** For a constraint of the form X=expr, the expression is evaluated in
+** straight-line code. For constraints of the form X IN (...)
** this routine sets up a loop that will iterate over all values of X.
*/
static int codeEqualityTerm(
@@ -123850,6 +126730,7 @@ static int codeEqualityTerm(
Vdbe *v = pParse->pVdbe;
int iReg; /* Register holding results */
+ assert( pLevel->pWLoop->aLTerm[iEq]==pTerm );
assert( iTarget>0 );
if( pX->op==TK_EQ || pX->op==TK_IS ){
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
@@ -123858,10 +126739,13 @@ static int codeEqualityTerm(
sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
- int eType;
+ int eType = IN_INDEX_NOOP;
int iTab;
struct InLoop *pIn;
WhereLoop *pLoop = pLevel->pWLoop;
+ int i;
+ int nEq = 0;
+ int *aiMap = 0;
if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0
&& pLoop->u.btree.pIndex!=0
@@ -123873,7 +126757,78 @@ static int codeEqualityTerm(
}
assert( pX->op==TK_IN );
iReg = iTarget;
- eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0);
+
+ for(i=0; i<iEq; i++){
+ if( pLoop->aLTerm[i] && pLoop->aLTerm[i]->pExpr==pX ){
+ disableTerm(pLevel, pTerm);
+ return iTarget;
+ }
+ }
+ for(i=iEq;i<pLoop->nLTerm; i++){
+ if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++;
+ }
+
+ if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
+ }else{
+ Select *pSelect = pX->x.pSelect;
+ sqlite3 *db = pParse->db;
+ u16 savedDbOptFlags = db->dbOptFlags;
+ ExprList *pOrigRhs = pSelect->pEList;
+ ExprList *pOrigLhs = pX->pLeft->x.pList;
+ ExprList *pRhs = 0; /* New Select.pEList for RHS */
+ ExprList *pLhs = 0; /* New pX->pLeft vector */
+
+ for(i=iEq;i<pLoop->nLTerm; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ int iField = pLoop->aLTerm[i]->iField - 1;
+ Expr *pNewRhs = sqlite3ExprDup(db, pOrigRhs->a[iField].pExpr, 0);
+ Expr *pNewLhs = sqlite3ExprDup(db, pOrigLhs->a[iField].pExpr, 0);
+
+ pRhs = sqlite3ExprListAppend(pParse, pRhs, pNewRhs);
+ pLhs = sqlite3ExprListAppend(pParse, pLhs, pNewLhs);
+ }
+ }
+ if( !db->mallocFailed ){
+ Expr *pLeft = pX->pLeft;
+
+ if( pSelect->pOrderBy ){
+ /* If the SELECT statement has an ORDER BY clause, zero the
+ ** iOrderByCol variables. These are set to non-zero when an
+ ** ORDER BY term exactly matches one of the terms of the
+ ** result-set. Since the result-set of the SELECT statement may
+ ** have been modified or reordered, these variables are no longer
+ ** set correctly. Since setting them is just an optimization,
+ ** it's easiest just to zero them here. */
+ ExprList *pOrderBy = pSelect->pOrderBy;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ pOrderBy->a[i].u.x.iOrderByCol = 0;
+ }
+ }
+
+ /* Take care here not to generate a TK_VECTOR containing only a
+ ** single value. Since the parser never creates such a vector, some
+ ** of the subroutines do not handle this case. */
+ if( pLhs->nExpr==1 ){
+ pX->pLeft = pLhs->a[0].pExpr;
+ }else{
+ pLeft->x.pList = pLhs;
+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * nEq);
+ testcase( aiMap==0 );
+ }
+ pSelect->pEList = pRhs;
+ db->dbOptFlags |= SQLITE_QueryFlattener;
+ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap);
+ db->dbOptFlags = savedDbOptFlags;
+ testcase( aiMap!=0 && aiMap[0]!=0 );
+ pSelect->pEList = pOrigRhs;
+ pLeft->x.pList = pOrigLhs;
+ pX->pLeft = pLeft;
+ }
+ sqlite3ExprListDelete(pParse->db, pLhs);
+ sqlite3ExprListDelete(pParse->db, pRhs);
+ }
+
if( eType==IN_INDEX_INDEX_DESC ){
testcase( bRev );
bRev = !bRev;
@@ -123883,28 +126838,45 @@ static int codeEqualityTerm(
VdbeCoverageIf(v, bRev);
VdbeCoverageIf(v, !bRev);
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
+
pLoop->wsFlags |= WHERE_IN_ABLE;
if( pLevel->u.in.nIn==0 ){
pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
}
- pLevel->u.in.nIn++;
+
+ i = pLevel->u.in.nIn;
+ pLevel->u.in.nIn += nEq;
pLevel->u.in.aInLoop =
sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
pIn = pLevel->u.in.aInLoop;
if( pIn ){
- pIn += pLevel->u.in.nIn - 1;
- pIn->iCur = iTab;
- if( eType==IN_INDEX_ROWID ){
- pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
- }else{
- pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
+ int iMap = 0; /* Index in aiMap[] */
+ pIn += i;
+ for(i=iEq;i<pLoop->nLTerm; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ int iOut = iReg + i - iEq;
+ if( eType==IN_INDEX_ROWID ){
+ testcase( nEq>1 ); /* Happens with a UNIQUE index on ROWID */
+ pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut);
+ }else{
+ int iCol = aiMap ? aiMap[iMap++] : 0;
+ pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut);
+ }
+ sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v);
+ if( i==iEq ){
+ pIn->iCur = iTab;
+ pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
+ }else{
+ pIn->eEndLoopOp = OP_Noop;
+ }
+ pIn++;
+ }
}
- pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
- sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v);
}else{
pLevel->u.in.nIn = 0;
}
+ sqlite3DbFree(pParse->db, aiMap);
#endif
}
disableTerm(pLevel, pTerm);
@@ -124030,9 +127002,15 @@ static int codeAllEqualityTerms(
sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
}
}
- testcase( pTerm->eOperator & WO_ISNULL );
- testcase( pTerm->eOperator & WO_IN );
- if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
+ if( pTerm->eOperator & WO_IN ){
+ if( pTerm->pExpr->flags & EP_xIsSelect ){
+ /* No affinity ever needs to be (or should be) applied to a value
+ ** from the RHS of an "? IN (SELECT ...)" expression. The
+ ** sqlite3FindInIndex() routine has already ensured that the
+ ** affinity of the comparison has been applied to the value. */
+ if( zAff ) zAff[j] = SQLITE_AFF_BLOB;
+ }
+ }else if( (pTerm->eOperator & WO_ISNULL)==0 ){
Expr *pRight = pTerm->pExpr->pRight;
if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
@@ -124356,6 +127334,39 @@ static void codeDeferredSeek(
}
/*
+** If the expression passed as the second argument is a vector, generate
+** code to write the first nReg elements of the vector into an array
+** of registers starting with iReg.
+**
+** If the expression is not a vector, then nReg must be passed 1. In
+** this case, generate code to evaluate the expression and leave the
+** result in register iReg.
+*/
+static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
+ assert( nReg>0 );
+ if( sqlite3ExprIsVector(p) ){
+#ifndef SQLITE_OMIT_SUBQUERY
+ if( (p->flags & EP_xIsSelect) ){
+ Vdbe *v = pParse->pVdbe;
+ int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
+ sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
+ }else
+#endif
+ {
+ int i;
+ ExprList *pList = p->x.pList;
+ assert( nReg<=pList->nExpr );
+ for(i=0; i<nReg; i++){
+ sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
+ }
+ }
+ }else{
+ assert( nReg==1 );
+ sqlite3ExprCode(pParse, p, iReg);
+ }
+}
+
+/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
@@ -124378,6 +127389,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
+ int addrHalt; /* addrBrk for the outermost loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
@@ -124419,6 +127431,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeComment((v, "init LEFT JOIN no-match flag"));
}
+ /* Compute a safe address to jump to if we discover that the table for
+ ** this loop is empty and can never contribute content. */
+ for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
+ addrHalt = pWInfo->a[j].addrBrk;
+
/* Special case of a FROM clause subquery implemented as a co-routine */
if( pTabItem->fg.viaCoroutine ){
int regYield = pTabItem->regReturn;
@@ -124450,14 +127467,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget);
addrNotFound = pLevel->addrNxt;
}else{
- sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
+ Expr *pRight = pTerm->pExpr->pRight;
+ codeExprOrVector(pParse, pRight, iTarget, 1);
}
}
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
pLoop->u.vtab.idxStr,
- pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
+ pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
VdbeCoverage(v);
pLoop->u.vtab.needFree = 0;
pLevel->p1 = iCur;
@@ -124490,7 +127508,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
/* Generate code that will continue to the next row if
** the IN constraint is not satisfied */
- pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0, 0);
+ pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0);
assert( pCompare!=0 || db->mallocFailed );
if( pCompare ){
pCompare->pLeft = pTerm->pExpr->pLeft;
@@ -124564,6 +127582,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( pStart ){
Expr *pX; /* The expression that defines the start bound */
int r1, rTemp; /* Registers for holding the start boundary */
+ int op; /* Cursor seek operation */
/* The following constant maps TK_xx codes into corresponding
** seek opcodes. It depends on a particular ordering of TK_xx
@@ -124583,8 +127602,16 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pX = pStart->pExpr;
assert( pX!=0 );
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
- r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
- sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
+ if( sqlite3ExprIsVector(pX->pRight) ){
+ r1 = rTemp = sqlite3GetTempReg(pParse);
+ codeExprOrVector(pParse, pX->pRight, r1, 1);
+ op = aMoveOp[(pX->op - TK_GT) | 0x0001];
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
+ disableTerm(pLevel, pStart);
+ op = aMoveOp[(pX->op - TK_GT)];
+ }
+ sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1);
VdbeComment((v, "pk"));
VdbeCoverageIf(v, pX->op==TK_GT);
VdbeCoverageIf(v, pX->op==TK_LE);
@@ -124592,9 +127619,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeCoverageIf(v, pX->op==TK_GE);
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
- disableTerm(pLevel, pStart);
}else{
- sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
+ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
}
@@ -124606,13 +127632,17 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
testcase( pEnd->wtFlags & TERM_VIRTUAL );
memEndValue = ++pParse->nMem;
- sqlite3ExprCode(pParse, pX->pRight, memEndValue);
- if( pX->op==TK_LT || pX->op==TK_GT ){
+ codeExprOrVector(pParse, pX->pRight, memEndValue, 1);
+ if( 0==sqlite3ExprIsVector(pX->pRight)
+ && (pX->op==TK_LT || pX->op==TK_GT)
+ ){
testOp = bRev ? OP_Le : OP_Ge;
}else{
testOp = bRev ? OP_Lt : OP_Gt;
}
- disableTerm(pLevel, pEnd);
+ if( 0==sqlite3ExprIsVector(pX->pRight) ){
+ disableTerm(pLevel, pEnd);
+ }
}
start = sqlite3VdbeCurrentAddr(v);
pLevel->op = bRev ? OP_Prev : OP_Next;
@@ -124679,6 +127709,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */
};
u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */
+ u16 nBtm = pLoop->u.btree.nBtm; /* Length of BTM vector */
+ u16 nTop = pLoop->u.btree.nTop; /* Length of TOP vector */
int regBase; /* Base register holding constraint values */
WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */
WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */
@@ -124691,7 +127723,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
int nExtraReg = 0; /* Number of extra registers needed */
int op; /* Instruction opcode */
char *zStartAff; /* Affinity for start of range constraint */
- char cEndAff = 0; /* Affinity for end of range constraint */
+ char *zEndAff = 0; /* Affinity for end of range constraint */
u8 bSeekPastNull = 0; /* True to seek past initial nulls */
u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
@@ -124725,14 +127757,14 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
j = nEq;
if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
pRangeStart = pLoop->aLTerm[j++];
- nExtraReg = 1;
+ nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm);
/* Like optimization range constraints always occur in pairs */
assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 ||
(pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
}
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
pRangeEnd = pLoop->aLTerm[j++];
- nExtraReg = 1;
+ nExtraReg = MAX(nExtraReg, pLoop->u.btree.nTop);
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
assert( pRangeStart!=0 ); /* LIKE opt constraints */
@@ -124750,11 +127782,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pLevel->iLikeRepCntr |= bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC);
}
#endif
- if( pRangeStart==0
- && (j = pIdx->aiColumn[nEq])>=0
- && pIdx->pTable->aCol[j].notNull==0
- ){
- bSeekPastNull = 1;
+ if( pRangeStart==0 ){
+ j = pIdx->aiColumn[nEq];
+ if( (j>=0 && pIdx->pTable->aCol[j].notNull==0) || j==XN_EXPR ){
+ bSeekPastNull = 1;
+ }
}
}
assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
@@ -124768,6 +127800,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
SWAP(u8, bSeekPastNull, bStopAtNull);
+ SWAP(u8, nBtm, nTop);
}
/* Generate code to evaluate all constraint terms using == or IN
@@ -124777,7 +127810,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd);
regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq );
- if( zStartAff ) cEndAff = zStartAff[nEq];
+ if( zStartAff && nTop ){
+ zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]);
+ }
addrNxt = pLevel->addrNxt;
testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
@@ -124792,7 +127827,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
nConstraint = nEq;
if( pRangeStart ){
Expr *pRight = pRangeStart->pExpr->pRight;
- sqlite3ExprCode(pParse, pRight, regBase+nEq);
+ codeExprOrVector(pParse, pRight, regBase+nEq, nBtm);
whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
if( (pRangeStart->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
@@ -124801,18 +127836,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
VdbeCoverage(v);
}
if( zStartAff ){
- if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_BLOB){
- /* Since the comparison is to be performed with no conversions
- ** applied to the operands, set the affinity to apply to pRight to
- ** SQLITE_AFF_BLOB. */
- zStartAff[nEq] = SQLITE_AFF_BLOB;
- }
- if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
- zStartAff[nEq] = SQLITE_AFF_BLOB;
- }
+ updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]);
}
- nConstraint++;
+ nConstraint += nBtm;
testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
+ if( sqlite3ExprIsVector(pRight)==0 ){
+ disableTerm(pLevel, pRangeStart);
+ }else{
+ startEq = 1;
+ }
bSeekPastNull = 0;
}else if( bSeekPastNull ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
@@ -124845,7 +127877,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
if( pRangeEnd ){
Expr *pRight = pRangeEnd->pExpr->pRight;
sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
- sqlite3ExprCode(pParse, pRight, regBase+nEq);
+ codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
@@ -124853,19 +127885,27 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
VdbeCoverage(v);
}
- if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_BLOB
- && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff)
- ){
- codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff);
+ if( zEndAff ){
+ updateRangeAffinityStr(pRight, nTop, zEndAff);
+ codeApplyAffinity(pParse, regBase+nEq, nTop, zEndAff);
+ }else{
+ assert( pParse->db->mallocFailed );
}
- nConstraint++;
+ nConstraint += nTop;
testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
+
+ if( sqlite3ExprIsVector(pRight)==0 ){
+ disableTerm(pLevel, pRangeEnd);
+ }else{
+ endEq = 1;
+ }
}else if( bStopAtNull ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
endEq = 0;
nConstraint++;
}
sqlite3DbFree(db, zStartAff);
+ sqlite3DbFree(db, zEndAff);
/* Top of the loop body */
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
@@ -124881,12 +127921,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
/* Seek the table cursor, if required */
- disableTerm(pLevel, pRangeStart);
- disableTerm(pLevel, pRangeEnd);
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
- if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE)!=0 ){
+ if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || (
+ (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE)
+ && (pWInfo->eOnePass==ONEPASS_SINGLE)
+ )){
iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
@@ -124906,9 +127947,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
}
- /* Record the instruction used to terminate the loop. Disable
- ** WHERE clause terms made redundant by the index range scan.
- */
+ /* Record the instruction used to terminate the loop. */
if( pLoop->wsFlags & WHERE_ONEROW ){
pLevel->op = OP_Noop;
}else if( bRev ){
@@ -124985,7 +128024,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
u16 wctrlFlags; /* Flags for sub-WHERE clause */
Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
Table *pTab = pTabItem->pTab;
-
+
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->eOperator & WO_OR );
@@ -125071,7 +128110,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
}
if( pAndExpr ){
- pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0);
+ pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr);
}
}
@@ -125144,7 +128183,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
if( iSet>=0 ){
sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid);
- sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0);
+ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid,
+ r, nPk);
if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
}
@@ -125226,7 +128266,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
codeCursorHint(pTabItem, pWInfo, pLevel, 0);
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
- pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
+ pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt);
VdbeCoverageIf(v, bRev==0);
VdbeCoverageIf(v, bRev!=0);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
@@ -125286,7 +128326,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
** the implied "t1.a=123" constraint.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
- Expr *pE, *pEAlt;
+ Expr *pE, sEAlt;
WhereTerm *pAlt;
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
@@ -125304,13 +128344,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
testcase( pAlt->eOperator & WO_IS );
testcase( pAlt->eOperator & WO_IN );
VdbeModuleComment((v, "begin transitive constraint"));
- pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
- if( pEAlt ){
- *pEAlt = *pAlt->pExpr;
- pEAlt->pLeft = pE->pLeft;
- sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
- sqlite3StackFree(db, pEAlt);
- }
+ sEAlt = *pAlt->pExpr;
+ sEAlt.pLeft = pE->pLeft;
+ sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);
}
/* For a LEFT OUTER JOIN, generate code that will record the fact that
@@ -125419,7 +128455,6 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
sqlite3DbFree(db, pOld);
}
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
- memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
}
pTerm = &pWC->a[idx = pWC->nTerm++];
if( p && ExprHasProperty(p, EP_Unlikely) ){
@@ -125431,13 +128466,15 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
pTerm->wtFlags = wtFlags;
pTerm->pWC = pWC;
pTerm->iParent = -1;
+ memset(&pTerm->eOperator, 0,
+ sizeof(WhereTerm) - offsetof(WhereTerm,eOperator));
return idx;
}
/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term. The allowed operators are
-** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
+** "=", "<", ">", "<=", ">=", "IN", "IS", and "IS NULL"
*/
static int allowedOp(int op){
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
@@ -125554,15 +128591,6 @@ static int isLikeOrGlob(
#endif
pList = pExpr->x.pList;
pLeft = pList->a[1].pExpr;
- if( pLeft->op!=TK_COLUMN
- || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
- || IsVirtual(pLeft->pTab) /* Value might be numeric */
- ){
- /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
- ** be the name of an indexed column with TEXT affinity. */
- return 0;
- }
- assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
op = pRight->op;
@@ -125579,6 +128607,23 @@ static int isLikeOrGlob(
z = pRight->u.zToken;
}
if( z ){
+
+ /* If the RHS begins with a digit or a minus sign, then the LHS must
+ ** be an ordinary column (not a virtual table column) with TEXT affinity.
+ ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false
+ ** even though "lhs LIKE rhs" is true. But if the RHS does not start
+ ** with a digit or '-', then "lhs LIKE rhs" will always be false if
+ ** the LHS is numeric and so the optimization still works.
+ */
+ if( sqlite3Isdigit(z[0]) || z[0]=='-' ){
+ if( pLeft->op!=TK_COLUMN
+ || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
+ || IsVirtual(pLeft->pTab) /* Value might be numeric */
+ ){
+ sqlite3ValueFree(pVal);
+ return 0;
+ }
+ }
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
@@ -125632,7 +128677,7 @@ static int isMatchOfColumn(
Expr *pExpr, /* Test this expression */
unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
){
- struct Op2 {
+ static const struct Op2 {
const char *zOp;
unsigned char eOp2;
} aOp[] = {
@@ -126075,7 +129120,7 @@ static void exprAnalyzeOrTerm(
}
assert( pLeft!=0 );
pDup = sqlite3ExprDup(db, pLeft, 0);
- pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
+ pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
@@ -126165,7 +129210,8 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
** in any index. Return TRUE (1) if pExpr is an indexed term and return
** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor
** number of the table that is indexed and *piColumn to the column number
-** of the column that is indexed, or -2 if an expression is being indexed.
+** of the column that is indexed, or XN_EXPR (-2) if an expression is being
+** indexed.
**
** If pExpr is a TK_COLUMN column reference, then this routine always returns
** true even if that particular column is not indexed, because the column
@@ -126173,6 +129219,7 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
*/
static int exprMightBeIndexed(
SrcList *pFrom, /* The FROM clause */
+ int op, /* The specific comparison operator */
Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */
Expr *pExpr, /* An operand of a comparison operator */
int *piCur, /* Write the referenced table cursor number here */
@@ -126181,6 +129228,17 @@ static int exprMightBeIndexed(
Index *pIdx;
int i;
int iCur;
+
+ /* If this expression is a vector to the left or right of a
+ ** inequality constraint (>, <, >= or <=), perform the processing
+ ** on the first element of the vector. */
+ assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
+ assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
+ assert( op<=TK_GE );
+ if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
+ pExpr = pExpr->x.pList->a[0].pExpr;
+ }
+
if( pExpr->op==TK_COLUMN ){
*piCur = pExpr->iTable;
*piColumn = pExpr->iColumn;
@@ -126193,10 +129251,10 @@ static int exprMightBeIndexed(
for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->aColExpr==0 ) continue;
for(i=0; i<pIdx->nKeyCol; i++){
- if( pIdx->aiColumn[i]!=(-2) ) continue;
- if( sqlite3ExprCompare(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
+ if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
+ if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
*piCur = iCur;
- *piColumn = -2;
+ *piColumn = XN_EXPR;
return 1;
}
}
@@ -126241,6 +129299,7 @@ static void exprAnalyze(
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */
+ int nLeft; /* Number of elements on left side vector */
if( db->mallocFailed ){
return;
@@ -126253,6 +129312,7 @@ static void exprAnalyze(
op = pExpr->op;
if( op==TK_IN ){
assert( pExpr->pRight==0 );
+ if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
}else{
@@ -126269,6 +129329,10 @@ static void exprAnalyze(
prereqAll |= x;
extraRight = x-1; /* ON clause terms may not be used with an index
** on left table of a LEFT JOIN. Ticket #3015 */
+ if( (prereqAll>>1)>=x ){
+ sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
+ return;
+ }
}
pTerm->prereqAll = prereqAll;
pTerm->leftCursor = -1;
@@ -126279,18 +129343,26 @@ static void exprAnalyze(
Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft);
Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight);
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
- if( exprMightBeIndexed(pSrc, prereqLeft, pLeft, &iCur, &iColumn) ){
+
+ if( pTerm->iField>0 ){
+ assert( op==TK_IN );
+ assert( pLeft->op==TK_VECTOR );
+ pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr;
+ }
+
+ if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){
pTerm->leftCursor = iCur;
pTerm->u.leftColumn = iColumn;
pTerm->eOperator = operatorMask(op) & opMask;
}
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
if( pRight
- && exprMightBeIndexed(pSrc, pTerm->prereqRight, pRight, &iCur, &iColumn)
+ && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn)
){
WhereTerm *pNew;
Expr *pDup;
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
+ assert( pTerm->iField==0 );
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite3ExprDup(db, pExpr, 0);
@@ -126351,7 +129423,7 @@ static void exprAnalyze(
int idxNew;
pNewExpr = sqlite3PExpr(pParse, ops[i],
sqlite3ExprDup(db, pExpr->pLeft, 0),
- sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
+ sqlite3ExprDup(db, pList->a[i].pExpr, 0));
transferJoinMarkings(pNewExpr, pExpr);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
@@ -126436,7 +129508,7 @@ static void exprAnalyze(
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
- pStr1, 0);
+ pStr1);
transferJoinMarkings(pNewExpr1, pExpr);
idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
testcase( idxNew1==0 );
@@ -126444,7 +129516,7 @@ static void exprAnalyze(
pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
- pStr2, 0);
+ pStr2);
transferJoinMarkings(pNewExpr2, pExpr);
idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
testcase( idxNew2==0 );
@@ -126477,7 +129549,7 @@ static void exprAnalyze(
if( (prereqExpr & prereqColumn)==0 ){
Expr *pNewExpr;
pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
- 0, sqlite3ExprDup(db, pRight, 0), 0);
+ 0, sqlite3ExprDup(db, pRight, 0));
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
@@ -126494,6 +129566,59 @@ static void exprAnalyze(
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+ /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create
+ ** new terms for each component comparison - "a = ?" and "b = ?". The
+ ** new terms completely replace the original vector comparison, which is
+ ** no longer used.
+ **
+ ** This is only required if at least one side of the comparison operation
+ ** is not a sub-select. */
+ if( pWC->op==TK_AND
+ && (pExpr->op==TK_EQ || pExpr->op==TK_IS)
+ && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1
+ && sqlite3ExprVectorSize(pExpr->pRight)==nLeft
+ && ( (pExpr->pLeft->flags & EP_xIsSelect)==0
+ || (pExpr->pRight->flags & EP_xIsSelect)==0)
+ ){
+ int i;
+ for(i=0; i<nLeft; i++){
+ int idxNew;
+ Expr *pNew;
+ Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i);
+ Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i);
+
+ pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
+ transferJoinMarkings(pNew, pExpr);
+ idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
+ exprAnalyze(pSrc, pWC, idxNew);
+ }
+ pTerm = &pWC->a[idxTerm];
+ pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL; /* Disable the original */
+ pTerm->eOperator = 0;
+ }
+
+ /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
+ ** a virtual term for each vector component. The expression object
+ ** used by each such virtual term is pExpr (the full vector IN(...)
+ ** expression). The WhereTerm.iField variable identifies the index within
+ ** the vector on the LHS that the virtual term represents.
+ **
+ ** This only works if the RHS is a simple SELECT, not a compound
+ */
+ if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0
+ && pExpr->pLeft->op==TK_VECTOR
+ && pExpr->x.pSelect->pPrior==0
+ ){
+ int i;
+ for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){
+ int idxNew;
+ idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL);
+ pWC->a[idxNew].iField = i+1;
+ exprAnalyze(pSrc, pWC, idxNew);
+ markTermAsChild(pWC, idxNew, idxTerm);
+ }
+ }
+
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
/* When sqlite_stat3 histogram data is available an operator of the
** form "x IS NOT NULL" can sometimes be evaluated more efficiently
@@ -126514,7 +129639,7 @@ static void exprAnalyze(
pNewExpr = sqlite3PExpr(pParse, TK_GT,
sqlite3ExprDup(db, pLeft, 0),
- sqlite3PExpr(pParse, TK_NULL, 0, 0, 0), 0);
+ sqlite3ExprAlloc(db, TK_NULL, 0, 0));
idxNew = whereClauseInsert(pWC, pNewExpr,
TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL);
@@ -126535,6 +129660,8 @@ static void exprAnalyze(
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
** an index for tables to the left of the join.
*/
+ testcase( pTerm!=&pWC->a[idxTerm] );
+ pTerm = &pWC->a[idxTerm];
pTerm->prereqRight |= extraRight;
}
@@ -126617,13 +129744,14 @@ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
** tree.
*/
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
- Bitmask mask = 0;
+ Bitmask mask;
if( p==0 ) return 0;
if( p->op==TK_COLUMN ){
mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
return mask;
}
- mask = sqlite3WhereExprUsage(pMaskSet, p->pRight);
+ assert( !ExprHasProperty(p, EP_TokenOnly) );
+ mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0;
if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
if( ExprHasProperty(p, EP_xIsSelect) ){
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
@@ -126691,13 +129819,13 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
pTab->zName, j);
return;
}
- pColRef = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+ pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
if( pColRef==0 ) return;
pColRef->iTable = pItem->iCursor;
pColRef->iColumn = k++;
pColRef->pTab = pTab;
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef,
- sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
+ sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0));
whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
}
}
@@ -126904,16 +130032,19 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
WhereTerm *pTerm; /* The term being tested */
int k = pScan->k; /* Where to start scanning */
- while( pScan->iEquiv<=pScan->nEquiv ){
- iCur = pScan->aiCur[pScan->iEquiv-1];
+ assert( pScan->iEquiv<=pScan->nEquiv );
+ pWC = pScan->pWC;
+ while(1){
iColumn = pScan->aiColumn[pScan->iEquiv-1];
- if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0;
- while( (pWC = pScan->pWC)!=0 ){
+ iCur = pScan->aiCur[pScan->iEquiv-1];
+ assert( pWC!=0 );
+ do{
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
if( pTerm->leftCursor==iCur
&& pTerm->u.leftColumn==iColumn
&& (iColumn!=XN_EXPR
- || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
+ || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
+ pScan->pIdxExpr,iCur)==0)
&& (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
){
if( (pTerm->eOperator & WO_EQUIV)!=0
@@ -126958,15 +130089,17 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
testcase( pTerm->eOperator & WO_IS );
continue;
}
+ pScan->pWC = pWC;
pScan->k = k+1;
return pTerm;
}
}
}
- pScan->pWC = pScan->pWC->pOuter;
+ pWC = pWC->pOuter;
k = 0;
- }
- pScan->pWC = pScan->pOrigWC;
+ }while( pWC!=0 );
+ if( pScan->iEquiv>=pScan->nEquiv ) break;
+ pWC = pScan->pOrigWC;
k = 0;
pScan->iEquiv++;
}
@@ -127000,24 +130133,25 @@ static WhereTerm *whereScanInit(
u32 opMask, /* Operator(s) to scan for */
Index *pIdx /* Must be compatible with this index */
){
- int j = 0;
-
- /* memset(pScan, 0, sizeof(*pScan)); */
pScan->pOrigWC = pWC;
pScan->pWC = pWC;
pScan->pIdxExpr = 0;
+ pScan->idxaff = 0;
+ pScan->zCollName = 0;
if( pIdx ){
- j = iColumn;
+ int j = iColumn;
iColumn = pIdx->aiColumn[j];
- if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
- if( iColumn==pIdx->pTable->iPKey ) iColumn = XN_ROWID;
- }
- if( pIdx && iColumn>=0 ){
- pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
- pScan->zCollName = pIdx->azColl[j];
- }else{
- pScan->idxaff = 0;
- pScan->zCollName = 0;
+ if( iColumn==XN_EXPR ){
+ pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
+ pScan->zCollName = pIdx->azColl[j];
+ }else if( iColumn==pIdx->pTable->iPKey ){
+ iColumn = XN_ROWID;
+ }else if( iColumn>=0 ){
+ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
+ pScan->zCollName = pIdx->azColl[j];
+ }
+ }else if( iColumn==XN_EXPR ){
+ return 0;
}
pScan->opMask = opMask;
pScan->k = 0;
@@ -127217,14 +130351,16 @@ static LogEst estLog(LogEst N){
** value stored in its output register.
*/
static void translateColumnToCopy(
- Vdbe *v, /* The VDBE containing code to translate */
+ Parse *pParse, /* Parsing context */
int iStart, /* Translate from this opcode to the end */
int iTabCur, /* OP_Column/OP_Rowid references to this table */
int iRegister, /* The first column is in this register */
int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */
){
+ Vdbe *v = pParse->pVdbe;
VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
int iEnd = sqlite3VdbeCurrentAddr(v);
+ if( pParse->db->mallocFailed ) return;
for(; iStart<iEnd; iStart++, pOp++){
if( pOp->p1!=iTabCur ) continue;
if( pOp->opcode==OP_Column ){
@@ -127357,7 +130493,7 @@ static void constructAutomaticIndex(
** transient index on 2nd and subsequent iterations of the loop. */
v = pParse->pVdbe;
assert( v!=0 );
- addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
@@ -127502,7 +130638,9 @@ static void constructAutomaticIndex(
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
if( pTabItem->fg.viaCoroutine ){
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
- translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1);
+ testcase( pParse->db->mallocFailed );
+ translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
+ pTabItem->regResult, 1);
sqlite3VdbeGoto(v, addrTop);
pTabItem->fg.viaCoroutine = 0;
}else{
@@ -127532,7 +130670,8 @@ static sqlite3_index_info *allocateIndexInfo(
WhereClause *pWC,
Bitmask mUnusable, /* Ignore terms with these prereqs */
struct SrcList_item *pSrc,
- ExprList *pOrderBy
+ ExprList *pOrderBy,
+ u16 *pmNoOmit /* Mask of terms not to omit */
){
int i, j;
int nTerm;
@@ -127542,6 +130681,7 @@ static sqlite3_index_info *allocateIndexInfo(
WhereTerm *pTerm;
int nOrderBy;
sqlite3_index_info *pIdxInfo;
+ u16 mNoOmit = 0;
/* Count the number of possible WHERE clause constraints referring
** to this virtual table */
@@ -127630,6 +130770,15 @@ static sqlite3_index_info *allocateIndexInfo(
assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
assert( WO_MATCH==SQLITE_INDEX_CONSTRAINT_MATCH );
assert( pTerm->eOperator & (WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_MATCH) );
+
+ if( op & (WO_LT|WO_LE|WO_GT|WO_GE)
+ && sqlite3ExprIsVector(pTerm->pExpr->pRight)
+ ){
+ if( i<16 ) mNoOmit |= (1 << i);
+ if( op==WO_LT ) pIdxCons[j].op = WO_LE;
+ if( op==WO_GT ) pIdxCons[j].op = WO_GE;
+ }
+
j++;
}
for(i=0; i<nOrderBy; i++){
@@ -127638,6 +130787,7 @@ static sqlite3_index_info *allocateIndexInfo(
pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder;
}
+ *pmNoOmit = mNoOmit;
return pIdxInfo;
}
@@ -127913,7 +131063,7 @@ static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){
/*
** Return the affinity for a single column of an index.
*/
-static char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
+SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
assert( iCol>=0 && iCol<pIdx->nColumn );
if( !pIdx->zColAff ){
if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
@@ -128090,7 +131240,8 @@ static int whereRangeScanEst(
if( nEq==pBuilder->nRecValid ){
UnpackedRecord *pRec = pBuilder->pRec;
tRowcnt a[2];
- u8 aff;
+ int nBtm = pLoop->u.btree.nBtm;
+ int nTop = pLoop->u.btree.nTop;
/* Variable iLower will be set to the estimate of the number of rows in
** the index that are less than the lower bound of the range query. The
@@ -128120,8 +131271,6 @@ static int whereRangeScanEst(
testcase( pRec->nField!=pBuilder->nRecValid );
pRec->nField = pBuilder->nRecValid;
}
- aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq);
- assert( nEq!=p->nKeyCol || aff==SQLITE_AFF_INTEGER );
/* Determine iLower and iUpper using ($P) only. */
if( nEq==0 ){
iLower = 0;
@@ -128140,17 +131289,20 @@ static int whereRangeScanEst(
if( p->aSortOrder[nEq] ){
/* The roles of pLower and pUpper are swapped for a DESC index */
SWAP(WhereTerm*, pLower, pUpper);
+ SWAP(int, nBtm, nTop);
}
/* If possible, improve on the iLower estimate using ($P:$L). */
if( pLower ){
- int bOk; /* True if value is extracted from pExpr */
+ int n; /* Values extracted from pExpr */
Expr *pExpr = pLower->pExpr->pRight;
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
- if( rc==SQLITE_OK && bOk ){
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n);
+ if( rc==SQLITE_OK && n ){
tRowcnt iNew;
+ u16 mask = WO_GT|WO_LE;
+ if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a);
- iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
+ iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0);
if( iNew>iLower ) iLower = iNew;
nOut--;
pLower = 0;
@@ -128159,13 +131311,15 @@ static int whereRangeScanEst(
/* If possible, improve on the iUpper estimate using ($P:$U). */
if( pUpper ){
- int bOk; /* True if value is extracted from pExpr */
+ int n; /* Values extracted from pExpr */
Expr *pExpr = pUpper->pExpr->pRight;
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
- if( rc==SQLITE_OK && bOk ){
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n);
+ if( rc==SQLITE_OK && n ){
tRowcnt iNew;
+ u16 mask = WO_GT|WO_LE;
+ if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT);
iUprIdx = whereKeyStats(pParse, p, pRec, 1, a);
- iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
+ iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0);
if( iNew<iUpper ) iUpper = iNew;
nOut--;
pUpper = 0;
@@ -128255,7 +131409,6 @@ static int whereEqualScanEst(
Index *p = pBuilder->pNew->u.btree.pIndex;
int nEq = pBuilder->pNew->u.btree.nEq;
UnpackedRecord *pRec = pBuilder->pRec;
- u8 aff; /* Column affinity */
int rc; /* Subfunction return code */
tRowcnt a[2]; /* Statistics */
int bOk;
@@ -128279,8 +131432,7 @@ static int whereEqualScanEst(
return SQLITE_OK;
}
- aff = sqlite3IndexColumnAffinity(pParse->db, p, nEq-1);
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk);
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk);
pBuilder->pRec = pRec;
if( rc!=SQLITE_OK ) return rc;
if( bOk==0 ) return SQLITE_NOTFOUND;
@@ -128369,9 +131521,14 @@ static void whereTermPrint(WhereTerm *pTerm, int iTerm){
sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor);
}
sqlite3DebugPrintf(
- "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x\n",
+ "TERM-%-3d %p %s %-12s prob=%-3d op=0x%03x wtFlags=0x%04x",
iTerm, pTerm, zType, zLeft, pTerm->truthProb,
pTerm->eOperator, pTerm->wtFlags);
+ if( pTerm->iField ){
+ sqlite3DebugPrintf(" iField=%d\n", pTerm->iField);
+ }else{
+ sqlite3DebugPrintf("\n");
+ }
sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
}
}
@@ -128893,6 +132050,72 @@ static void whereLoopOutputAdjust(
if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce;
}
+/*
+** Term pTerm is a vector range comparison operation. The first comparison
+** in the vector can be optimized using column nEq of the index. This
+** function returns the total number of vector elements that can be used
+** as part of the range comparison.
+**
+** For example, if the query is:
+**
+** WHERE a = ? AND (b, c, d) > (?, ?, ?)
+**
+** and the index:
+**
+** CREATE INDEX ... ON (a, b, c, d, e)
+**
+** then this function would be invoked with nEq=1. The value returned in
+** this case is 3.
+*/
+static int whereRangeVectorLen(
+ Parse *pParse, /* Parsing context */
+ int iCur, /* Cursor open on pIdx */
+ Index *pIdx, /* The index to be used for a inequality constraint */
+ int nEq, /* Number of prior equality constraints on same index */
+ WhereTerm *pTerm /* The vector inequality constraint */
+){
+ int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft);
+ int i;
+
+ nCmp = MIN(nCmp, (pIdx->nColumn - nEq));
+ for(i=1; i<nCmp; i++){
+ /* Test if comparison i of pTerm is compatible with column (i+nEq)
+ ** of the index. If not, exit the loop. */
+ char aff; /* Comparison affinity */
+ char idxaff = 0; /* Indexed columns affinity */
+ CollSeq *pColl; /* Comparison collation sequence */
+ Expr *pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
+ Expr *pRhs = pTerm->pExpr->pRight;
+ if( pRhs->flags & EP_xIsSelect ){
+ pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
+ }else{
+ pRhs = pRhs->x.pList->a[i].pExpr;
+ }
+
+ /* Check that the LHS of the comparison is a column reference to
+ ** the right column of the right source table. And that the sort
+ ** order of the index column is the same as the sort order of the
+ ** leftmost index column. */
+ if( pLhs->op!=TK_COLUMN
+ || pLhs->iTable!=iCur
+ || pLhs->iColumn!=pIdx->aiColumn[i+nEq]
+ || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq]
+ ){
+ break;
+ }
+
+ testcase( pLhs->iColumn==XN_ROWID );
+ aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs));
+ idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn);
+ if( aff!=idxaff ) break;
+
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
+ if( pColl==0 ) break;
+ if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break;
+ }
+ return i;
+}
+
/*
** Adjust the cost C by the costMult facter T. This only occurs if
** compiled with -DSQLITE_ENABLE_COSTMULT
@@ -128931,6 +132154,8 @@ static int whereLoopAddBtreeIndex(
Bitmask saved_prereq; /* Original value of pNew->prereq */
u16 saved_nLTerm; /* Original value of pNew->nLTerm */
u16 saved_nEq; /* Original value of pNew->u.btree.nEq */
+ u16 saved_nBtm; /* Original value of pNew->u.btree.nBtm */
+ u16 saved_nTop; /* Original value of pNew->u.btree.nTop */
u16 saved_nSkip; /* Original value of pNew->nSkip */
u32 saved_wsFlags; /* Original value of pNew->wsFlags */
LogEst saved_nOut; /* Original value of pNew->nOut */
@@ -128941,12 +132166,15 @@ static int whereLoopAddBtreeIndex(
pNew = pBuilder->pNew;
if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
+ WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n",
+ pProbe->zName, pNew->u.btree.nEq));
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
opMask = WO_LT|WO_LE;
}else{
+ assert( pNew->u.btree.nBtm==0 );
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
}
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
@@ -128954,6 +132182,8 @@ static int whereLoopAddBtreeIndex(
assert( pNew->u.btree.nEq<pProbe->nColumn );
saved_nEq = pNew->u.btree.nEq;
+ saved_nBtm = pNew->u.btree.nBtm;
+ saved_nTop = pNew->u.btree.nTop;
saved_nSkip = pNew->nSkip;
saved_nLTerm = pNew->nLTerm;
saved_wsFlags = pNew->wsFlags;
@@ -128995,8 +132225,15 @@ static int whereLoopAddBtreeIndex(
continue;
}
+ if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
+ pBuilder->bldFlags |= SQLITE_BLDF_UNIQUE;
+ }else{
+ pBuilder->bldFlags |= SQLITE_BLDF_INDEXED;
+ }
pNew->wsFlags = saved_wsFlags;
pNew->u.btree.nEq = saved_nEq;
+ pNew->u.btree.nBtm = saved_nBtm;
+ pNew->u.btree.nTop = saved_nTop;
pNew->nLTerm = saved_nLTerm;
if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
pNew->aLTerm[pNew->nLTerm++] = pTerm;
@@ -129013,14 +132250,23 @@ static int whereLoopAddBtreeIndex(
pNew->wsFlags |= WHERE_COLUMN_IN;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
+ int i;
nIn = 46; assert( 46==sqlite3LogEst(25) );
+
+ /* The expression may actually be of the form (x, y) IN (SELECT...).
+ ** In this case there is a separate term for each of (x) and (y).
+ ** However, the nIn multiplier should only be applied once, not once
+ ** for each such term. The following loop checks that pTerm is the
+ ** first such term in use, and sets nIn back to 0 if it is not. */
+ for(i=0; i<pNew->nLTerm-1; i++){
+ if( pNew->aLTerm[i] && pNew->aLTerm[i]->pExpr==pExpr ) nIn = 0;
+ }
}else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){
/* "x IN (value, value, ...)" */
nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
+ assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
+ ** changes "x IN (?)" into "x=?". */
}
- assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
- ** changes "x IN (?)" into "x=?". */
-
}else if( eOp & (WO_EQ|WO_IS) ){
int iCol = pProbe->aiColumn[saved_nEq];
pNew->wsFlags |= WHERE_COLUMN_EQ;
@@ -129040,6 +132286,9 @@ static int whereLoopAddBtreeIndex(
testcase( eOp & WO_GT );
testcase( eOp & WO_GE );
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
+ pNew->u.btree.nBtm = whereRangeVectorLen(
+ pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
+ );
pBtm = pTerm;
pTop = 0;
if( pTerm->wtFlags & TERM_LIKEOPT ){
@@ -129052,12 +132301,16 @@ static int whereLoopAddBtreeIndex(
if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
pNew->aLTerm[pNew->nLTerm++] = pTop;
pNew->wsFlags |= WHERE_TOP_LIMIT;
+ pNew->u.btree.nTop = 1;
}
}else{
assert( eOp & (WO_LT|WO_LE) );
testcase( eOp & WO_LT );
testcase( eOp & WO_LE );
pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_TOP_LIMIT;
+ pNew->u.btree.nTop = whereRangeVectorLen(
+ pParse, pSrc->iCursor, pProbe, saved_nEq, pTerm
+ );
pTop = pTerm;
pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ?
pNew->aLTerm[pNew->nLTerm-2] : 0;
@@ -129157,6 +132410,8 @@ static int whereLoopAddBtreeIndex(
}
pNew->prereq = saved_prereq;
pNew->u.btree.nEq = saved_nEq;
+ pNew->u.btree.nBtm = saved_nBtm;
+ pNew->u.btree.nTop = saved_nTop;
pNew->nSkip = saved_nSkip;
pNew->wsFlags = saved_wsFlags;
pNew->nOut = saved_nOut;
@@ -129196,6 +132451,8 @@ static int whereLoopAddBtreeIndex(
pNew->wsFlags = saved_wsFlags;
}
+ WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n",
+ pProbe->zName, saved_nEq, rc));
return rc;
}
@@ -129278,7 +132535,7 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
/*
** Add all WhereLoop objects for a single table of the join where the table
-** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
+** is identified by pBuilder->pNew->iTab. That table is guaranteed to be
** a b-tree table, not a virtual table.
**
** The costs (WhereLoop.rRun) of the b-tree loops added by this function
@@ -129432,6 +132689,8 @@ static int whereLoopAddBtree(
}
rSize = pProbe->aiRowLogEst[0];
pNew->u.btree.nEq = 0;
+ pNew->u.btree.nBtm = 0;
+ pNew->u.btree.nTop = 0;
pNew->nSkip = 0;
pNew->nLTerm = 0;
pNew->iSortIdx = 0;
@@ -129518,7 +132777,15 @@ static int whereLoopAddBtree(
}
}
+ pBuilder->bldFlags = 0;
rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
+ if( pBuilder->bldFlags==SQLITE_BLDF_INDEXED ){
+ /* If a non-unique index is used, or if a prefix of the key for
+ ** unique index is used (making the index functionally non-unique)
+ ** then the sqlite_stat1 data becomes important for scoring the
+ ** plan */
+ pTab->tabFlags |= TF_StatsUsed;
+ }
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
sqlite3Stat4ProbeFree(pBuilder->pRec);
pBuilder->nRecValid = 0;
@@ -129560,6 +132827,7 @@ static int whereLoopAddVirtualOne(
Bitmask mUsable, /* Mask of usable tables */
u16 mExclude, /* Exclude terms using these operators */
sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */
+ u16 mNoOmit, /* Do not omit these constraints */
int *pbIn /* OUT: True if plan uses an IN(...) op */
){
WhereClause *pWC = pBuilder->pWC;
@@ -129648,6 +132916,7 @@ static int whereLoopAddVirtualOne(
}
}
}
+ pNew->u.vtab.omitMask &= ~mNoOmit;
pNew->nLTerm = mxTerm+1;
assert( pNew->nLTerm<=pNew->nLSlot );
@@ -129721,6 +132990,7 @@ static int whereLoopAddVirtual(
int bIn; /* True if plan uses IN(...) operator */
WhereLoop *pNew;
Bitmask mBest; /* Tables used by best possible plan */
+ u16 mNoOmit;
assert( (mPrereq & mUnusable)==0 );
pWInfo = pBuilder->pWInfo;
@@ -129729,7 +132999,8 @@ static int whereLoopAddVirtual(
pNew = pBuilder->pNew;
pSrc = &pWInfo->pTabList->a[pNew->iTab];
assert( IsVirtual(pSrc->pTab) );
- p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy);
+ p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy,
+ &mNoOmit);
if( p==0 ) return SQLITE_NOMEM_BKPT;
pNew->rSetup = 0;
pNew->wsFlags = WHERE_VIRTUALTABLE;
@@ -129743,7 +133014,7 @@ static int whereLoopAddVirtual(
/* First call xBestIndex() with all constraints usable. */
WHERETRACE(0x40, (" VirtualOne: all usable\n"));
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, &bIn);
+ rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
/* If the call to xBestIndex() with all terms enabled produced a plan
** that does not require any source tables (IOW: a plan with mBest==0),
@@ -129760,7 +133031,8 @@ static int whereLoopAddVirtual(
** xBestIndex again, this time with IN(...) terms disabled. */
if( bIn ){
WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n"));
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, WO_IN, p, &bIn);
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
assert( bIn==0 );
mBestNoIn = pNew->prereq & ~mPrereq;
if( mBestNoIn==0 ){
@@ -129786,7 +133058,8 @@ static int whereLoopAddVirtual(
if( mNext==mBest || mNext==mBestNoIn ) continue;
WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n",
(sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mNext|mPrereq, 0, p, &bIn);
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
if( pNew->prereq==mPrereq ){
seenZero = 1;
if( bIn==0 ) seenZeroNoIN = 1;
@@ -129798,7 +133071,8 @@ static int whereLoopAddVirtual(
** usable), make a call here with all source tables disabled */
if( rc==SQLITE_OK && seenZero==0 ){
WHERETRACE(0x40, (" VirtualOne: all disabled\n"));
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, 0, p, &bIn);
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
if( bIn==0 ) seenZeroNoIN = 1;
}
@@ -129807,7 +133081,8 @@ static int whereLoopAddVirtual(
** operator, make a final call to obtain one here. */
if( rc==SQLITE_OK && seenZeroNoIN==0 ){
WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n"));
- rc = whereLoopAddVirtualOne(pBuilder, mPrereq, mPrereq, WO_IN, p, &bIn);
+ rc = whereLoopAddVirtualOne(
+ pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
}
}
@@ -130107,6 +133382,14 @@ static i8 wherePathSatisfiesOrderBy(
pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
~ready, eqOpMask, 0);
if( pTerm==0 ) continue;
+ if( pTerm->eOperator==WO_IN ){
+ /* IN terms are only valid for sorting in the ORDER BY LIMIT
+ ** optimization, and then only if they are actually used
+ ** by the query plan */
+ assert( wctrlFlags & WHERE_ORDERBY_LIMIT );
+ for(j=0; j<pLoop->nLTerm && pTerm!=pLoop->aLTerm[j]; j++){}
+ if( j>=pLoop->nLTerm ) continue;
+ }
if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
const char *z1, *z2;
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
@@ -130143,20 +133426,42 @@ static i8 wherePathSatisfiesOrderBy(
rev = revSet = 0;
distinctColumns = 0;
for(j=0; j<nColumn; j++){
- u8 bOnce; /* True to run the ORDER BY search loop */
+ u8 bOnce = 1; /* True to run the ORDER BY search loop */
- /* Skip over == and IS and ISNULL terms.
- ** (Also skip IN terms when doing WHERE_ORDERBY_LIMIT processing)
- */
- if( j<pLoop->u.btree.nEq
- && pLoop->nSkip==0
- && ((i = pLoop->aLTerm[j]->eOperator) & eqOpMask)!=0
- ){
- if( i & WO_ISNULL ){
- testcase( isOrderDistinct );
- isOrderDistinct = 0;
+ assert( j>=pLoop->u.btree.nEq
+ || (pLoop->aLTerm[j]==0)==(j<pLoop->nSkip)
+ );
+ if( j<pLoop->u.btree.nEq && j>=pLoop->nSkip ){
+ u16 eOp = pLoop->aLTerm[j]->eOperator;
+
+ /* Skip over == and IS and ISNULL terms. (Also skip IN terms when
+ ** doing WHERE_ORDERBY_LIMIT processing).
+ **
+ ** If the current term is a column of an ((?,?) IN (SELECT...))
+ ** expression for which the SELECT returns more than one column,
+ ** check that it is the only column used by this loop. Otherwise,
+ ** if it is one of two or more, none of the columns can be
+ ** considered to match an ORDER BY term. */
+ if( (eOp & eqOpMask)!=0 ){
+ if( eOp & WO_ISNULL ){
+ testcase( isOrderDistinct );
+ isOrderDistinct = 0;
+ }
+ continue;
+ }else if( ALWAYS(eOp & WO_IN) ){
+ /* ALWAYS() justification: eOp is an equality operator due to the
+ ** j<pLoop->u.btree.nEq constraint above. Any equality other
+ ** than WO_IN is captured by the previous "if". So this one
+ ** always has to be WO_IN. */
+ Expr *pX = pLoop->aLTerm[j]->pExpr;
+ for(i=j+1; i<pLoop->u.btree.nEq; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ assert( (pLoop->aLTerm[i]->eOperator & WO_IN) );
+ bOnce = 0;
+ break;
+ }
+ }
}
- continue;
}
/* Get the column number in the table (iColumn) and sort order
@@ -130185,7 +133490,6 @@ static i8 wherePathSatisfiesOrderBy(
/* Find the ORDER BY term that corresponds to the j-th column
** of the index and mark that ORDER BY term off
*/
- bOnce = 1;
isMatch = 0;
for(i=0; bOnce && i<nOrderBy; i++){
if( MASKBIT(i) & obSat ) continue;
@@ -130222,7 +133526,7 @@ static i8 wherePathSatisfiesOrderBy(
}
}
if( isMatch ){
- if( iColumn<0 ){
+ if( iColumn==XN_ROWID ){
testcase( distinctColumns==0 );
distinctColumns = 1;
}
@@ -130661,9 +133965,9 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
&& nRowEst
){
Bitmask notUsed;
- int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pDistinctSet, pFrom,
+ int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pResultSet, pFrom,
WHERE_DISTINCTBY, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed);
- if( rc==pWInfo->pDistinctSet->nExpr ){
+ if( rc==pWInfo->pResultSet->nExpr ){
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
}
@@ -130677,13 +133981,20 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
pWInfo->revMask = pFrom->revLoop;
if( pWInfo->nOBSat<=0 ){
pWInfo->nOBSat = 0;
- if( nLoop>0 && (pFrom->aLoop[nLoop-1]->wsFlags & WHERE_ONEROW)==0 ){
- Bitmask m = 0;
- int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
+ if( nLoop>0 ){
+ u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags;
+ if( (wsFlags & WHERE_ONEROW)==0
+ && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN)
+ ){
+ Bitmask m = 0;
+ int rc = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom,
WHERE_ORDERBY_LIMIT, nLoop-1, pFrom->aLoop[nLoop-1], &m);
- if( rc==pWInfo->pOrderBy->nExpr ){
- pWInfo->bOrderedInnerLoop = 1;
- pWInfo->revMask = m;
+ testcase( wsFlags & WHERE_IPK );
+ testcase( wsFlags & WHERE_COLUMN_IN );
+ if( rc==pWInfo->pOrderBy->nExpr ){
+ pWInfo->bOrderedInnerLoop = 1;
+ pWInfo->revMask = m;
+ }
}
}
}
@@ -130893,7 +134204,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */
Expr *pWhere, /* The WHERE clause */
ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */
- ExprList *pDistinctSet, /* Try not to output two rows that duplicate these */
+ ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */
u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */
int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number
** If WHERE_USE_LIMIT, then the limit amount */
@@ -130960,22 +134271,25 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** some architectures. Hence the ROUND8() below.
*/
nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
- pWInfo = sqlite3DbMallocZero(db, nByteWInfo + sizeof(WhereLoop));
+ pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
if( db->mallocFailed ){
sqlite3DbFree(db, pWInfo);
pWInfo = 0;
goto whereBeginError;
}
- pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
- pWInfo->nLevel = nTabList;
pWInfo->pParse = pParse;
pWInfo->pTabList = pTabList;
pWInfo->pOrderBy = pOrderBy;
- pWInfo->pDistinctSet = pDistinctSet;
+ pWInfo->pResultSet = pResultSet;
+ pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
+ pWInfo->nLevel = nTabList;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
pWInfo->wctrlFlags = wctrlFlags;
pWInfo->iLimit = iAuxArg;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
+ memset(&pWInfo->nOBSat, 0,
+ offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
+ memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
pMaskSet = &pWInfo->sMaskSet;
sWLB.pWInfo = pWInfo;
@@ -131044,13 +134358,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( db->mallocFailed ) goto whereBeginError;
if( wctrlFlags & WHERE_WANT_DISTINCT ){
- if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pDistinctSet) ){
+ if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
/* The DISTINCT marking is pointless. Ignore it. */
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}else if( pOrderBy==0 ){
/* Try to ORDER BY the result set to make distinct processing easier */
pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
- pWInfo->pOrderBy = pDistinctSet;
+ pWInfo->pOrderBy = pResultSet;
}
}
@@ -131126,10 +134440,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
#endif
/* Attempt to omit tables from the join that do not effect the result */
if( pWInfo->nLevel>=2
- && pDistinctSet!=0
+ && pResultSet!=0
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
){
- Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pDistinctSet);
+ Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
if( sWLB.pOrderBy ){
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
@@ -131379,10 +134693,12 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
- sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
- VdbeCoverage(v);
- VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
- VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
+ if( pIn->eEndLoopOp!=OP_Noop ){
+ sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
+ }
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
}
@@ -131401,13 +134717,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
}
#endif
if( pLevel->iLeftJoin ){
+ int ws = pLoop->wsFlags;
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
- || (pLoop->wsFlags & WHERE_INDEXED)!=0 );
- if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
+ assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
+ if( (ws & WHERE_IDX_ONLY)==0 ){
sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
}
- if( pLoop->wsFlags & WHERE_INDEXED ){
+ if( (ws & WHERE_INDEXED)
+ || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx)
+ ){
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
}
if( pLevel->op==OP_Return ){
@@ -131440,33 +134758,13 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** the co-routine into OP_Copy of result contained in a register.
** OP_Rowid becomes OP_Null.
*/
- if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){
- translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
+ if( pTabItem->fg.viaCoroutine ){
+ testcase( pParse->db->mallocFailed );
+ translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
pTabItem->regResult, 0);
continue;
}
- /* Close all of the cursors that were opened by sqlite3WhereBegin.
- ** Except, do not close cursors that will be reused by the OR optimization
- ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors
- ** created for the ONEPASS optimization.
- */
- if( (pTab->tabFlags & TF_Ephemeral)==0
- && pTab->pSelect==0
- && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
- ){
- int ws = pLoop->wsFlags;
- if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
- sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
- }
- if( (ws & WHERE_INDEXED)!=0
- && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
- && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
- ){
- sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
- }
- }
-
/* If this scan uses an index, make VDBE code substitutions to read data
** from the index instead of from the table where possible. In some cases
** this optimization prevents the table from ever being read, which can
@@ -131505,7 +134803,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
pOp->p2 = x;
pOp->p1 = pLevel->iIdxCur;
}
- assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 );
+ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0
+ || pWInfo->eOnePass );
}else if( pOp->opcode==OP_Rowid ){
pOp->p1 = pLevel->iIdxCur;
pOp->opcode = OP_IdxRowid;
@@ -131570,6 +134869,19 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
#define YYPARSEFREENEVERNULL 1
/*
+** In the amalgamation, the parse.c file generated by lemon and the
+** tokenize.c file are concatenated. In that case, sqlite3RunParser()
+** has access to the the size of the yyParser object and so the parser
+** engine can be allocated from stack. In that case, only the
+** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked
+** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be
+** omitted.
+*/
+#ifdef SQLITE_AMALGAMATION
+# define sqlite3Parser_ENGINEALWAYSONSTACK 1
+#endif
+
+/*
** Alternative datatype for the argument to the malloc() routine passed
** into sqlite3ParserAlloc(). The default is size_t.
*/
@@ -131585,15 +134897,6 @@ struct LimitVal {
};
/*
-** An instance of this structure is used to store the LIKE,
-** GLOB, NOT LIKE, and NOT GLOB operators.
-*/
-struct LikeOp {
- Token eOperator; /* "like" or "glob" or "regexp" */
- int bNot; /* True if the NOT keyword is present */
-};
-
-/*
** An instance of the following structure describes the event of a
** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
** TK_DELETE, or TK_INSTEAD. If the event is of the form
@@ -131605,11 +134908,6 @@ struct LikeOp {
struct TrigEvent { int a; IdList * b; };
/*
-** An instance of this structure holds the ATTACH key and the key type.
-*/
-struct AttachKey { int type; Token key; };
-
-/*
** Disable lookaside memory allocation for objects that might be
** shared across database connections.
*/
@@ -131655,7 +134953,24 @@ static void disableLookaside(Parse *pParse){
** that created the expression.
*/
static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
- pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, &t);
+ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
+ if( p ){
+ memset(p, 0, sizeof(Expr));
+ p->op = (u8)op;
+ p->flags = EP_Leaf;
+ p->iAgg = -1;
+ p->u.zToken = (char*)&p[1];
+ memcpy(p->u.zToken, t.z, t.n);
+ p->u.zToken[t.n] = 0;
+ if( sqlite3Isquote(p->u.zToken[0]) ){
+ if( p->u.zToken[0]=='"' ) p->flags |= EP_DblQuoted;
+ sqlite3Dequote(p->u.zToken);
+ }
+#if SQLITE_MAX_EXPR_DEPTH>0
+ p->nHeight = 1;
+#endif
+ }
+ pOut->pExpr = p;
pOut->zStart = t.z;
pOut->zEnd = &t.z[t.n];
}
@@ -131669,7 +134984,7 @@ static void disableLookaside(Parse *pParse){
ExprSpan *pLeft, /* The left operand, and output */
ExprSpan *pRight /* The right operand */
){
- pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
+ pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr);
pLeft->zEnd = pRight->zEnd;
}
@@ -131678,7 +134993,7 @@ static void disableLookaside(Parse *pParse){
*/
static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
if( doNot ){
- pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0);
+ pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0);
}
}
@@ -131690,7 +135005,7 @@ static void disableLookaside(Parse *pParse){
ExprSpan *pOperand, /* The operand, and output */
Token *pPostOp /* The operand token for setting the span */
){
- pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
pOperand->zEnd = &pPostOp->z[pPostOp->n];
}
@@ -131715,7 +135030,7 @@ static void disableLookaside(Parse *pParse){
Token *pPreOp /* The operand token for setting the span */
){
pOut->zStart = pPreOp->z;
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
pOut->zEnd = pOperand->zEnd;
}
@@ -131818,7 +135133,6 @@ typedef union {
With* yy285;
struct TrigEvent yy332;
struct LimitVal yy354;
- struct LikeOp yy392;
struct {int value; int mask;} yy497;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
@@ -131829,16 +135143,16 @@ typedef union {
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
#define YYFALLBACK 1
-#define YYNSTATE 443
-#define YYNRULE 328
-#define YY_MAX_SHIFT 442
-#define YY_MIN_SHIFTREDUCE 653
-#define YY_MAX_SHIFTREDUCE 980
-#define YY_MIN_REDUCE 981
-#define YY_MAX_REDUCE 1308
-#define YY_ERROR_ACTION 1309
-#define YY_ACCEPT_ACTION 1310
-#define YY_NO_ACTION 1311
+#define YYNSTATE 456
+#define YYNRULE 332
+#define YY_MAX_SHIFT 455
+#define YY_MIN_SHIFTREDUCE 668
+#define YY_MAX_SHIFTREDUCE 999
+#define YY_MIN_REDUCE 1000
+#define YY_MAX_REDUCE 1331
+#define YY_ERROR_ACTION 1332
+#define YY_ACCEPT_ACTION 1333
+#define YY_NO_ACTION 1334
/************* End control #defines *******************************************/
/* Define the yytestcase() macro to be a no-op if is not already defined
@@ -131870,7 +135184,7 @@ typedef union {
**
** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
** and YY_MAX_REDUCE
-
+**
** N == YY_ERROR_ACTION A syntax error has occurred.
**
** N == YY_ACCEPT_ACTION The parser accepts its input.
@@ -131879,16 +135193,20 @@ typedef union {
** slots in the yy_action[] table.
**
** The action table is constructed as a single large table named yy_action[].
-** Given state S and lookahead X, the action is computed as
+** Given state S and lookahead X, the action is computed as either:
**
-** yy_action[ yy_shift_ofst[S] + X ]
+** (A) N = yy_action[ yy_shift_ofst[S] + X ]
+** (B) N = yy_default[S]
**
-** If the index value yy_shift_ofst[S]+X is out of range or if the value
-** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
-** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
-** and that yy_default[S] should be used instead.
+** The (A) formula is preferred. The B formula is used instead if:
+** (1) The yy_shift_ofst[S]+X value is out of range, or
+** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or
+** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT.
+** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that
+** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
+** Hence only tests (1) and (2) need to be evaluated.)
**
-** The formula above is for computing the action when the lookahead is
+** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the yy_reduce_ofst[] array is used in place of
** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
@@ -131906,159 +135224,165 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (1507)
+#define YY_ACTTAB_COUNT (1567)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 317, 814, 341, 808, 5, 195, 195, 802, 93, 94,
- /* 10 */ 84, 823, 823, 835, 838, 827, 827, 91, 91, 92,
- /* 20 */ 92, 92, 92, 293, 90, 90, 90, 90, 89, 89,
- /* 30 */ 88, 88, 88, 87, 341, 317, 958, 958, 807, 807,
- /* 40 */ 807, 928, 344, 93, 94, 84, 823, 823, 835, 838,
- /* 50 */ 827, 827, 91, 91, 92, 92, 92, 92, 328, 90,
- /* 60 */ 90, 90, 90, 89, 89, 88, 88, 88, 87, 341,
- /* 70 */ 89, 89, 88, 88, 88, 87, 341, 776, 958, 958,
- /* 80 */ 317, 88, 88, 88, 87, 341, 777, 69, 93, 94,
- /* 90 */ 84, 823, 823, 835, 838, 827, 827, 91, 91, 92,
- /* 100 */ 92, 92, 92, 437, 90, 90, 90, 90, 89, 89,
- /* 110 */ 88, 88, 88, 87, 341, 1310, 147, 147, 2, 317,
- /* 120 */ 76, 25, 74, 49, 49, 87, 341, 93, 94, 84,
- /* 130 */ 823, 823, 835, 838, 827, 827, 91, 91, 92, 92,
- /* 140 */ 92, 92, 95, 90, 90, 90, 90, 89, 89, 88,
- /* 150 */ 88, 88, 87, 341, 939, 939, 317, 260, 415, 400,
- /* 160 */ 398, 58, 737, 737, 93, 94, 84, 823, 823, 835,
- /* 170 */ 838, 827, 827, 91, 91, 92, 92, 92, 92, 57,
- /* 180 */ 90, 90, 90, 90, 89, 89, 88, 88, 88, 87,
- /* 190 */ 341, 317, 1253, 928, 344, 269, 940, 941, 242, 93,
- /* 200 */ 94, 84, 823, 823, 835, 838, 827, 827, 91, 91,
- /* 210 */ 92, 92, 92, 92, 293, 90, 90, 90, 90, 89,
- /* 220 */ 89, 88, 88, 88, 87, 341, 317, 919, 1303, 793,
- /* 230 */ 691, 1303, 724, 724, 93, 94, 84, 823, 823, 835,
- /* 240 */ 838, 827, 827, 91, 91, 92, 92, 92, 92, 337,
- /* 250 */ 90, 90, 90, 90, 89, 89, 88, 88, 88, 87,
- /* 260 */ 341, 317, 114, 919, 1304, 684, 395, 1304, 124, 93,
- /* 270 */ 94, 84, 823, 823, 835, 838, 827, 827, 91, 91,
- /* 280 */ 92, 92, 92, 92, 683, 90, 90, 90, 90, 89,
- /* 290 */ 89, 88, 88, 88, 87, 341, 317, 86, 83, 169,
- /* 300 */ 801, 917, 234, 399, 93, 94, 84, 823, 823, 835,
- /* 310 */ 838, 827, 827, 91, 91, 92, 92, 92, 92, 686,
- /* 320 */ 90, 90, 90, 90, 89, 89, 88, 88, 88, 87,
- /* 330 */ 341, 317, 436, 742, 86, 83, 169, 917, 741, 93,
- /* 340 */ 94, 84, 823, 823, 835, 838, 827, 827, 91, 91,
- /* 350 */ 92, 92, 92, 92, 902, 90, 90, 90, 90, 89,
- /* 360 */ 89, 88, 88, 88, 87, 341, 317, 321, 434, 434,
- /* 370 */ 434, 1, 722, 722, 93, 94, 84, 823, 823, 835,
- /* 380 */ 838, 827, 827, 91, 91, 92, 92, 92, 92, 190,
- /* 390 */ 90, 90, 90, 90, 89, 89, 88, 88, 88, 87,
- /* 400 */ 341, 317, 685, 292, 939, 939, 150, 977, 310, 93,
- /* 410 */ 94, 84, 823, 823, 835, 838, 827, 827, 91, 91,
- /* 420 */ 92, 92, 92, 92, 437, 90, 90, 90, 90, 89,
- /* 430 */ 89, 88, 88, 88, 87, 341, 926, 2, 372, 719,
- /* 440 */ 698, 369, 950, 317, 49, 49, 940, 941, 719, 177,
- /* 450 */ 72, 93, 94, 84, 823, 823, 835, 838, 827, 827,
- /* 460 */ 91, 91, 92, 92, 92, 92, 322, 90, 90, 90,
- /* 470 */ 90, 89, 89, 88, 88, 88, 87, 341, 317, 415,
- /* 480 */ 405, 824, 824, 836, 839, 75, 93, 82, 84, 823,
- /* 490 */ 823, 835, 838, 827, 827, 91, 91, 92, 92, 92,
- /* 500 */ 92, 430, 90, 90, 90, 90, 89, 89, 88, 88,
- /* 510 */ 88, 87, 341, 317, 340, 340, 340, 658, 659, 660,
- /* 520 */ 333, 288, 94, 84, 823, 823, 835, 838, 827, 827,
- /* 530 */ 91, 91, 92, 92, 92, 92, 437, 90, 90, 90,
- /* 540 */ 90, 89, 89, 88, 88, 88, 87, 341, 317, 882,
- /* 550 */ 882, 375, 828, 66, 330, 409, 49, 49, 84, 823,
- /* 560 */ 823, 835, 838, 827, 827, 91, 91, 92, 92, 92,
- /* 570 */ 92, 351, 90, 90, 90, 90, 89, 89, 88, 88,
- /* 580 */ 88, 87, 341, 80, 432, 742, 3, 1180, 351, 350,
- /* 590 */ 741, 334, 796, 939, 939, 761, 80, 432, 278, 3,
- /* 600 */ 204, 161, 279, 393, 274, 392, 191, 362, 437, 277,
- /* 610 */ 745, 77, 78, 272, 800, 254, 355, 243, 79, 342,
- /* 620 */ 342, 86, 83, 169, 77, 78, 234, 399, 49, 49,
- /* 630 */ 435, 79, 342, 342, 437, 940, 941, 186, 442, 655,
- /* 640 */ 390, 387, 386, 435, 235, 213, 108, 421, 761, 351,
- /* 650 */ 437, 385, 167, 732, 10, 10, 124, 124, 671, 814,
- /* 660 */ 421, 439, 438, 415, 414, 802, 362, 168, 327, 124,
- /* 670 */ 49, 49, 814, 219, 439, 438, 800, 186, 802, 326,
- /* 680 */ 390, 387, 386, 437, 1248, 1248, 23, 939, 939, 80,
- /* 690 */ 432, 385, 3, 761, 416, 876, 807, 807, 807, 809,
- /* 700 */ 19, 290, 149, 49, 49, 415, 396, 260, 910, 807,
- /* 710 */ 807, 807, 809, 19, 312, 237, 145, 77, 78, 746,
- /* 720 */ 168, 702, 437, 149, 79, 342, 342, 114, 358, 940,
- /* 730 */ 941, 302, 223, 397, 345, 313, 435, 260, 415, 417,
- /* 740 */ 858, 374, 31, 31, 80, 432, 761, 3, 348, 92,
- /* 750 */ 92, 92, 92, 421, 90, 90, 90, 90, 89, 89,
- /* 760 */ 88, 88, 88, 87, 341, 814, 114, 439, 438, 796,
- /* 770 */ 367, 802, 77, 78, 701, 796, 124, 1187, 220, 79,
- /* 780 */ 342, 342, 124, 747, 734, 939, 939, 775, 404, 939,
- /* 790 */ 939, 435, 254, 360, 253, 402, 895, 346, 254, 360,
- /* 800 */ 253, 774, 807, 807, 807, 809, 19, 800, 421, 90,
- /* 810 */ 90, 90, 90, 89, 89, 88, 88, 88, 87, 341,
- /* 820 */ 814, 114, 439, 438, 939, 939, 802, 940, 941, 114,
- /* 830 */ 437, 940, 941, 86, 83, 169, 192, 166, 309, 979,
- /* 840 */ 70, 432, 700, 3, 382, 870, 238, 86, 83, 169,
- /* 850 */ 10, 10, 361, 406, 763, 190, 222, 807, 807, 807,
- /* 860 */ 809, 19, 870, 872, 329, 24, 940, 941, 77, 78,
- /* 870 */ 359, 437, 335, 260, 218, 79, 342, 342, 437, 307,
- /* 880 */ 306, 305, 207, 303, 339, 338, 668, 435, 339, 338,
- /* 890 */ 407, 10, 10, 762, 216, 216, 939, 939, 49, 49,
- /* 900 */ 437, 260, 97, 241, 421, 225, 402, 189, 188, 187,
- /* 910 */ 309, 918, 980, 149, 221, 898, 814, 868, 439, 438,
- /* 920 */ 10, 10, 802, 870, 915, 316, 898, 163, 162, 171,
- /* 930 */ 249, 240, 322, 410, 412, 687, 687, 272, 940, 941,
- /* 940 */ 239, 965, 901, 437, 226, 403, 226, 437, 963, 367,
- /* 950 */ 964, 173, 248, 807, 807, 807, 809, 19, 174, 367,
- /* 960 */ 899, 124, 172, 48, 48, 9, 9, 35, 35, 966,
- /* 970 */ 966, 899, 363, 966, 966, 814, 900, 808, 725, 939,
- /* 980 */ 939, 802, 895, 318, 980, 324, 125, 900, 726, 420,
- /* 990 */ 92, 92, 92, 92, 85, 90, 90, 90, 90, 89,
- /* 1000 */ 89, 88, 88, 88, 87, 341, 216, 216, 437, 946,
- /* 1010 */ 349, 292, 807, 807, 807, 114, 291, 693, 402, 705,
- /* 1020 */ 890, 940, 941, 437, 245, 889, 247, 437, 36, 36,
- /* 1030 */ 437, 353, 391, 437, 260, 252, 260, 437, 361, 437,
- /* 1040 */ 706, 437, 370, 12, 12, 224, 437, 27, 27, 437,
- /* 1050 */ 37, 37, 437, 38, 38, 752, 368, 39, 39, 28,
- /* 1060 */ 28, 29, 29, 215, 166, 331, 40, 40, 437, 41,
- /* 1070 */ 41, 437, 42, 42, 437, 866, 246, 731, 437, 879,
- /* 1080 */ 437, 256, 437, 878, 437, 267, 437, 261, 11, 11,
- /* 1090 */ 437, 43, 43, 437, 99, 99, 437, 373, 44, 44,
- /* 1100 */ 45, 45, 32, 32, 46, 46, 47, 47, 437, 426,
- /* 1110 */ 33, 33, 776, 116, 116, 437, 117, 117, 437, 124,
- /* 1120 */ 437, 777, 437, 260, 437, 957, 437, 352, 118, 118,
- /* 1130 */ 437, 195, 437, 111, 437, 53, 53, 264, 34, 34,
- /* 1140 */ 100, 100, 50, 50, 101, 101, 102, 102, 437, 260,
- /* 1150 */ 98, 98, 115, 115, 113, 113, 437, 262, 437, 265,
- /* 1160 */ 437, 943, 958, 437, 727, 437, 681, 437, 106, 106,
- /* 1170 */ 68, 437, 893, 730, 437, 365, 105, 105, 103, 103,
- /* 1180 */ 104, 104, 217, 52, 52, 54, 54, 51, 51, 694,
- /* 1190 */ 259, 26, 26, 266, 30, 30, 677, 323, 433, 323,
- /* 1200 */ 674, 423, 427, 943, 958, 114, 114, 431, 681, 865,
- /* 1210 */ 1277, 233, 366, 714, 112, 20, 154, 704, 703, 810,
- /* 1220 */ 914, 55, 159, 311, 798, 255, 383, 194, 68, 200,
- /* 1230 */ 21, 694, 268, 114, 114, 114, 270, 711, 712, 68,
- /* 1240 */ 114, 739, 770, 715, 71, 194, 861, 875, 875, 200,
- /* 1250 */ 696, 865, 874, 874, 679, 699, 273, 110, 229, 419,
- /* 1260 */ 768, 810, 799, 378, 748, 759, 418, 210, 294, 281,
- /* 1270 */ 295, 806, 283, 682, 676, 665, 664, 666, 933, 151,
- /* 1280 */ 285, 7, 1267, 308, 251, 790, 354, 244, 892, 364,
- /* 1290 */ 287, 422, 300, 164, 160, 936, 974, 127, 197, 137,
- /* 1300 */ 909, 907, 971, 388, 276, 863, 862, 56, 698, 325,
- /* 1310 */ 148, 59, 122, 66, 356, 381, 357, 176, 152, 62,
- /* 1320 */ 371, 130, 877, 181, 377, 760, 211, 182, 132, 133,
- /* 1330 */ 134, 135, 258, 146, 140, 795, 787, 263, 183, 379,
- /* 1340 */ 667, 394, 184, 332, 894, 314, 718, 717, 857, 716,
- /* 1350 */ 696, 315, 709, 690, 65, 196, 6, 408, 289, 708,
- /* 1360 */ 275, 689, 688, 948, 756, 757, 280, 282, 425, 755,
- /* 1370 */ 284, 336, 73, 67, 754, 429, 411, 96, 286, 413,
- /* 1380 */ 205, 934, 673, 22, 209, 440, 119, 120, 109, 206,
- /* 1390 */ 208, 441, 662, 661, 656, 843, 654, 343, 158, 236,
- /* 1400 */ 170, 347, 107, 227, 121, 738, 873, 298, 296, 297,
- /* 1410 */ 299, 871, 794, 128, 129, 728, 230, 131, 175, 250,
- /* 1420 */ 888, 136, 138, 231, 232, 139, 60, 61, 891, 178,
- /* 1430 */ 179, 887, 8, 13, 180, 257, 880, 968, 194, 141,
- /* 1440 */ 142, 376, 153, 670, 380, 185, 143, 277, 63, 384,
- /* 1450 */ 14, 707, 271, 15, 389, 64, 319, 320, 126, 228,
- /* 1460 */ 813, 812, 841, 736, 123, 16, 401, 740, 4, 769,
- /* 1470 */ 165, 212, 214, 193, 144, 764, 71, 68, 17, 18,
- /* 1480 */ 856, 842, 840, 897, 845, 896, 199, 198, 923, 155,
- /* 1490 */ 424, 929, 924, 156, 201, 202, 428, 844, 157, 203,
- /* 1500 */ 811, 680, 81, 1269, 1268, 301, 304,
+ /* 0 */ 325, 832, 351, 825, 5, 203, 203, 819, 99, 100,
+ /* 10 */ 90, 978, 978, 853, 856, 845, 845, 97, 97, 98,
+ /* 20 */ 98, 98, 98, 301, 96, 96, 96, 96, 95, 95,
+ /* 30 */ 94, 94, 94, 93, 351, 325, 976, 976, 824, 824,
+ /* 40 */ 826, 946, 354, 99, 100, 90, 978, 978, 853, 856,
+ /* 50 */ 845, 845, 97, 97, 98, 98, 98, 98, 338, 96,
+ /* 60 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
+ /* 70 */ 95, 95, 94, 94, 94, 93, 351, 791, 976, 976,
+ /* 80 */ 325, 94, 94, 94, 93, 351, 792, 75, 99, 100,
+ /* 90 */ 90, 978, 978, 853, 856, 845, 845, 97, 97, 98,
+ /* 100 */ 98, 98, 98, 450, 96, 96, 96, 96, 95, 95,
+ /* 110 */ 94, 94, 94, 93, 351, 1333, 155, 155, 2, 325,
+ /* 120 */ 275, 146, 132, 52, 52, 93, 351, 99, 100, 90,
+ /* 130 */ 978, 978, 853, 856, 845, 845, 97, 97, 98, 98,
+ /* 140 */ 98, 98, 101, 96, 96, 96, 96, 95, 95, 94,
+ /* 150 */ 94, 94, 93, 351, 957, 957, 325, 268, 428, 413,
+ /* 160 */ 411, 61, 752, 752, 99, 100, 90, 978, 978, 853,
+ /* 170 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 60,
+ /* 180 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 190 */ 351, 325, 270, 329, 273, 277, 958, 959, 250, 99,
+ /* 200 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 210 */ 98, 98, 98, 98, 301, 96, 96, 96, 96, 95,
+ /* 220 */ 95, 94, 94, 94, 93, 351, 325, 937, 1326, 698,
+ /* 230 */ 706, 1326, 242, 412, 99, 100, 90, 978, 978, 853,
+ /* 240 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 347,
+ /* 250 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 260 */ 351, 325, 937, 1327, 384, 699, 1327, 381, 379, 99,
+ /* 270 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 280 */ 98, 98, 98, 98, 701, 96, 96, 96, 96, 95,
+ /* 290 */ 95, 94, 94, 94, 93, 351, 325, 92, 89, 178,
+ /* 300 */ 833, 935, 373, 700, 99, 100, 90, 978, 978, 853,
+ /* 310 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 375,
+ /* 320 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 330 */ 351, 325, 1275, 946, 354, 818, 935, 739, 739, 99,
+ /* 340 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 350 */ 98, 98, 98, 98, 230, 96, 96, 96, 96, 95,
+ /* 360 */ 95, 94, 94, 94, 93, 351, 325, 968, 227, 92,
+ /* 370 */ 89, 178, 373, 300, 99, 100, 90, 978, 978, 853,
+ /* 380 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 920,
+ /* 390 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 400 */ 351, 325, 449, 447, 447, 447, 147, 737, 737, 99,
+ /* 410 */ 100, 90, 978, 978, 853, 856, 845, 845, 97, 97,
+ /* 420 */ 98, 98, 98, 98, 296, 96, 96, 96, 96, 95,
+ /* 430 */ 95, 94, 94, 94, 93, 351, 325, 419, 231, 957,
+ /* 440 */ 957, 158, 25, 422, 99, 100, 90, 978, 978, 853,
+ /* 450 */ 856, 845, 845, 97, 97, 98, 98, 98, 98, 450,
+ /* 460 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 470 */ 351, 443, 224, 224, 420, 957, 957, 961, 325, 52,
+ /* 480 */ 52, 958, 959, 176, 415, 78, 99, 100, 90, 978,
+ /* 490 */ 978, 853, 856, 845, 845, 97, 97, 98, 98, 98,
+ /* 500 */ 98, 379, 96, 96, 96, 96, 95, 95, 94, 94,
+ /* 510 */ 94, 93, 351, 325, 428, 418, 298, 958, 959, 961,
+ /* 520 */ 81, 99, 88, 90, 978, 978, 853, 856, 845, 845,
+ /* 530 */ 97, 97, 98, 98, 98, 98, 717, 96, 96, 96,
+ /* 540 */ 96, 95, 95, 94, 94, 94, 93, 351, 325, 842,
+ /* 550 */ 842, 854, 857, 996, 318, 343, 379, 100, 90, 978,
+ /* 560 */ 978, 853, 856, 845, 845, 97, 97, 98, 98, 98,
+ /* 570 */ 98, 450, 96, 96, 96, 96, 95, 95, 94, 94,
+ /* 580 */ 94, 93, 351, 325, 350, 350, 350, 260, 377, 340,
+ /* 590 */ 928, 52, 52, 90, 978, 978, 853, 856, 845, 845,
+ /* 600 */ 97, 97, 98, 98, 98, 98, 361, 96, 96, 96,
+ /* 610 */ 96, 95, 95, 94, 94, 94, 93, 351, 86, 445,
+ /* 620 */ 846, 3, 1202, 361, 360, 378, 344, 813, 957, 957,
+ /* 630 */ 1299, 86, 445, 729, 3, 212, 169, 287, 405, 282,
+ /* 640 */ 404, 199, 232, 450, 300, 760, 83, 84, 280, 245,
+ /* 650 */ 262, 365, 251, 85, 352, 352, 92, 89, 178, 83,
+ /* 660 */ 84, 242, 412, 52, 52, 448, 85, 352, 352, 246,
+ /* 670 */ 958, 959, 194, 455, 670, 402, 399, 398, 448, 243,
+ /* 680 */ 221, 114, 434, 776, 361, 450, 397, 268, 747, 224,
+ /* 690 */ 224, 132, 132, 198, 832, 434, 452, 451, 428, 427,
+ /* 700 */ 819, 415, 734, 713, 132, 52, 52, 832, 268, 452,
+ /* 710 */ 451, 734, 194, 819, 363, 402, 399, 398, 450, 1270,
+ /* 720 */ 1270, 23, 957, 957, 86, 445, 397, 3, 228, 429,
+ /* 730 */ 894, 824, 824, 826, 827, 19, 203, 720, 52, 52,
+ /* 740 */ 428, 408, 439, 249, 824, 824, 826, 827, 19, 229,
+ /* 750 */ 403, 153, 83, 84, 761, 177, 241, 450, 721, 85,
+ /* 760 */ 352, 352, 120, 157, 958, 959, 58, 976, 409, 355,
+ /* 770 */ 330, 448, 268, 428, 430, 320, 790, 32, 32, 86,
+ /* 780 */ 445, 776, 3, 341, 98, 98, 98, 98, 434, 96,
+ /* 790 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 351,
+ /* 800 */ 832, 120, 452, 451, 813, 886, 819, 83, 84, 976,
+ /* 810 */ 813, 132, 410, 919, 85, 352, 352, 132, 407, 789,
+ /* 820 */ 957, 957, 92, 89, 178, 916, 448, 262, 370, 261,
+ /* 830 */ 82, 913, 80, 262, 370, 261, 776, 824, 824, 826,
+ /* 840 */ 827, 19, 933, 434, 96, 96, 96, 96, 95, 95,
+ /* 850 */ 94, 94, 94, 93, 351, 832, 74, 452, 451, 957,
+ /* 860 */ 957, 819, 958, 959, 120, 92, 89, 178, 944, 2,
+ /* 870 */ 917, 964, 268, 1, 975, 76, 445, 762, 3, 708,
+ /* 880 */ 900, 900, 387, 957, 957, 757, 918, 371, 740, 778,
+ /* 890 */ 756, 257, 824, 824, 826, 827, 19, 417, 741, 450,
+ /* 900 */ 24, 958, 959, 83, 84, 369, 957, 957, 177, 226,
+ /* 910 */ 85, 352, 352, 884, 315, 314, 313, 215, 311, 10,
+ /* 920 */ 10, 683, 448, 349, 348, 958, 959, 908, 777, 157,
+ /* 930 */ 120, 957, 957, 337, 776, 416, 711, 310, 450, 434,
+ /* 940 */ 450, 321, 450, 791, 103, 200, 175, 450, 958, 959,
+ /* 950 */ 907, 832, 792, 452, 451, 9, 9, 819, 10, 10,
+ /* 960 */ 52, 52, 51, 51, 180, 716, 248, 10, 10, 171,
+ /* 970 */ 170, 167, 339, 958, 959, 247, 984, 702, 702, 450,
+ /* 980 */ 715, 233, 686, 982, 888, 983, 182, 913, 824, 824,
+ /* 990 */ 826, 827, 19, 183, 256, 423, 132, 181, 394, 10,
+ /* 1000 */ 10, 888, 890, 749, 957, 957, 916, 268, 985, 198,
+ /* 1010 */ 985, 349, 348, 425, 415, 299, 817, 832, 326, 825,
+ /* 1020 */ 120, 332, 133, 819, 268, 98, 98, 98, 98, 91,
+ /* 1030 */ 96, 96, 96, 96, 95, 95, 94, 94, 94, 93,
+ /* 1040 */ 351, 157, 810, 371, 382, 359, 958, 959, 358, 268,
+ /* 1050 */ 450, 917, 368, 324, 824, 824, 826, 450, 709, 450,
+ /* 1060 */ 264, 380, 888, 450, 876, 746, 253, 918, 255, 433,
+ /* 1070 */ 36, 36, 234, 450, 234, 120, 269, 37, 37, 12,
+ /* 1080 */ 12, 334, 272, 27, 27, 450, 330, 118, 450, 162,
+ /* 1090 */ 742, 280, 450, 38, 38, 450, 985, 356, 985, 450,
+ /* 1100 */ 709, 1209, 450, 132, 450, 39, 39, 450, 40, 40,
+ /* 1110 */ 450, 362, 41, 41, 450, 42, 42, 450, 254, 28,
+ /* 1120 */ 28, 450, 29, 29, 31, 31, 450, 43, 43, 450,
+ /* 1130 */ 44, 44, 450, 714, 45, 45, 450, 11, 11, 767,
+ /* 1140 */ 450, 46, 46, 450, 268, 450, 105, 105, 450, 47,
+ /* 1150 */ 47, 450, 48, 48, 450, 237, 33, 33, 450, 172,
+ /* 1160 */ 49, 49, 450, 50, 50, 34, 34, 274, 122, 122,
+ /* 1170 */ 450, 123, 123, 450, 124, 124, 450, 897, 56, 56,
+ /* 1180 */ 450, 896, 35, 35, 450, 267, 450, 817, 450, 817,
+ /* 1190 */ 106, 106, 450, 53, 53, 385, 107, 107, 450, 817,
+ /* 1200 */ 108, 108, 817, 450, 104, 104, 121, 121, 119, 119,
+ /* 1210 */ 450, 117, 112, 112, 450, 276, 450, 225, 111, 111,
+ /* 1220 */ 450, 730, 450, 109, 109, 450, 673, 674, 675, 911,
+ /* 1230 */ 110, 110, 317, 998, 55, 55, 57, 57, 692, 331,
+ /* 1240 */ 54, 54, 26, 26, 696, 30, 30, 317, 936, 197,
+ /* 1250 */ 196, 195, 335, 281, 336, 446, 331, 745, 689, 436,
+ /* 1260 */ 440, 444, 120, 72, 386, 223, 175, 345, 757, 932,
+ /* 1270 */ 20, 286, 319, 756, 815, 372, 374, 202, 202, 202,
+ /* 1280 */ 263, 395, 285, 74, 208, 21, 696, 719, 718, 883,
+ /* 1290 */ 120, 120, 120, 120, 120, 754, 278, 828, 77, 74,
+ /* 1300 */ 726, 727, 785, 783, 879, 202, 999, 208, 893, 892,
+ /* 1310 */ 893, 892, 694, 816, 763, 116, 774, 1289, 431, 432,
+ /* 1320 */ 302, 999, 390, 303, 823, 697, 691, 680, 159, 289,
+ /* 1330 */ 679, 883, 681, 951, 291, 218, 293, 7, 316, 828,
+ /* 1340 */ 173, 805, 259, 364, 252, 910, 376, 713, 295, 435,
+ /* 1350 */ 308, 168, 954, 993, 135, 400, 990, 284, 881, 880,
+ /* 1360 */ 205, 927, 925, 59, 333, 62, 144, 156, 130, 72,
+ /* 1370 */ 802, 366, 367, 393, 137, 185, 189, 160, 139, 383,
+ /* 1380 */ 67, 895, 140, 141, 142, 148, 389, 812, 775, 266,
+ /* 1390 */ 219, 190, 154, 391, 912, 875, 271, 406, 191, 322,
+ /* 1400 */ 682, 733, 192, 342, 732, 724, 731, 711, 723, 421,
+ /* 1410 */ 705, 71, 323, 6, 204, 771, 288, 79, 297, 346,
+ /* 1420 */ 772, 704, 290, 283, 703, 770, 292, 294, 966, 239,
+ /* 1430 */ 769, 102, 861, 438, 426, 240, 424, 442, 73, 213,
+ /* 1440 */ 688, 238, 22, 453, 952, 214, 217, 216, 454, 677,
+ /* 1450 */ 676, 671, 753, 125, 115, 235, 126, 669, 353, 166,
+ /* 1460 */ 127, 244, 179, 357, 306, 304, 305, 307, 113, 891,
+ /* 1470 */ 327, 889, 811, 328, 134, 128, 136, 138, 743, 258,
+ /* 1480 */ 906, 184, 143, 129, 909, 186, 63, 64, 145, 187,
+ /* 1490 */ 905, 65, 8, 66, 13, 188, 202, 898, 265, 149,
+ /* 1500 */ 987, 388, 150, 685, 161, 392, 285, 193, 279, 396,
+ /* 1510 */ 151, 401, 68, 14, 15, 722, 69, 236, 831, 131,
+ /* 1520 */ 830, 859, 70, 751, 16, 414, 755, 4, 174, 220,
+ /* 1530 */ 222, 784, 201, 152, 779, 77, 74, 17, 18, 874,
+ /* 1540 */ 860, 858, 915, 863, 914, 207, 206, 941, 163, 437,
+ /* 1550 */ 947, 942, 164, 209, 1002, 441, 862, 165, 210, 829,
+ /* 1560 */ 695, 87, 312, 211, 1291, 1290, 309,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 19, 95, 53, 97, 22, 24, 24, 101, 27, 28,
@@ -132073,281 +135397,290 @@ static const YYCODETYPE yy_lookahead[] = {
/* 90 */ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
/* 100 */ 39, 40, 41, 152, 43, 44, 45, 46, 47, 48,
/* 110 */ 49, 50, 51, 52, 53, 144, 145, 146, 147, 19,
- /* 120 */ 137, 22, 139, 172, 173, 52, 53, 27, 28, 29,
+ /* 120 */ 16, 22, 92, 172, 173, 52, 53, 27, 28, 29,
/* 130 */ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
/* 140 */ 40, 41, 81, 43, 44, 45, 46, 47, 48, 49,
/* 150 */ 50, 51, 52, 53, 55, 56, 19, 152, 207, 208,
/* 160 */ 115, 24, 117, 118, 27, 28, 29, 30, 31, 32,
/* 170 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 79,
/* 180 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 190 */ 53, 19, 0, 1, 2, 23, 97, 98, 193, 27,
+ /* 190 */ 53, 19, 88, 157, 90, 23, 97, 98, 193, 27,
/* 200 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
/* 210 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47,
- /* 220 */ 48, 49, 50, 51, 52, 53, 19, 22, 23, 163,
- /* 230 */ 23, 26, 190, 191, 27, 28, 29, 30, 31, 32,
+ /* 220 */ 48, 49, 50, 51, 52, 53, 19, 22, 23, 172,
+ /* 230 */ 23, 26, 119, 120, 27, 28, 29, 30, 31, 32,
/* 240 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 187,
/* 250 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 260 */ 53, 19, 196, 22, 23, 23, 49, 26, 92, 27,
+ /* 260 */ 53, 19, 22, 23, 228, 23, 26, 231, 152, 27,
/* 270 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
/* 280 */ 38, 39, 40, 41, 172, 43, 44, 45, 46, 47,
/* 290 */ 48, 49, 50, 51, 52, 53, 19, 221, 222, 223,
- /* 300 */ 23, 96, 119, 120, 27, 28, 29, 30, 31, 32,
- /* 310 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 172,
+ /* 300 */ 23, 96, 152, 172, 27, 28, 29, 30, 31, 32,
+ /* 310 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152,
/* 320 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 330 */ 53, 19, 152, 116, 221, 222, 223, 96, 121, 27,
+ /* 330 */ 53, 19, 0, 1, 2, 23, 96, 190, 191, 27,
/* 340 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- /* 350 */ 38, 39, 40, 41, 241, 43, 44, 45, 46, 47,
- /* 360 */ 48, 49, 50, 51, 52, 53, 19, 157, 168, 169,
- /* 370 */ 170, 22, 190, 191, 27, 28, 29, 30, 31, 32,
- /* 380 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 30,
+ /* 350 */ 38, 39, 40, 41, 238, 43, 44, 45, 46, 47,
+ /* 360 */ 48, 49, 50, 51, 52, 53, 19, 185, 218, 221,
+ /* 370 */ 222, 223, 152, 152, 27, 28, 29, 30, 31, 32,
+ /* 380 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 241,
/* 390 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- /* 400 */ 53, 19, 172, 152, 55, 56, 24, 247, 248, 27,
+ /* 400 */ 53, 19, 152, 168, 169, 170, 22, 190, 191, 27,
/* 410 */ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
/* 420 */ 38, 39, 40, 41, 152, 43, 44, 45, 46, 47,
- /* 430 */ 48, 49, 50, 51, 52, 53, 146, 147, 228, 179,
- /* 440 */ 180, 231, 185, 19, 172, 173, 97, 98, 188, 26,
- /* 450 */ 138, 27, 28, 29, 30, 31, 32, 33, 34, 35,
- /* 460 */ 36, 37, 38, 39, 40, 41, 107, 43, 44, 45,
- /* 470 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 207,
- /* 480 */ 208, 30, 31, 32, 33, 138, 27, 28, 29, 30,
+ /* 430 */ 48, 49, 50, 51, 52, 53, 19, 19, 218, 55,
+ /* 440 */ 56, 24, 22, 152, 27, 28, 29, 30, 31, 32,
+ /* 450 */ 33, 34, 35, 36, 37, 38, 39, 40, 41, 152,
+ /* 460 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 470 */ 53, 250, 194, 195, 56, 55, 56, 55, 19, 172,
+ /* 480 */ 173, 97, 98, 152, 206, 138, 27, 28, 29, 30,
/* 490 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- /* 500 */ 41, 250, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 510 */ 51, 52, 53, 19, 168, 169, 170, 7, 8, 9,
- /* 520 */ 19, 152, 28, 29, 30, 31, 32, 33, 34, 35,
- /* 530 */ 36, 37, 38, 39, 40, 41, 152, 43, 44, 45,
- /* 540 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 108,
- /* 550 */ 109, 110, 101, 130, 53, 152, 172, 173, 29, 30,
+ /* 500 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50,
+ /* 510 */ 51, 52, 53, 19, 207, 208, 152, 97, 98, 97,
+ /* 520 */ 138, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ /* 530 */ 36, 37, 38, 39, 40, 41, 181, 43, 44, 45,
+ /* 540 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 30,
+ /* 550 */ 31, 32, 33, 247, 248, 19, 152, 28, 29, 30,
/* 560 */ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
/* 570 */ 41, 152, 43, 44, 45, 46, 47, 48, 49, 50,
- /* 580 */ 51, 52, 53, 19, 20, 116, 22, 23, 169, 170,
- /* 590 */ 121, 207, 85, 55, 56, 26, 19, 20, 101, 22,
- /* 600 */ 99, 100, 101, 102, 103, 104, 105, 152, 152, 112,
- /* 610 */ 210, 47, 48, 112, 152, 108, 109, 110, 54, 55,
- /* 620 */ 56, 221, 222, 223, 47, 48, 119, 120, 172, 173,
- /* 630 */ 66, 54, 55, 56, 152, 97, 98, 99, 148, 149,
- /* 640 */ 102, 103, 104, 66, 154, 23, 156, 83, 26, 230,
- /* 650 */ 152, 113, 152, 163, 172, 173, 92, 92, 21, 95,
- /* 660 */ 83, 97, 98, 207, 208, 101, 152, 98, 186, 92,
- /* 670 */ 172, 173, 95, 218, 97, 98, 152, 99, 101, 217,
- /* 680 */ 102, 103, 104, 152, 119, 120, 196, 55, 56, 19,
- /* 690 */ 20, 113, 22, 124, 163, 11, 132, 133, 134, 135,
- /* 700 */ 136, 152, 152, 172, 173, 207, 208, 152, 152, 132,
- /* 710 */ 133, 134, 135, 136, 164, 152, 84, 47, 48, 49,
- /* 720 */ 98, 181, 152, 152, 54, 55, 56, 196, 91, 97,
- /* 730 */ 98, 160, 218, 163, 244, 164, 66, 152, 207, 208,
- /* 740 */ 103, 217, 172, 173, 19, 20, 124, 22, 193, 38,
- /* 750 */ 39, 40, 41, 83, 43, 44, 45, 46, 47, 48,
- /* 760 */ 49, 50, 51, 52, 53, 95, 196, 97, 98, 85,
- /* 770 */ 152, 101, 47, 48, 181, 85, 92, 140, 193, 54,
- /* 780 */ 55, 56, 92, 49, 195, 55, 56, 175, 163, 55,
- /* 790 */ 56, 66, 108, 109, 110, 206, 163, 242, 108, 109,
- /* 800 */ 110, 175, 132, 133, 134, 135, 136, 152, 83, 43,
- /* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- /* 820 */ 95, 196, 97, 98, 55, 56, 101, 97, 98, 196,
- /* 830 */ 152, 97, 98, 221, 222, 223, 211, 212, 22, 23,
- /* 840 */ 19, 20, 181, 22, 19, 152, 152, 221, 222, 223,
- /* 850 */ 172, 173, 219, 19, 124, 30, 238, 132, 133, 134,
- /* 860 */ 135, 136, 169, 170, 186, 232, 97, 98, 47, 48,
- /* 870 */ 237, 152, 217, 152, 5, 54, 55, 56, 152, 10,
- /* 880 */ 11, 12, 13, 14, 47, 48, 17, 66, 47, 48,
- /* 890 */ 56, 172, 173, 124, 194, 195, 55, 56, 172, 173,
- /* 900 */ 152, 152, 22, 152, 83, 186, 206, 108, 109, 110,
- /* 910 */ 22, 23, 96, 152, 193, 12, 95, 152, 97, 98,
- /* 920 */ 172, 173, 101, 230, 152, 164, 12, 47, 48, 60,
- /* 930 */ 152, 62, 107, 207, 186, 55, 56, 112, 97, 98,
- /* 940 */ 71, 100, 193, 152, 183, 152, 185, 152, 107, 152,
- /* 950 */ 109, 82, 16, 132, 133, 134, 135, 136, 89, 152,
- /* 960 */ 57, 92, 93, 172, 173, 172, 173, 172, 173, 132,
- /* 970 */ 133, 57, 152, 132, 133, 95, 73, 97, 75, 55,
- /* 980 */ 56, 101, 163, 114, 96, 245, 246, 73, 85, 75,
- /* 990 */ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- /* 1000 */ 48, 49, 50, 51, 52, 53, 194, 195, 152, 171,
- /* 1010 */ 141, 152, 132, 133, 134, 196, 225, 179, 206, 65,
- /* 1020 */ 152, 97, 98, 152, 88, 152, 90, 152, 172, 173,
- /* 1030 */ 152, 219, 78, 152, 152, 238, 152, 152, 219, 152,
- /* 1040 */ 86, 152, 152, 172, 173, 238, 152, 172, 173, 152,
- /* 1050 */ 172, 173, 152, 172, 173, 213, 237, 172, 173, 172,
- /* 1060 */ 173, 172, 173, 211, 212, 111, 172, 173, 152, 172,
- /* 1070 */ 173, 152, 172, 173, 152, 193, 140, 193, 152, 59,
- /* 1080 */ 152, 152, 152, 63, 152, 16, 152, 152, 172, 173,
- /* 1090 */ 152, 172, 173, 152, 172, 173, 152, 77, 172, 173,
- /* 1100 */ 172, 173, 172, 173, 172, 173, 172, 173, 152, 250,
- /* 1110 */ 172, 173, 61, 172, 173, 152, 172, 173, 152, 92,
- /* 1120 */ 152, 70, 152, 152, 152, 26, 152, 100, 172, 173,
- /* 1130 */ 152, 24, 152, 22, 152, 172, 173, 152, 172, 173,
- /* 1140 */ 172, 173, 172, 173, 172, 173, 172, 173, 152, 152,
- /* 1150 */ 172, 173, 172, 173, 172, 173, 152, 88, 152, 90,
- /* 1160 */ 152, 55, 55, 152, 193, 152, 55, 152, 172, 173,
- /* 1170 */ 26, 152, 163, 163, 152, 19, 172, 173, 172, 173,
- /* 1180 */ 172, 173, 22, 172, 173, 172, 173, 172, 173, 55,
- /* 1190 */ 193, 172, 173, 152, 172, 173, 166, 167, 166, 167,
- /* 1200 */ 163, 163, 163, 97, 97, 196, 196, 163, 97, 55,
- /* 1210 */ 23, 199, 56, 26, 22, 22, 24, 100, 101, 55,
- /* 1220 */ 23, 209, 123, 26, 23, 23, 23, 26, 26, 26,
- /* 1230 */ 37, 97, 152, 196, 196, 196, 23, 7, 8, 26,
- /* 1240 */ 196, 23, 23, 152, 26, 26, 23, 132, 133, 26,
- /* 1250 */ 106, 97, 132, 133, 23, 152, 152, 26, 210, 191,
- /* 1260 */ 152, 97, 152, 234, 152, 152, 152, 233, 152, 210,
- /* 1270 */ 152, 152, 210, 152, 152, 152, 152, 152, 152, 197,
- /* 1280 */ 210, 198, 122, 150, 239, 201, 214, 214, 201, 239,
- /* 1290 */ 214, 227, 200, 184, 198, 155, 67, 243, 122, 22,
- /* 1300 */ 159, 159, 69, 176, 175, 175, 175, 240, 180, 159,
- /* 1310 */ 220, 240, 27, 130, 18, 18, 159, 158, 220, 137,
- /* 1320 */ 159, 189, 236, 158, 74, 159, 159, 158, 192, 192,
- /* 1330 */ 192, 192, 235, 22, 189, 189, 201, 159, 158, 177,
- /* 1340 */ 159, 107, 158, 76, 201, 177, 174, 174, 201, 174,
- /* 1350 */ 106, 177, 182, 174, 107, 159, 22, 125, 159, 182,
- /* 1360 */ 174, 176, 174, 174, 216, 216, 215, 215, 177, 216,
- /* 1370 */ 215, 53, 137, 128, 216, 177, 127, 129, 215, 126,
- /* 1380 */ 25, 13, 162, 26, 6, 161, 165, 165, 178, 153,
- /* 1390 */ 153, 151, 151, 151, 151, 224, 4, 3, 22, 142,
- /* 1400 */ 15, 94, 16, 178, 165, 205, 23, 202, 204, 203,
- /* 1410 */ 201, 23, 120, 131, 111, 20, 226, 123, 125, 16,
- /* 1420 */ 1, 123, 131, 229, 229, 111, 37, 37, 56, 64,
- /* 1430 */ 122, 1, 5, 22, 107, 140, 80, 87, 26, 80,
- /* 1440 */ 107, 72, 24, 20, 19, 105, 22, 112, 22, 79,
- /* 1450 */ 22, 58, 23, 22, 79, 22, 249, 249, 246, 79,
- /* 1460 */ 23, 23, 23, 116, 68, 22, 26, 23, 22, 56,
- /* 1470 */ 122, 23, 23, 64, 22, 124, 26, 26, 64, 64,
- /* 1480 */ 23, 23, 23, 23, 11, 23, 22, 26, 23, 22,
- /* 1490 */ 24, 1, 23, 22, 26, 122, 24, 23, 22, 122,
- /* 1500 */ 23, 23, 22, 122, 122, 23, 15,
+ /* 580 */ 51, 52, 53, 19, 168, 169, 170, 238, 19, 53,
+ /* 590 */ 152, 172, 173, 29, 30, 31, 32, 33, 34, 35,
+ /* 600 */ 36, 37, 38, 39, 40, 41, 152, 43, 44, 45,
+ /* 610 */ 46, 47, 48, 49, 50, 51, 52, 53, 19, 20,
+ /* 620 */ 101, 22, 23, 169, 170, 56, 207, 85, 55, 56,
+ /* 630 */ 23, 19, 20, 26, 22, 99, 100, 101, 102, 103,
+ /* 640 */ 104, 105, 238, 152, 152, 210, 47, 48, 112, 152,
+ /* 650 */ 108, 109, 110, 54, 55, 56, 221, 222, 223, 47,
+ /* 660 */ 48, 119, 120, 172, 173, 66, 54, 55, 56, 152,
+ /* 670 */ 97, 98, 99, 148, 149, 102, 103, 104, 66, 154,
+ /* 680 */ 23, 156, 83, 26, 230, 152, 113, 152, 163, 194,
+ /* 690 */ 195, 92, 92, 30, 95, 83, 97, 98, 207, 208,
+ /* 700 */ 101, 206, 179, 180, 92, 172, 173, 95, 152, 97,
+ /* 710 */ 98, 188, 99, 101, 219, 102, 103, 104, 152, 119,
+ /* 720 */ 120, 196, 55, 56, 19, 20, 113, 22, 193, 163,
+ /* 730 */ 11, 132, 133, 134, 135, 136, 24, 65, 172, 173,
+ /* 740 */ 207, 208, 250, 152, 132, 133, 134, 135, 136, 193,
+ /* 750 */ 78, 84, 47, 48, 49, 98, 199, 152, 86, 54,
+ /* 760 */ 55, 56, 196, 152, 97, 98, 209, 55, 163, 244,
+ /* 770 */ 107, 66, 152, 207, 208, 164, 175, 172, 173, 19,
+ /* 780 */ 20, 124, 22, 111, 38, 39, 40, 41, 83, 43,
+ /* 790 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 800 */ 95, 196, 97, 98, 85, 152, 101, 47, 48, 97,
+ /* 810 */ 85, 92, 207, 193, 54, 55, 56, 92, 49, 175,
+ /* 820 */ 55, 56, 221, 222, 223, 12, 66, 108, 109, 110,
+ /* 830 */ 137, 163, 139, 108, 109, 110, 26, 132, 133, 134,
+ /* 840 */ 135, 136, 152, 83, 43, 44, 45, 46, 47, 48,
+ /* 850 */ 49, 50, 51, 52, 53, 95, 26, 97, 98, 55,
+ /* 860 */ 56, 101, 97, 98, 196, 221, 222, 223, 146, 147,
+ /* 870 */ 57, 171, 152, 22, 26, 19, 20, 49, 22, 179,
+ /* 880 */ 108, 109, 110, 55, 56, 116, 73, 219, 75, 124,
+ /* 890 */ 121, 152, 132, 133, 134, 135, 136, 163, 85, 152,
+ /* 900 */ 232, 97, 98, 47, 48, 237, 55, 56, 98, 5,
+ /* 910 */ 54, 55, 56, 193, 10, 11, 12, 13, 14, 172,
+ /* 920 */ 173, 17, 66, 47, 48, 97, 98, 152, 124, 152,
+ /* 930 */ 196, 55, 56, 186, 124, 152, 106, 160, 152, 83,
+ /* 940 */ 152, 164, 152, 61, 22, 211, 212, 152, 97, 98,
+ /* 950 */ 152, 95, 70, 97, 98, 172, 173, 101, 172, 173,
+ /* 960 */ 172, 173, 172, 173, 60, 181, 62, 172, 173, 47,
+ /* 970 */ 48, 123, 186, 97, 98, 71, 100, 55, 56, 152,
+ /* 980 */ 181, 186, 21, 107, 152, 109, 82, 163, 132, 133,
+ /* 990 */ 134, 135, 136, 89, 16, 207, 92, 93, 19, 172,
+ /* 1000 */ 173, 169, 170, 195, 55, 56, 12, 152, 132, 30,
+ /* 1010 */ 134, 47, 48, 186, 206, 225, 152, 95, 114, 97,
+ /* 1020 */ 196, 245, 246, 101, 152, 38, 39, 40, 41, 42,
+ /* 1030 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ /* 1040 */ 53, 152, 163, 219, 152, 141, 97, 98, 193, 152,
+ /* 1050 */ 152, 57, 91, 164, 132, 133, 134, 152, 55, 152,
+ /* 1060 */ 152, 237, 230, 152, 103, 193, 88, 73, 90, 75,
+ /* 1070 */ 172, 173, 183, 152, 185, 196, 152, 172, 173, 172,
+ /* 1080 */ 173, 217, 152, 172, 173, 152, 107, 22, 152, 24,
+ /* 1090 */ 193, 112, 152, 172, 173, 152, 132, 242, 134, 152,
+ /* 1100 */ 97, 140, 152, 92, 152, 172, 173, 152, 172, 173,
+ /* 1110 */ 152, 100, 172, 173, 152, 172, 173, 152, 140, 172,
+ /* 1120 */ 173, 152, 172, 173, 172, 173, 152, 172, 173, 152,
+ /* 1130 */ 172, 173, 152, 152, 172, 173, 152, 172, 173, 213,
+ /* 1140 */ 152, 172, 173, 152, 152, 152, 172, 173, 152, 172,
+ /* 1150 */ 173, 152, 172, 173, 152, 210, 172, 173, 152, 26,
+ /* 1160 */ 172, 173, 152, 172, 173, 172, 173, 152, 172, 173,
+ /* 1170 */ 152, 172, 173, 152, 172, 173, 152, 59, 172, 173,
+ /* 1180 */ 152, 63, 172, 173, 152, 193, 152, 152, 152, 152,
+ /* 1190 */ 172, 173, 152, 172, 173, 77, 172, 173, 152, 152,
+ /* 1200 */ 172, 173, 152, 152, 172, 173, 172, 173, 172, 173,
+ /* 1210 */ 152, 22, 172, 173, 152, 152, 152, 22, 172, 173,
+ /* 1220 */ 152, 152, 152, 172, 173, 152, 7, 8, 9, 163,
+ /* 1230 */ 172, 173, 22, 23, 172, 173, 172, 173, 166, 167,
+ /* 1240 */ 172, 173, 172, 173, 55, 172, 173, 22, 23, 108,
+ /* 1250 */ 109, 110, 217, 152, 217, 166, 167, 163, 163, 163,
+ /* 1260 */ 163, 163, 196, 130, 217, 211, 212, 217, 116, 23,
+ /* 1270 */ 22, 101, 26, 121, 23, 23, 23, 26, 26, 26,
+ /* 1280 */ 23, 23, 112, 26, 26, 37, 97, 100, 101, 55,
+ /* 1290 */ 196, 196, 196, 196, 196, 23, 23, 55, 26, 26,
+ /* 1300 */ 7, 8, 23, 152, 23, 26, 96, 26, 132, 132,
+ /* 1310 */ 134, 134, 23, 152, 152, 26, 152, 122, 152, 191,
+ /* 1320 */ 152, 96, 234, 152, 152, 152, 152, 152, 197, 210,
+ /* 1330 */ 152, 97, 152, 152, 210, 233, 210, 198, 150, 97,
+ /* 1340 */ 184, 201, 239, 214, 214, 201, 239, 180, 214, 227,
+ /* 1350 */ 200, 198, 155, 67, 243, 176, 69, 175, 175, 175,
+ /* 1360 */ 122, 159, 159, 240, 159, 240, 22, 220, 27, 130,
+ /* 1370 */ 201, 18, 159, 18, 189, 158, 158, 220, 192, 159,
+ /* 1380 */ 137, 236, 192, 192, 192, 189, 74, 189, 159, 235,
+ /* 1390 */ 159, 158, 22, 177, 201, 201, 159, 107, 158, 177,
+ /* 1400 */ 159, 174, 158, 76, 174, 182, 174, 106, 182, 125,
+ /* 1410 */ 174, 107, 177, 22, 159, 216, 215, 137, 159, 53,
+ /* 1420 */ 216, 176, 215, 174, 174, 216, 215, 215, 174, 229,
+ /* 1430 */ 216, 129, 224, 177, 126, 229, 127, 177, 128, 25,
+ /* 1440 */ 162, 226, 26, 161, 13, 153, 6, 153, 151, 151,
+ /* 1450 */ 151, 151, 205, 165, 178, 178, 165, 4, 3, 22,
+ /* 1460 */ 165, 142, 15, 94, 202, 204, 203, 201, 16, 23,
+ /* 1470 */ 249, 23, 120, 249, 246, 111, 131, 123, 20, 16,
+ /* 1480 */ 1, 125, 123, 111, 56, 64, 37, 37, 131, 122,
+ /* 1490 */ 1, 37, 5, 37, 22, 107, 26, 80, 140, 80,
+ /* 1500 */ 87, 72, 107, 20, 24, 19, 112, 105, 23, 79,
+ /* 1510 */ 22, 79, 22, 22, 22, 58, 22, 79, 23, 68,
+ /* 1520 */ 23, 23, 26, 116, 22, 26, 23, 22, 122, 23,
+ /* 1530 */ 23, 56, 64, 22, 124, 26, 26, 64, 64, 23,
+ /* 1540 */ 23, 23, 23, 11, 23, 22, 26, 23, 22, 24,
+ /* 1550 */ 1, 23, 22, 26, 251, 24, 23, 22, 122, 23,
+ /* 1560 */ 23, 22, 15, 122, 122, 122, 23,
};
-#define YY_SHIFT_USE_DFLT (-95)
-#define YY_SHIFT_COUNT (442)
-#define YY_SHIFT_MIN (-94)
-#define YY_SHIFT_MAX (1491)
+#define YY_SHIFT_USE_DFLT (1567)
+#define YY_SHIFT_COUNT (455)
+#define YY_SHIFT_MIN (-94)
+#define YY_SHIFT_MAX (1549)
static const short yy_shift_ofst[] = {
- /* 0 */ 40, 564, 869, 577, 725, 725, 725, 725, 690, -19,
- /* 10 */ 16, 16, 100, 725, 725, 725, 725, 725, 725, 725,
- /* 20 */ 841, 841, 538, 507, 684, 565, 61, 137, 172, 207,
- /* 30 */ 242, 277, 312, 347, 382, 424, 424, 424, 424, 424,
- /* 40 */ 424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
- /* 50 */ 459, 424, 494, 529, 529, 670, 725, 725, 725, 725,
- /* 60 */ 725, 725, 725, 725, 725, 725, 725, 725, 725, 725,
- /* 70 */ 725, 725, 725, 725, 725, 725, 725, 725, 725, 725,
- /* 80 */ 725, 725, 725, 725, 821, 725, 725, 725, 725, 725,
- /* 90 */ 725, 725, 725, 725, 725, 725, 725, 725, 952, 711,
- /* 100 */ 711, 711, 711, 711, 766, 23, 32, 924, 637, 825,
- /* 110 */ 837, 837, 924, 73, 183, -51, -95, -95, -95, 501,
- /* 120 */ 501, 501, 903, 903, 632, 205, 241, 924, 924, 924,
- /* 130 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
- /* 140 */ 924, 924, 924, 924, 924, 924, 924, 192, 1027, 1106,
- /* 150 */ 1106, 183, 176, 176, 176, 176, 176, 176, -95, -95,
- /* 160 */ -95, 880, -94, -94, 578, 734, 99, 730, 769, 349,
- /* 170 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
- /* 180 */ 924, 924, 924, 924, 924, 924, 924, 954, 954, 954,
- /* 190 */ 924, 924, 622, 924, 924, 924, -18, 924, 924, 914,
- /* 200 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
- /* 210 */ 441, 1020, 1107, 1107, 1107, 569, 45, 217, 510, 423,
- /* 220 */ 834, 834, 1156, 423, 1156, 1144, 1187, 359, 1051, 834,
- /* 230 */ -17, 1051, 1051, 1099, 469, 1192, 1229, 1176, 1176, 1233,
- /* 240 */ 1233, 1176, 1277, 1285, 1183, 1296, 1296, 1296, 1296, 1176,
- /* 250 */ 1297, 1183, 1277, 1285, 1285, 1183, 1176, 1297, 1182, 1250,
- /* 260 */ 1176, 1176, 1297, 1311, 1176, 1297, 1176, 1297, 1311, 1234,
- /* 270 */ 1234, 1234, 1267, 1311, 1234, 1244, 1234, 1267, 1234, 1234,
- /* 280 */ 1232, 1247, 1232, 1247, 1232, 1247, 1232, 1247, 1176, 1334,
- /* 290 */ 1176, 1235, 1311, 1318, 1318, 1311, 1248, 1253, 1245, 1249,
- /* 300 */ 1183, 1355, 1357, 1368, 1368, 1378, 1378, 1378, 1378, -95,
- /* 310 */ -95, -95, -95, -95, -95, -95, -95, 451, 936, 816,
- /* 320 */ 888, 1069, 799, 1111, 1197, 1193, 1201, 1202, 1203, 1213,
- /* 330 */ 1134, 1117, 1230, 497, 1218, 1219, 1154, 1223, 1115, 1120,
- /* 340 */ 1231, 1164, 1160, 1392, 1394, 1376, 1257, 1385, 1307, 1386,
- /* 350 */ 1383, 1388, 1292, 1282, 1303, 1294, 1395, 1293, 1403, 1419,
- /* 360 */ 1298, 1291, 1389, 1390, 1314, 1372, 1365, 1308, 1430, 1427,
- /* 370 */ 1411, 1327, 1295, 1356, 1412, 1359, 1350, 1369, 1333, 1418,
- /* 380 */ 1423, 1425, 1335, 1340, 1424, 1370, 1426, 1428, 1429, 1431,
- /* 390 */ 1375, 1393, 1433, 1380, 1396, 1437, 1438, 1439, 1347, 1443,
- /* 400 */ 1444, 1446, 1440, 1348, 1448, 1449, 1413, 1409, 1452, 1351,
- /* 410 */ 1450, 1414, 1451, 1415, 1457, 1450, 1458, 1459, 1460, 1461,
- /* 420 */ 1462, 1464, 1473, 1465, 1467, 1466, 1468, 1469, 1471, 1472,
- /* 430 */ 1468, 1474, 1476, 1477, 1478, 1480, 1373, 1377, 1381, 1382,
- /* 440 */ 1482, 1491, 1490,
+ /* 0 */ 40, 599, 904, 612, 760, 760, 760, 760, 725, -19,
+ /* 10 */ 16, 16, 100, 760, 760, 760, 760, 760, 760, 760,
+ /* 20 */ 876, 876, 573, 542, 719, 600, 61, 137, 172, 207,
+ /* 30 */ 242, 277, 312, 347, 382, 417, 459, 459, 459, 459,
+ /* 40 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459,
+ /* 50 */ 459, 459, 459, 494, 459, 529, 564, 564, 705, 760,
+ /* 60 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 70 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 80 */ 760, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 90 */ 856, 760, 760, 760, 760, 760, 760, 760, 760, 760,
+ /* 100 */ 760, 760, 760, 760, 987, 746, 746, 746, 746, 746,
+ /* 110 */ 801, 23, 32, 949, 961, 979, 964, 964, 949, 73,
+ /* 120 */ 113, -51, 1567, 1567, 1567, 536, 536, 536, 99, 99,
+ /* 130 */ 813, 813, 667, 205, 240, 949, 949, 949, 949, 949,
+ /* 140 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
+ /* 150 */ 949, 949, 949, 949, 949, 332, 1011, 422, 422, 113,
+ /* 160 */ 30, 30, 30, 30, 30, 30, 1567, 1567, 1567, 922,
+ /* 170 */ -94, -94, 384, 613, 828, 420, 765, 804, 851, 949,
+ /* 180 */ 949, 949, 949, 949, 949, 949, 949, 949, 949, 949,
+ /* 190 */ 949, 949, 949, 949, 949, 672, 672, 672, 949, 949,
+ /* 200 */ 657, 949, 949, 949, -18, 949, 949, 994, 949, 949,
+ /* 210 */ 949, 949, 949, 949, 949, 949, 949, 949, 772, 1118,
+ /* 220 */ 712, 712, 712, 810, 45, 769, 1219, 1133, 418, 418,
+ /* 230 */ 569, 1133, 569, 830, 607, 663, 882, 418, 693, 882,
+ /* 240 */ 882, 848, 1152, 1065, 1286, 1238, 1238, 1287, 1287, 1238,
+ /* 250 */ 1344, 1341, 1239, 1353, 1353, 1353, 1353, 1238, 1355, 1239,
+ /* 260 */ 1344, 1341, 1341, 1239, 1238, 1355, 1243, 1312, 1238, 1238,
+ /* 270 */ 1355, 1370, 1238, 1355, 1238, 1355, 1370, 1290, 1290, 1290,
+ /* 280 */ 1327, 1370, 1290, 1301, 1290, 1327, 1290, 1290, 1284, 1304,
+ /* 290 */ 1284, 1304, 1284, 1304, 1284, 1304, 1238, 1391, 1238, 1280,
+ /* 300 */ 1370, 1366, 1366, 1370, 1302, 1308, 1310, 1309, 1239, 1414,
+ /* 310 */ 1416, 1431, 1431, 1440, 1440, 1440, 1440, 1567, 1567, 1567,
+ /* 320 */ 1567, 1567, 1567, 1567, 1567, 519, 978, 1210, 1225, 104,
+ /* 330 */ 1141, 1189, 1246, 1248, 1251, 1252, 1253, 1257, 1258, 1273,
+ /* 340 */ 1003, 1187, 1293, 1170, 1272, 1279, 1234, 1281, 1176, 1177,
+ /* 350 */ 1289, 1242, 1195, 1453, 1455, 1437, 1319, 1447, 1369, 1452,
+ /* 360 */ 1446, 1448, 1352, 1345, 1364, 1354, 1458, 1356, 1463, 1479,
+ /* 370 */ 1359, 1357, 1449, 1450, 1454, 1456, 1372, 1428, 1421, 1367,
+ /* 380 */ 1489, 1487, 1472, 1388, 1358, 1417, 1470, 1419, 1413, 1429,
+ /* 390 */ 1395, 1480, 1483, 1486, 1394, 1402, 1488, 1430, 1490, 1491,
+ /* 400 */ 1485, 1492, 1432, 1457, 1494, 1438, 1451, 1495, 1497, 1498,
+ /* 410 */ 1496, 1407, 1502, 1503, 1505, 1499, 1406, 1506, 1507, 1475,
+ /* 420 */ 1468, 1511, 1410, 1509, 1473, 1510, 1474, 1516, 1509, 1517,
+ /* 430 */ 1518, 1519, 1520, 1521, 1523, 1532, 1524, 1526, 1525, 1527,
+ /* 440 */ 1528, 1530, 1531, 1527, 1533, 1535, 1536, 1537, 1539, 1436,
+ /* 450 */ 1441, 1442, 1443, 1543, 1547, 1549,
};
#define YY_REDUCE_USE_DFLT (-130)
-#define YY_REDUCE_COUNT (316)
+#define YY_REDUCE_COUNT (324)
#define YY_REDUCE_MIN (-129)
-#define YY_REDUCE_MAX (1243)
+#define YY_REDUCE_MAX (1300)
static const short yy_reduce_ofst[] = {
- /* 0 */ -29, 531, 490, 570, -49, 272, 456, 498, 633, 400,
- /* 10 */ 612, 626, 113, 482, 678, 719, 384, 726, 748, 791,
- /* 20 */ 419, 693, 761, 812, 819, 625, 76, 76, 76, 76,
+ /* 0 */ -29, 566, 525, 605, -49, 307, 491, 533, 668, 435,
+ /* 10 */ 601, 644, 148, 747, 786, 795, 419, 788, 827, 790,
+ /* 20 */ 454, 832, 889, 495, 824, 734, 76, 76, 76, 76,
/* 30 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
/* 40 */ 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
- /* 50 */ 76, 76, 76, 76, 76, 793, 795, 856, 871, 875,
- /* 60 */ 878, 881, 885, 887, 889, 894, 897, 900, 916, 919,
- /* 70 */ 922, 926, 928, 930, 932, 934, 938, 941, 944, 956,
- /* 80 */ 963, 966, 968, 970, 972, 974, 978, 980, 982, 996,
- /* 90 */ 1004, 1006, 1008, 1011, 1013, 1015, 1019, 1022, 76, 76,
- /* 100 */ 76, 76, 76, 76, 76, 76, 76, 555, 210, 260,
- /* 110 */ 200, 346, 571, 76, 700, 76, 76, 76, 76, 838,
- /* 120 */ 838, 838, 42, 182, 251, 160, 160, 550, 5, 455,
- /* 130 */ 585, 721, 749, 882, 884, 971, 618, 462, 797, 514,
- /* 140 */ 807, 524, 997, -129, 655, 859, 62, 290, 66, 1030,
- /* 150 */ 1032, 589, 1009, 1010, 1037, 1038, 1039, 1044, 740, 852,
- /* 160 */ 1012, 112, 147, 230, 257, 180, 369, 403, 500, 549,
- /* 170 */ 556, 563, 694, 751, 765, 772, 778, 820, 868, 873,
- /* 180 */ 890, 929, 935, 985, 1041, 1080, 1091, 540, 593, 661,
- /* 190 */ 1103, 1104, 842, 1108, 1110, 1112, 1048, 1113, 1114, 1068,
- /* 200 */ 1116, 1118, 1119, 180, 1121, 1122, 1123, 1124, 1125, 1126,
- /* 210 */ 1029, 1034, 1059, 1062, 1070, 842, 1082, 1083, 1133, 1084,
- /* 220 */ 1072, 1073, 1045, 1087, 1050, 1127, 1109, 1128, 1129, 1076,
- /* 230 */ 1064, 1130, 1131, 1092, 1096, 1140, 1054, 1141, 1142, 1067,
- /* 240 */ 1071, 1150, 1090, 1132, 1135, 1136, 1137, 1138, 1139, 1157,
- /* 250 */ 1159, 1143, 1098, 1145, 1146, 1147, 1161, 1165, 1086, 1097,
- /* 260 */ 1166, 1167, 1169, 1162, 1178, 1180, 1181, 1184, 1168, 1172,
- /* 270 */ 1173, 1175, 1170, 1174, 1179, 1185, 1186, 1177, 1188, 1189,
- /* 280 */ 1148, 1151, 1149, 1152, 1153, 1155, 1158, 1163, 1196, 1171,
- /* 290 */ 1199, 1190, 1191, 1194, 1195, 1198, 1200, 1204, 1206, 1205,
- /* 300 */ 1209, 1220, 1224, 1236, 1237, 1240, 1241, 1242, 1243, 1207,
- /* 310 */ 1208, 1212, 1221, 1222, 1210, 1225, 1239,
+ /* 50 */ 76, 76, 76, 76, 76, 76, 76, 76, 783, 898,
+ /* 60 */ 905, 907, 911, 921, 933, 936, 940, 943, 947, 950,
+ /* 70 */ 952, 955, 958, 962, 965, 969, 974, 977, 980, 984,
+ /* 80 */ 988, 991, 993, 996, 999, 1002, 1006, 1010, 1018, 1021,
+ /* 90 */ 1024, 1028, 1032, 1034, 1036, 1040, 1046, 1051, 1058, 1062,
+ /* 100 */ 1064, 1068, 1070, 1073, 76, 76, 76, 76, 76, 76,
+ /* 110 */ 76, 76, 76, 855, 36, 523, 235, 416, 777, 76,
+ /* 120 */ 278, 76, 76, 76, 76, 700, 700, 700, 150, 220,
+ /* 130 */ 147, 217, 221, 306, 306, 611, 5, 535, 556, 620,
+ /* 140 */ 720, 872, 897, 116, 864, 349, 1035, 1037, 404, 1047,
+ /* 150 */ 992, -129, 1050, 492, 62, 722, 879, 1072, 1089, 808,
+ /* 160 */ 1066, 1094, 1095, 1096, 1097, 1098, 776, 1054, 557, 57,
+ /* 170 */ 112, 131, 167, 182, 250, 272, 291, 331, 364, 438,
+ /* 180 */ 497, 517, 591, 653, 690, 739, 775, 798, 892, 908,
+ /* 190 */ 924, 930, 1015, 1063, 1069, 355, 784, 799, 981, 1101,
+ /* 200 */ 926, 1151, 1161, 1162, 945, 1164, 1166, 1128, 1168, 1171,
+ /* 210 */ 1172, 250, 1173, 1174, 1175, 1178, 1180, 1181, 1088, 1102,
+ /* 220 */ 1119, 1124, 1126, 926, 1131, 1139, 1188, 1140, 1129, 1130,
+ /* 230 */ 1103, 1144, 1107, 1179, 1156, 1167, 1182, 1134, 1122, 1183,
+ /* 240 */ 1184, 1150, 1153, 1197, 1111, 1202, 1203, 1123, 1125, 1205,
+ /* 250 */ 1147, 1185, 1169, 1186, 1190, 1191, 1192, 1213, 1217, 1193,
+ /* 260 */ 1157, 1196, 1198, 1194, 1220, 1218, 1145, 1154, 1229, 1231,
+ /* 270 */ 1233, 1216, 1237, 1240, 1241, 1244, 1222, 1227, 1230, 1232,
+ /* 280 */ 1223, 1235, 1236, 1245, 1249, 1226, 1250, 1254, 1199, 1201,
+ /* 290 */ 1204, 1207, 1209, 1211, 1214, 1212, 1255, 1208, 1259, 1215,
+ /* 300 */ 1256, 1200, 1206, 1260, 1247, 1261, 1263, 1262, 1266, 1278,
+ /* 310 */ 1282, 1292, 1294, 1297, 1298, 1299, 1300, 1221, 1224, 1228,
+ /* 320 */ 1288, 1291, 1276, 1277, 1295,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1258, 1248, 1248, 1248, 1180, 1180, 1180, 1180, 1248, 1077,
- /* 10 */ 1106, 1106, 1232, 1309, 1309, 1309, 1309, 1309, 1309, 1179,
- /* 20 */ 1309, 1309, 1309, 1309, 1248, 1081, 1112, 1309, 1309, 1309,
- /* 30 */ 1309, 1309, 1309, 1309, 1309, 1231, 1233, 1120, 1119, 1214,
- /* 40 */ 1093, 1117, 1110, 1114, 1181, 1175, 1176, 1174, 1178, 1182,
- /* 50 */ 1309, 1113, 1144, 1159, 1143, 1309, 1309, 1309, 1309, 1309,
- /* 60 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 70 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 80 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 90 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1153, 1158,
- /* 100 */ 1165, 1157, 1154, 1146, 1145, 1147, 1148, 1309, 1000, 1048,
- /* 110 */ 1309, 1309, 1309, 1149, 1309, 1150, 1162, 1161, 1160, 1239,
- /* 120 */ 1266, 1265, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 130 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 140 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1258, 1248, 1006,
- /* 150 */ 1006, 1309, 1248, 1248, 1248, 1248, 1248, 1248, 1244, 1081,
- /* 160 */ 1072, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 170 */ 1309, 1236, 1234, 1309, 1195, 1309, 1309, 1309, 1309, 1309,
- /* 180 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 190 */ 1309, 1309, 1309, 1309, 1309, 1309, 1077, 1309, 1309, 1309,
- /* 200 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1260,
- /* 210 */ 1309, 1209, 1077, 1077, 1077, 1079, 1061, 1071, 985, 1116,
- /* 220 */ 1095, 1095, 1298, 1116, 1298, 1023, 1280, 1020, 1106, 1095,
- /* 230 */ 1177, 1106, 1106, 1078, 1071, 1309, 1301, 1086, 1086, 1300,
- /* 240 */ 1300, 1086, 1125, 1051, 1116, 1057, 1057, 1057, 1057, 1086,
- /* 250 */ 997, 1116, 1125, 1051, 1051, 1116, 1086, 997, 1213, 1295,
- /* 260 */ 1086, 1086, 997, 1188, 1086, 997, 1086, 997, 1188, 1049,
- /* 270 */ 1049, 1049, 1038, 1188, 1049, 1023, 1049, 1038, 1049, 1049,
- /* 280 */ 1099, 1094, 1099, 1094, 1099, 1094, 1099, 1094, 1086, 1183,
- /* 290 */ 1086, 1309, 1188, 1192, 1192, 1188, 1111, 1100, 1109, 1107,
- /* 300 */ 1116, 1003, 1041, 1263, 1263, 1259, 1259, 1259, 1259, 1306,
- /* 310 */ 1306, 1244, 1275, 1275, 1025, 1025, 1275, 1309, 1309, 1309,
- /* 320 */ 1309, 1309, 1309, 1270, 1309, 1197, 1309, 1309, 1309, 1309,
- /* 330 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 340 */ 1309, 1309, 1131, 1309, 981, 1241, 1309, 1309, 1240, 1309,
- /* 350 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 360 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1297, 1309, 1309,
- /* 370 */ 1309, 1309, 1309, 1309, 1212, 1211, 1309, 1309, 1309, 1309,
- /* 380 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 390 */ 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1309, 1063, 1309,
- /* 400 */ 1309, 1309, 1284, 1309, 1309, 1309, 1309, 1309, 1309, 1309,
- /* 410 */ 1108, 1309, 1101, 1309, 1309, 1288, 1309, 1309, 1309, 1309,
- /* 420 */ 1309, 1309, 1309, 1309, 1309, 1309, 1250, 1309, 1309, 1309,
- /* 430 */ 1249, 1309, 1309, 1309, 1309, 1309, 1133, 1309, 1132, 1136,
- /* 440 */ 1309, 991, 1309,
+ /* 0 */ 1280, 1270, 1270, 1270, 1202, 1202, 1202, 1202, 1270, 1096,
+ /* 10 */ 1125, 1125, 1254, 1332, 1332, 1332, 1332, 1332, 1332, 1201,
+ /* 20 */ 1332, 1332, 1332, 1332, 1270, 1100, 1131, 1332, 1332, 1332,
+ /* 30 */ 1332, 1203, 1204, 1332, 1332, 1332, 1253, 1255, 1141, 1140,
+ /* 40 */ 1139, 1138, 1236, 1112, 1136, 1129, 1133, 1203, 1197, 1198,
+ /* 50 */ 1196, 1200, 1204, 1332, 1132, 1167, 1181, 1166, 1332, 1332,
+ /* 60 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 70 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 80 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 90 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 100 */ 1332, 1332, 1332, 1332, 1175, 1180, 1187, 1179, 1176, 1169,
+ /* 110 */ 1168, 1170, 1171, 1332, 1019, 1067, 1332, 1332, 1332, 1172,
+ /* 120 */ 1332, 1173, 1184, 1183, 1182, 1261, 1288, 1287, 1332, 1332,
+ /* 130 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 140 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 150 */ 1332, 1332, 1332, 1332, 1332, 1280, 1270, 1025, 1025, 1332,
+ /* 160 */ 1270, 1270, 1270, 1270, 1270, 1270, 1266, 1100, 1091, 1332,
+ /* 170 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 180 */ 1258, 1256, 1332, 1217, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 190 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 200 */ 1332, 1332, 1332, 1332, 1096, 1332, 1332, 1332, 1332, 1332,
+ /* 210 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1282, 1332, 1231,
+ /* 220 */ 1096, 1096, 1096, 1098, 1080, 1090, 1004, 1135, 1114, 1114,
+ /* 230 */ 1321, 1135, 1321, 1042, 1302, 1039, 1125, 1114, 1199, 1125,
+ /* 240 */ 1125, 1097, 1090, 1332, 1324, 1105, 1105, 1323, 1323, 1105,
+ /* 250 */ 1146, 1070, 1135, 1076, 1076, 1076, 1076, 1105, 1016, 1135,
+ /* 260 */ 1146, 1070, 1070, 1135, 1105, 1016, 1235, 1318, 1105, 1105,
+ /* 270 */ 1016, 1210, 1105, 1016, 1105, 1016, 1210, 1068, 1068, 1068,
+ /* 280 */ 1057, 1210, 1068, 1042, 1068, 1057, 1068, 1068, 1118, 1113,
+ /* 290 */ 1118, 1113, 1118, 1113, 1118, 1113, 1105, 1205, 1105, 1332,
+ /* 300 */ 1210, 1214, 1214, 1210, 1130, 1119, 1128, 1126, 1135, 1022,
+ /* 310 */ 1060, 1285, 1285, 1281, 1281, 1281, 1281, 1329, 1329, 1266,
+ /* 320 */ 1297, 1297, 1044, 1044, 1297, 1332, 1332, 1332, 1332, 1332,
+ /* 330 */ 1332, 1292, 1332, 1219, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 340 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 350 */ 1332, 1332, 1152, 1332, 1000, 1263, 1332, 1332, 1262, 1332,
+ /* 360 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 370 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1320,
+ /* 380 */ 1332, 1332, 1332, 1332, 1332, 1332, 1234, 1233, 1332, 1332,
+ /* 390 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 400 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332,
+ /* 410 */ 1332, 1082, 1332, 1332, 1332, 1306, 1332, 1332, 1332, 1332,
+ /* 420 */ 1332, 1332, 1332, 1127, 1332, 1120, 1332, 1332, 1311, 1332,
+ /* 430 */ 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1332, 1272,
+ /* 440 */ 1332, 1332, 1332, 1271, 1332, 1332, 1332, 1332, 1332, 1154,
+ /* 450 */ 1332, 1153, 1157, 1332, 1010, 1332,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -132581,7 +135914,7 @@ static const char *const yyTokenName[] = {
"VALUES", "DISTINCT", "DOT", "FROM",
"JOIN", "USING", "ORDER", "GROUP",
"HAVING", "LIMIT", "WHERE", "INTO",
- "INTEGER", "FLOAT", "BLOB", "VARIABLE",
+ "FLOAT", "BLOB", "INTEGER", "VARIABLE",
"CASE", "WHEN", "THEN", "ELSE",
"INDEX", "ALTER", "ADD", "error",
"input", "cmdlist", "ecmd", "explain",
@@ -132757,195 +136090,199 @@ static const char *const yyRuleName[] = {
/* 136 */ "where_opt ::= WHERE expr",
/* 137 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
/* 138 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 139 */ "setlist ::= nm EQ expr",
- /* 140 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
- /* 141 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
- /* 142 */ "insert_cmd ::= INSERT orconf",
- /* 143 */ "insert_cmd ::= REPLACE",
- /* 144 */ "idlist_opt ::=",
- /* 145 */ "idlist_opt ::= LP idlist RP",
- /* 146 */ "idlist ::= idlist COMMA nm",
- /* 147 */ "idlist ::= nm",
- /* 148 */ "expr ::= LP expr RP",
- /* 149 */ "term ::= NULL",
- /* 150 */ "expr ::= ID|INDEXED",
- /* 151 */ "expr ::= JOIN_KW",
- /* 152 */ "expr ::= nm DOT nm",
- /* 153 */ "expr ::= nm DOT nm DOT nm",
- /* 154 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 155 */ "term ::= STRING",
- /* 156 */ "expr ::= VARIABLE",
- /* 157 */ "expr ::= expr COLLATE ID|STRING",
- /* 158 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 159 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
- /* 160 */ "expr ::= ID|INDEXED LP STAR RP",
- /* 161 */ "term ::= CTIME_KW",
- /* 162 */ "expr ::= expr AND expr",
- /* 163 */ "expr ::= expr OR expr",
- /* 164 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 165 */ "expr ::= expr EQ|NE expr",
- /* 166 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 167 */ "expr ::= expr PLUS|MINUS expr",
- /* 168 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 169 */ "expr ::= expr CONCAT expr",
- /* 170 */ "likeop ::= LIKE_KW|MATCH",
- /* 171 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 172 */ "expr ::= expr likeop expr",
- /* 173 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 174 */ "expr ::= expr ISNULL|NOTNULL",
- /* 175 */ "expr ::= expr NOT NULL",
- /* 176 */ "expr ::= expr IS expr",
- /* 177 */ "expr ::= expr IS NOT expr",
- /* 178 */ "expr ::= NOT expr",
- /* 179 */ "expr ::= BITNOT expr",
- /* 180 */ "expr ::= MINUS expr",
- /* 181 */ "expr ::= PLUS expr",
- /* 182 */ "between_op ::= BETWEEN",
- /* 183 */ "between_op ::= NOT BETWEEN",
- /* 184 */ "expr ::= expr between_op expr AND expr",
- /* 185 */ "in_op ::= IN",
- /* 186 */ "in_op ::= NOT IN",
- /* 187 */ "expr ::= expr in_op LP exprlist RP",
- /* 188 */ "expr ::= LP select RP",
- /* 189 */ "expr ::= expr in_op LP select RP",
- /* 190 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 191 */ "expr ::= EXISTS LP select RP",
- /* 192 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 193 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 194 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 195 */ "case_else ::= ELSE expr",
- /* 196 */ "case_else ::=",
- /* 197 */ "case_operand ::= expr",
- /* 198 */ "case_operand ::=",
- /* 199 */ "exprlist ::=",
- /* 200 */ "nexprlist ::= nexprlist COMMA expr",
- /* 201 */ "nexprlist ::= expr",
- /* 202 */ "paren_exprlist ::=",
- /* 203 */ "paren_exprlist ::= LP exprlist RP",
- /* 204 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 205 */ "uniqueflag ::= UNIQUE",
- /* 206 */ "uniqueflag ::=",
- /* 207 */ "eidlist_opt ::=",
- /* 208 */ "eidlist_opt ::= LP eidlist RP",
- /* 209 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 210 */ "eidlist ::= nm collate sortorder",
- /* 211 */ "collate ::=",
- /* 212 */ "collate ::= COLLATE ID|STRING",
- /* 213 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 214 */ "cmd ::= VACUUM",
- /* 215 */ "cmd ::= VACUUM nm",
- /* 216 */ "cmd ::= PRAGMA nm dbnm",
- /* 217 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 218 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 219 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 220 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 221 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 222 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 223 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 224 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 225 */ "trigger_time ::= BEFORE",
- /* 226 */ "trigger_time ::= AFTER",
- /* 227 */ "trigger_time ::= INSTEAD OF",
- /* 228 */ "trigger_time ::=",
- /* 229 */ "trigger_event ::= DELETE|INSERT",
- /* 230 */ "trigger_event ::= UPDATE",
- /* 231 */ "trigger_event ::= UPDATE OF idlist",
- /* 232 */ "when_clause ::=",
- /* 233 */ "when_clause ::= WHEN expr",
- /* 234 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 235 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 236 */ "trnm ::= nm DOT nm",
- /* 237 */ "tridxby ::= INDEXED BY nm",
- /* 238 */ "tridxby ::= NOT INDEXED",
- /* 239 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 240 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
- /* 241 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 242 */ "trigger_cmd ::= select",
- /* 243 */ "expr ::= RAISE LP IGNORE RP",
- /* 244 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 245 */ "raisetype ::= ROLLBACK",
- /* 246 */ "raisetype ::= ABORT",
- /* 247 */ "raisetype ::= FAIL",
- /* 248 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 249 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 250 */ "cmd ::= DETACH database_kw_opt expr",
- /* 251 */ "key_opt ::=",
- /* 252 */ "key_opt ::= KEY expr",
- /* 253 */ "cmd ::= REINDEX",
- /* 254 */ "cmd ::= REINDEX nm dbnm",
- /* 255 */ "cmd ::= ANALYZE",
- /* 256 */ "cmd ::= ANALYZE nm dbnm",
- /* 257 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 258 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
- /* 259 */ "add_column_fullname ::= fullname",
- /* 260 */ "cmd ::= create_vtab",
- /* 261 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 262 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 263 */ "vtabarg ::=",
- /* 264 */ "vtabargtoken ::= ANY",
- /* 265 */ "vtabargtoken ::= lp anylist RP",
- /* 266 */ "lp ::= LP",
- /* 267 */ "with ::=",
- /* 268 */ "with ::= WITH wqlist",
- /* 269 */ "with ::= WITH RECURSIVE wqlist",
- /* 270 */ "wqlist ::= nm eidlist_opt AS LP select RP",
- /* 271 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
- /* 272 */ "input ::= cmdlist",
- /* 273 */ "cmdlist ::= cmdlist ecmd",
- /* 274 */ "cmdlist ::= ecmd",
- /* 275 */ "ecmd ::= SEMI",
- /* 276 */ "ecmd ::= explain cmdx SEMI",
- /* 277 */ "explain ::=",
- /* 278 */ "trans_opt ::=",
- /* 279 */ "trans_opt ::= TRANSACTION",
- /* 280 */ "trans_opt ::= TRANSACTION nm",
- /* 281 */ "savepoint_opt ::= SAVEPOINT",
- /* 282 */ "savepoint_opt ::=",
- /* 283 */ "cmd ::= create_table create_table_args",
- /* 284 */ "columnlist ::= columnlist COMMA columnname carglist",
- /* 285 */ "columnlist ::= columnname carglist",
- /* 286 */ "nm ::= ID|INDEXED",
- /* 287 */ "nm ::= STRING",
- /* 288 */ "nm ::= JOIN_KW",
- /* 289 */ "typetoken ::= typename",
- /* 290 */ "typename ::= ID|STRING",
- /* 291 */ "signed ::= plus_num",
- /* 292 */ "signed ::= minus_num",
- /* 293 */ "carglist ::= carglist ccons",
- /* 294 */ "carglist ::=",
- /* 295 */ "ccons ::= NULL onconf",
- /* 296 */ "conslist_opt ::= COMMA conslist",
- /* 297 */ "conslist ::= conslist tconscomma tcons",
- /* 298 */ "conslist ::= tcons",
- /* 299 */ "tconscomma ::=",
- /* 300 */ "defer_subclause_opt ::= defer_subclause",
- /* 301 */ "resolvetype ::= raisetype",
- /* 302 */ "selectnowith ::= oneselect",
- /* 303 */ "oneselect ::= values",
- /* 304 */ "sclp ::= selcollist COMMA",
- /* 305 */ "as ::= ID|STRING",
- /* 306 */ "expr ::= term",
- /* 307 */ "exprlist ::= nexprlist",
- /* 308 */ "nmnum ::= plus_num",
- /* 309 */ "nmnum ::= nm",
- /* 310 */ "nmnum ::= ON",
- /* 311 */ "nmnum ::= DELETE",
- /* 312 */ "nmnum ::= DEFAULT",
- /* 313 */ "plus_num ::= INTEGER|FLOAT",
- /* 314 */ "foreach_clause ::=",
- /* 315 */ "foreach_clause ::= FOR EACH ROW",
- /* 316 */ "trnm ::= nm",
- /* 317 */ "tridxby ::=",
- /* 318 */ "database_kw_opt ::= DATABASE",
- /* 319 */ "database_kw_opt ::=",
- /* 320 */ "kwcolumn_opt ::=",
- /* 321 */ "kwcolumn_opt ::= COLUMNKW",
- /* 322 */ "vtabarglist ::= vtabarg",
- /* 323 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 324 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 325 */ "anylist ::=",
- /* 326 */ "anylist ::= anylist LP anylist RP",
- /* 327 */ "anylist ::= anylist ANY",
+ /* 139 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
+ /* 140 */ "setlist ::= nm EQ expr",
+ /* 141 */ "setlist ::= LP idlist RP EQ expr",
+ /* 142 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
+ /* 143 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
+ /* 144 */ "insert_cmd ::= INSERT orconf",
+ /* 145 */ "insert_cmd ::= REPLACE",
+ /* 146 */ "idlist_opt ::=",
+ /* 147 */ "idlist_opt ::= LP idlist RP",
+ /* 148 */ "idlist ::= idlist COMMA nm",
+ /* 149 */ "idlist ::= nm",
+ /* 150 */ "expr ::= LP expr RP",
+ /* 151 */ "term ::= NULL",
+ /* 152 */ "expr ::= ID|INDEXED",
+ /* 153 */ "expr ::= JOIN_KW",
+ /* 154 */ "expr ::= nm DOT nm",
+ /* 155 */ "expr ::= nm DOT nm DOT nm",
+ /* 156 */ "term ::= FLOAT|BLOB",
+ /* 157 */ "term ::= STRING",
+ /* 158 */ "term ::= INTEGER",
+ /* 159 */ "expr ::= VARIABLE",
+ /* 160 */ "expr ::= expr COLLATE ID|STRING",
+ /* 161 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 162 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 163 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 164 */ "term ::= CTIME_KW",
+ /* 165 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 166 */ "expr ::= expr AND expr",
+ /* 167 */ "expr ::= expr OR expr",
+ /* 168 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 169 */ "expr ::= expr EQ|NE expr",
+ /* 170 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 171 */ "expr ::= expr PLUS|MINUS expr",
+ /* 172 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 173 */ "expr ::= expr CONCAT expr",
+ /* 174 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 175 */ "expr ::= expr likeop expr",
+ /* 176 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 177 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 178 */ "expr ::= expr NOT NULL",
+ /* 179 */ "expr ::= expr IS expr",
+ /* 180 */ "expr ::= expr IS NOT expr",
+ /* 181 */ "expr ::= NOT expr",
+ /* 182 */ "expr ::= BITNOT expr",
+ /* 183 */ "expr ::= MINUS expr",
+ /* 184 */ "expr ::= PLUS expr",
+ /* 185 */ "between_op ::= BETWEEN",
+ /* 186 */ "between_op ::= NOT BETWEEN",
+ /* 187 */ "expr ::= expr between_op expr AND expr",
+ /* 188 */ "in_op ::= IN",
+ /* 189 */ "in_op ::= NOT IN",
+ /* 190 */ "expr ::= expr in_op LP exprlist RP",
+ /* 191 */ "expr ::= LP select RP",
+ /* 192 */ "expr ::= expr in_op LP select RP",
+ /* 193 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 194 */ "expr ::= EXISTS LP select RP",
+ /* 195 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 196 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 197 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 198 */ "case_else ::= ELSE expr",
+ /* 199 */ "case_else ::=",
+ /* 200 */ "case_operand ::= expr",
+ /* 201 */ "case_operand ::=",
+ /* 202 */ "exprlist ::=",
+ /* 203 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 204 */ "nexprlist ::= expr",
+ /* 205 */ "paren_exprlist ::=",
+ /* 206 */ "paren_exprlist ::= LP exprlist RP",
+ /* 207 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 208 */ "uniqueflag ::= UNIQUE",
+ /* 209 */ "uniqueflag ::=",
+ /* 210 */ "eidlist_opt ::=",
+ /* 211 */ "eidlist_opt ::= LP eidlist RP",
+ /* 212 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 213 */ "eidlist ::= nm collate sortorder",
+ /* 214 */ "collate ::=",
+ /* 215 */ "collate ::= COLLATE ID|STRING",
+ /* 216 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 217 */ "cmd ::= VACUUM",
+ /* 218 */ "cmd ::= VACUUM nm",
+ /* 219 */ "cmd ::= PRAGMA nm dbnm",
+ /* 220 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 221 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 222 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 223 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 224 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 225 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 226 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 227 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 228 */ "trigger_time ::= BEFORE",
+ /* 229 */ "trigger_time ::= AFTER",
+ /* 230 */ "trigger_time ::= INSTEAD OF",
+ /* 231 */ "trigger_time ::=",
+ /* 232 */ "trigger_event ::= DELETE|INSERT",
+ /* 233 */ "trigger_event ::= UPDATE",
+ /* 234 */ "trigger_event ::= UPDATE OF idlist",
+ /* 235 */ "when_clause ::=",
+ /* 236 */ "when_clause ::= WHEN expr",
+ /* 237 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 238 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 239 */ "trnm ::= nm DOT nm",
+ /* 240 */ "tridxby ::= INDEXED BY nm",
+ /* 241 */ "tridxby ::= NOT INDEXED",
+ /* 242 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 243 */ "trigger_cmd ::= insert_cmd INTO trnm idlist_opt select",
+ /* 244 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 245 */ "trigger_cmd ::= select",
+ /* 246 */ "expr ::= RAISE LP IGNORE RP",
+ /* 247 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 248 */ "raisetype ::= ROLLBACK",
+ /* 249 */ "raisetype ::= ABORT",
+ /* 250 */ "raisetype ::= FAIL",
+ /* 251 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 252 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 253 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 254 */ "key_opt ::=",
+ /* 255 */ "key_opt ::= KEY expr",
+ /* 256 */ "cmd ::= REINDEX",
+ /* 257 */ "cmd ::= REINDEX nm dbnm",
+ /* 258 */ "cmd ::= ANALYZE",
+ /* 259 */ "cmd ::= ANALYZE nm dbnm",
+ /* 260 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 261 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 262 */ "add_column_fullname ::= fullname",
+ /* 263 */ "cmd ::= create_vtab",
+ /* 264 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 265 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 266 */ "vtabarg ::=",
+ /* 267 */ "vtabargtoken ::= ANY",
+ /* 268 */ "vtabargtoken ::= lp anylist RP",
+ /* 269 */ "lp ::= LP",
+ /* 270 */ "with ::=",
+ /* 271 */ "with ::= WITH wqlist",
+ /* 272 */ "with ::= WITH RECURSIVE wqlist",
+ /* 273 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 274 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 275 */ "input ::= cmdlist",
+ /* 276 */ "cmdlist ::= cmdlist ecmd",
+ /* 277 */ "cmdlist ::= ecmd",
+ /* 278 */ "ecmd ::= SEMI",
+ /* 279 */ "ecmd ::= explain cmdx SEMI",
+ /* 280 */ "explain ::=",
+ /* 281 */ "trans_opt ::=",
+ /* 282 */ "trans_opt ::= TRANSACTION",
+ /* 283 */ "trans_opt ::= TRANSACTION nm",
+ /* 284 */ "savepoint_opt ::= SAVEPOINT",
+ /* 285 */ "savepoint_opt ::=",
+ /* 286 */ "cmd ::= create_table create_table_args",
+ /* 287 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 288 */ "columnlist ::= columnname carglist",
+ /* 289 */ "nm ::= ID|INDEXED",
+ /* 290 */ "nm ::= STRING",
+ /* 291 */ "nm ::= JOIN_KW",
+ /* 292 */ "typetoken ::= typename",
+ /* 293 */ "typename ::= ID|STRING",
+ /* 294 */ "signed ::= plus_num",
+ /* 295 */ "signed ::= minus_num",
+ /* 296 */ "carglist ::= carglist ccons",
+ /* 297 */ "carglist ::=",
+ /* 298 */ "ccons ::= NULL onconf",
+ /* 299 */ "conslist_opt ::= COMMA conslist",
+ /* 300 */ "conslist ::= conslist tconscomma tcons",
+ /* 301 */ "conslist ::= tcons",
+ /* 302 */ "tconscomma ::=",
+ /* 303 */ "defer_subclause_opt ::= defer_subclause",
+ /* 304 */ "resolvetype ::= raisetype",
+ /* 305 */ "selectnowith ::= oneselect",
+ /* 306 */ "oneselect ::= values",
+ /* 307 */ "sclp ::= selcollist COMMA",
+ /* 308 */ "as ::= ID|STRING",
+ /* 309 */ "expr ::= term",
+ /* 310 */ "likeop ::= LIKE_KW|MATCH",
+ /* 311 */ "exprlist ::= nexprlist",
+ /* 312 */ "nmnum ::= plus_num",
+ /* 313 */ "nmnum ::= nm",
+ /* 314 */ "nmnum ::= ON",
+ /* 315 */ "nmnum ::= DELETE",
+ /* 316 */ "nmnum ::= DEFAULT",
+ /* 317 */ "plus_num ::= INTEGER|FLOAT",
+ /* 318 */ "foreach_clause ::=",
+ /* 319 */ "foreach_clause ::= FOR EACH ROW",
+ /* 320 */ "trnm ::= nm",
+ /* 321 */ "tridxby ::=",
+ /* 322 */ "database_kw_opt ::= DATABASE",
+ /* 323 */ "database_kw_opt ::=",
+ /* 324 */ "kwcolumn_opt ::=",
+ /* 325 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 326 */ "vtabarglist ::= vtabarg",
+ /* 327 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 328 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 329 */ "anylist ::=",
+ /* 330 */ "anylist ::= anylist LP anylist RP",
+ /* 331 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
@@ -132992,6 +136329,31 @@ static int yyGrowStack(yyParser *p){
# define YYMALLOCARGTYPE size_t
#endif
+/* Initialize a new parser that has already been allocated.
+*/
+SQLITE_PRIVATE void sqlite3ParserInit(void *yypParser){
+ yyParser *pParser = (yyParser*)yypParser;
+#ifdef YYTRACKMAXSTACKDEPTH
+ pParser->yyhwm = 0;
+#endif
+#if YYSTACKDEPTH<=0
+ pParser->yytos = NULL;
+ pParser->yystack = NULL;
+ pParser->yystksz = 0;
+ if( yyGrowStack(pParser) ){
+ pParser->yystack = &pParser->yystk0;
+ pParser->yystksz = 1;
+ }
+#endif
+#ifndef YYNOERRORRECOVERY
+ pParser->yyerrcnt = -1;
+#endif
+ pParser->yytos = pParser->yystack;
+ pParser->yystack[0].stateno = 0;
+ pParser->yystack[0].major = 0;
+}
+
+#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
/*
** This function allocates a new parser.
** The only argument is a pointer to a function which works like
@@ -133007,28 +136369,11 @@ static int yyGrowStack(yyParser *p){
SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE)){
yyParser *pParser;
pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) );
- if( pParser ){
-#ifdef YYTRACKMAXSTACKDEPTH
- pParser->yyhwm = 0;
-#endif
-#if YYSTACKDEPTH<=0
- pParser->yytos = NULL;
- pParser->yystack = NULL;
- pParser->yystksz = 0;
- if( yyGrowStack(pParser) ){
- pParser->yystack = &pParser->yystk0;
- pParser->yystksz = 1;
- }
-#endif
-#ifndef YYNOERRORRECOVERY
- pParser->yyerrcnt = -1;
-#endif
- pParser->yytos = pParser->yystack;
- pParser->yystack[0].stateno = 0;
- pParser->yystack[0].major = 0;
- }
+ if( pParser ) sqlite3ParserInit(pParser);
return pParser;
}
+#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
+
/* The following function deletes the "minor type" or semantic value
** associated with a symbol. The symbol can be either a terminal
@@ -133154,6 +136499,18 @@ static void yy_pop_parser_stack(yyParser *pParser){
yy_destructor(pParser, yytos->major, &yytos->minor);
}
+/*
+** Clear all secondary memory allocations from the parser
+*/
+SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){
+ yyParser *pParser = (yyParser*)p;
+ while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
+#if YYSTACKDEPTH<=0
+ if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
+#endif
+}
+
+#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
/*
** Deallocate and destroy a parser. Destructors are called for
** all stack elements before shutting the parser down.
@@ -133166,16 +136523,13 @@ SQLITE_PRIVATE void sqlite3ParserFree(
void *p, /* The parser to be deleted */
void (*freeProc)(void*) /* Function used to reclaim memory */
){
- yyParser *pParser = (yyParser*)p;
#ifndef YYPARSEFREENEVERNULL
- if( pParser==0 ) return;
-#endif
- while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack);
+ if( p==0 ) return;
#endif
- (*freeProc)((void*)pParser);
+ sqlite3ParserFinalize(p);
+ (*freeProc)(p);
}
+#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */
/*
** Return the peak depth of the stack for a parser.
@@ -133202,50 +136556,47 @@ static unsigned int yy_find_shift_action(
assert( stateno <= YY_SHIFT_COUNT );
do{
i = yy_shift_ofst[stateno];
- if( i==YY_SHIFT_USE_DFLT ) return yy_default[stateno];
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
- if( iLookAhead>0 ){
#ifdef YYFALLBACK
- YYCODETYPE iFallback; /* Fallback token */
- if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
- && (iFallback = yyFallback[iLookAhead])!=0 ){
+ YYCODETYPE iFallback; /* Fallback token */
+ if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+ && (iFallback = yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
- }
-#endif
- assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
- iLookAhead = iFallback;
- continue;
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
}
#endif
+ assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
+ }
+#endif
#ifdef YYWILDCARD
- {
- int j = i - iLookAhead + YYWILDCARD;
- if(
+ {
+ int j = i - iLookAhead + YYWILDCARD;
+ if(
#if YY_SHIFT_MIN+YYWILDCARD<0
- j>=0 &&
+ j>=0 &&
#endif
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
- j<YY_ACTTAB_COUNT &&
+ j<YY_ACTTAB_COUNT &&
#endif
- yy_lookahead[j]==YYWILDCARD
- ){
+ yy_lookahead[j]==YYWILDCARD && iLookAhead>0
+ ){
#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
- yyTracePrompt, yyTokenName[iLookAhead],
- yyTokenName[YYWILDCARD]);
- }
-#endif /* NDEBUG */
- return yy_action[j];
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead],
+ yyTokenName[YYWILDCARD]);
}
+#endif /* NDEBUG */
+ return yy_action[j];
}
-#endif /* YYWILDCARD */
}
+#endif /* YYWILDCARD */
return yy_default[stateno];
}else{
return yy_action[i];
@@ -133289,7 +136640,6 @@ static int yy_find_reduce_action(
*/
static void yyStackOverflow(yyParser *yypParser){
sqlite3ParserARG_FETCH;
- yypParser->yytos--;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
@@ -133344,12 +136694,14 @@ static void yy_shift(
#endif
#if YYSTACKDEPTH>0
if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){
+ yypParser->yytos--;
yyStackOverflow(yypParser);
return;
}
#else
if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){
if( yyGrowStack(yypParser) ){
+ yypParser->yytos--;
yyStackOverflow(yypParser);
return;
}
@@ -133511,7 +136863,9 @@ static const struct {
{ 201, 2 },
{ 149, 8 },
{ 218, 5 },
+ { 218, 7 },
{ 218, 3 },
+ { 218, 5 },
{ 149, 6 },
{ 149, 7 },
{ 219, 2 },
@@ -133528,12 +136882,14 @@ static const struct {
{ 173, 5 },
{ 172, 1 },
{ 172, 1 },
+ { 172, 1 },
{ 173, 1 },
{ 173, 3 },
{ 173, 6 },
{ 173, 5 },
{ 173, 4 },
{ 172, 1 },
+ { 173, 5 },
{ 173, 3 },
{ 173, 3 },
{ 173, 3 },
@@ -133542,7 +136898,6 @@ static const struct {
{ 173, 3 },
{ 173, 3 },
{ 173, 3 },
- { 221, 1 },
{ 221, 2 },
{ 173, 3 },
{ 173, 5 },
@@ -133679,6 +137034,7 @@ static const struct {
{ 209, 2 },
{ 210, 1 },
{ 173, 1 },
+ { 221, 1 },
{ 208, 1 },
{ 230, 1 },
{ 230, 1 },
@@ -133821,7 +137177,7 @@ static void yy_reduce(
case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
case 90: /* distinct ::= */ yytestcase(yyruleno==90);
- case 211: /* collate ::= */ yytestcase(yyruleno==211);
+ case 214: /* collate ::= */ yytestcase(yyruleno==214);
{yymsp[1].minor.yy194 = 0;}
break;
case 17: /* ifnotexists ::= IF NOT EXISTS */
@@ -133887,7 +137243,7 @@ static void yy_reduce(
case 33: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0, 0);
+ v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0);
v.zStart = yymsp[-1].minor.yy0.z;
v.zEnd = yymsp[0].minor.yy190.zEnd;
sqlite3AddDefaultValue(pParse,&v);
@@ -133960,14 +137316,14 @@ static void yy_reduce(
break;
case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
- case 142: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==142);
+ case 144: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==144);
{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
break;
case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
- case 183: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==183);
- case 186: /* in_op ::= NOT IN */ yytestcase(yyruleno==186);
- case 212: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==212);
+ case 186: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==186);
+ case 189: /* in_op ::= NOT IN */ yytestcase(yyruleno==189);
+ case 215: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==215);
{yymsp[-1].minor.yy194 = 1;}
break;
case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
@@ -134003,7 +137359,7 @@ static void yy_reduce(
{yymsp[0].minor.yy194 = OE_Ignore;}
break;
case 73: /* resolvetype ::= REPLACE */
- case 143: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==143);
+ case 145: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==145);
{yymsp[0].minor.yy194 = OE_Replace;}
break;
case 74: /* cmd ::= DROP TABLE ifexists fullname */
@@ -134131,9 +137487,9 @@ static void yy_reduce(
case 91: /* sclp ::= */
case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
- case 199: /* exprlist ::= */ yytestcase(yyruleno==199);
- case 202: /* paren_exprlist ::= */ yytestcase(yyruleno==202);
- case 207: /* eidlist_opt ::= */ yytestcase(yyruleno==207);
+ case 202: /* exprlist ::= */ yytestcase(yyruleno==202);
+ case 205: /* paren_exprlist ::= */ yytestcase(yyruleno==205);
+ case 210: /* eidlist_opt ::= */ yytestcase(yyruleno==210);
{yymsp[1].minor.yy148 = 0;}
break;
case 92: /* selcollist ::= sclp expr as */
@@ -134151,16 +137507,16 @@ static void yy_reduce(
break;
case 94: /* selcollist ::= sclp nm DOT STAR */
{
- Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &yymsp[0].minor.yy0);
- Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
+ Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
+ Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+ Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
}
break;
case 95: /* as ::= AS nm */
case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
- case 221: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==221);
- case 222: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==222);
+ case 224: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==224);
+ case 225: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==225);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
case 97: /* from ::= */
@@ -134243,14 +137599,14 @@ static void yy_reduce(
case 112: /* on_opt ::= ON expr */
case 129: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==129);
case 136: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==136);
- case 195: /* case_else ::= ELSE expr */ yytestcase(yyruleno==195);
+ case 198: /* case_else ::= ELSE expr */ yytestcase(yyruleno==198);
{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
break;
case 113: /* on_opt ::= */
case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
- case 196: /* case_else ::= */ yytestcase(yyruleno==196);
- case 198: /* case_operand ::= */ yytestcase(yyruleno==198);
+ case 199: /* case_else ::= */ yytestcase(yyruleno==199);
+ case 201: /* case_operand ::= */ yytestcase(yyruleno==201);
{yymsp[1].minor.yy72 = 0;}
break;
case 115: /* indexed_opt ::= INDEXED BY nm */
@@ -134263,7 +137619,7 @@ static void yy_reduce(
{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
break;
case 118: /* using_opt ::= */
- case 144: /* idlist_opt ::= */ yytestcase(yyruleno==144);
+ case 146: /* idlist_opt ::= */ yytestcase(yyruleno==146);
{yymsp[1].minor.yy254 = 0;}
break;
case 120: /* orderby_opt ::= ORDER BY sortlist */
@@ -134324,69 +137680,89 @@ static void yy_reduce(
sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 1);
}
break;
- case 139: /* setlist ::= nm EQ expr */
+ case 139: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
+{
+ yymsp[-6].minor.yy148 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy148, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr);
+}
+ break;
+ case 140: /* setlist ::= nm EQ expr */
{
yylhsminor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr);
sqlite3ExprListSetName(pParse, yylhsminor.yy148, &yymsp[-2].minor.yy0, 1);
}
yymsp[-2].minor.yy148 = yylhsminor.yy148;
break;
- case 140: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
+ case 141: /* setlist ::= LP idlist RP EQ expr */
+{
+ yymsp[-4].minor.yy148 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr);
+}
+ break;
+ case 142: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
{
sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1);
sqlite3Insert(pParse, yymsp[-2].minor.yy185, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, yymsp[-4].minor.yy194);
}
break;
- case 141: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
+ case 143: /* cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
{
sqlite3WithPush(pParse, yymsp[-6].minor.yy285, 1);
sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);
}
break;
- case 145: /* idlist_opt ::= LP idlist RP */
+ case 147: /* idlist_opt ::= LP idlist RP */
{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
break;
- case 146: /* idlist ::= idlist COMMA nm */
+ case 148: /* idlist ::= idlist COMMA nm */
{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
break;
- case 147: /* idlist ::= nm */
+ case 149: /* idlist ::= nm */
{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
- case 148: /* expr ::= LP expr RP */
+ case 150: /* expr ::= LP expr RP */
{spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/ yymsp[-2].minor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr;}
break;
- case 149: /* term ::= NULL */
- case 154: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==154);
- case 155: /* term ::= STRING */ yytestcase(yyruleno==155);
+ case 151: /* term ::= NULL */
+ case 156: /* term ::= FLOAT|BLOB */ yytestcase(yyruleno==156);
+ case 157: /* term ::= STRING */ yytestcase(yyruleno==157);
{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0);/*A-overwrites-X*/}
break;
- case 150: /* expr ::= ID|INDEXED */
- case 151: /* expr ::= JOIN_KW */ yytestcase(yyruleno==151);
+ case 152: /* expr ::= ID|INDEXED */
+ case 153: /* expr ::= JOIN_KW */ yytestcase(yyruleno==153);
{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 152: /* expr ::= nm DOT nm */
+ case 154: /* expr ::= nm DOT nm */
{
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
+ Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+ Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
break;
- case 153: /* expr ::= nm DOT nm DOT nm */
+ case 155: /* expr ::= nm DOT nm DOT nm */
{
- Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
- Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
- Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
+ Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1);
+ Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1);
+ Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1);
+ Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
break;
- case 156: /* expr ::= VARIABLE */
+ case 158: /* term ::= INTEGER */
+{
+ yylhsminor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
+ yylhsminor.yy190.zStart = yymsp[0].minor.yy0.z;
+ yylhsminor.yy190.zEnd = yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n;
+ if( yylhsminor.yy190.pExpr ) yylhsminor.yy190.pExpr->flags |= EP_Leaf|EP_Resolved;
+}
+ yymsp[0].minor.yy190 = yylhsminor.yy190;
+ break;
+ case 159: /* expr ::= VARIABLE */
{
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
+ u32 n = yymsp[0].minor.yy0.n;
spanExpr(&yymsp[0].minor.yy190, pParse, TK_VARIABLE, yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy190.pExpr, n);
}else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
@@ -134398,25 +137774,26 @@ static void yy_reduce(
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
yymsp[0].minor.yy190.pExpr = 0;
}else{
- yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
+ yymsp[0].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
if( yymsp[0].minor.yy190.pExpr ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy190.pExpr->iTable);
}
}
}
break;
- case 157: /* expr ::= expr COLLATE ID|STRING */
+ case 160: /* expr ::= expr COLLATE ID|STRING */
{
yymsp[-2].minor.yy190.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0, 1);
yymsp[-2].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 158: /* expr ::= CAST LP expr AS typetoken RP */
+ case 161: /* expr ::= CAST LP expr AS typetoken RP */
{
spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0);
+ yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, 0);
}
break;
- case 159: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ case 162: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
@@ -134429,96 +137806,110 @@ static void yy_reduce(
}
yymsp[-4].minor.yy190 = yylhsminor.yy190;
break;
- case 160: /* expr ::= ID|INDEXED LP STAR RP */
+ case 163: /* expr ::= ID|INDEXED LP STAR RP */
{
yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
spanSet(&yylhsminor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
yymsp[-3].minor.yy190 = yylhsminor.yy190;
break;
- case 161: /* term ::= CTIME_KW */
+ case 164: /* term ::= CTIME_KW */
{
yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
yymsp[0].minor.yy190 = yylhsminor.yy190;
break;
- case 162: /* expr ::= expr AND expr */
- case 163: /* expr ::= expr OR expr */ yytestcase(yyruleno==163);
- case 164: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==164);
- case 165: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==165);
- case 166: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==166);
- case 167: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==167);
- case 168: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==168);
- case 169: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==169);
-{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
+ case 165: /* expr ::= LP nexprlist COMMA expr RP */
+{
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy148, yymsp[-1].minor.yy190.pExpr);
+ yylhsminor.yy190.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yylhsminor.yy190.pExpr ){
+ yylhsminor.yy190.pExpr->x.pList = pList;
+ spanSet(&yylhsminor.yy190, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+ }else{
+ sqlite3ExprListDelete(pParse->db, pList);
+ }
+}
+ yymsp[-4].minor.yy190 = yylhsminor.yy190;
break;
- case 170: /* likeop ::= LIKE_KW|MATCH */
-{yymsp[0].minor.yy392.eOperator = yymsp[0].minor.yy0; yymsp[0].minor.yy392.bNot = 0;/*A-overwrites-X*/}
+ case 166: /* expr ::= expr AND expr */
+ case 167: /* expr ::= expr OR expr */ yytestcase(yyruleno==167);
+ case 168: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==168);
+ case 169: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==169);
+ case 170: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==170);
+ case 171: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==171);
+ case 172: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==172);
+ case 173: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==173);
+{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
break;
- case 171: /* likeop ::= NOT LIKE_KW|MATCH */
-{yymsp[-1].minor.yy392.eOperator = yymsp[0].minor.yy0; yymsp[-1].minor.yy392.bNot = 1;}
+ case 174: /* likeop ::= NOT LIKE_KW|MATCH */
+{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
break;
- case 172: /* expr ::= expr likeop expr */
+ case 175: /* expr ::= expr likeop expr */
{
ExprList *pList;
+ int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
+ yymsp[-1].minor.yy0.n &= 0x7fffffff;
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy190.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy190.pExpr);
- yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy392.eOperator);
- exprNot(pParse, yymsp[-1].minor.yy392.bNot, &yymsp[-2].minor.yy190);
+ yymsp[-2].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0);
+ exprNot(pParse, bNot, &yymsp[-2].minor.yy190);
yymsp[-2].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
if( yymsp[-2].minor.yy190.pExpr ) yymsp[-2].minor.yy190.pExpr->flags |= EP_InfixFunc;
}
break;
- case 173: /* expr ::= expr likeop expr ESCAPE expr */
+ case 176: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
+ int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
+ yymsp[-3].minor.yy0.n &= 0x7fffffff;
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy190.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
- yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy392.eOperator);
- exprNot(pParse, yymsp[-3].minor.yy392.bNot, &yymsp[-4].minor.yy190);
+ yymsp[-4].minor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0);
+ exprNot(pParse, bNot, &yymsp[-4].minor.yy190);
yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
if( yymsp[-4].minor.yy190.pExpr ) yymsp[-4].minor.yy190.pExpr->flags |= EP_InfixFunc;
}
break;
- case 174: /* expr ::= expr ISNULL|NOTNULL */
+ case 177: /* expr ::= expr ISNULL|NOTNULL */
{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
break;
- case 175: /* expr ::= expr NOT NULL */
+ case 178: /* expr ::= expr NOT NULL */
{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
break;
- case 176: /* expr ::= expr IS expr */
+ case 179: /* expr ::= expr IS expr */
{
spanBinaryExpr(pParse,TK_IS,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-2].minor.yy190.pExpr, TK_ISNULL);
}
break;
- case 177: /* expr ::= expr IS NOT expr */
+ case 180: /* expr ::= expr IS NOT expr */
{
spanBinaryExpr(pParse,TK_ISNOT,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy190);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, TK_NOTNULL);
}
break;
- case 178: /* expr ::= NOT expr */
- case 179: /* expr ::= BITNOT expr */ yytestcase(yyruleno==179);
+ case 181: /* expr ::= NOT expr */
+ case 182: /* expr ::= BITNOT expr */ yytestcase(yyruleno==182);
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
break;
- case 180: /* expr ::= MINUS expr */
+ case 183: /* expr ::= MINUS expr */
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
break;
- case 181: /* expr ::= PLUS expr */
+ case 184: /* expr ::= PLUS expr */
{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
break;
- case 182: /* between_op ::= BETWEEN */
- case 185: /* in_op ::= IN */ yytestcase(yyruleno==185);
+ case 185: /* between_op ::= BETWEEN */
+ case 188: /* in_op ::= IN */ yytestcase(yyruleno==188);
{yymsp[0].minor.yy194 = 0;}
break;
- case 184: /* expr ::= expr between_op expr AND expr */
+ case 187: /* expr ::= expr between_op expr AND expr */
{
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0);
if( yymsp[-4].minor.yy190.pExpr ){
yymsp[-4].minor.yy190.pExpr->x.pList = pList;
}else{
@@ -134528,7 +137919,7 @@ static void yy_reduce(
yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
}
break;
- case 187: /* expr ::= expr in_op LP exprlist RP */
+ case 190: /* expr ::= expr in_op LP exprlist RP */
{
if( yymsp[-1].minor.yy148==0 ){
/* Expressions of the form
@@ -134540,7 +137931,7 @@ static void yy_reduce(
** regardless of the value of expr1.
*/
sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy190.pExpr);
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy194]);
+ yymsp[-4].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy194],1);
}else if( yymsp[-1].minor.yy148->nExpr==1 ){
/* Expressions of the form:
**
@@ -134567,9 +137958,9 @@ static void yy_reduce(
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy194 ? TK_NE : TK_EQ, yymsp[-4].minor.yy190.pExpr, pRHS, 0);
+ yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, yymsp[-3].minor.yy194 ? TK_NE : TK_EQ, yymsp[-4].minor.yy190.pExpr, pRHS);
}else{
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
if( yymsp[-4].minor.yy190.pExpr ){
yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148;
sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr);
@@ -134581,44 +137972,44 @@ static void yy_reduce(
yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 188: /* expr ::= LP select RP */
+ case 191: /* expr ::= LP select RP */
{
spanSet(&yymsp[-2].minor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
- yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ yymsp[-2].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
}
break;
- case 189: /* expr ::= expr in_op LP select RP */
+ case 192: /* expr ::= expr in_op LP select RP */
{
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, yymsp[-1].minor.yy243);
exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 190: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 193: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
if( yymsp[0].minor.yy148 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy148);
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy190.pExpr, pSelect);
exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
yymsp[-4].minor.yy190.zEnd = yymsp[-1].minor.yy0.z ? &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n] : &yymsp[-2].minor.yy0.z[yymsp[-2].minor.yy0.n];
}
break;
- case 191: /* expr ::= EXISTS LP select RP */
+ case 194: /* expr ::= EXISTS LP select RP */
{
Expr *p;
spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-B*/
- p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ p = yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
}
break;
- case 192: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 195: /* expr ::= CASE case_operand case_exprlist case_else END */
{
spanSet(&yymsp[-4].minor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-C*/
- yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0, 0);
+ yymsp[-4].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, 0);
if( yymsp[-4].minor.yy190.pExpr ){
yymsp[-4].minor.yy190.pExpr->x.pList = yymsp[-1].minor.yy72 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72) : yymsp[-2].minor.yy148;
sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy190.pExpr);
@@ -134628,78 +138019,80 @@ static void yy_reduce(
}
}
break;
- case 193: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 196: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
- case 194: /* case_exprlist ::= WHEN expr THEN expr */
+ case 197: /* case_exprlist ::= WHEN expr THEN expr */
{
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
- case 197: /* case_operand ::= expr */
+ case 200: /* case_operand ::= expr */
{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
break;
- case 200: /* nexprlist ::= nexprlist COMMA expr */
+ case 203: /* nexprlist ::= nexprlist COMMA expr */
{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
break;
- case 201: /* nexprlist ::= expr */
+ case 204: /* nexprlist ::= expr */
{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
break;
- case 203: /* paren_exprlist ::= LP exprlist RP */
- case 208: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==208);
+ case 206: /* paren_exprlist ::= LP exprlist RP */
+ case 211: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==211);
{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
break;
- case 204: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ case 207: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy148, yymsp[-10].minor.yy194,
&yymsp[-11].minor.yy0, yymsp[0].minor.yy72, SQLITE_SO_ASC, yymsp[-8].minor.yy194, SQLITE_IDXTYPE_APPDEF);
}
break;
- case 205: /* uniqueflag ::= UNIQUE */
- case 246: /* raisetype ::= ABORT */ yytestcase(yyruleno==246);
+ case 208: /* uniqueflag ::= UNIQUE */
+ case 249: /* raisetype ::= ABORT */ yytestcase(yyruleno==249);
{yymsp[0].minor.yy194 = OE_Abort;}
break;
- case 206: /* uniqueflag ::= */
+ case 209: /* uniqueflag ::= */
{yymsp[1].minor.yy194 = OE_None;}
break;
- case 209: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 212: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
yymsp[-4].minor.yy148 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194);
}
break;
- case 210: /* eidlist ::= nm collate sortorder */
+ case 213: /* eidlist ::= nm collate sortorder */
{
yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
}
break;
- case 213: /* cmd ::= DROP INDEX ifexists fullname */
+ case 216: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
break;
- case 214: /* cmd ::= VACUUM */
- case 215: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==215);
-{sqlite3Vacuum(pParse);}
+ case 217: /* cmd ::= VACUUM */
+{sqlite3Vacuum(pParse,0);}
break;
- case 216: /* cmd ::= PRAGMA nm dbnm */
+ case 218: /* cmd ::= VACUUM nm */
+{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
+ break;
+ case 219: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 217: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 220: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 218: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 221: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 219: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 222: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 220: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 223: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 223: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 226: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
@@ -134707,53 +138100,53 @@ static void yy_reduce(
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
}
break;
- case 224: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 227: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 225: /* trigger_time ::= BEFORE */
+ case 228: /* trigger_time ::= BEFORE */
{ yymsp[0].minor.yy194 = TK_BEFORE; }
break;
- case 226: /* trigger_time ::= AFTER */
+ case 229: /* trigger_time ::= AFTER */
{ yymsp[0].minor.yy194 = TK_AFTER; }
break;
- case 227: /* trigger_time ::= INSTEAD OF */
+ case 230: /* trigger_time ::= INSTEAD OF */
{ yymsp[-1].minor.yy194 = TK_INSTEAD;}
break;
- case 228: /* trigger_time ::= */
+ case 231: /* trigger_time ::= */
{ yymsp[1].minor.yy194 = TK_BEFORE; }
break;
- case 229: /* trigger_event ::= DELETE|INSERT */
- case 230: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==230);
+ case 232: /* trigger_event ::= DELETE|INSERT */
+ case 233: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==233);
{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
break;
- case 231: /* trigger_event ::= UPDATE OF idlist */
+ case 234: /* trigger_event ::= UPDATE OF idlist */
{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
break;
- case 232: /* when_clause ::= */
- case 251: /* key_opt ::= */ yytestcase(yyruleno==251);
+ case 235: /* when_clause ::= */
+ case 254: /* key_opt ::= */ yytestcase(yyruleno==254);
{ yymsp[1].minor.yy72 = 0; }
break;
- case 233: /* when_clause ::= WHEN expr */
- case 252: /* key_opt ::= KEY expr */ yytestcase(yyruleno==252);
+ case 236: /* when_clause ::= WHEN expr */
+ case 255: /* key_opt ::= KEY expr */ yytestcase(yyruleno==255);
{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
break;
- case 234: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 237: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
assert( yymsp[-2].minor.yy145!=0 );
yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145;
}
break;
- case 235: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 238: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
assert( yymsp[-1].minor.yy145!=0 );
yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
}
break;
- case 236: /* trnm ::= nm DOT nm */
+ case 239: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -134761,195 +138154,196 @@ static void yy_reduce(
"statements within triggers");
}
break;
- case 237: /* tridxby ::= INDEXED BY nm */
+ case 240: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 238: /* tridxby ::= NOT INDEXED */
+ case 241: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 239: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+ case 242: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
break;
- case 240: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
+ case 243: /* trigger_cmd ::= insert_cmd INTO trnm idlist_opt select */
{yymsp[-4].minor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);/*A-overwrites-R*/}
break;
- case 241: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+ case 244: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
break;
- case 242: /* trigger_cmd ::= select */
+ case 245: /* trigger_cmd ::= select */
{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
break;
- case 243: /* expr ::= RAISE LP IGNORE RP */
+ case 246: /* expr ::= RAISE LP IGNORE RP */
{
spanSet(&yymsp[-3].minor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ yymsp[-3].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
if( yymsp[-3].minor.yy190.pExpr ){
yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore;
}
}
break;
- case 244: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 247: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
spanSet(&yymsp[-5].minor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/
- yymsp[-5].minor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ yymsp[-5].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
if( yymsp[-5].minor.yy190.pExpr ) {
yymsp[-5].minor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
}
}
break;
- case 245: /* raisetype ::= ROLLBACK */
+ case 248: /* raisetype ::= ROLLBACK */
{yymsp[0].minor.yy194 = OE_Rollback;}
break;
- case 247: /* raisetype ::= FAIL */
+ case 250: /* raisetype ::= FAIL */
{yymsp[0].minor.yy194 = OE_Fail;}
break;
- case 248: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 251: /* cmd ::= DROP TRIGGER ifexists fullname */
{
sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
}
break;
- case 249: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 252: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
}
break;
- case 250: /* cmd ::= DETACH database_kw_opt expr */
+ case 253: /* cmd ::= DETACH database_kw_opt expr */
{
sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
}
break;
- case 253: /* cmd ::= REINDEX */
+ case 256: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 254: /* cmd ::= REINDEX nm dbnm */
+ case 257: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 255: /* cmd ::= ANALYZE */
+ case 258: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 256: /* cmd ::= ANALYZE nm dbnm */
+ case 259: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 257: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 260: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
}
break;
- case 258: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 261: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
- case 259: /* add_column_fullname ::= fullname */
+ case 262: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
}
break;
- case 260: /* cmd ::= create_vtab */
+ case 263: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 261: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 264: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 262: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 265: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy194);
}
break;
- case 263: /* vtabarg ::= */
+ case 266: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 264: /* vtabargtoken ::= ANY */
- case 265: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==265);
- case 266: /* lp ::= LP */ yytestcase(yyruleno==266);
+ case 267: /* vtabargtoken ::= ANY */
+ case 268: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==268);
+ case 269: /* lp ::= LP */ yytestcase(yyruleno==269);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 267: /* with ::= */
+ case 270: /* with ::= */
{yymsp[1].minor.yy285 = 0;}
break;
- case 268: /* with ::= WITH wqlist */
+ case 271: /* with ::= WITH wqlist */
{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
break;
- case 269: /* with ::= WITH RECURSIVE wqlist */
+ case 272: /* with ::= WITH RECURSIVE wqlist */
{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
break;
- case 270: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ case 273: /* wqlist ::= nm eidlist_opt AS LP select RP */
{
yymsp[-5].minor.yy285 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243); /*A-overwrites-X*/
}
break;
- case 271: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ case 274: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
{
yymsp[-7].minor.yy285 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy285, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy148, yymsp[-1].minor.yy243);
}
break;
default:
- /* (272) input ::= cmdlist */ yytestcase(yyruleno==272);
- /* (273) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==273);
- /* (274) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=274);
- /* (275) ecmd ::= SEMI */ yytestcase(yyruleno==275);
- /* (276) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==276);
- /* (277) explain ::= */ yytestcase(yyruleno==277);
- /* (278) trans_opt ::= */ yytestcase(yyruleno==278);
- /* (279) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==279);
- /* (280) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==280);
- /* (281) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==281);
- /* (282) savepoint_opt ::= */ yytestcase(yyruleno==282);
- /* (283) cmd ::= create_table create_table_args */ yytestcase(yyruleno==283);
- /* (284) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==284);
- /* (285) columnlist ::= columnname carglist */ yytestcase(yyruleno==285);
- /* (286) nm ::= ID|INDEXED */ yytestcase(yyruleno==286);
- /* (287) nm ::= STRING */ yytestcase(yyruleno==287);
- /* (288) nm ::= JOIN_KW */ yytestcase(yyruleno==288);
- /* (289) typetoken ::= typename */ yytestcase(yyruleno==289);
- /* (290) typename ::= ID|STRING */ yytestcase(yyruleno==290);
- /* (291) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=291);
- /* (292) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=292);
- /* (293) carglist ::= carglist ccons */ yytestcase(yyruleno==293);
- /* (294) carglist ::= */ yytestcase(yyruleno==294);
- /* (295) ccons ::= NULL onconf */ yytestcase(yyruleno==295);
- /* (296) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==296);
- /* (297) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==297);
- /* (298) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=298);
- /* (299) tconscomma ::= */ yytestcase(yyruleno==299);
- /* (300) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=300);
- /* (301) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=301);
- /* (302) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=302);
- /* (303) oneselect ::= values */ yytestcase(yyruleno==303);
- /* (304) sclp ::= selcollist COMMA */ yytestcase(yyruleno==304);
- /* (305) as ::= ID|STRING */ yytestcase(yyruleno==305);
- /* (306) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=306);
- /* (307) exprlist ::= nexprlist */ yytestcase(yyruleno==307);
- /* (308) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=308);
- /* (309) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=309);
- /* (310) nmnum ::= ON */ yytestcase(yyruleno==310);
- /* (311) nmnum ::= DELETE */ yytestcase(yyruleno==311);
- /* (312) nmnum ::= DEFAULT */ yytestcase(yyruleno==312);
- /* (313) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==313);
- /* (314) foreach_clause ::= */ yytestcase(yyruleno==314);
- /* (315) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==315);
- /* (316) trnm ::= nm */ yytestcase(yyruleno==316);
- /* (317) tridxby ::= */ yytestcase(yyruleno==317);
- /* (318) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==318);
- /* (319) database_kw_opt ::= */ yytestcase(yyruleno==319);
- /* (320) kwcolumn_opt ::= */ yytestcase(yyruleno==320);
- /* (321) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==321);
- /* (322) vtabarglist ::= vtabarg */ yytestcase(yyruleno==322);
- /* (323) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==323);
- /* (324) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==324);
- /* (325) anylist ::= */ yytestcase(yyruleno==325);
- /* (326) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==326);
- /* (327) anylist ::= anylist ANY */ yytestcase(yyruleno==327);
+ /* (275) input ::= cmdlist */ yytestcase(yyruleno==275);
+ /* (276) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==276);
+ /* (277) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=277);
+ /* (278) ecmd ::= SEMI */ yytestcase(yyruleno==278);
+ /* (279) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==279);
+ /* (280) explain ::= */ yytestcase(yyruleno==280);
+ /* (281) trans_opt ::= */ yytestcase(yyruleno==281);
+ /* (282) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==282);
+ /* (283) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==283);
+ /* (284) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==284);
+ /* (285) savepoint_opt ::= */ yytestcase(yyruleno==285);
+ /* (286) cmd ::= create_table create_table_args */ yytestcase(yyruleno==286);
+ /* (287) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==287);
+ /* (288) columnlist ::= columnname carglist */ yytestcase(yyruleno==288);
+ /* (289) nm ::= ID|INDEXED */ yytestcase(yyruleno==289);
+ /* (290) nm ::= STRING */ yytestcase(yyruleno==290);
+ /* (291) nm ::= JOIN_KW */ yytestcase(yyruleno==291);
+ /* (292) typetoken ::= typename */ yytestcase(yyruleno==292);
+ /* (293) typename ::= ID|STRING */ yytestcase(yyruleno==293);
+ /* (294) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=294);
+ /* (295) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=295);
+ /* (296) carglist ::= carglist ccons */ yytestcase(yyruleno==296);
+ /* (297) carglist ::= */ yytestcase(yyruleno==297);
+ /* (298) ccons ::= NULL onconf */ yytestcase(yyruleno==298);
+ /* (299) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==299);
+ /* (300) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==300);
+ /* (301) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=301);
+ /* (302) tconscomma ::= */ yytestcase(yyruleno==302);
+ /* (303) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=303);
+ /* (304) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=304);
+ /* (305) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=305);
+ /* (306) oneselect ::= values */ yytestcase(yyruleno==306);
+ /* (307) sclp ::= selcollist COMMA */ yytestcase(yyruleno==307);
+ /* (308) as ::= ID|STRING */ yytestcase(yyruleno==308);
+ /* (309) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=309);
+ /* (310) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==310);
+ /* (311) exprlist ::= nexprlist */ yytestcase(yyruleno==311);
+ /* (312) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=312);
+ /* (313) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=313);
+ /* (314) nmnum ::= ON */ yytestcase(yyruleno==314);
+ /* (315) nmnum ::= DELETE */ yytestcase(yyruleno==315);
+ /* (316) nmnum ::= DEFAULT */ yytestcase(yyruleno==316);
+ /* (317) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==317);
+ /* (318) foreach_clause ::= */ yytestcase(yyruleno==318);
+ /* (319) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==319);
+ /* (320) trnm ::= nm */ yytestcase(yyruleno==320);
+ /* (321) tridxby ::= */ yytestcase(yyruleno==321);
+ /* (322) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==322);
+ /* (323) database_kw_opt ::= */ yytestcase(yyruleno==323);
+ /* (324) kwcolumn_opt ::= */ yytestcase(yyruleno==324);
+ /* (325) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==325);
+ /* (326) vtabarglist ::= vtabarg */ yytestcase(yyruleno==326);
+ /* (327) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==327);
+ /* (328) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==328);
+ /* (329) anylist ::= */ yytestcase(yyruleno==329);
+ /* (330) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==330);
+ /* (331) anylist ::= anylist ANY */ yytestcase(yyruleno==331);
break;
/********** End reduce actions ************************************************/
};
@@ -135140,7 +138534,7 @@ SQLITE_PRIVATE void sqlite3Parser(
yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
yymajor = YYNOCODE;
}else{
- while( yypParser->yytos >= &yypParser->yystack
+ while( yypParser->yytos >= yypParser->yystack
&& yymx != YYERRORSYMBOL
&& (yyact = yy_find_reduce_action(
yypParser->yytos->stateno,
@@ -135298,13 +138692,13 @@ static const unsigned char aiClass[] = {
/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
/* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 12, 17, 20, 10,
+/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10,
/* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27,
-/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 7,
+/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 6,
/* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8,
/* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27,
/* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27,
-/* 9x */ 25, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27,
+/* Ax */ 27, 25, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27,
/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27,
/* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27,
/* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27,
@@ -135981,12 +139375,15 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
*/
SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
int nErr = 0; /* Number of errors encountered */
- int i; /* Loop counter */
void *pEngine; /* The LEMON-generated LALR(1) parser */
+ int n = 0; /* Length of the next token token */
int tokenType; /* type of the next token */
int lastTokenParsed = -1; /* type of the previous token */
sqlite3 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
+#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+ unsigned char zSpace[sizeof(yyParser)]; /* Space for parser engine object */
+#endif
assert( zSql!=0 );
mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
@@ -135995,27 +139392,41 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
}
pParse->rc = SQLITE_OK;
pParse->zTail = zSql;
- i = 0;
assert( pzErrMsg!=0 );
/* sqlite3ParserTrace(stdout, "parser: "); */
+#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+ pEngine = zSpace;
+ sqlite3ParserInit(pEngine);
+#else
pEngine = sqlite3ParserAlloc(sqlite3Malloc);
if( pEngine==0 ){
sqlite3OomFault(db);
return SQLITE_NOMEM_BKPT;
}
+#endif
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
- assert( pParse->nzVar==0 );
- assert( pParse->azVar==0 );
- while( zSql[i]!=0 ){
- assert( i>=0 );
- pParse->sLastToken.z = &zSql[i];
- pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
- i += pParse->sLastToken.n;
- if( i>mxSqlLen ){
- pParse->rc = SQLITE_TOOBIG;
- break;
+ assert( pParse->pVList==0 );
+ while( 1 ){
+ if( zSql[0]!=0 ){
+ n = sqlite3GetToken((u8*)zSql, &tokenType);
+ mxSqlLen -= n;
+ if( mxSqlLen<0 ){
+ pParse->rc = SQLITE_TOOBIG;
+ break;
+ }
+ }else{
+ /* Upon reaching the end of input, call the parser two more times
+ ** with tokens TK_SEMI and 0, in that order. */
+ if( lastTokenParsed==TK_SEMI ){
+ tokenType = 0;
+ }else if( lastTokenParsed==0 ){
+ break;
+ }else{
+ tokenType = TK_SEMI;
+ }
+ zSql -= n;
}
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
@@ -136024,27 +139435,21 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
break;
}
if( tokenType==TK_ILLEGAL ){
- sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
- &pParse->sLastToken);
+ sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql);
break;
}
+ zSql += n;
}else{
+ pParse->sLastToken.z = zSql;
+ pParse->sLastToken.n = n;
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
+ zSql += n;
if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
}
assert( nErr==0 );
- pParse->zTail = &zSql[i];
- if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
- assert( zSql[i]==0 );
- if( lastTokenParsed!=TK_SEMI ){
- sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
- }
- if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
- sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
- }
- }
+ pParse->zTail = zSql;
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
@@ -136052,7 +139457,11 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
);
sqlite3_mutex_leave(sqlite3MallocMutex());
#endif /* YYDEBUG */
+#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
+ sqlite3ParserFinalize(pEngine);
+#else
sqlite3ParserFree(pEngine, sqlite3_free);
+#endif
if( db->mallocFailed ){
pParse->rc = SQLITE_NOMEM_BKPT;
}
@@ -136091,8 +139500,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
- for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
- sqlite3DbFree(db, pParse->azVar);
+ sqlite3DbFree(db, pParse->pVList);
while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc;
pParse->pAinc = p->pNext;
@@ -136212,7 +139620,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
** to recognize the end of a trigger can be omitted. All we have to do
** is look for a semicolon that is not part of an string or comment.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
+SQLITE_API int sqlite3_complete(const char *zSql){
u8 state = 0; /* Current state, using numbers defined in header comment */
u8 token; /* Value of the next token */
@@ -136377,7 +139785,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
** above, except that the parameter is required to be UTF-16 encoded, not
** UTF-8.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
+SQLITE_API int sqlite3_complete16(const void *zSql){
sqlite3_value *pVal;
char const *zSql8;
int rc;
@@ -136537,24 +139945,24 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
** a pointer to the to the sqlite3_version[] string constant.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void){ return sqlite3_version; }
+SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
** pointer to a string constant whose value is the same as the
** SQLITE_SOURCE_ID C preprocessor macro.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
** returns an integer equal to SQLITE_VERSION_NUMBER.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
+SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns
** zero if and only if SQLite was compiled with mutexing code omitted due to
** the SQLITE_THREADSAFE compile-time option being set to 0.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
+SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
/*
** When compiling the test fixture or with debugging enabled (on Win32),
@@ -136627,7 +140035,7 @@ SQLITE_API char *sqlite3_data_directory = 0;
** * Recursive calls to this routine from thread X return immediately
** without blocking.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
+SQLITE_API int sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
#ifdef SQLITE_EXTRA_INIT
@@ -136793,7 +140201,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
** on when SQLite is already shut down. If SQLite is already shut down
** when this routine is invoked, then this routine is a harmless no-op.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){
+SQLITE_API int sqlite3_shutdown(void){
#ifdef SQLITE_OMIT_WSD
int rc = sqlite3_wsd_init(4096, 24);
if( rc!=SQLITE_OK ){
@@ -136847,7 +140255,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void){
** threadsafe. Failure to heed these warnings can lead to unpredictable
** behavior.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
+SQLITE_API int sqlite3_config(int op, ...){
va_list ap;
int rc = SQLITE_OK;
@@ -137212,7 +140620,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
/*
** Return the mutex associated with a database connection.
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -137226,7 +140634,7 @@ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
** Free up as much memory as we can from the given database
** connection.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){
+SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
int i;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -137250,7 +140658,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3 *db){
** Flush any dirty pages in the pager-cache for any attached database
** to disk.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3 *db){
+SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){
int i;
int rc = SQLITE_OK;
int bSeenBusy = 0;
@@ -137279,11 +140687,16 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3 *db){
/*
** Configuration settings for an individual database connection
*/
-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
+SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
switch( op ){
+ case SQLITE_DBCONFIG_MAINDBNAME: {
+ db->aDb[0].zDbSName = va_arg(ap,char*);
+ rc = SQLITE_OK;
+ break;
+ }
case SQLITE_DBCONFIG_LOOKASIDE: {
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
@@ -137300,6 +140713,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
+ { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -137400,7 +140814,7 @@ static int nocaseCollatingFunc(
/*
** Return the ROWID of the most recent insert
*/
-SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
+SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -137411,9 +140825,24 @@ SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
}
/*
+** Set the value returned by the sqlite3_last_insert_rowid() API function.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return;
+ }
+#endif
+ sqlite3_mutex_enter(db->mutex);
+ db->lastRowid = iRowid;
+ sqlite3_mutex_leave(db->mutex);
+}
+
+/*
** Return the number of changes in the most recent call to sqlite3_exec().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
+SQLITE_API int sqlite3_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -137426,7 +140855,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
/*
** Return the number of changes since the database handle was opened.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){
+SQLITE_API int sqlite3_total_changes(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -137577,8 +141006,8 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
** unclosed resources, and arranges for deallocation when the last
** prepare statement or sqlite3_backup closes.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
+SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
@@ -137985,7 +141414,7 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
** This routine sets the busy callback for an Sqlite database to the
** given callback function with the given argument.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
+SQLITE_API int sqlite3_busy_handler(
sqlite3 *db,
int (*xBusy)(void*,int),
void *pArg
@@ -138008,7 +141437,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
** given callback function with the given argument. The progress callback will
** be invoked every nOps opcodes.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
+SQLITE_API void sqlite3_progress_handler(
sqlite3 *db,
int nOps,
int (*xProgress)(void*),
@@ -138039,7 +141468,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
+SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
@@ -138055,9 +141484,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3 *db, int ms){
/*
** Cause any pending operation to stop at its earliest opportunity.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){
+SQLITE_API void sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
- if( !sqlite3SafetyCheckOk(db) ){
+ if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){
(void)SQLITE_MISUSE_BKPT;
return;
}
@@ -138171,7 +141600,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
/*
** Create new user functions.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
+SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunc,
int nArg,
@@ -138185,7 +141614,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
xFinal, 0);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
+SQLITE_API int sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunc,
int nArg,
@@ -138228,7 +141657,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
}
#ifndef SQLITE_OMIT_UTF16
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -138268,7 +141697,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
** A global function must exist in order for name resolution to work
** properly.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
+SQLITE_API int sqlite3_overload_function(
sqlite3 *db,
const char *zName,
int nArg
@@ -138300,7 +141729,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
** SQL statement.
*/
#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
+SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -138321,7 +141750,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,c
/* Register a trace callback using the version-2 interface.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_trace_v2(
+SQLITE_API int sqlite3_trace_v2(
sqlite3 *db, /* Trace this connection */
unsigned mTrace, /* Mask of events to be traced */
int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */
@@ -138333,6 +141762,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_trace_v2(
}
#endif
sqlite3_mutex_enter(db->mutex);
+ if( mTrace==0 ) xTrace = 0;
+ if( xTrace==0 ) mTrace = 0;
db->mTrace = mTrace;
db->xTrace = xTrace;
db->pTraceArg = pArg;
@@ -138349,7 +141780,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_trace_v2(
** profile is a pointer to a function that is invoked at the conclusion of
** each SQL statement that is run.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
+SQLITE_API void *sqlite3_profile(
sqlite3 *db,
void (*xProfile)(void*,const char*,sqlite_uint64),
void *pArg
@@ -138377,7 +141808,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
** If the invoked function returns non-zero, then the commit becomes a
** rollback.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(
+SQLITE_API void *sqlite3_commit_hook(
sqlite3 *db, /* Attach the hook to this database */
int (*xCallback)(void*), /* Function to invoke on each commit */
void *pArg /* Argument to the function */
@@ -138402,7 +141833,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
void *pArg /* Argument to the function */
@@ -138427,7 +141858,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
** Register a callback to be invoked each time a transaction is rolled
** back by this database connection.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
+SQLITE_API void *sqlite3_rollback_hook(
sqlite3 *db, /* Attach the hook to this database */
void (*xCallback)(void*), /* Callback function */
void *pArg /* Argument to the function */
@@ -138453,7 +141884,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
** Register a callback to be invoked each time a row is updated,
** inserted or deleted using this database connection.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_preupdate_hook(
+SQLITE_API void *sqlite3_preupdate_hook(
sqlite3 *db, /* Attach the hook to this database */
void(*xCallback)( /* Callback function */
void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64),
@@ -138502,7 +141933,7 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook(
** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
** configured by this function.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(nFrame);
@@ -138523,7 +141954,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame
** Register a callback to be invoked each time a transaction is written
** into the write-ahead-log by this database connection.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3 *db, /* Attach the hook to this db handle */
int(*xCallback)(void *, sqlite3*, const char*, int),
void *pArg /* First argument passed to xCallback() */
@@ -138550,7 +141981,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
/*
** Checkpoint database zDb.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -138594,6 +142025,13 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
sqlite3Error(db, rc);
}
rc = sqlite3ApiExit(db, rc);
+
+ /* If there are no active statements, clear the interrupt flag at this
+ ** point. */
+ if( db->nVdbeActive==0 ){
+ db->u1.isInterrupted = 0;
+ }
+
sqlite3_mutex_leave(db->mutex);
return rc;
#endif
@@ -138605,7 +142043,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
** to contains a zero-length string, all attached databases are
** checkpointed.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
/* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
@@ -138696,7 +142134,7 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
+SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
const char *z;
if( !db ){
return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
@@ -138724,7 +142162,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
+SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
static const u16 outOfMem[] = {
'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
};
@@ -138769,7 +142207,7 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
** Return the most recent error code generated by an SQLite routine. If NULL is
** passed to this function, we assume a malloc() failed during sqlite3_open().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
+SQLITE_API int sqlite3_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
@@ -138778,7 +142216,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
}
return db->errCode & db->errMask;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
if( db && !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
@@ -138787,7 +142225,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
}
return db->errCode;
}
-SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3 *db){
+SQLITE_API int sqlite3_system_errno(sqlite3 *db){
return db ? db->iSysErrno : 0;
}
@@ -138796,7 +142234,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3 *db){
** argument. For now, this simply calls the internal sqlite3ErrStr()
** function.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int rc){
+SQLITE_API const char *sqlite3_errstr(int rc){
return sqlite3ErrStr(rc);
}
@@ -138944,7 +142382,7 @@ static const int aHardLimit[] = {
** It merely prevents new constructs that exceed the limit
** from forming.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
+SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
int oldLimit;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -139096,6 +142534,7 @@ SQLITE_PRIVATE int sqlite3ParseUri(
assert( octet>=0 && octet<256 );
if( octet==0 ){
+#ifndef SQLITE_ENABLE_URI_00_ERROR
/* This branch is taken when "%00" appears within the URI. In this
** case we ignore all text in the remainder of the path, name or
** value currently being parsed. So ignore the current character
@@ -139108,6 +142547,12 @@ SQLITE_PRIVATE int sqlite3ParseUri(
iIn++;
}
continue;
+#else
+ /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */
+ *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri");
+ rc = SQLITE_ERROR;
+ goto parse_uri_out;
+#endif
}
c = octet;
}else if( eState==1 && (c=='&' || c=='=') ){
@@ -139212,7 +142657,9 @@ SQLITE_PRIVATE int sqlite3ParseUri(
}else{
zFile = sqlite3_malloc64(nUri+2);
if( !zFile ) return SQLITE_NOMEM_BKPT;
- memcpy(zFile, zUri, nUri);
+ if( nUri ){
+ memcpy(zFile, zUri, nUri);
+ }
zFile[nUri] = '\0';
zFile[nUri+1] = '\0';
flags &= ~SQLITE_OPEN_URI;
@@ -139427,9 +142874,9 @@ static int openDatabase(
/* The default safety_level for the main database is FULL; for the temp
** database it is OFF. This matches the pager layer defaults.
*/
- db->aDb[0].zName = "main";
+ db->aDb[0].zDbSName = "main";
db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
- db->aDb[1].zName = "temp";
+ db->aDb[1].zDbSName = "temp";
db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
db->magic = SQLITE_MAGIC_OPEN;
@@ -139443,11 +142890,20 @@ static int openDatabase(
*/
sqlite3Error(db, SQLITE_OK);
sqlite3RegisterPerConnectionBuiltinFunctions(db);
+ rc = sqlite3_errcode(db);
+
+#ifdef SQLITE_ENABLE_FTS5
+ /* Register any built-in FTS5 module before loading the automatic
+ ** extensions. This allows automatic extensions to register FTS5
+ ** tokenizers and auxiliary functions. */
+ if( !db->mallocFailed && rc==SQLITE_OK ){
+ rc = sqlite3Fts5Init(db);
+ }
+#endif
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
*/
- rc = sqlite3_errcode(db);
if( rc==SQLITE_OK ){
sqlite3AutoLoadExtensions(db);
rc = sqlite3_errcode(db);
@@ -139476,12 +142932,6 @@ static int openDatabase(
}
#endif
-#ifdef SQLITE_ENABLE_FTS5
- if( !db->mallocFailed && rc==SQLITE_OK ){
- rc = sqlite3Fts5Init(db);
- }
-#endif
-
#ifdef SQLITE_ENABLE_ICU
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3IcuInit(db);
@@ -139568,14 +143018,14 @@ opendb_out:
/*
** Open a new database handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *zFilename,
sqlite3 **ppDb
){
return openDatabase(zFilename, ppDb,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
}
-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -139588,7 +143038,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
/*
** Open a new database handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *zFilename,
sqlite3 **ppDb
){
@@ -139627,7 +143077,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open16(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3* db,
const char *zName,
int enc,
@@ -139640,7 +143090,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3* db,
const char *zName,
int enc,
@@ -139665,7 +143115,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
/*
** Register a new collation sequence with the database handle db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3* db,
const void *zName,
int enc,
@@ -139695,7 +143145,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
@@ -139716,7 +143166,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
** Register a collation sequence factory callback with the database handle
** db. Replace any previously installed collation sequence factory.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3 *db,
void *pCollNeededArg,
void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
@@ -139738,7 +143188,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
+SQLITE_API int sqlite3_global_recover(void){
return SQLITE_OK;
}
#endif
@@ -139749,7 +143199,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
+SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
(void)SQLITE_MISUSE_BKPT;
@@ -139806,7 +143256,7 @@ SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
** SQLite no longer uses thread-specific data so this routine is now a
** no-op. It is retained for historical compatibility.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
+SQLITE_API void sqlite3_thread_cleanup(void){
}
#endif
@@ -139814,7 +143264,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
** Return meta information about a specific column of a database table.
** See comment in sqlite3.h (sqlite.h.in) for details.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -139932,7 +143382,7 @@ error_out:
/*
** Sleep for a little while. Return the amount of time slept.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
+SQLITE_API int sqlite3_sleep(int ms){
sqlite3_vfs *pVfs;
int rc;
pVfs = sqlite3_vfs_find(0);
@@ -139948,7 +143398,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
/*
** Enable or disable the extended result codes.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
#endif
@@ -139961,7 +143411,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3 *db, int ono
/*
** Invoke the xFileControl method on a particular database.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
+SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
int rc = SQLITE_ERROR;
Btree *pBtree;
@@ -140001,9 +143451,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3 *db, const char *zDbN
/*
** Interface to the testing logic.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
+SQLITE_API int sqlite3_test_control(int op, ...){
int rc = 0;
-#ifdef SQLITE_OMIT_BUILTIN_TEST
+#ifdef SQLITE_UNTESTABLE
UNUSED_PARAMETER(op);
#else
va_list ap;
@@ -140269,6 +143719,15 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
break;
}
+ /* Set the threshold at which OP_Once counters reset back to zero.
+ ** By default this is 0x7ffffffe (over 2 billion), but that value is
+ ** too big to test in a reasonable amount of time, so this control is
+ ** provided to set a small and easily reachable reset value.
+ */
+ case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: {
+ sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int);
+ break;
+ }
/* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
**
@@ -140331,7 +143790,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
}
}
va_end(ap);
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
+#endif /* SQLITE_UNTESTABLE */
return rc;
}
@@ -140346,7 +143805,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
** parameter if it exists. If the parameter does not exist, this routine
** returns a NULL pointer.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){
+SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
if( zFilename==0 || zParam==0 ) return 0;
zFilename += sqlite3Strlen30(zFilename) + 1;
while( zFilename[0] ){
@@ -140361,7 +143820,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilenam
/*
** Return a boolean value for a query parameter.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
+SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
bDflt = bDflt!=0;
return z ? sqlite3GetBoolean(z, bDflt) : bDflt;
@@ -140370,7 +143829,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFilename, const c
/*
** Return a 64-bit integer value for a query parameter.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(
+SQLITE_API sqlite3_int64 sqlite3_uri_int64(
const char *zFilename, /* Filename as passed to xOpen */
const char *zParam, /* URI parameter sought */
sqlite3_int64 bDflt /* return if parameter is missing */
@@ -140387,22 +143846,15 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(
** Return the Btree pointer identified by zDbName. Return NULL if not found.
*/
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
- int i;
- for(i=0; i<db->nDb; i++){
- if( db->aDb[i].pBt
- && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0)
- ){
- return db->aDb[i].pBt;
- }
- }
- return 0;
+ int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0;
+ return iDb<0 ? 0 : db->aDb[iDb].pBt;
}
/*
** Return the filename of the database associated with a database
** connection.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName){
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
@@ -140418,7 +143870,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const cha
** Return 1 if database is read-only or 0 if read/write. Return -1 if
** no such database exists.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
Btree *pBt;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
@@ -140435,14 +143887,13 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbNa
** Obtain a snapshot handle for the snapshot of database zDb currently
** being read by handle db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_get(
+SQLITE_API int sqlite3_snapshot_get(
sqlite3 *db,
const char *zDb,
sqlite3_snapshot **ppSnapshot
){
int rc = SQLITE_ERROR;
#ifndef SQLITE_OMIT_WAL
- int iDb;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
@@ -140451,13 +143902,15 @@ SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_get(
#endif
sqlite3_mutex_enter(db->mutex);
- iDb = sqlite3FindDbName(db, zDb);
- if( iDb==0 || iDb>1 ){
- Btree *pBt = db->aDb[iDb].pBt;
- if( 0==sqlite3BtreeIsInTrans(pBt) ){
- rc = sqlite3BtreeBeginTrans(pBt, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
+ if( db->autoCommit==0 ){
+ int iDb = sqlite3FindDbName(db, zDb);
+ if( iDb==0 || iDb>1 ){
+ Btree *pBt = db->aDb[iDb].pBt;
+ if( 0==sqlite3BtreeIsInTrans(pBt) ){
+ rc = sqlite3BtreeBeginTrans(pBt, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
+ }
}
}
}
@@ -140470,7 +143923,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_get(
/*
** Open a read-transaction on the snapshot idendified by pSnapshot.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_open(
+SQLITE_API int sqlite3_snapshot_open(
sqlite3 *db,
const char *zDb,
sqlite3_snapshot *pSnapshot
@@ -140505,9 +143958,41 @@ SQLITE_API int SQLITE_STDCALL sqlite3_snapshot_open(
}
/*
+** Recover as many snapshots as possible from the wal file associated with
+** schema zDb of database db.
+*/
+SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){
+ int rc = SQLITE_ERROR;
+ int iDb;
+#ifndef SQLITE_OMIT_WAL
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( !sqlite3SafetyCheckOk(db) ){
+ return SQLITE_MISUSE_BKPT;
+ }
+#endif
+
+ sqlite3_mutex_enter(db->mutex);
+ iDb = sqlite3FindDbName(db, zDb);
+ if( iDb==0 || iDb>1 ){
+ Btree *pBt = db->aDb[iDb].pBt;
+ if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
+ rc = sqlite3BtreeBeginTrans(pBt, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt));
+ sqlite3BtreeCommit(pBt);
+ }
+ }
+ }
+ sqlite3_mutex_leave(db->mutex);
+#endif /* SQLITE_OMIT_WAL */
+ return rc;
+}
+
+/*
** Free a snapshot handle obtained from sqlite3_snapshot_get().
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
+SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
sqlite3_free(pSnapshot);
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
@@ -140661,7 +144146,7 @@ static void leaveMutex(void){
** on the same "db". If xNotify==0 then any prior callbacks are immediately
** cancelled.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *db,
void (*xNotify)(void **, int),
void *pArg
@@ -141654,6 +145139,7 @@ struct Fts3Table {
** statements is run and reset within a single virtual table API call.
*/
sqlite3_stmt *aStmt[40];
+ sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */
char *zReadExprlist;
char *zWriteExprlist;
@@ -141723,6 +145209,7 @@ struct Fts3Cursor {
i16 eSearch; /* Search strategy (see below) */
u8 isEof; /* True if at End Of Results */
u8 isRequireSeek; /* True if must seek pStmt to %_content row */
+ u8 bSeekStmt; /* True if pStmt is a seek */
sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */
Fts3Expr *pExpr; /* Parsed MATCH query string */
int iLangid; /* Language being queried for */
@@ -142102,8 +145589,9 @@ SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){
** Return the number of bytes read, or 0 on error.
** The value is stored in *v.
*/
-SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){
- const char *pStart = p;
+SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){
+ const unsigned char *p = (const unsigned char*)pBuf;
+ const unsigned char *pStart = p;
u32 a;
u64 b;
int shift;
@@ -142245,6 +145733,7 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
assert( p->pSegments==0 );
/* Free any prepared statements held */
+ sqlite3_finalize(p->pSeekStmt);
for(i=0; i<SizeofArray(p->aStmt); i++){
sqlite3_finalize(p->aStmt[i]);
}
@@ -143116,9 +146605,9 @@ static int fts3InitVtab(
p->pTokenizer = pTokenizer;
p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
p->bHasDocsize = (isFts4 && bNoDocsize==0);
- p->bHasStat = isFts4;
- p->bFts4 = isFts4;
- p->bDescIdx = bDescIdx;
+ p->bHasStat = (u8)isFts4;
+ p->bFts4 = (u8)isFts4;
+ p->bDescIdx = (u8)bDescIdx;
p->nAutoincrmerge = 0xff; /* 0xff means setting unknown */
p->zContentTbl = zContent;
p->zLanguageid = zLanguageid;
@@ -143149,7 +146638,9 @@ static int fts3InitVtab(
char *z;
int n = 0;
z = (char *)sqlite3Fts3NextToken(aCol[iCol], &n);
- memcpy(zCsr, z, n);
+ if( n>0 ){
+ memcpy(zCsr, z, n);
+ }
zCsr[n] = '\0';
sqlite3Fts3Dequote(zCsr);
p->azColumn[iCol] = zCsr;
@@ -143434,13 +146925,33 @@ static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
}
/*
+** Finalize the statement handle at pCsr->pStmt.
+**
+** Or, if that statement handle is one created by fts3CursorSeekStmt(),
+** and the Fts3Table.pSeekStmt slot is currently NULL, save the statement
+** pointer there instead of finalizing it.
+*/
+static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){
+ if( pCsr->bSeekStmt ){
+ Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
+ if( p->pSeekStmt==0 ){
+ p->pSeekStmt = pCsr->pStmt;
+ sqlite3_reset(pCsr->pStmt);
+ pCsr->pStmt = 0;
+ }
+ pCsr->bSeekStmt = 0;
+ }
+ sqlite3_finalize(pCsr->pStmt);
+}
+
+/*
** Close the cursor. For additional information see the documentation
** on the xClose method of the virtual table interface.
*/
static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
Fts3Cursor *pCsr = (Fts3Cursor *)pCursor;
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
- sqlite3_finalize(pCsr->pStmt);
+ fts3CursorFinalizeStmt(pCsr);
sqlite3Fts3ExprFree(pCsr->pExpr);
sqlite3Fts3FreeDeferredTokens(pCsr);
sqlite3_free(pCsr->aDoclist);
@@ -143458,20 +146969,23 @@ static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){
**
** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
** it. If an error occurs, return an SQLite error code.
-**
-** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
*/
-static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
+static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
int rc = SQLITE_OK;
if( pCsr->pStmt==0 ){
Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
char *zSql;
- zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
- if( !zSql ) return SQLITE_NOMEM;
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
- sqlite3_free(zSql);
+ if( p->pSeekStmt ){
+ pCsr->pStmt = p->pSeekStmt;
+ p->pSeekStmt = 0;
+ }else{
+ zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
+ if( !zSql ) return SQLITE_NOMEM;
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
+ sqlite3_free(zSql);
+ }
+ if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1;
}
- *ppStmt = pCsr->pStmt;
return rc;
}
@@ -143483,9 +146997,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
int rc = SQLITE_OK;
if( pCsr->isRequireSeek ){
- sqlite3_stmt *pStmt = 0;
-
- rc = fts3CursorSeekStmt(pCsr, &pStmt);
+ rc = fts3CursorSeekStmt(pCsr);
if( rc==SQLITE_OK ){
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
pCsr->isRequireSeek = 0;
@@ -144943,7 +148455,7 @@ static int fts3FilterMethod(
assert( iIdx==nVal );
/* In case the cursor has been used before, clear it now. */
- sqlite3_finalize(pCsr->pStmt);
+ fts3CursorFinalizeStmt(pCsr);
sqlite3_free(pCsr->aDoclist);
sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
sqlite3Fts3ExprFree(pCsr->pExpr);
@@ -145011,7 +148523,7 @@ static int fts3FilterMethod(
rc = SQLITE_NOMEM;
}
}else if( eSearch==FTS3_DOCID_SEARCH ){
- rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
+ rc = fts3CursorSeekStmt(pCsr);
if( rc==SQLITE_OK ){
rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons);
}
@@ -145139,8 +148651,10 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
const u32 nMinMerge = 64; /* Minimum amount of incr-merge work to do */
Fts3Table *p = (Fts3Table*)pVtab;
- int rc = sqlite3Fts3PendingTermsFlush(p);
+ int rc;
+ i64 iLastRowid = sqlite3_last_insert_rowid(p->db);
+ rc = sqlite3Fts3PendingTermsFlush(p);
if( rc==SQLITE_OK
&& p->nLeafAdd>(nMinMerge/16)
&& p->nAutoincrmerge && p->nAutoincrmerge!=0xff
@@ -145155,6 +148669,7 @@ static int fts3SyncMethod(sqlite3_vtab *pVtab){
if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge);
}
sqlite3Fts3SegmentsClose(p);
+ sqlite3_set_last_insert_rowid(p->db, iLastRowid);
return rc;
}
@@ -145175,7 +148690,7 @@ static int fts3SetHasStat(Fts3Table *p){
if( rc==SQLITE_OK ){
int bHasStat = (sqlite3_step(pStmt)==SQLITE_ROW);
rc = sqlite3_finalize(pStmt);
- if( rc==SQLITE_OK ) p->bHasStat = bHasStat;
+ if( rc==SQLITE_OK ) p->bHasStat = (u8)bHasStat;
}
sqlite3_free(zSql);
}else{
@@ -147664,7 +151179,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init(
+SQLITE_API int sqlite3_fts3_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -156765,11 +160280,14 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){
** Convert the text beginning at *pz into an integer and return
** its value. Advance *pz to point to the first character past
** the integer.
+**
+** This function used for parameters to merge= and incrmerge=
+** commands.
*/
static int fts3Getint(const char **pz){
const char *z = *pz;
int i = 0;
- while( (*z)>='0' && (*z)<='9' ) i = 10*i + *(z++) - '0';
+ while( (*z)>='0' && (*z)<='9' && i<214748363 ) i = 10*i + *(z++) - '0';
*pz = z;
return i;
}
@@ -159335,16 +162853,16 @@ static int unicodeAddExceptions(
){
const unsigned char *z = (const unsigned char *)zIn;
const unsigned char *zTerm = &z[nIn];
- int iCode;
+ unsigned int iCode;
int nEntry = 0;
assert( bAlnum==0 || bAlnum==1 );
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- assert( (sqlite3FtsUnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
- if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
- && sqlite3FtsUnicodeIsdiacritic(iCode)==0
+ assert( (sqlite3FtsUnicodeIsalnum((int)iCode) & 0xFFFFFFFE)==0 );
+ if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
+ && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
){
nEntry++;
}
@@ -159361,13 +162879,13 @@ static int unicodeAddExceptions(
z = (const unsigned char *)zIn;
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- if( sqlite3FtsUnicodeIsalnum(iCode)!=bAlnum
- && sqlite3FtsUnicodeIsdiacritic(iCode)==0
+ if( sqlite3FtsUnicodeIsalnum((int)iCode)!=bAlnum
+ && sqlite3FtsUnicodeIsdiacritic((int)iCode)==0
){
int i, j;
- for(i=0; i<nNew && aNew[i]<iCode; i++);
+ for(i=0; i<nNew && aNew[i]<(int)iCode; i++);
for(j=nNew; j>i; j--) aNew[j] = aNew[j-1];
- aNew[i] = iCode;
+ aNew[i] = (int)iCode;
nNew++;
}
}
@@ -159517,7 +163035,7 @@ static int unicodeNext(
){
unicode_cursor *pCsr = (unicode_cursor *)pC;
unicode_tokenizer *p = ((unicode_tokenizer *)pCsr->base.pTokenizer);
- int iCode = 0;
+ unsigned int iCode = 0;
char *zOut;
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
const unsigned char *zStart = z;
@@ -159529,7 +163047,7 @@ static int unicodeNext(
** the input. */
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
- if( unicodeIsAlnum(p, iCode) ) break;
+ if( unicodeIsAlnum(p, (int)iCode) ) break;
zStart = z;
}
if( zStart>=zTerm ) return SQLITE_DONE;
@@ -159549,7 +163067,7 @@ static int unicodeNext(
/* Write the folded case of the last character read to the output */
zEnd = z;
- iOut = sqlite3FtsUnicodeFold(iCode, p->bRemoveDiacritic);
+ iOut = sqlite3FtsUnicodeFold((int)iCode, p->bRemoveDiacritic);
if( iOut ){
WRITE_UTF8(zOut, iOut);
}
@@ -159557,8 +163075,8 @@ static int unicodeNext(
/* If the cursor is not at EOF, read the next character */
if( z>=zTerm ) break;
READ_UTF8(z, zTerm, iCode);
- }while( unicodeIsAlnum(p, iCode)
- || sqlite3FtsUnicodeIsdiacritic(iCode)
+ }while( unicodeIsAlnum(p, (int)iCode)
+ || sqlite3FtsUnicodeIsdiacritic((int)iCode)
);
/* Set the output variables and return. */
@@ -159722,9 +163240,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
- if( c<128 ){
- return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
- }else if( c<(1<<22) ){
+ if( (unsigned int)c<128 ){
+ return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
+ }else if( (unsigned int)c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes = 0;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
@@ -159917,16 +163435,17 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
int ret = c;
- assert( c>=0 );
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
+ const struct TableEntry *p;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
int iRes = -1;
+ assert( c>aEntry[0].iCode );
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
int cmp = (c - aEntry[iTest].iCode);
@@ -159937,14 +163456,12 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
iHi = iTest-1;
}
}
- assert( iRes<0 || c>=aEntry[iRes].iCode );
- if( iRes>=0 ){
- const struct TableEntry *p = &aEntry[iRes];
- if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
- ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
- assert( ret>0 );
- }
+ assert( iRes>=0 && c>=aEntry[iRes].iCode );
+ p = &aEntry[iRes];
+ if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
+ ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
+ assert( ret>0 );
}
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
@@ -160031,6 +163548,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
+typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
@@ -160079,13 +163597,16 @@ struct Rtree {
sqlite3 *db; /* Host database connection */
int iNodeSize; /* Size in bytes of each node in the node table */
u8 nDim; /* Number of dimensions */
+ u8 nDim2; /* Twice the number of dimensions */
u8 eCoordType; /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
u8 nBytesPerCell; /* Bytes consumed per cell */
+ u8 inWrTrans; /* True if inside write transaction */
int iDepth; /* Current depth of the r-tree structure */
char *zDb; /* Name of database containing r-tree table */
char *zName; /* Name of r-tree table */
- int nBusy; /* Current number of users of this structure */
+ u32 nBusy; /* Current number of users of this structure */
i64 nRowEst; /* Estimated number of rows in this table */
+ u32 nCursor; /* Number of open cursors */
/* List of nodes removed during a CondenseTree operation. List is
** linked together via the pointer normally used for hash chains -
@@ -160095,8 +163616,10 @@ struct Rtree {
RtreeNode *pDeleted;
int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */
+ /* Blob I/O on xxx_node */
+ sqlite3_blob *pNodeBlob;
+
/* Statements to read/write/delete a record from xxx_node */
- sqlite3_stmt *pReadNode;
sqlite3_stmt *pWriteNode;
sqlite3_stmt *pDeleteNode;
@@ -160325,6 +163848,58 @@ struct RtreeMatchArg {
# define MIN(x,y) ((x) > (y) ? (y) : (x))
#endif
+/* What version of GCC is being used. 0 means GCC is not being used .
+** Note that the GCC_VERSION macro will also be set correctly when using
+** clang, since clang works hard to be gcc compatible. So the gcc
+** optimizations will also work when compiling with clang.
+*/
+#ifndef GCC_VERSION
+#if defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define GCC_VERSION (__GNUC__*1000000+__GNUC_MINOR__*1000+__GNUC_PATCHLEVEL__)
+#else
+# define GCC_VERSION 0
+#endif
+#endif
+
+/* The testcase() macro should already be defined in the amalgamation. If
+** it is not, make it a no-op.
+*/
+#ifndef SQLITE_AMALGAMATION
+# define testcase(X)
+#endif
+
+/*
+** Macros to determine whether the machine is big or little endian,
+** and whether or not that determination is run-time or compile-time.
+**
+** For best performance, an attempt is made to guess at the byte-order
+** using C-preprocessor macros. If that is unsuccessful, or if
+** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined
+** at run-time.
+*/
+#ifndef SQLITE_BYTEORDER
+#if defined(i386) || defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
+ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \
+ defined(__arm__)
+# define SQLITE_BYTEORDER 1234
+#elif defined(sparc) || defined(__ppc__)
+# define SQLITE_BYTEORDER 4321
+#else
+# define SQLITE_BYTEORDER 0 /* 0 means "unknown at compile-time" */
+#endif
+#endif
+
+
+/* What version of MSVC is being used. 0 means MSVC is not being used */
+#ifndef MSVC_VERSION
+#if defined(_MSC_VER) && !defined(SQLITE_DISABLE_INTRINSIC)
+# define MSVC_VERSION _MSC_VER
+#else
+# define MSVC_VERSION 0
+#endif
+#endif
+
/*
** Functions to deserialize a 16 bit integer, 32 bit real number and
** 64 bit integer. The deserialized value is returned.
@@ -160333,24 +163908,47 @@ static int readInt16(u8 *p){
return (p[0]<<8) + p[1];
}
static void readCoord(u8 *p, RtreeCoord *pCoord){
+ assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
+#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ pCoord->u = _byteswap_ulong(*(u32*)p);
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ pCoord->u = __builtin_bswap32(*(u32*)p);
+#elif SQLITE_BYTEORDER==4321
+ pCoord->u = *(u32*)p;
+#else
pCoord->u = (
(((u32)p[0]) << 24) +
(((u32)p[1]) << 16) +
(((u32)p[2]) << 8) +
(((u32)p[3]) << 0)
);
+#endif
}
static i64 readInt64(u8 *p){
- return (
- (((i64)p[0]) << 56) +
- (((i64)p[1]) << 48) +
- (((i64)p[2]) << 40) +
- (((i64)p[3]) << 32) +
- (((i64)p[4]) << 24) +
- (((i64)p[5]) << 16) +
- (((i64)p[6]) << 8) +
- (((i64)p[7]) << 0)
+#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ u64 x;
+ memcpy(&x, p, 8);
+ return (i64)_byteswap_uint64(x);
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ u64 x;
+ memcpy(&x, p, 8);
+ return (i64)__builtin_bswap64(x);
+#elif SQLITE_BYTEORDER==4321
+ i64 x;
+ memcpy(&x, p, 8);
+ return x;
+#else
+ return (i64)(
+ (((u64)p[0]) << 56) +
+ (((u64)p[1]) << 48) +
+ (((u64)p[2]) << 40) +
+ (((u64)p[3]) << 32) +
+ (((u64)p[4]) << 24) +
+ (((u64)p[5]) << 16) +
+ (((u64)p[6]) << 8) +
+ (((u64)p[7]) << 0)
);
+#endif
}
/*
@@ -160358,23 +163956,43 @@ static i64 readInt64(u8 *p){
** 64 bit integer. The value returned is the number of bytes written
** to the argument buffer (always 2, 4 and 8 respectively).
*/
-static int writeInt16(u8 *p, int i){
+static void writeInt16(u8 *p, int i){
p[0] = (i>> 8)&0xFF;
p[1] = (i>> 0)&0xFF;
- return 2;
}
static int writeCoord(u8 *p, RtreeCoord *pCoord){
u32 i;
+ assert( ((((char*)p) - (char*)0)&3)==0 ); /* p is always 4-byte aligned */
assert( sizeof(RtreeCoord)==4 );
assert( sizeof(u32)==4 );
+#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ i = __builtin_bswap32(pCoord->u);
+ memcpy(p, &i, 4);
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ i = _byteswap_ulong(pCoord->u);
+ memcpy(p, &i, 4);
+#elif SQLITE_BYTEORDER==4321
+ i = pCoord->u;
+ memcpy(p, &i, 4);
+#else
i = pCoord->u;
p[0] = (i>>24)&0xFF;
p[1] = (i>>16)&0xFF;
p[2] = (i>> 8)&0xFF;
p[3] = (i>> 0)&0xFF;
+#endif
return 4;
}
static int writeInt64(u8 *p, i64 i){
+#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+ i = (i64)__builtin_bswap64((u64)i);
+ memcpy(p, &i, 8);
+#elif SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+ i = (i64)_byteswap_uint64((u64)i);
+ memcpy(p, &i, 8);
+#elif SQLITE_BYTEORDER==4321
+ memcpy(p, &i, 8);
+#else
p[0] = (i>>56)&0xFF;
p[1] = (i>>48)&0xFF;
p[2] = (i>>40)&0xFF;
@@ -160383,6 +164001,7 @@ static int writeInt64(u8 *p, i64 i){
p[5] = (i>>16)&0xFF;
p[6] = (i>> 8)&0xFF;
p[7] = (i>> 0)&0xFF;
+#endif
return 8;
}
@@ -160466,6 +164085,17 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){
}
/*
+** Clear the Rtree.pNodeBlob object
+*/
+static void nodeBlobReset(Rtree *pRtree){
+ if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
+ sqlite3_blob *pBlob = pRtree->pNodeBlob;
+ pRtree->pNodeBlob = 0;
+ sqlite3_blob_close(pBlob);
+ }
+}
+
+/*
** Obtain a reference to an r-tree node.
*/
static int nodeAcquire(
@@ -160474,9 +164104,8 @@ static int nodeAcquire(
RtreeNode *pParent, /* Either the parent node or NULL */
RtreeNode **ppNode /* OUT: Acquired node */
){
- int rc;
- int rc2 = SQLITE_OK;
- RtreeNode *pNode;
+ int rc = SQLITE_OK;
+ RtreeNode *pNode = 0;
/* Check if the requested node is already in the hash table. If so,
** increase its reference count and return it.
@@ -160492,28 +164121,45 @@ static int nodeAcquire(
return SQLITE_OK;
}
- sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
- rc = sqlite3_step(pRtree->pReadNode);
- if( rc==SQLITE_ROW ){
- const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
- if( pRtree->iNodeSize==sqlite3_column_bytes(pRtree->pReadNode, 0) ){
- pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
- if( !pNode ){
- rc2 = SQLITE_NOMEM;
- }else{
- pNode->pParent = pParent;
- pNode->zData = (u8 *)&pNode[1];
- pNode->nRef = 1;
- pNode->iNode = iNode;
- pNode->isDirty = 0;
- pNode->pNext = 0;
- memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
- nodeReference(pParent);
- }
+ if( pRtree->pNodeBlob ){
+ sqlite3_blob *pBlob = pRtree->pNodeBlob;
+ pRtree->pNodeBlob = 0;
+ rc = sqlite3_blob_reopen(pBlob, iNode);
+ pRtree->pNodeBlob = pBlob;
+ if( rc ){
+ nodeBlobReset(pRtree);
+ if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM;
+ }
+ }
+ if( pRtree->pNodeBlob==0 ){
+ char *zTab = sqlite3_mprintf("%s_node", pRtree->zName);
+ if( zTab==0 ) return SQLITE_NOMEM;
+ rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0,
+ &pRtree->pNodeBlob);
+ sqlite3_free(zTab);
+ }
+ if( rc ){
+ nodeBlobReset(pRtree);
+ *ppNode = 0;
+ /* If unable to open an sqlite3_blob on the desired row, that can only
+ ** be because the shadow tables hold erroneous data. */
+ if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;
+ }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
+ pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
+ if( !pNode ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pNode->pParent = pParent;
+ pNode->zData = (u8 *)&pNode[1];
+ pNode->nRef = 1;
+ pNode->iNode = iNode;
+ pNode->isDirty = 0;
+ pNode->pNext = 0;
+ rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData,
+ pRtree->iNodeSize, 0);
+ nodeReference(pParent);
}
}
- rc = sqlite3_reset(pRtree->pReadNode);
- if( rc==SQLITE_OK ) rc = rc2;
/* If the root node was just loaded, set pRtree->iDepth to the height
** of the r-tree structure. A height of zero means all data is stored on
@@ -160565,7 +164211,7 @@ static void nodeOverwriteCell(
int ii;
u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
p += writeInt64(p, pCell->iRowid);
- for(ii=0; ii<(pRtree->nDim*2); ii++){
+ for(ii=0; ii<pRtree->nDim2; ii++){
p += writeCoord(p, &pCell->aCoord[ii]);
}
pNode->isDirty = 1;
@@ -160699,13 +164345,16 @@ static void nodeGetCell(
){
u8 *pData;
RtreeCoord *pCoord;
- int ii;
+ int ii = 0;
pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
pCoord = pCell->aCoord;
- for(ii=0; ii<pRtree->nDim*2; ii++){
- readCoord(&pData[ii*4], &pCoord[ii]);
- }
+ do{
+ readCoord(pData, &pCoord[ii]);
+ readCoord(pData+4, &pCoord[ii+1]);
+ pData += 8;
+ ii += 2;
+ }while( ii<pRtree->nDim2 );
}
@@ -160756,7 +164405,9 @@ static void rtreeReference(Rtree *pRtree){
static void rtreeRelease(Rtree *pRtree){
pRtree->nBusy--;
if( pRtree->nBusy==0 ){
- sqlite3_finalize(pRtree->pReadNode);
+ pRtree->inWrTrans = 0;
+ pRtree->nCursor = 0;
+ nodeBlobReset(pRtree);
sqlite3_finalize(pRtree->pWriteNode);
sqlite3_finalize(pRtree->pDeleteNode);
sqlite3_finalize(pRtree->pReadRowid);
@@ -160794,6 +164445,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){
if( !zCreate ){
rc = SQLITE_NOMEM;
}else{
+ nodeBlobReset(pRtree);
rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
sqlite3_free(zCreate);
}
@@ -160809,6 +164461,7 @@ static int rtreeDestroy(sqlite3_vtab *pVtab){
*/
static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
int rc = SQLITE_NOMEM;
+ Rtree *pRtree = (Rtree *)pVTab;
RtreeCursor *pCsr;
pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
@@ -160816,6 +164469,7 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
memset(pCsr, 0, sizeof(RtreeCursor));
pCsr->base.pVtab = pVTab;
rc = SQLITE_OK;
+ pRtree->nCursor++;
}
*ppCursor = (sqlite3_vtab_cursor *)pCsr;
@@ -160848,10 +164502,13 @@ static int rtreeClose(sqlite3_vtab_cursor *cur){
Rtree *pRtree = (Rtree *)(cur->pVtab);
int ii;
RtreeCursor *pCsr = (RtreeCursor *)cur;
+ assert( pRtree->nCursor>0 );
freeCursorConstraints(pCsr);
sqlite3_free(pCsr->aPoint);
for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]);
sqlite3_free(pCsr);
+ pRtree->nCursor--;
+ nodeBlobReset(pRtree);
return SQLITE_OK;
}
@@ -160874,15 +164531,22 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){
** false. a[] is the four bytes of the on-disk record to be decoded.
** Store the results in "r".
**
-** There are three versions of this macro, one each for little-endian and
-** big-endian processors and a third generic implementation. The endian-
-** specific implementations are much faster and are preferred if the
-** processor endianness is known at compile-time. The SQLITE_BYTEORDER
-** macro is part of sqliteInt.h and hence the endian-specific
-** implementation will only be used if this module is compiled as part
-** of the amalgamation.
+** There are five versions of this macro. The last one is generic. The
+** other four are various architectures-specific optimizations.
*/
-#if defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==1234
+#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
+#define RTREE_DECODE_COORD(eInt, a, r) { \
+ RtreeCoord c; /* Coordinate decoded */ \
+ c.u = _byteswap_ulong(*(u32*)a); \
+ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
+}
+#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
+#define RTREE_DECODE_COORD(eInt, a, r) { \
+ RtreeCoord c; /* Coordinate decoded */ \
+ c.u = __builtin_bswap32(*(u32*)a); \
+ r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
+}
+#elif SQLITE_BYTEORDER==1234
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
memcpy(&c.u,a,4); \
@@ -160890,7 +164554,7 @@ static int rtreeEof(sqlite3_vtab_cursor *cur){
((c.u&0xff)<<24)|((c.u&0xff00)<<8); \
r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \
}
-#elif defined(SQLITE_BYTEORDER) && SQLITE_BYTEORDER==4321
+#elif SQLITE_BYTEORDER==4321
#define RTREE_DECODE_COORD(eInt, a, r) { \
RtreeCoord c; /* Coordinate decoded */ \
memcpy(&c.u,a,4); \
@@ -160917,10 +164581,10 @@ static int rtreeCallbackConstraint(
sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */
int *peWithin /* OUT: visibility of the cell */
){
- int i; /* Loop counter */
sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */
int nCoord = pInfo->nCoord; /* No. of coordinates */
int rc; /* Callback return code */
+ RtreeCoord c; /* Translator union */
sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */
assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY );
@@ -160930,13 +164594,41 @@ static int rtreeCallbackConstraint(
pInfo->iRowid = readInt64(pCellData);
}
pCellData += 8;
- for(i=0; i<nCoord; i++, pCellData += 4){
- RTREE_DECODE_COORD(eInt, pCellData, aCoord[i]);
+#ifndef SQLITE_RTREE_INT_ONLY
+ if( eInt==0 ){
+ switch( nCoord ){
+ case 10: readCoord(pCellData+36, &c); aCoord[9] = c.f;
+ readCoord(pCellData+32, &c); aCoord[8] = c.f;
+ case 8: readCoord(pCellData+28, &c); aCoord[7] = c.f;
+ readCoord(pCellData+24, &c); aCoord[6] = c.f;
+ case 6: readCoord(pCellData+20, &c); aCoord[5] = c.f;
+ readCoord(pCellData+16, &c); aCoord[4] = c.f;
+ case 4: readCoord(pCellData+12, &c); aCoord[3] = c.f;
+ readCoord(pCellData+8, &c); aCoord[2] = c.f;
+ default: readCoord(pCellData+4, &c); aCoord[1] = c.f;
+ readCoord(pCellData, &c); aCoord[0] = c.f;
+ }
+ }else
+#endif
+ {
+ switch( nCoord ){
+ case 10: readCoord(pCellData+36, &c); aCoord[9] = c.i;
+ readCoord(pCellData+32, &c); aCoord[8] = c.i;
+ case 8: readCoord(pCellData+28, &c); aCoord[7] = c.i;
+ readCoord(pCellData+24, &c); aCoord[6] = c.i;
+ case 6: readCoord(pCellData+20, &c); aCoord[5] = c.i;
+ readCoord(pCellData+16, &c); aCoord[4] = c.i;
+ case 4: readCoord(pCellData+12, &c); aCoord[3] = c.i;
+ readCoord(pCellData+8, &c); aCoord[2] = c.i;
+ default: readCoord(pCellData+4, &c); aCoord[1] = c.i;
+ readCoord(pCellData, &c); aCoord[0] = c.i;
+ }
}
if( pConstraint->op==RTREE_MATCH ){
+ int eWithin = 0;
rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo,
- nCoord, aCoord, &i);
- if( i==0 ) *peWithin = NOT_WITHIN;
+ nCoord, aCoord, &eWithin);
+ if( eWithin==0 ) *peWithin = NOT_WITHIN;
*prScore = RTREE_ZERO;
}else{
pInfo->aCoord = aCoord;
@@ -160972,6 +164664,7 @@ static void rtreeNonleafConstraint(
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
|| p->op==RTREE_GT || p->op==RTREE_EQ );
+ assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
switch( p->op ){
case RTREE_LE:
case RTREE_LT:
@@ -161012,6 +164705,7 @@ static void rtreeLeafConstraint(
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
|| p->op==RTREE_GT || p->op==RTREE_EQ );
pCellData += 8 + p->iCoord*4;
+ assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
RTREE_DECODE_COORD(eInt, pCellData, xN);
switch( p->op ){
case RTREE_LE: if( xN <= p->u.rValue ) return; break;
@@ -161080,7 +164774,7 @@ static int rtreeSearchPointCompare(
}
/*
-** Interchange to search points in a cursor.
+** Interchange two search points in a cursor.
*/
static void rtreeSearchPointSwap(RtreeCursor *p, int i, int j){
RtreeSearchPoint t = p->aPoint[i];
@@ -161328,7 +165022,7 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){
if( rScore<RTREE_ZERO ) rScore = RTREE_ZERO;
p = rtreeSearchPointNew(pCur, rScore, x.iLevel);
if( p==0 ) return SQLITE_NOMEM;
- p->eWithin = eWithin;
+ p->eWithin = (u8)eWithin;
p->id = x.id;
p->iCell = x.iCell;
RTREE_QUEUE_TRACE(pCur, "PUSH-S:");
@@ -161387,7 +165081,6 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
if( i==0 ){
sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
}else{
- if( rc ) return rc;
nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
@@ -161505,7 +165198,7 @@ static int rtreeFilter(
if( idxNum==1 ){
/* Special case - lookup by rowid. */
RtreeNode *pLeaf; /* Leaf on which the required cell resides */
- RtreeSearchPoint *p; /* Search point for the the leaf */
+ RtreeSearchPoint *p; /* Search point for the leaf */
i64 iRowid = sqlite3_value_int64(argv[0]);
i64 iNode = 0;
rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode);
@@ -161516,7 +165209,7 @@ static int rtreeFilter(
p->id = iNode;
p->eWithin = PARTLY_WITHIN;
rc = nodeRowidIndex(pRtree, pLeaf, iRowid, &iCell);
- p->iCell = iCell;
+ p->iCell = (u8)iCell;
RTREE_QUEUE_TRACE(pCsr, "PUSH-F1:");
}else{
pCsr->atEOF = 1;
@@ -161549,7 +165242,7 @@ static int rtreeFilter(
if( rc!=SQLITE_OK ){
break;
}
- p->pInfo->nCoord = pRtree->nDim*2;
+ p->pInfo->nCoord = pRtree->nDim2;
p->pInfo->anQueue = pCsr->anQueue;
p->pInfo->mxLevel = pRtree->iDepth + 1;
}else{
@@ -161564,7 +165257,7 @@ static int rtreeFilter(
}
if( rc==SQLITE_OK ){
RtreeSearchPoint *pNew;
- pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, pRtree->iDepth+1);
+ pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
if( pNew==0 ) return SQLITE_NOMEM;
pNew->id = 1;
pNew->iCell = 0;
@@ -161583,19 +165276,6 @@ static int rtreeFilter(
}
/*
-** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
-** extension is currently being used by a version of SQLite too old to
-** support estimatedRows. In that case this function is a no-op.
-*/
-static void setEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
-#if SQLITE_VERSION_NUMBER>=3008002
- if( sqlite3_libversion_number()>=3008002 ){
- pIdxInfo->estimatedRows = nRow;
- }
-#endif
-}
-
-/*
** Rtree virtual table module xBestIndex method. There are three
** table scan strategies to choose from (in order from most to
** least desirable):
@@ -161674,7 +165354,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
** a single row.
*/
pIdxInfo->estimatedCost = 30.0;
- setEstimatedRows(pIdxInfo, 1);
+ pIdxInfo->estimatedRows = 1;
return SQLITE_OK;
}
@@ -161692,7 +165372,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
break;
}
zIdxStr[iIdx++] = op;
- zIdxStr[iIdx++] = p->iColumn - 1 + '0';
+ zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
pIdxInfo->aConstraintUsage[ii].omit = 1;
}
@@ -161706,7 +165386,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
nRow = pRtree->nRowEst >> (iIdx/2);
pIdxInfo->estimatedCost = (double)6.0 * (double)nRow;
- setEstimatedRows(pIdxInfo, nRow);
+ pIdxInfo->estimatedRows = nRow;
return rc;
}
@@ -161716,9 +165396,26 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
*/
static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
RtreeDValue area = (RtreeDValue)1;
- int ii;
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
- area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
+ assert( pRtree->nDim>=1 && pRtree->nDim<=5 );
+#ifndef SQLITE_RTREE_INT_ONLY
+ if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+ switch( pRtree->nDim ){
+ case 5: area = p->aCoord[9].f - p->aCoord[8].f;
+ case 4: area *= p->aCoord[7].f - p->aCoord[6].f;
+ case 3: area *= p->aCoord[5].f - p->aCoord[4].f;
+ case 2: area *= p->aCoord[3].f - p->aCoord[2].f;
+ default: area *= p->aCoord[1].f - p->aCoord[0].f;
+ }
+ }else
+#endif
+ {
+ switch( pRtree->nDim ){
+ case 5: area = p->aCoord[9].i - p->aCoord[8].i;
+ case 4: area *= p->aCoord[7].i - p->aCoord[6].i;
+ case 3: area *= p->aCoord[5].i - p->aCoord[4].i;
+ case 2: area *= p->aCoord[3].i - p->aCoord[2].i;
+ default: area *= p->aCoord[1].i - p->aCoord[0].i;
+ }
}
return area;
}
@@ -161728,11 +165425,12 @@ static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
** of the objects size in each dimension.
*/
static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
- RtreeDValue margin = (RtreeDValue)0;
- int ii;
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ RtreeDValue margin = 0;
+ int ii = pRtree->nDim2 - 2;
+ do{
margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
- }
+ ii -= 2;
+ }while( ii>=0 );
return margin;
}
@@ -161740,17 +165438,19 @@ static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
** Store the union of cells p1 and p2 in p1.
*/
static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
- int ii;
+ int ii = 0;
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ do{
p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f);
p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f);
- }
+ ii += 2;
+ }while( ii<pRtree->nDim2 );
}else{
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ do{
p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i);
p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i);
- }
+ ii += 2;
+ }while( ii<pRtree->nDim2 );
}
}
@@ -161761,7 +165461,7 @@ static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
int ii;
int isInt = (pRtree->eCoordType==RTREE_COORD_INT32);
- for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+ for(ii=0; ii<pRtree->nDim2; ii+=2){
RtreeCoord *a1 = &p1->aCoord[ii];
RtreeCoord *a2 = &p2->aCoord[ii];
if( (!isInt && (a2[0].f<a1[0].f || a2[1].f>a1[1].f))
@@ -161796,7 +165496,7 @@ static RtreeDValue cellOverlap(
for(ii=0; ii<nCell; ii++){
int jj;
RtreeDValue o = (RtreeDValue)1;
- for(jj=0; jj<(pRtree->nDim*2); jj+=2){
+ for(jj=0; jj<pRtree->nDim2; jj+=2){
RtreeDValue x1, x2;
x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
@@ -162852,7 +166552,7 @@ static int rtreeUpdate(
** This problem was discovered after years of use, so we silently ignore
** these kinds of misdeclared tables to avoid breaking any legacy.
*/
- assert( nData<=(pRtree->nDim*2 + 3) );
+ assert( nData<=(pRtree->nDim2 + 3) );
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
@@ -162943,6 +166643,27 @@ constraint:
}
/*
+** Called when a transaction starts.
+*/
+static int rtreeBeginTransaction(sqlite3_vtab *pVtab){
+ Rtree *pRtree = (Rtree *)pVtab;
+ assert( pRtree->inWrTrans==0 );
+ pRtree->inWrTrans++;
+ return SQLITE_OK;
+}
+
+/*
+** Called when a transaction completes (either by COMMIT or ROLLBACK).
+** The sqlite3_blob object should be released at this point.
+*/
+static int rtreeEndTransaction(sqlite3_vtab *pVtab){
+ Rtree *pRtree = (Rtree *)pVtab;
+ pRtree->inWrTrans = 0;
+ nodeBlobReset(pRtree);
+ return SQLITE_OK;
+}
+
+/*
** The xRename method for rtree module virtual tables.
*/
static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
@@ -162963,6 +166684,7 @@ static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
return rc;
}
+
/*
** This function populates the pRtree->nRowEst variable with an estimate
** of the number of rows in the virtual table. If possible, this is based
@@ -162975,10 +166697,12 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
int rc;
i64 nRow = 0;
- if( sqlite3_table_column_metadata(db,pRtree->zDb,"sqlite_stat1",
- 0,0,0,0,0,0)==SQLITE_ERROR ){
+ rc = sqlite3_table_column_metadata(
+ db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
+ );
+ if( rc!=SQLITE_OK ){
pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
- return SQLITE_OK;
+ return rc==SQLITE_ERROR ? SQLITE_OK : rc;
}
zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
if( zSql==0 ){
@@ -163020,15 +166744,15 @@ static sqlite3_module rtreeModule = {
rtreeColumn, /* xColumn - read data */
rtreeRowid, /* xRowid - read data */
rtreeUpdate, /* xUpdate - write data */
- 0, /* xBegin - begin transaction */
- 0, /* xSync - sync transaction */
- 0, /* xCommit - commit transaction */
- 0, /* xRollback - rollback transaction */
+ rtreeBeginTransaction, /* xBegin - begin transaction */
+ rtreeEndTransaction, /* xSync - sync transaction */
+ rtreeEndTransaction, /* xCommit - commit transaction */
+ rtreeEndTransaction, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
rtreeRename, /* xRename - rename the table */
0, /* xSavepoint */
0, /* xRelease */
- 0 /* xRollbackTo */
+ 0, /* xRollbackTo */
};
static int rtreeSqlInit(
@@ -163040,10 +166764,9 @@ static int rtreeSqlInit(
){
int rc = SQLITE_OK;
- #define N_STATEMENT 9
+ #define N_STATEMENT 8
static const char *azSql[N_STATEMENT] = {
- /* Read and write the xxx_node table */
- "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1",
+ /* Write the xxx_node table */
"INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
"DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
@@ -163081,15 +166804,14 @@ static int rtreeSqlInit(
}
}
- appStmt[0] = &pRtree->pReadNode;
- appStmt[1] = &pRtree->pWriteNode;
- appStmt[2] = &pRtree->pDeleteNode;
- appStmt[3] = &pRtree->pReadRowid;
- appStmt[4] = &pRtree->pWriteRowid;
- appStmt[5] = &pRtree->pDeleteRowid;
- appStmt[6] = &pRtree->pReadParent;
- appStmt[7] = &pRtree->pWriteParent;
- appStmt[8] = &pRtree->pDeleteParent;
+ appStmt[0] = &pRtree->pWriteNode;
+ appStmt[1] = &pRtree->pDeleteNode;
+ appStmt[2] = &pRtree->pReadRowid;
+ appStmt[3] = &pRtree->pWriteRowid;
+ appStmt[4] = &pRtree->pDeleteRowid;
+ appStmt[5] = &pRtree->pReadParent;
+ appStmt[6] = &pRtree->pWriteParent;
+ appStmt[7] = &pRtree->pDeleteParent;
rc = rtreeQueryStat1(db, pRtree);
for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
@@ -163227,9 +166949,10 @@ static int rtreeInit(
pRtree->base.pModule = &rtreeModule;
pRtree->zDb = (char *)&pRtree[1];
pRtree->zName = &pRtree->zDb[nDb+1];
- pRtree->nDim = (argc-4)/2;
- pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2;
- pRtree->eCoordType = eCoordType;
+ pRtree->nDim = (u8)((argc-4)/2);
+ pRtree->nDim2 = pRtree->nDim*2;
+ pRtree->nBytesPerCell = 8 + pRtree->nDim2*4;
+ pRtree->eCoordType = (u8)eCoordType;
memcpy(pRtree->zDb, argv[1], nDb);
memcpy(pRtree->zName, argv[2], nName);
@@ -163302,7 +167025,8 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
UNUSED_PARAMETER(nArg);
memset(&node, 0, sizeof(RtreeNode));
memset(&tree, 0, sizeof(Rtree));
- tree.nDim = sqlite3_value_int(apArg[0]);
+ tree.nDim = (u8)sqlite3_value_int(apArg[0]);
+ tree.nDim2 = tree.nDim*2;
tree.nBytesPerCell = 8 + 8 * tree.nDim;
node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
@@ -163315,7 +167039,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
nodeGetCell(&tree, &node, ii, &cell);
sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
nCell = (int)strlen(zCell);
- for(jj=0; jj<tree.nDim*2; jj++){
+ for(jj=0; jj<tree.nDim2; jj++){
#ifndef SQLITE_RTREE_INT_ONLY
sqlite3_snprintf(512-nCell,&zCell[nCell], " %g",
(double)cell.aCoord[jj].f);
@@ -163465,7 +167189,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zGeom, /* Name of the new SQL function */
int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
@@ -163489,7 +167213,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
** Register a new 2nd-generation geometry function for use with the
** r-tree MATCH operator.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db, /* Register SQL function on this connection */
const char *zQueryFunc, /* Name of new SQL function */
int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */
@@ -163514,7 +167238,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init(
+SQLITE_API int sqlite3_rtree_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -163879,7 +167603,7 @@ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
** of upper() or lower().
**
** lower('I', 'en_us') -> 'i'
-** lower('I', 'tr_tr') -> 'ı' (small dotless i)
+** lower('I', 'tr_tr') -> '\u131' (small dotless i)
**
** http://www.icu-project.org/userguide/posix.html#case_mappings
*/
@@ -164023,38 +167747,36 @@ static void icuLoadCollation(
** Register the ICU extension functions with database db.
*/
SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
- struct IcuScalar {
+ static const struct IcuScalar {
const char *zName; /* Function name */
- int nArg; /* Number of arguments */
- int enc; /* Optimal text encoding */
- void *pContext; /* sqlite3_user_data() context */
+ unsigned char nArg; /* Number of arguments */
+ unsigned short enc; /* Optimal text encoding */
+ unsigned char iContext; /* sqlite3_user_data() context */
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
} scalars[] = {
- {"regexp", 2, SQLITE_ANY, 0, icuRegexpFunc},
-
- {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16},
-
- {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16},
- {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16},
- {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16},
- {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16},
-
- {"like", 2, SQLITE_UTF8, 0, icuLikeFunc},
- {"like", 3, SQLITE_UTF8, 0, icuLikeFunc},
-
- {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation},
+ {"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation},
+ {"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc},
+ {"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"upper", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"upper", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"lower", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"lower", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
+ {"upper", 1, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
+ {"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
+ {"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
};
-
int rc = SQLITE_OK;
int i;
+
for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
- struct IcuScalar *p = &scalars[i];
+ const struct IcuScalar *p = &scalars[i];
rc = sqlite3_create_function(
- db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0
+ db, p->zName, p->nArg, p->enc,
+ p->iContext ? (void*)db : (void*)0,
+ p->xFunc, 0, 0
);
}
@@ -164065,7 +167787,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_icu_init(
+SQLITE_API int sqlite3_icu_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -164541,7 +168263,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
** may also be named data<integer>_<target>, where <integer> is any sequence
** of zero or more numeric characters (0-9). This can be significant because
** tables within the RBU database are always processed in order sorted by
-** name. By judicious selection of the the <integer> portion of the names
+** name. By judicious selection of the <integer> portion of the names
** of the RBU tables the user can therefore control the order in which they
** are processed. This can be useful, for example, to ensure that "external
** content" FTS4 tables are updated before their underlying content tables.
@@ -164745,7 +168467,7 @@ typedef struct sqlite3rbu sqlite3rbu;
** not work out of the box with zipvfs. Refer to the comment describing
** the zipvfs_create_vfs() API below for details on using RBU with zipvfs.
*/
-SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
+SQLITE_API sqlite3rbu *sqlite3rbu_open(
const char *zTarget,
const char *zRbu,
const char *zState
@@ -164756,16 +168478,22 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
** An RBU vacuum is similar to SQLite's built-in VACUUM command, except
** that it can be suspended and resumed like an RBU update.
**
-** The second argument to this function, which may not be NULL, identifies
-** a database in which to store the state of the RBU vacuum operation if
-** it is suspended. The first time sqlite3rbu_vacuum() is called, to start
-** an RBU vacuum operation, the state database should either not exist or
-** be empty (contain no tables). If an RBU vacuum is suspended by calling
+** The second argument to this function identifies a database in which
+** to store the state of the RBU vacuum operation if it is suspended. The
+** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum
+** operation, the state database should either not exist or be empty
+** (contain no tables). If an RBU vacuum is suspended by calling
** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has
** returned SQLITE_DONE, the vacuum state is stored in the state database.
** The vacuum can be resumed by calling this function to open a new RBU
** handle specifying the same target and state databases.
**
+** If the second argument passed to this function is NULL, then the
+** name of the state database is "<database>-vacuum", where <database>
+** is the name of the target database file. In this case, on UNIX, if the
+** state database is not already present in the file-system, it is created
+** with the same permissions as the target db is made.
+**
** This function does not delete the state database after an RBU vacuum
** is completed, even if it created it. However, if the call to
** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents
@@ -164778,7 +168506,7 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
** a description of the complications associated with using RBU with
** zipvfs databases.
*/
-SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
+SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
const char *zTarget,
const char *zState
);
@@ -164814,7 +168542,7 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
** Database handles returned by this function remain valid until the next
** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db().
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu*, int bRbu);
+SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu);
/*
** Do some work towards applying the RBU update to the target db.
@@ -164828,7 +168556,7 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu*, int bRbu);
** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops
** that immediately return the same value.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *pRbu);
+SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu);
/*
** Force RBU to save its state to disk.
@@ -164840,7 +168568,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *pRbu);
**
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *pRbu);
+SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu);
/*
** Close an RBU handle.
@@ -164860,14 +168588,14 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *pRbu);
** update has been partially applied, or SQLITE_DONE if it has been
** completely applied.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg);
+SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg);
/*
** Return the total number of key-value operations (inserts, deletes or
** updates) that have been performed on the target database since the
** current RBU update was started.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu);
+SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu);
/*
** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100)
@@ -164909,7 +168637,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu);
** table exists but is not correctly populated, the value of the *pnOne
** output variable during stage 1 is undefined.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo);
+SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo);
/*
** Obtain an indication as to the current stage of an RBU update or vacuum.
@@ -164947,7 +168675,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnO
#define SQLITE_RBU_STATE_DONE 4
#define SQLITE_RBU_STATE_ERROR 5
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_state(sqlite3rbu *pRbu);
+SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu);
/*
** Create an RBU VFS named zName that accesses the underlying file-system
@@ -164991,7 +168719,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_state(sqlite3rbu *pRbu);
** file-system via "rbu" all the time, even if it only uses RBU functionality
** occasionally.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_create_vfs(const char *zName, const char *zParent);
+SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent);
/*
** Deregister and destroy an RBU vfs created by an earlier call to
@@ -165001,7 +168729,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_create_vfs(const char *zName, const cha
** before all database handles that use it have been closed, the results
** are undefined.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName);
+SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
#if 0
} /* end of the 'extern "C"' block */
@@ -165279,6 +169007,7 @@ struct sqlite3rbu {
RbuObjIter objiter; /* Iterator for skipping through tbl/idx */
const char *zVfsName; /* Name of automatically created rbu vfs */
rbu_file *pTargetFd; /* File handle open on target db */
+ int nPagePerSector; /* Pages per sector for pTargetFd */
i64 iOalSz;
i64 nPhaseOneStep;
@@ -167256,16 +170985,19 @@ static RbuState *rbuLoadState(sqlite3rbu *p){
** Open the database handle and attach the RBU database as "rbu". If an
** error occurs, leave an error code and message in the RBU handle.
*/
-static void rbuOpenDatabase(sqlite3rbu *p){
- assert( p->rc==SQLITE_OK );
- assert( p->dbMain==0 && p->dbRbu==0 );
- assert( rbuIsVacuum(p) || p->zTarget!=0 );
+static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
+ assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
+ assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
/* Open the RBU database */
p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
+ if( p->zState==0 ){
+ const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
+ p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile);
+ }
}
/* If using separate RBU and state databases, attach the state database to
@@ -167328,7 +171060,7 @@ static void rbuOpenDatabase(sqlite3rbu *p){
}else{
RbuState *pState = rbuLoadState(p);
if( pState ){
- bOpen = (pState->eStage>RBU_STAGE_MOVE);
+ bOpen = (pState->eStage>=RBU_STAGE_MOVE);
rbuFreeState(pState);
}
}
@@ -167340,6 +171072,15 @@ static void rbuOpenDatabase(sqlite3rbu *p){
if( !rbuIsVacuum(p) ){
p->dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
}else if( p->pRbuFd->pWalFd ){
+ if( pbRetry ){
+ p->pRbuFd->bNolock = 0;
+ sqlite3_close(p->dbRbu);
+ sqlite3_close(p->dbMain);
+ p->dbMain = 0;
+ p->dbRbu = 0;
+ *pbRetry = 1;
+ return;
+ }
p->rc = SQLITE_ERROR;
p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database");
}else{
@@ -167520,16 +171261,35 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
}
- if( p->rc==SQLITE_OK ){
+ if( p->rc==SQLITE_OK && p->nFrame>0 ){
p->eStage = RBU_STAGE_CKPT;
p->nStep = (pState ? pState->nRow : 0);
p->aBuf = rbuMalloc(p, p->pgsz);
p->iWalCksum = rbuShmChecksum(p);
}
- if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){
- p->rc = SQLITE_DONE;
- p->eStage = RBU_STAGE_DONE;
+ if( p->rc==SQLITE_OK ){
+ if( p->nFrame==0 || (pState && pState->iWalCksum!=p->iWalCksum) ){
+ p->rc = SQLITE_DONE;
+ p->eStage = RBU_STAGE_DONE;
+ }else{
+ int nSectorSize;
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
+ assert( p->nPagePerSector==0 );
+ nSectorSize = pDb->pMethods->xSectorSize(pDb);
+ if( nSectorSize>p->pgsz ){
+ p->nPagePerSector = nSectorSize / p->pgsz;
+ }else{
+ p->nPagePerSector = 1;
+ }
+
+ /* Call xSync() on the wal file. This causes SQLite to sync the
+ ** directory in which the target database and the wal file reside, in
+ ** case it has not been synced since the rename() call in
+ ** rbuMoveOalFile(). */
+ p->rc = pWal->pMethods->xSync(pWal, SQLITE_SYNC_NORMAL);
+ }
}
}
@@ -167702,7 +171462,7 @@ static void rbuMoveOalFile(sqlite3rbu *p){
#endif
if( p->rc==SQLITE_OK ){
- rbuOpenDatabase(p);
+ rbuOpenDatabase(p, 0);
rbuSetupCheckpoint(p, 0);
}
}
@@ -168095,7 +171855,7 @@ static void rbuCreateTargetSchema(sqlite3rbu *p){
/*
** Step the RBU object.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *p){
+SQLITE_API int sqlite3rbu_step(sqlite3rbu *p){
if( p ){
switch( p->eStage ){
case RBU_STAGE_OAL: {
@@ -168184,9 +171944,26 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *p){
p->rc = SQLITE_DONE;
}
}else{
- RbuFrame *pFrame = &p->aFrame[p->nStep];
- rbuCheckpointFrame(p, pFrame);
- p->nStep++;
+ /* At one point the following block copied a single frame from the
+ ** wal file to the database file. So that one call to sqlite3rbu_step()
+ ** checkpointed a single frame.
+ **
+ ** However, if the sector-size is larger than the page-size, and the
+ ** application calls sqlite3rbu_savestate() or close() immediately
+ ** after this step, then rbu_step() again, then a power failure occurs,
+ ** then the database page written here may be damaged. Work around
+ ** this by checkpointing frames until the next page in the aFrame[]
+ ** lies on a different disk sector to the current one. */
+ u32 iSector;
+ do{
+ RbuFrame *pFrame = &p->aFrame[p->nStep];
+ iSector = (pFrame->iDbPage-1) / p->nPagePerSector;
+ rbuCheckpointFrame(p, pFrame);
+ p->nStep++;
+ }while( p->nStep<p->nFrame
+ && iSector==((p->aFrame[p->nStep].iDbPage-1) / p->nPagePerSector)
+ && p->rc==SQLITE_OK
+ );
}
p->nProgress++;
}
@@ -168400,8 +172177,7 @@ static sqlite3rbu *openRbuHandle(
sqlite3rbu *p;
size_t nTarget = zTarget ? strlen(zTarget) : 0;
size_t nRbu = strlen(zRbu);
- size_t nState = zState ? strlen(zState) : 0;
- size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1+ nState+1;
+ size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1;
p = (sqlite3rbu*)sqlite3_malloc64(nByte);
if( p ){
@@ -168414,6 +172190,7 @@ static sqlite3rbu *openRbuHandle(
/* Open the target, RBU and state databases */
if( p->rc==SQLITE_OK ){
char *pCsr = (char*)&p[1];
+ int bRetry = 0;
if( zTarget ){
p->zTarget = pCsr;
memcpy(p->zTarget, zTarget, nTarget+1);
@@ -168423,10 +172200,20 @@ static sqlite3rbu *openRbuHandle(
memcpy(p->zRbu, zRbu, nRbu+1);
pCsr += nRbu+1;
if( zState ){
- p->zState = pCsr;
- memcpy(p->zState, zState, nState+1);
+ p->zState = rbuMPrintf(p, "%s", zState);
+ }
+
+ /* If the first attempt to open the database file fails and the bRetry
+ ** flag it set, this means that the db was not opened because it seemed
+ ** to be a wal-mode db. But, this may have happened due to an earlier
+ ** RBU vacuum operation leaving an old wal file in the directory.
+ ** If this is the case, it will have been checkpointed and deleted
+ ** when the handle was closed and a second attempt to open the
+ ** database may succeed. */
+ rbuOpenDatabase(p, &bRetry);
+ if( bRetry ){
+ rbuOpenDatabase(p, 0);
}
- rbuOpenDatabase(p);
}
if( p->rc==SQLITE_OK ){
@@ -168535,13 +172322,28 @@ static sqlite3rbu *openRbuHandle(
}
/*
+** Allocate and return an RBU handle with all fields zeroed except for the
+** error code, which is set to SQLITE_MISUSE.
+*/
+static sqlite3rbu *rbuMisuseError(void){
+ sqlite3rbu *pRet;
+ pRet = sqlite3_malloc64(sizeof(sqlite3rbu));
+ if( pRet ){
+ memset(pRet, 0, sizeof(sqlite3rbu));
+ pRet->rc = SQLITE_MISUSE;
+ }
+ return pRet;
+}
+
+/*
** Open and return a new RBU handle.
*/
-SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
+SQLITE_API sqlite3rbu *sqlite3rbu_open(
const char *zTarget,
const char *zRbu,
const char *zState
){
+ if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
/* TODO: Check that zTarget and zRbu are non-NULL */
return openRbuHandle(zTarget, zRbu, zState);
}
@@ -168549,10 +172351,11 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
/*
** Open a handle to begin or resume an RBU VACUUM operation.
*/
-SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
+SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
const char *zTarget,
const char *zState
){
+ if( zTarget==0 ){ return rbuMisuseError(); }
/* TODO: Check that both arguments are non-NULL */
return openRbuHandle(0, zTarget, zState);
}
@@ -168560,7 +172363,7 @@ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
/*
** Return the database handle used by pRbu.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
+SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){
sqlite3 *db = 0;
if( pRbu ){
db = (bRbu ? pRbu->dbRbu : pRbu->dbMain);
@@ -168592,7 +172395,7 @@ static void rbuEditErrmsg(sqlite3rbu *p){
/*
** Close the RBU handle.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
+SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
int rc;
if( p ){
@@ -168601,6 +172404,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
}
+ /* Sync the db file if currently doing an incremental checkpoint */
+ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
+ }
+
rbuSaveState(p, p->eStage);
if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){
@@ -168630,6 +172439,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
rbuEditErrmsg(p);
rc = p->rc;
*pzErrmsg = p->zErrmsg;
+ sqlite3_free(p->zState);
sqlite3_free(p);
}else{
rc = SQLITE_NOMEM;
@@ -168643,7 +172453,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
** updates) that have been performed on the target database since the
** current RBU update was started.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){
+SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){
return pRbu->nProgress;
}
@@ -168651,7 +172461,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){
** Return permyriadage progress indications for the two main stages of
** an RBU update.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
+SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){
const int MAX_PROGRESS = 10000;
switch( p->eStage ){
case RBU_STAGE_OAL:
@@ -168686,7 +172496,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne,
/*
** Return the current state of the RBU vacuum or update operation.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_state(sqlite3rbu *p){
+SQLITE_API int sqlite3rbu_state(sqlite3rbu *p){
int aRes[] = {
0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE,
0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE
@@ -168714,7 +172524,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_state(sqlite3rbu *p){
}
}
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){
+SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
int rc = p->rc;
if( rc==SQLITE_DONE ) return SQLITE_OK;
@@ -168724,6 +172534,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){
if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0);
}
+ /* Sync the db file */
+ if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){
+ sqlite3_file *pDb = p->pTargetFd->pReal;
+ rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
+ }
+
p->rc = rc;
rbuSaveState(p, p->eStage);
rc = p->rc;
@@ -169541,7 +173357,7 @@ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
** Deregister and destroy an RBU vfs created by an earlier call to
** sqlite3rbu_create_vfs().
*/
-SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName){
+SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
if( pVfs && pVfs->xOpen==rbuVfsOpen ){
sqlite3_mutex_free(((rbu_vfs*)pVfs)->mutex);
@@ -169555,7 +173371,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName){
** via existing VFS zParent. The new object is registered as a non-default
** VFS with SQLite before returning.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3rbu_create_vfs(const char *zName, const char *zParent){
+SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){
/* Template for VFS */
static sqlite3_vfs vfs_template = {
@@ -170241,7 +174057,7 @@ static int statFilter(
" UNION ALL "
"SELECT name, rootpage, type"
" FROM \"%w\".%s WHERE rootpage!=0"
- " ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster);
+ " ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName, zMaster);
if( zSql==0 ){
return SQLITE_NOMEM_BKPT;
}else{
@@ -170295,7 +174111,7 @@ static int statColumn(
default: { /* schema */
sqlite3 *db = sqlite3_context_db_handle(ctx);
int iDb = pCsr->iDb;
- sqlite3_result_text(ctx, db->aDb[iDb].zName, -1, SQLITE_STATIC);
+ sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC);
break;
}
}
@@ -170718,9 +174534,7 @@ static int sessionSerializeValue(
if( aBuf ){
sessionVarintPut(&aBuf[1], n);
- memcpy(&aBuf[nVarint + 1], eType==SQLITE_TEXT ?
- sqlite3_value_text(pValue) : sqlite3_value_blob(pValue), n
- );
+ if( n ) memcpy(&aBuf[nVarint + 1], z, n);
}
nByte = 1 + nVarint + n;
@@ -171800,7 +175614,7 @@ static int sessionDiffFindModified(
return rc;
}
-SQLITE_API int SQLITE_STDCALL sqlite3session_diff(
+SQLITE_API int sqlite3session_diff(
sqlite3_session *pSession,
const char *zFrom,
const char *zTbl,
@@ -171894,7 +175708,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3session_diff(
** Create a session object. This session object will record changes to
** database zDb attached to connection db.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_create(
+SQLITE_API int sqlite3session_create(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of db (e.g. "main") */
sqlite3_session **ppSession /* OUT: New session object */
@@ -171956,7 +175770,7 @@ static void sessionDeleteTable(SessionTable *pList){
/*
** Delete a session object previously allocated using sqlite3session_create().
*/
-SQLITE_API void SQLITE_STDCALL sqlite3session_delete(sqlite3_session *pSession){
+SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){
sqlite3 *db = pSession->db;
sqlite3_session *pHead;
sqlite3_session **pp;
@@ -171985,7 +175799,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3session_delete(sqlite3_session *pSession){
/*
** Set a table filter on a Session Object.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3session_table_filter(
+SQLITE_API void sqlite3session_table_filter(
sqlite3_session *pSession,
int(*xFilter)(void*, const char*),
void *pCtx /* First argument passed to xFilter */
@@ -172003,7 +175817,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3session_table_filter(
** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias)
** or not.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_attach(
+SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
const char *zName /* Table name */
){
@@ -172136,7 +175950,7 @@ static void sessionAppendBlob(
int nBlob,
int *pRc
){
- if( 0==sessionBufferGrow(p, nBlob, pRc) ){
+ if( nBlob>0 && 0==sessionBufferGrow(p, nBlob, pRc) ){
memcpy(&p->aBuf[p->nBuf], aBlob, nBlob);
p->nBuf += nBlob;
}
@@ -172322,13 +176136,13 @@ static int sessionAppendUpdate(
}
default: {
- int nByte;
- int nHdr = 1 + sessionVarintGet(&pCsr[1], &nByte);
+ int n;
+ int nHdr = 1 + sessionVarintGet(&pCsr[1], &n);
assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
- nAdvance = nHdr + nByte;
+ nAdvance = nHdr + n;
if( eType==sqlite3_column_type(pStmt, i)
- && nByte==sqlite3_column_bytes(pStmt, i)
- && 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), nByte)
+ && n==sqlite3_column_bytes(pStmt, i)
+ && (n==0 || 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), n))
){
break;
}
@@ -172693,7 +176507,7 @@ static int sessionGenerateChangeset(
** It is the responsibility of the caller to eventually free the buffer
** using sqlite3_free().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_changeset(
+SQLITE_API int sqlite3session_changeset(
sqlite3_session *pSession, /* Session object */
int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
void **ppChangeset /* OUT: Buffer containing changeset */
@@ -172704,7 +176518,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3session_changeset(
/*
** Streaming version of sqlite3session_changeset().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_changeset_strm(
+SQLITE_API int sqlite3session_changeset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
@@ -172715,7 +176529,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3session_changeset_strm(
/*
** Streaming version of sqlite3session_patchset().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_patchset_strm(
+SQLITE_API int sqlite3session_patchset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
@@ -172730,7 +176544,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3session_patchset_strm(
** It is the responsibility of the caller to eventually free the buffer
** using sqlite3_free().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_patchset(
+SQLITE_API int sqlite3session_patchset(
sqlite3_session *pSession, /* Session object */
int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
void **ppPatchset /* OUT: Buffer containing changeset */
@@ -172741,7 +176555,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3session_patchset(
/*
** Enable or disable the session object passed as the first argument.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_enable(sqlite3_session *pSession, int bEnable){
+SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable){
int ret;
sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
if( bEnable>=0 ){
@@ -172755,7 +176569,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3session_enable(sqlite3_session *pSession, i
/*
** Enable or disable the session object passed as the first argument.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
+SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){
int ret;
sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
if( bIndirect>=0 ){
@@ -172770,7 +176584,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3session_indirect(sqlite3_session *pSession,
** Return true if there have been no changes to monitored tables recorded
** by the session object passed as the only argument.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3session_isempty(sqlite3_session *pSession){
+SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){
int ret = 0;
SessionTable *pTab;
@@ -172820,7 +176634,7 @@ static int sessionChangesetStart(
/*
** Create an iterator used to iterate through the contents of a changeset.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_start(
+SQLITE_API int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int nChangeset, /* Size of buffer pChangeset in bytes */
void *pChangeset /* Pointer to buffer containing changeset */
@@ -172831,7 +176645,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_start(
/*
** Streaming version of sqlite3changeset_start().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_start_strm(
+SQLITE_API int sqlite3changeset_start_strm(
sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
@@ -173252,7 +177066,7 @@ static int sessionChangesetNext(
** This function may not be called on iterators passed to a conflict handler
** callback by changeset_apply().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_next(sqlite3_changeset_iter *p){
+SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){
return sessionChangesetNext(p, 0, 0);
}
@@ -173261,7 +177075,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_next(sqlite3_changeset_iter *p){
** from a changeset iterator. It may only be called after changeset_next()
** has returned SQLITE_ROW.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_op(
+SQLITE_API int sqlite3changeset_op(
sqlite3_changeset_iter *pIter, /* Iterator handle */
const char **pzTab, /* OUT: Pointer to table name */
int *pnCol, /* OUT: Number of columns in table */
@@ -173281,7 +177095,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_op(
** to. This function may only be called after changeset_next() returns
** SQLITE_ROW.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_pk(
+SQLITE_API int sqlite3changeset_pk(
sqlite3_changeset_iter *pIter, /* Iterator object */
unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
int *pnCol /* OUT: Number of entries in output array */
@@ -173304,7 +177118,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_pk(
** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
** not modified. Otherwise, SQLITE_OK.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_old(
+SQLITE_API int sqlite3changeset_old(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Index of old.* value to retrieve */
sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
@@ -173332,7 +177146,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_old(
** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is
** not modified. Otherwise, SQLITE_OK.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_new(
+SQLITE_API int sqlite3changeset_new(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Index of new.* value to retrieve */
sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
@@ -173366,7 +177180,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_new(
** If value iVal is out-of-range or some other error occurs, an SQLite error
** code is returned. Otherwise, SQLITE_OK.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_conflict(
+SQLITE_API int sqlite3changeset_conflict(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Index of conflict record value to fetch */
sqlite3_value **ppValue /* OUT: Value from conflicting row */
@@ -173374,7 +177188,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_conflict(
if( !pIter->pConflict ){
return SQLITE_MISUSE;
}
- if( iVal<0 || iVal>=sqlite3_column_count(pIter->pConflict) ){
+ if( iVal<0 || iVal>=pIter->nCol ){
return SQLITE_RANGE;
}
*ppValue = sqlite3_column_value(pIter->pConflict, iVal);
@@ -173389,7 +177203,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_conflict(
**
** In all other cases this function returns SQLITE_MISUSE.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_fk_conflicts(
+SQLITE_API int sqlite3changeset_fk_conflicts(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int *pnOut /* OUT: Number of FK violations */
){
@@ -173407,7 +177221,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_fk_conflicts(
** This function may not be called on iterators passed to a conflict handler
** callback by changeset_apply().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_finalize(sqlite3_changeset_iter *p){
+SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *p){
int rc = SQLITE_OK;
if( p ){
int i; /* Used to iterate through p->apValue[] */
@@ -173581,7 +177395,7 @@ static int sessionChangesetInvert(
/*
** Invert a changeset object.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_invert(
+SQLITE_API int sqlite3changeset_invert(
int nChangeset, /* Number of bytes in input */
const void *pChangeset, /* Input changeset */
int *pnInverted, /* OUT: Number of bytes in output changeset */
@@ -173600,7 +177414,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_invert(
/*
** Streaming version of sqlite3changeset_invert().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_invert_strm(
+SQLITE_API int sqlite3changeset_invert_strm(
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData),
@@ -173841,7 +177655,13 @@ static int sessionInsertRow(
sessionAppendStr(&buf, "INSERT INTO main.", &rc);
sessionAppendIdent(&buf, zTab, &rc);
- sessionAppendStr(&buf, " VALUES(?", &rc);
+ sessionAppendStr(&buf, "(", &rc);
+ for(i=0; i<p->nCol; i++){
+ if( i!=0 ) sessionAppendStr(&buf, ", ", &rc);
+ sessionAppendIdent(&buf, p->azCol[i], &rc);
+ }
+
+ sessionAppendStr(&buf, ") VALUES(?", &rc);
for(i=1; i<p->nCol; i++){
sessionAppendStr(&buf, ", ?", &rc);
}
@@ -174387,11 +178207,17 @@ static int sessionChangesetApply(
nTab = (int)strlen(zTab);
sApply.azCol = (const char **)zTab;
}else{
+ int nMinCol = 0;
+ int i;
+
sqlite3changeset_pk(pIter, &abPK, 0);
rc = sessionTableInfo(
db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
);
if( rc!=SQLITE_OK ) break;
+ for(i=0; i<sApply.nCol; i++){
+ if( sApply.abPK[i] ) nMinCol = i+1;
+ }
if( sApply.nCol==0 ){
schemaMismatch = 1;
@@ -174399,26 +178225,29 @@ static int sessionChangesetApply(
"sqlite3changeset_apply(): no such table: %s", zTab
);
}
- else if( sApply.nCol!=nCol ){
+ else if( sApply.nCol<nCol ){
schemaMismatch = 1;
sqlite3_log(SQLITE_SCHEMA,
- "sqlite3changeset_apply(): table %s has %d columns, expected %d",
+ "sqlite3changeset_apply(): table %s has %d columns, "
+ "expected %d or more",
zTab, sApply.nCol, nCol
);
}
- else if( memcmp(sApply.abPK, abPK, nCol)!=0 ){
+ else if( nCol<nMinCol || memcmp(sApply.abPK, abPK, nCol)!=0 ){
schemaMismatch = 1;
sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
"primary key mismatch for table %s", zTab
);
}
- else if(
- (rc = sessionSelectRow(db, zTab, &sApply))
- || (rc = sessionUpdateRow(db, zTab, &sApply))
- || (rc = sessionDeleteRow(db, zTab, &sApply))
- || (rc = sessionInsertRow(db, zTab, &sApply))
- ){
- break;
+ else{
+ sApply.nCol = nCol;
+ if((rc = sessionSelectRow(db, zTab, &sApply))
+ || (rc = sessionUpdateRow(db, zTab, &sApply))
+ || (rc = sessionDeleteRow(db, zTab, &sApply))
+ || (rc = sessionInsertRow(db, zTab, &sApply))
+ ){
+ break;
+ }
}
nTab = sqlite3Strlen30(zTab);
}
@@ -174480,7 +178309,7 @@ static int sessionChangesetApply(
** attached to handle "db". Invoke the supplied conflict handler callback
** to resolve any conflicts encountered while applying the change.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_apply(
+SQLITE_API int sqlite3changeset_apply(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
@@ -174508,7 +178337,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_apply(
** attached to handle "db". Invoke the supplied conflict handler callback
** to resolve any conflicts encountered while applying the change.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_apply_strm(
+SQLITE_API int sqlite3changeset_apply_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
@@ -174843,7 +178672,7 @@ static int sessionChangegroupOutput(
/*
** Allocate a new, empty, sqlite3_changegroup.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changegroup_new(sqlite3_changegroup **pp){
+SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){
int rc = SQLITE_OK; /* Return code */
sqlite3_changegroup *p; /* New object */
p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup));
@@ -174860,7 +178689,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changegroup_new(sqlite3_changegroup **pp){
** Add the changeset currently stored in buffer pData, size nData bytes,
** to changeset-group p.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
+SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */
int rc; /* Return code */
@@ -174876,7 +178705,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changegroup_add(sqlite3_changegroup *pGrp,
** Obtain a buffer containing a changeset representing the concatenation
** of all changesets added to the group so far.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changegroup_output(
+SQLITE_API int sqlite3changegroup_output(
sqlite3_changegroup *pGrp,
int *pnData,
void **ppData
@@ -174887,7 +178716,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changegroup_output(
/*
** Streaming versions of changegroup_add().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changegroup_add_strm(
+SQLITE_API int sqlite3changegroup_add_strm(
sqlite3_changegroup *pGrp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
@@ -174906,7 +178735,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changegroup_add_strm(
/*
** Streaming versions of changegroup_output().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changegroup_output_strm(
+SQLITE_API int sqlite3changegroup_output_strm(
sqlite3_changegroup *pGrp,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
@@ -174917,7 +178746,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changegroup_output_strm(
/*
** Delete a changegroup object.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
+SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){
if( pGrp ){
sessionDeleteTable(pGrp->pList);
sqlite3_free(pGrp);
@@ -174927,7 +178756,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3changegroup_delete(sqlite3_changegroup *pG
/*
** Combine two changesets together.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_concat(
+SQLITE_API int sqlite3changeset_concat(
int nLeft, /* Number of bytes in lhs input */
void *pLeft, /* Lhs input changeset */
int nRight /* Number of bytes in rhs input */,
@@ -174956,7 +178785,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_concat(
/*
** Streaming version of sqlite3changeset_concat().
*/
-SQLITE_API int SQLITE_STDCALL sqlite3changeset_concat_strm(
+SQLITE_API int sqlite3changeset_concat_strm(
int (*xInputA)(void *pIn, void *pData, int *pnData),
void *pInA,
int (*xInputB)(void *pIn, void *pData, int *pnData),
@@ -175010,7 +178839,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3changeset_concat_strm(
** how JSONB might improve on that.)
*/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
-#if !defined(_SQLITEINT_H_)
+#if !defined(SQLITEINT_H)
/* #include "sqlite3ext.h" */
#endif
SQLITE_EXTENSION_INIT1
@@ -175037,13 +178866,15 @@ SQLITE_EXTENSION_INIT1
#ifdef sqlite3Isdigit
/* Use the SQLite core versions if this routine is part of the
** SQLite amalgamation */
-# define safe_isdigit(x) sqlite3Isdigit(x)
-# define safe_isalnum(x) sqlite3Isalnum(x)
+# define safe_isdigit(x) sqlite3Isdigit(x)
+# define safe_isalnum(x) sqlite3Isalnum(x)
+# define safe_isxdigit(x) sqlite3Isxdigit(x)
#else
/* Use the standard library for separate compilation */
#include <ctype.h> /* amalgamator: keep */
-# define safe_isdigit(x) isdigit((unsigned char)(x))
-# define safe_isalnum(x) isalnum((unsigned char)(x))
+# define safe_isdigit(x) isdigit((unsigned char)(x))
+# define safe_isalnum(x) isalnum((unsigned char)(x))
+# define safe_isxdigit(x) isxdigit((unsigned char)(x))
#endif
/*
@@ -175124,9 +178955,10 @@ static const char * const jsonType[] = {
#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */
#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */
#define JNODE_REMOVE 0x04 /* Do not output */
-#define JNODE_REPLACE 0x08 /* Replace with JsonNode.iVal */
-#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */
-#define JNODE_LABEL 0x20 /* Is a label of an object */
+#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */
+#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */
+#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */
+#define JNODE_LABEL 0x40 /* Is a label of an object */
/* A single node of parsed JSON
@@ -175134,12 +178966,13 @@ static const char * const jsonType[] = {
struct JsonNode {
u8 eType; /* One of the JSON_ type values */
u8 jnFlags; /* JNODE flags */
- u8 iVal; /* Replacement value when JNODE_REPLACE */
u32 n; /* Bytes of content, or number of sub-nodes */
union {
const char *zJContent; /* Content for INT, REAL, and STRING */
u32 iAppend; /* More terms for ARRAY and OBJECT */
u32 iKey; /* Key for ARRAY objects in json_tree() */
+ u32 iReplace; /* Replacement content for JNODE_REPLACE */
+ JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */
} u;
};
@@ -175396,6 +179229,13 @@ static void jsonRenderNode(
JsonString *pOut, /* Write JSON here */
sqlite3_value **aReplace /* Replacement values */
){
+ if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
+ if( pNode->jnFlags & JNODE_REPLACE ){
+ jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
+ return;
+ }
+ pNode = pNode->u.pPatch;
+ }
switch( pNode->eType ){
default: {
assert( pNode->eType==JSON_NULL );
@@ -175427,12 +179267,7 @@ static void jsonRenderNode(
jsonAppendChar(pOut, '[');
for(;;){
while( j<=pNode->n ){
- if( pNode[j].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ){
- if( pNode[j].jnFlags & JNODE_REPLACE ){
- jsonAppendSeparator(pOut);
- jsonAppendValue(pOut, aReplace[pNode[j].iVal]);
- }
- }else{
+ if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){
jsonAppendSeparator(pOut);
jsonRenderNode(&pNode[j], pOut, aReplace);
}
@@ -175454,11 +179289,7 @@ static void jsonRenderNode(
jsonAppendSeparator(pOut);
jsonRenderNode(&pNode[j], pOut, aReplace);
jsonAppendChar(pOut, ':');
- if( pNode[j+1].jnFlags & JNODE_REPLACE ){
- jsonAppendValue(pOut, aReplace[pNode[j+1].iVal]);
- }else{
- jsonRenderNode(&pNode[j+1], pOut, aReplace);
- }
+ jsonRenderNode(&pNode[j+1], pOut, aReplace);
}
j += 1 + jsonNodeSize(&pNode[j+1]);
}
@@ -175581,12 +179412,13 @@ static void jsonReturn(
c = z[++i];
if( c=='u' ){
u32 v = 0, k;
- for(k=0; k<4 && i<n-2; i++, k++){
+ for(k=0; k<4; i++, k++){
+ assert( i<n-2 );
c = z[i+1];
- if( c>='0' && c<='9' ) v = v*16 + c - '0';
- else if( c>='A' && c<='F' ) v = v*16 + c - 'A' + 10;
- else if( c>='a' && c<='f' ) v = v*16 + c - 'a' + 10;
- else break;
+ assert( safe_isxdigit(c) );
+ if( c<='9' ) v = v*16 + c - '0';
+ else if( c<='F' ) v = v*16 + c - 'A' + 10;
+ else v = v*16 + c - 'a' + 10;
}
if( v==0 ) break;
if( v<=0x7f ){
@@ -175684,13 +179516,21 @@ static int jsonParseAddNode(
p = &pParse->aNode[pParse->nNode];
p->eType = (u8)eType;
p->jnFlags = 0;
- p->iVal = 0;
p->n = n;
p->u.zJContent = zContent;
return pParse->nNode++;
}
/*
+** Return true if z[] begins with 4 (or more) hexadecimal digits
+*/
+static int jsonIs4Hex(const char *z){
+ int i;
+ for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0;
+ return 1;
+}
+
+/*
** Parse a single JSON value which begins at pParse->zJson[i]. Return the
** index of the first character past the end of the value parsed.
**
@@ -175764,8 +179604,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
if( c==0 ) return -1;
if( c=='\\' ){
c = pParse->zJson[++j];
- if( c==0 ) return -1;
- jnFlags = JNODE_ESCAPE;
+ if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
+ || c=='n' || c=='r' || c=='t'
+ || (c=='u' && jsonIs4Hex(pParse->zJson+j+1)) ){
+ jnFlags = JNODE_ESCAPE;
+ }else{
+ return -1;
+ }
}else if( c=='"' ){
break;
}
@@ -176136,6 +179981,25 @@ static void jsonWrongNumArgs(
sqlite3_free(zMsg);
}
+/*
+** Mark all NULL entries in the Object passed in as JNODE_REMOVE.
+*/
+static void jsonRemoveAllNulls(JsonNode *pNode){
+ int i, n;
+ assert( pNode->eType==JSON_OBJECT );
+ n = pNode->n;
+ for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){
+ switch( pNode[i].eType ){
+ case JSON_NULL:
+ pNode[i].jnFlags |= JNODE_REMOVE;
+ break;
+ case JSON_OBJECT:
+ jsonRemoveAllNulls(&pNode[i]);
+ break;
+ }
+ }
+}
+
/****************************************************************************
** SQL functions used for testing and debugging
@@ -176328,6 +180192,105 @@ static void jsonExtractFunc(
jsonParseReset(&x);
}
+/* This is the RFC 7396 MergePatch algorithm.
+*/
+static JsonNode *jsonMergePatch(
+ JsonParse *pParse, /* The JSON parser that contains the TARGET */
+ int iTarget, /* Node of the TARGET in pParse */
+ JsonNode *pPatch /* The PATCH */
+){
+ u32 i, j;
+ u32 iRoot;
+ JsonNode *pTarget;
+ if( pPatch->eType!=JSON_OBJECT ){
+ return pPatch;
+ }
+ assert( iTarget>=0 && iTarget<pParse->nNode );
+ pTarget = &pParse->aNode[iTarget];
+ assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
+ if( pTarget->eType!=JSON_OBJECT ){
+ jsonRemoveAllNulls(pPatch);
+ return pPatch;
+ }
+ iRoot = iTarget;
+ for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
+ u32 nKey;
+ const char *zKey;
+ assert( pPatch[i].eType==JSON_STRING );
+ assert( pPatch[i].jnFlags & JNODE_LABEL );
+ nKey = pPatch[i].n;
+ zKey = pPatch[i].u.zJContent;
+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+ for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
+ assert( pTarget[j].eType==JSON_STRING );
+ assert( pTarget[j].jnFlags & JNODE_LABEL );
+ assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
+ if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
+ if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
+ if( pPatch[i+1].eType==JSON_NULL ){
+ pTarget[j+1].jnFlags |= JNODE_REMOVE;
+ }else{
+ JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
+ if( pNew==0 ) return 0;
+ pTarget = &pParse->aNode[iTarget];
+ if( pNew!=&pTarget[j+1] ){
+ pTarget[j+1].u.pPatch = pNew;
+ pTarget[j+1].jnFlags |= JNODE_PATCH;
+ }
+ }
+ break;
+ }
+ }
+ if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){
+ int iStart, iPatch;
+ iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0);
+ jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
+ iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+ if( pParse->oom ) return 0;
+ jsonRemoveAllNulls(pPatch);
+ pTarget = &pParse->aNode[iTarget];
+ pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
+ pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
+ iRoot = iStart;
+ pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
+ pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
+ }
+ }
+ return pTarget;
+}
+
+/*
+** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON
+** object that is the result of running the RFC 7396 MergePatch() algorithm
+** on the two arguments.
+*/
+static void jsonPatchFunc(
+ sqlite3_context *ctx,
+ int argc,
+ sqlite3_value **argv
+){
+ JsonParse x; /* The JSON that is being patched */
+ JsonParse y; /* The patch */
+ JsonNode *pResult; /* The result of the merge */
+
+ UNUSED_PARAM(argc);
+ if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return;
+ if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){
+ jsonParseReset(&x);
+ return;
+ }
+ pResult = jsonMergePatch(&x, 0, y.aNode);
+ assert( pResult!=0 || x.oom );
+ if( pResult ){
+ jsonReturnJson(pResult, ctx, 0);
+ }else{
+ sqlite3_result_error_nomem(ctx);
+ }
+ jsonParseReset(&x);
+ jsonParseReset(&y);
+}
+
+
/*
** Implementation of the json_object(NAME,VALUE,...) function. Return a JSON
** object that contains all name/value given in arguments. Or if any name
@@ -176431,11 +180394,11 @@ static void jsonReplaceFunc(
if( x.nErr ) goto replace_err;
if( pNode ){
pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->iVal = (u8)(i+1);
+ pNode->u.iReplace = i + 1;
}
}
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
}else{
jsonReturnJson(x.aNode, ctx, argv);
}
@@ -176485,11 +180448,11 @@ static void jsonSetFunc(
goto jsonSetDone;
}else if( pNode && (bApnd || bIsSet) ){
pNode->jnFlags |= (u8)JNODE_REPLACE;
- pNode->iVal = (u8)(i+1);
+ pNode->u.iReplace = i + 1;
}
}
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
- sqlite3_result_value(ctx, argv[x.aNode[0].iVal]);
+ sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
}else{
jsonReturnJson(x.aNode, ctx, argv);
}
@@ -176633,7 +180596,7 @@ static void jsonObjectFinal(sqlite3_context *ctx){
if( pStr ){
jsonAppendChar(pStr, '}');
if( pStr->bErr ){
- if( pStr->bErr==0 ) sqlite3_result_error_nomem(ctx);
+ if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx);
assert( pStr->bStatic );
}else{
sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed,
@@ -176911,9 +180874,9 @@ static int jsonEachColumn(
/* For json_each() path and root are the same so fall through
** into the root case */
}
- case JEACH_ROOT: {
+ default: {
const char *zRoot = p->zRoot;
- if( zRoot==0 ) zRoot = "$";
+ if( zRoot==0 ) zRoot = "$";
sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC);
break;
}
@@ -177132,6 +181095,7 @@ SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
{ "json_extract", -1, 0, jsonExtractFunc },
{ "json_insert", -1, 0, jsonSetFunc },
{ "json_object", -1, 0, jsonObjectFunc },
+ { "json_patch", 2, 0, jsonPatchFunc },
{ "json_quote", 1, 0, jsonQuoteFunc },
{ "json_remove", -1, 0, jsonRemoveFunc },
{ "json_replace", -1, 0, jsonReplaceFunc },
@@ -177188,7 +181152,7 @@ SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_json_init(
+SQLITE_API int sqlite3_json_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -177825,7 +181789,9 @@ typedef short i16;
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
-#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
+#ifndef ArraySize
+# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
+#endif
#define testcase(x)
#define ALWAYS(x) 1
@@ -178532,6 +182498,7 @@ static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
+static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*);
static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
@@ -178589,12 +182556,13 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
#define FTS5_COLON 5
#define FTS5_LP 6
#define FTS5_RP 7
-#define FTS5_LCP 8
-#define FTS5_RCP 9
-#define FTS5_STRING 10
-#define FTS5_COMMA 11
-#define FTS5_PLUS 12
-#define FTS5_STAR 13
+#define FTS5_MINUS 8
+#define FTS5_LCP 9
+#define FTS5_RCP 10
+#define FTS5_STRING 11
+#define FTS5_COMMA 12
+#define FTS5_PLUS 13
+#define FTS5_STAR 14
/*
** 2000-05-29
@@ -178708,17 +182676,17 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
#endif
/************* Begin control #defines *****************************************/
#define fts5YYCODETYPE unsigned char
-#define fts5YYNOCODE 27
+#define fts5YYNOCODE 28
#define fts5YYACTIONTYPE unsigned char
#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
typedef union {
int fts5yyinit;
sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
- Fts5Colset* fts5yy3;
- Fts5ExprPhrase* fts5yy11;
- Fts5ExprNode* fts5yy18;
- int fts5yy20;
- Fts5ExprNearset* fts5yy26;
+ int fts5yy4;
+ Fts5Colset* fts5yy11;
+ Fts5ExprNode* fts5yy24;
+ Fts5ExprNearset* fts5yy46;
+ Fts5ExprPhrase* fts5yy53;
} fts5YYMINORTYPE;
#ifndef fts5YYSTACKDEPTH
#define fts5YYSTACKDEPTH 100
@@ -178727,16 +182695,16 @@ typedef union {
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
-#define fts5YYNSTATE 26
-#define fts5YYNRULE 24
-#define fts5YY_MAX_SHIFT 25
-#define fts5YY_MIN_SHIFTREDUCE 40
-#define fts5YY_MAX_SHIFTREDUCE 63
-#define fts5YY_MIN_REDUCE 64
-#define fts5YY_MAX_REDUCE 87
-#define fts5YY_ERROR_ACTION 88
-#define fts5YY_ACCEPT_ACTION 89
-#define fts5YY_NO_ACTION 90
+#define fts5YYNSTATE 29
+#define fts5YYNRULE 26
+#define fts5YY_MAX_SHIFT 28
+#define fts5YY_MIN_SHIFTREDUCE 45
+#define fts5YY_MAX_SHIFTREDUCE 70
+#define fts5YY_MIN_REDUCE 71
+#define fts5YY_MAX_REDUCE 96
+#define fts5YY_ERROR_ACTION 97
+#define fts5YY_ACCEPT_ACTION 98
+#define fts5YY_NO_ACTION 99
/************* End control #defines *******************************************/
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
@@ -178768,7 +182736,7 @@ typedef union {
**
** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
** and fts5YY_MAX_REDUCE
-
+**
** N == fts5YY_ERROR_ACTION A syntax error has occurred.
**
** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
@@ -178777,16 +182745,20 @@ typedef union {
** slots in the fts5yy_action[] table.
**
** The action table is constructed as a single large table named fts5yy_action[].
-** Given state S and lookahead X, the action is computed as
+** Given state S and lookahead X, the action is computed as either:
**
-** fts5yy_action[ fts5yy_shift_ofst[S] + X ]
+** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
+** (B) N = fts5yy_default[S]
**
-** If the index value fts5yy_shift_ofst[S]+X is out of range or if the value
-** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X or if fts5yy_shift_ofst[S]
-** is equal to fts5YY_SHIFT_USE_DFLT, it means that the action is not in the table
-** and that fts5yy_default[S] should be used instead.
+** The (A) formula is preferred. The B formula is used instead if:
+** (1) The fts5yy_shift_ofst[S]+X value is out of range, or
+** (2) fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X, or
+** (3) fts5yy_shift_ofst[S] equal fts5YY_SHIFT_USE_DFLT.
+** (Implementation note: fts5YY_SHIFT_USE_DFLT is chosen so that
+** fts5YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
+** Hence only tests (1) and (2) need to be evaluated.)
**
-** The formula above is for computing the action when the lookahead is
+** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
** the fts5yy_shift_ofst[] array and fts5YY_REDUCE_USE_DFLT is used in place of
@@ -178804,48 +182776,50 @@ typedef union {
** fts5yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define fts5YY_ACTTAB_COUNT (78)
+#define fts5YY_ACTTAB_COUNT (85)
static const fts5YYACTIONTYPE fts5yy_action[] = {
- /* 0 */ 89, 15, 46, 5, 48, 24, 12, 19, 23, 14,
- /* 10 */ 46, 5, 48, 24, 20, 21, 23, 43, 46, 5,
- /* 20 */ 48, 24, 6, 18, 23, 17, 46, 5, 48, 24,
- /* 30 */ 75, 7, 23, 25, 46, 5, 48, 24, 62, 47,
- /* 40 */ 23, 48, 24, 7, 11, 23, 9, 3, 4, 2,
- /* 50 */ 62, 50, 52, 44, 64, 3, 4, 2, 49, 4,
- /* 60 */ 2, 1, 23, 11, 16, 9, 12, 2, 10, 61,
- /* 70 */ 53, 59, 62, 60, 22, 13, 55, 8,
+ /* 0 */ 98, 16, 51, 5, 53, 27, 83, 7, 26, 15,
+ /* 10 */ 51, 5, 53, 27, 13, 69, 26, 48, 51, 5,
+ /* 20 */ 53, 27, 19, 11, 26, 9, 20, 51, 5, 53,
+ /* 30 */ 27, 13, 22, 26, 28, 51, 5, 53, 27, 68,
+ /* 40 */ 1, 26, 19, 11, 17, 9, 52, 10, 53, 27,
+ /* 50 */ 23, 24, 26, 54, 3, 4, 2, 26, 6, 21,
+ /* 60 */ 49, 71, 3, 4, 2, 7, 56, 59, 55, 59,
+ /* 70 */ 4, 2, 12, 69, 58, 60, 18, 67, 62, 69,
+ /* 80 */ 25, 66, 8, 14, 2,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
- /* 0 */ 15, 16, 17, 18, 19, 20, 10, 11, 23, 16,
- /* 10 */ 17, 18, 19, 20, 23, 24, 23, 16, 17, 18,
- /* 20 */ 19, 20, 22, 23, 23, 16, 17, 18, 19, 20,
- /* 30 */ 5, 6, 23, 16, 17, 18, 19, 20, 13, 17,
- /* 40 */ 23, 19, 20, 6, 8, 23, 10, 1, 2, 3,
- /* 50 */ 13, 9, 10, 7, 0, 1, 2, 3, 19, 2,
- /* 60 */ 3, 6, 23, 8, 21, 10, 10, 3, 10, 25,
- /* 70 */ 10, 10, 13, 25, 12, 10, 7, 5,
+ /* 0 */ 16, 17, 18, 19, 20, 21, 5, 6, 24, 17,
+ /* 10 */ 18, 19, 20, 21, 11, 14, 24, 17, 18, 19,
+ /* 20 */ 20, 21, 8, 9, 24, 11, 17, 18, 19, 20,
+ /* 30 */ 21, 11, 12, 24, 17, 18, 19, 20, 21, 26,
+ /* 40 */ 6, 24, 8, 9, 22, 11, 18, 11, 20, 21,
+ /* 50 */ 24, 25, 24, 20, 1, 2, 3, 24, 23, 24,
+ /* 60 */ 7, 0, 1, 2, 3, 6, 10, 11, 10, 11,
+ /* 70 */ 2, 3, 9, 14, 11, 11, 22, 26, 7, 14,
+ /* 80 */ 13, 11, 5, 11, 3,
};
-#define fts5YY_SHIFT_USE_DFLT (-5)
-#define fts5YY_SHIFT_COUNT (25)
-#define fts5YY_SHIFT_MIN (-4)
-#define fts5YY_SHIFT_MAX (72)
-static const signed char fts5yy_shift_ofst[] = {
- /* 0 */ 55, 55, 55, 55, 55, 36, -4, 56, 58, 25,
- /* 10 */ 37, 60, 59, 59, 46, 54, 42, 57, 62, 61,
- /* 20 */ 62, 69, 65, 62, 72, 64,
+#define fts5YY_SHIFT_USE_DFLT (85)
+#define fts5YY_SHIFT_COUNT (28)
+#define fts5YY_SHIFT_MIN (0)
+#define fts5YY_SHIFT_MAX (81)
+static const unsigned char fts5yy_shift_ofst[] = {
+ /* 0 */ 34, 34, 34, 34, 34, 14, 20, 3, 36, 1,
+ /* 10 */ 59, 64, 64, 65, 65, 53, 61, 56, 58, 63,
+ /* 20 */ 68, 67, 70, 67, 71, 72, 67, 77, 81,
};
-#define fts5YY_REDUCE_USE_DFLT (-16)
-#define fts5YY_REDUCE_COUNT (13)
-#define fts5YY_REDUCE_MIN (-15)
-#define fts5YY_REDUCE_MAX (48)
+#define fts5YY_REDUCE_USE_DFLT (-17)
+#define fts5YY_REDUCE_COUNT (14)
+#define fts5YY_REDUCE_MIN (-16)
+#define fts5YY_REDUCE_MAX (54)
static const signed char fts5yy_reduce_ofst[] = {
- /* 0 */ -15, -7, 1, 9, 17, 22, -9, 0, 39, 44,
- /* 10 */ 44, 43, 44, 48,
+ /* 0 */ -16, -8, 0, 9, 17, 28, 26, 35, 33, 13,
+ /* 10 */ 13, 22, 54, 13, 51,
};
static const fts5YYACTIONTYPE fts5yy_default[] = {
- /* 0 */ 88, 88, 88, 88, 88, 69, 82, 88, 88, 87,
- /* 10 */ 87, 88, 87, 87, 88, 88, 88, 66, 80, 88,
- /* 20 */ 81, 88, 88, 78, 88, 65,
+ /* 0 */ 97, 97, 97, 97, 97, 76, 91, 97, 97, 96,
+ /* 10 */ 96, 97, 97, 96, 96, 97, 97, 97, 97, 97,
+ /* 20 */ 73, 89, 97, 90, 97, 97, 87, 97, 72,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -178952,11 +182926,11 @@ static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
static const char *const fts5yyTokenName[] = {
"$", "OR", "AND", "NOT",
"TERM", "COLON", "LP", "RP",
- "LCP", "RCP", "STRING", "COMMA",
- "PLUS", "STAR", "error", "input",
- "expr", "cnearset", "exprlist", "nearset",
- "colset", "colsetlist", "nearphrases", "phrase",
- "neardist_opt", "star_opt",
+ "MINUS", "LCP", "RCP", "STRING",
+ "COMMA", "PLUS", "STAR", "error",
+ "input", "expr", "cnearset", "exprlist",
+ "nearset", "colset", "colsetlist", "nearphrases",
+ "phrase", "neardist_opt", "star_opt",
};
#endif /* NDEBUG */
@@ -178974,20 +182948,22 @@ static const char *const fts5yyRuleName[] = {
/* 7 */ "exprlist ::= exprlist cnearset",
/* 8 */ "cnearset ::= nearset",
/* 9 */ "cnearset ::= colset COLON nearset",
- /* 10 */ "colset ::= LCP colsetlist RCP",
- /* 11 */ "colset ::= STRING",
- /* 12 */ "colsetlist ::= colsetlist STRING",
- /* 13 */ "colsetlist ::= STRING",
- /* 14 */ "nearset ::= phrase",
- /* 15 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
- /* 16 */ "nearphrases ::= phrase",
- /* 17 */ "nearphrases ::= nearphrases phrase",
- /* 18 */ "neardist_opt ::=",
- /* 19 */ "neardist_opt ::= COMMA STRING",
- /* 20 */ "phrase ::= phrase PLUS STRING star_opt",
- /* 21 */ "phrase ::= STRING star_opt",
- /* 22 */ "star_opt ::= STAR",
- /* 23 */ "star_opt ::=",
+ /* 10 */ "colset ::= MINUS LCP colsetlist RCP",
+ /* 11 */ "colset ::= LCP colsetlist RCP",
+ /* 12 */ "colset ::= STRING",
+ /* 13 */ "colset ::= MINUS STRING",
+ /* 14 */ "colsetlist ::= colsetlist STRING",
+ /* 15 */ "colsetlist ::= STRING",
+ /* 16 */ "nearset ::= phrase",
+ /* 17 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+ /* 18 */ "nearphrases ::= phrase",
+ /* 19 */ "nearphrases ::= nearphrases phrase",
+ /* 20 */ "neardist_opt ::=",
+ /* 21 */ "neardist_opt ::= COMMA STRING",
+ /* 22 */ "phrase ::= phrase PLUS STRING star_opt",
+ /* 23 */ "phrase ::= STRING star_opt",
+ /* 24 */ "star_opt ::= STAR",
+ /* 25 */ "star_opt ::=",
};
#endif /* NDEBUG */
@@ -179034,6 +183010,31 @@ static int fts5yyGrowStack(fts5yyParser *p){
# define fts5YYMALLOCARGTYPE size_t
#endif
+/* Initialize a new parser that has already been allocated.
+*/
+static void sqlite3Fts5ParserInit(void *fts5yypParser){
+ fts5yyParser *pParser = (fts5yyParser*)fts5yypParser;
+#ifdef fts5YYTRACKMAXSTACKDEPTH
+ pParser->fts5yyhwm = 0;
+#endif
+#if fts5YYSTACKDEPTH<=0
+ pParser->fts5yytos = NULL;
+ pParser->fts5yystack = NULL;
+ pParser->fts5yystksz = 0;
+ if( fts5yyGrowStack(pParser) ){
+ pParser->fts5yystack = &pParser->fts5yystk0;
+ pParser->fts5yystksz = 1;
+ }
+#endif
+#ifndef fts5YYNOERRORRECOVERY
+ pParser->fts5yyerrcnt = -1;
+#endif
+ pParser->fts5yytos = pParser->fts5yystack;
+ pParser->fts5yystack[0].stateno = 0;
+ pParser->fts5yystack[0].major = 0;
+}
+
+#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
/*
** This function allocates a new parser.
** The only argument is a pointer to a function which works like
@@ -179049,28 +183050,11 @@ static int fts5yyGrowStack(fts5yyParser *p){
static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE)){
fts5yyParser *pParser;
pParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) );
- if( pParser ){
-#ifdef fts5YYTRACKMAXSTACKDEPTH
- pParser->fts5yyhwm = 0;
-#endif
-#if fts5YYSTACKDEPTH<=0
- pParser->fts5yytos = NULL;
- pParser->fts5yystack = NULL;
- pParser->fts5yystksz = 0;
- if( fts5yyGrowStack(pParser) ){
- pParser->fts5yystack = &pParser->fts5yystk0;
- pParser->fts5yystksz = 1;
- }
-#endif
-#ifndef fts5YYNOERRORRECOVERY
- pParser->fts5yyerrcnt = -1;
-#endif
- pParser->fts5yytos = pParser->fts5yystack;
- pParser->fts5yystack[0].stateno = 0;
- pParser->fts5yystack[0].major = 0;
- }
+ if( pParser ) sqlite3Fts5ParserInit(pParser);
return pParser;
}
+#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
+
/* The following function deletes the "minor type" or semantic value
** associated with a symbol. The symbol can be either a terminal
@@ -179097,33 +183081,33 @@ static void fts5yy_destructor(
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
- case 15: /* input */
+ case 16: /* input */
{
(void)pParse;
}
break;
- case 16: /* expr */
- case 17: /* cnearset */
- case 18: /* exprlist */
+ case 17: /* expr */
+ case 18: /* cnearset */
+ case 19: /* exprlist */
{
- sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy18));
+ sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
}
break;
- case 19: /* nearset */
- case 22: /* nearphrases */
+ case 20: /* nearset */
+ case 23: /* nearphrases */
{
- sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy26));
+ sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
}
break;
- case 20: /* colset */
- case 21: /* colsetlist */
+ case 21: /* colset */
+ case 22: /* colsetlist */
{
- sqlite3_free((fts5yypminor->fts5yy3));
+ sqlite3_free((fts5yypminor->fts5yy11));
}
break;
- case 23: /* phrase */
+ case 24: /* phrase */
{
- sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy11));
+ sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
}
break;
/********* End destructor definitions *****************************************/
@@ -179152,6 +183136,18 @@ static void fts5yy_pop_parser_stack(fts5yyParser *pParser){
fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
}
+/*
+** Clear all secondary memory allocations from the parser
+*/
+static void sqlite3Fts5ParserFinalize(void *p){
+ fts5yyParser *pParser = (fts5yyParser*)p;
+ while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser);
+#if fts5YYSTACKDEPTH<=0
+ if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack);
+#endif
+}
+
+#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
/*
** Deallocate and destroy a parser. Destructors are called for
** all stack elements before shutting the parser down.
@@ -179164,16 +183160,13 @@ static void sqlite3Fts5ParserFree(
void *p, /* The parser to be deleted */
void (*freeProc)(void*) /* Function used to reclaim memory */
){
- fts5yyParser *pParser = (fts5yyParser*)p;
#ifndef fts5YYPARSEFREENEVERNULL
- if( pParser==0 ) return;
-#endif
- while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser);
-#if fts5YYSTACKDEPTH<=0
- if( pParser->fts5yystack!=&pParser->fts5yystk0 ) free(pParser->fts5yystack);
+ if( p==0 ) return;
#endif
- (*freeProc)((void*)pParser);
+ sqlite3Fts5ParserFinalize(p);
+ (*freeProc)(p);
}
+#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */
/*
** Return the peak depth of the stack for a parser.
@@ -179200,50 +183193,47 @@ static unsigned int fts5yy_find_shift_action(
assert( stateno <= fts5YY_SHIFT_COUNT );
do{
i = fts5yy_shift_ofst[stateno];
- if( i==fts5YY_SHIFT_USE_DFLT ) return fts5yy_default[stateno];
assert( iLookAhead!=fts5YYNOCODE );
i += iLookAhead;
if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
- if( iLookAhead>0 ){
#ifdef fts5YYFALLBACK
- fts5YYCODETYPE iFallback; /* Fallback token */
- if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
- && (iFallback = fts5yyFallback[iLookAhead])!=0 ){
+ fts5YYCODETYPE iFallback; /* Fallback token */
+ if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
+ && (iFallback = fts5yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE, "%sFALLBACK %s => %s\n",
- fts5yyTracePrompt, fts5yyTokenName[iLookAhead], fts5yyTokenName[iFallback]);
- }
-#endif
- assert( fts5yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
- iLookAhead = iFallback;
- continue;
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE, "%sFALLBACK %s => %s\n",
+ fts5yyTracePrompt, fts5yyTokenName[iLookAhead], fts5yyTokenName[iFallback]);
}
#endif
+ assert( fts5yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
+ iLookAhead = iFallback;
+ continue;
+ }
+#endif
#ifdef fts5YYWILDCARD
- {
- int j = i - iLookAhead + fts5YYWILDCARD;
- if(
+ {
+ int j = i - iLookAhead + fts5YYWILDCARD;
+ if(
#if fts5YY_SHIFT_MIN+fts5YYWILDCARD<0
- j>=0 &&
+ j>=0 &&
#endif
#if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT
- j<fts5YY_ACTTAB_COUNT &&
+ j<fts5YY_ACTTAB_COUNT &&
#endif
- fts5yy_lookahead[j]==fts5YYWILDCARD
- ){
+ fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0
+ ){
#ifndef NDEBUG
- if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE, "%sWILDCARD %s => %s\n",
- fts5yyTracePrompt, fts5yyTokenName[iLookAhead],
- fts5yyTokenName[fts5YYWILDCARD]);
- }
-#endif /* NDEBUG */
- return fts5yy_action[j];
+ if( fts5yyTraceFILE ){
+ fprintf(fts5yyTraceFILE, "%sWILDCARD %s => %s\n",
+ fts5yyTracePrompt, fts5yyTokenName[iLookAhead],
+ fts5yyTokenName[fts5YYWILDCARD]);
}
+#endif /* NDEBUG */
+ return fts5yy_action[j];
}
-#endif /* fts5YYWILDCARD */
}
+#endif /* fts5YYWILDCARD */
return fts5yy_default[stateno];
}else{
return fts5yy_action[i];
@@ -179287,7 +183277,6 @@ static int fts5yy_find_reduce_action(
*/
static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
sqlite3Fts5ParserARG_FETCH;
- fts5yypParser->fts5yytos--;
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fprintf(fts5yyTraceFILE,"%sStack Overflow!\n",fts5yyTracePrompt);
@@ -179342,12 +183331,14 @@ static void fts5yy_shift(
#endif
#if fts5YYSTACKDEPTH>0
if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5YYSTACKDEPTH] ){
+ fts5yypParser->fts5yytos--;
fts5yyStackOverflow(fts5yypParser);
return;
}
#else
if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz] ){
if( fts5yyGrowStack(fts5yypParser) ){
+ fts5yypParser->fts5yytos--;
fts5yyStackOverflow(fts5yypParser);
return;
}
@@ -179370,30 +183361,32 @@ static const struct {
fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} fts5yyRuleInfo[] = {
- { 15, 1 },
- { 16, 3 },
- { 16, 3 },
- { 16, 3 },
- { 16, 3 },
{ 16, 1 },
- { 18, 1 },
- { 18, 2 },
- { 17, 1 },
{ 17, 3 },
- { 20, 3 },
- { 20, 1 },
- { 21, 2 },
- { 21, 1 },
+ { 17, 3 },
+ { 17, 3 },
+ { 17, 3 },
+ { 17, 1 },
{ 19, 1 },
- { 19, 5 },
- { 22, 1 },
+ { 19, 2 },
+ { 18, 1 },
+ { 18, 3 },
+ { 21, 4 },
+ { 21, 3 },
+ { 21, 1 },
+ { 21, 2 },
{ 22, 2 },
- { 24, 0 },
- { 24, 2 },
- { 23, 4 },
+ { 22, 1 },
+ { 20, 1 },
+ { 20, 5 },
+ { 23, 1 },
{ 23, 2 },
- { 25, 1 },
{ 25, 0 },
+ { 25, 2 },
+ { 24, 4 },
+ { 24, 2 },
+ { 26, 1 },
+ { 26, 0 },
};
static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
@@ -179458,120 +183451,131 @@ static void fts5yy_reduce(
/********** Begin reduce actions **********************************************/
fts5YYMINORTYPE fts5yylhsminor;
case 0: /* input ::= expr */
-{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy18); }
+{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
break;
case 1: /* expr ::= expr AND expr */
{
- fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+ fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
- fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
+ fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 2: /* expr ::= expr OR expr */
{
- fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+ fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
- fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
+ fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 3: /* expr ::= expr NOT expr */
{
- fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18, 0);
+ fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
- fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
+ fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 4: /* expr ::= LP expr RP */
-{fts5yymsp[-2].minor.fts5yy18 = fts5yymsp[-1].minor.fts5yy18;}
+{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
break;
case 5: /* expr ::= exprlist */
case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
-{fts5yylhsminor.fts5yy18 = fts5yymsp[0].minor.fts5yy18;}
- fts5yymsp[0].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
+{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
+ fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 7: /* exprlist ::= exprlist cnearset */
{
- fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy18, fts5yymsp[0].minor.fts5yy18);
+ fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
}
- fts5yymsp[-1].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
+ fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 8: /* cnearset ::= nearset */
{
- fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26);
+ fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
}
- fts5yymsp[0].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
+ fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 9: /* cnearset ::= colset COLON nearset */
{
- sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy26, fts5yymsp[-2].minor.fts5yy3);
- fts5yylhsminor.fts5yy18 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy26);
+ sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy46, fts5yymsp[-2].minor.fts5yy11);
+ fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
+}
+ fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ break;
+ case 10: /* colset ::= MINUS LCP colsetlist RCP */
+{
+ fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
}
- fts5yymsp[-2].minor.fts5yy18 = fts5yylhsminor.fts5yy18;
break;
- case 10: /* colset ::= LCP colsetlist RCP */
-{ fts5yymsp[-2].minor.fts5yy3 = fts5yymsp[-1].minor.fts5yy3; }
+ case 11: /* colset ::= LCP colsetlist RCP */
+{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
+ break;
+ case 12: /* colset ::= STRING */
+{
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+}
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
- case 11: /* colset ::= STRING */
+ case 13: /* colset ::= MINUS STRING */
{
- fts5yylhsminor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
}
- fts5yymsp[0].minor.fts5yy3 = fts5yylhsminor.fts5yy3;
break;
- case 12: /* colsetlist ::= colsetlist STRING */
+ case 14: /* colsetlist ::= colsetlist STRING */
{
- fts5yylhsminor.fts5yy3 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy3, &fts5yymsp[0].minor.fts5yy0); }
- fts5yymsp[-1].minor.fts5yy3 = fts5yylhsminor.fts5yy3;
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
+ fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
- case 13: /* colsetlist ::= STRING */
+ case 15: /* colsetlist ::= STRING */
{
- fts5yylhsminor.fts5yy3 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
}
- fts5yymsp[0].minor.fts5yy3 = fts5yylhsminor.fts5yy3;
+ fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
- case 14: /* nearset ::= phrase */
-{ fts5yylhsminor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); }
- fts5yymsp[0].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
+ case 16: /* nearset ::= phrase */
+{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
+ fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 15: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+ case 17: /* nearset ::= STRING LP nearphrases neardist_opt RP */
{
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
- sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy26, &fts5yymsp[-1].minor.fts5yy0);
- fts5yylhsminor.fts5yy26 = fts5yymsp[-2].minor.fts5yy26;
+ sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
+ fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
}
- fts5yymsp[-4].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
+ fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 16: /* nearphrases ::= phrase */
+ case 18: /* nearphrases ::= phrase */
{
- fts5yylhsminor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11);
+ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
}
- fts5yymsp[0].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
+ fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 17: /* nearphrases ::= nearphrases phrase */
+ case 19: /* nearphrases ::= nearphrases phrase */
{
- fts5yylhsminor.fts5yy26 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy26, fts5yymsp[0].minor.fts5yy11);
+ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
}
- fts5yymsp[-1].minor.fts5yy26 = fts5yylhsminor.fts5yy26;
+ fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
- case 18: /* neardist_opt ::= */
+ case 20: /* neardist_opt ::= */
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
break;
- case 19: /* neardist_opt ::= COMMA STRING */
+ case 21: /* neardist_opt ::= COMMA STRING */
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
break;
- case 20: /* phrase ::= phrase PLUS STRING star_opt */
+ case 22: /* phrase ::= phrase PLUS STRING star_opt */
{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy11, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
+ fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
- fts5yymsp[-3].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 21: /* phrase ::= STRING star_opt */
+ case 23: /* phrase ::= STRING star_opt */
{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy20);
+ fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
- fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
- case 22: /* star_opt ::= STAR */
-{ fts5yymsp[0].minor.fts5yy20 = 1; }
+ case 24: /* star_opt ::= STAR */
+{ fts5yymsp[0].minor.fts5yy4 = 1; }
break;
- case 23: /* star_opt ::= */
-{ fts5yymsp[1].minor.fts5yy20 = 0; }
+ case 25: /* star_opt ::= */
+{ fts5yymsp[1].minor.fts5yy4 = 0; }
break;
default:
break;
@@ -179765,7 +183769,7 @@ static void sqlite3Fts5Parser(
fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion);
fts5yymajor = fts5YYNOCODE;
}else{
- while( fts5yypParser->fts5yytos >= &fts5yypParser->fts5yystack
+ while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack
&& fts5yymx != fts5YYERRORSYMBOL
&& (fts5yyact = fts5yy_find_reduce_action(
fts5yypParser->fts5yytos->stateno,
@@ -180029,7 +184033,7 @@ static int fts5HighlightCb(
if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
p->iOff = iEndOff;
- if( iPos<p->iter.iEnd ){
+ if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){
fts5HighlightAppend(&rc, p, p->zClose, -1);
}
}
@@ -180087,6 +184091,118 @@ static void fts5HighlightFunction(
**************************************************************************/
/*
+** Context object passed to the fts5SentenceFinderCb() function.
+*/
+typedef struct Fts5SFinder Fts5SFinder;
+struct Fts5SFinder {
+ int iPos; /* Current token position */
+ int nFirstAlloc; /* Allocated size of aFirst[] */
+ int nFirst; /* Number of entries in aFirst[] */
+ int *aFirst; /* Array of first token in each sentence */
+ const char *zDoc; /* Document being tokenized */
+};
+
+/*
+** Add an entry to the Fts5SFinder.aFirst[] array. Grow the array if
+** necessary. Return SQLITE_OK if successful, or SQLITE_NOMEM if an
+** error occurs.
+*/
+static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){
+ if( p->nFirstAlloc==p->nFirst ){
+ int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64;
+ int *aNew;
+
+ aNew = (int*)sqlite3_realloc(p->aFirst, nNew*sizeof(int));
+ if( aNew==0 ) return SQLITE_NOMEM;
+ p->aFirst = aNew;
+ p->nFirstAlloc = nNew;
+ }
+ p->aFirst[p->nFirst++] = iAdd;
+ return SQLITE_OK;
+}
+
+/*
+** This function is an xTokenize() callback used by the auxiliary snippet()
+** function. Its job is to identify tokens that are the first in a sentence.
+** For each such token, an entry is added to the SFinder.aFirst[] array.
+*/
+static int fts5SentenceFinderCb(
+ void *pContext, /* Pointer to HighlightContext object */
+ int tflags, /* Mask of FTS5_TOKEN_* flags */
+ const char *pToken, /* Buffer containing token */
+ int nToken, /* Size of token in bytes */
+ int iStartOff, /* Start offset of token */
+ int iEndOff /* End offset of token */
+){
+ int rc = SQLITE_OK;
+
+ UNUSED_PARAM2(pToken, nToken);
+ UNUSED_PARAM(iEndOff);
+
+ if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
+ Fts5SFinder *p = (Fts5SFinder*)pContext;
+ if( p->iPos>0 ){
+ int i;
+ char c = 0;
+ for(i=iStartOff-1; i>=0; i--){
+ c = p->zDoc[i];
+ if( c!=' ' && c!='\t' && c!='\n' && c!='\r' ) break;
+ }
+ if( i!=iStartOff-1 && (c=='.' || c==':') ){
+ rc = fts5SentenceFinderAdd(p, p->iPos);
+ }
+ }else{
+ rc = fts5SentenceFinderAdd(p, 0);
+ }
+ p->iPos++;
+ }
+ return rc;
+}
+
+static int fts5SnippetScore(
+ const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
+ Fts5Context *pFts, /* First arg to pass to pApi functions */
+ int nDocsize, /* Size of column in tokens */
+ unsigned char *aSeen, /* Array with one element per query phrase */
+ int iCol, /* Column to score */
+ int iPos, /* Starting offset to score */
+ int nToken, /* Max tokens per snippet */
+ int *pnScore, /* OUT: Score */
+ int *piPos /* OUT: Adjusted offset */
+){
+ int rc;
+ int i;
+ int ip = 0;
+ int ic = 0;
+ int iOff = 0;
+ int iFirst = -1;
+ int nInst;
+ int nScore = 0;
+ int iLast = 0;
+
+ rc = pApi->xInstCount(pFts, &nInst);
+ for(i=0; i<nInst && rc==SQLITE_OK; i++){
+ rc = pApi->xInst(pFts, i, &ip, &ic, &iOff);
+ if( rc==SQLITE_OK && ic==iCol && iOff>=iPos && iOff<(iPos+nToken) ){
+ nScore += (aSeen[ip] ? 1 : 1000);
+ aSeen[ip] = 1;
+ if( iFirst<0 ) iFirst = iOff;
+ iLast = iOff + pApi->xPhraseSize(pFts, ip);
+ }
+ }
+
+ *pnScore = nScore;
+ if( piPos ){
+ int iAdj = iFirst - (nToken - (iLast-iFirst)) / 2;
+ if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
+ if( iAdj<0 ) iAdj = 0;
+ *piPos = iAdj;
+ }
+
+ return rc;
+}
+
+/*
** Implementation of snippet() function.
*/
static void fts5SnippetFunction(
@@ -180107,9 +184223,10 @@ static void fts5SnippetFunction(
unsigned char *aSeen; /* Array of "seen instance" flags */
int iBestCol; /* Column containing best snippet */
int iBestStart = 0; /* First token of best snippet */
- int iBestLast; /* Last token of best snippet */
int nBestScore = 0; /* Score of best snippet */
int nColSize = 0; /* Total size of iBestCol in tokens */
+ Fts5SFinder sFinder; /* Used to find the beginnings of sentences */
+ int nCol;
if( nVal!=5 ){
const char *zErr = "wrong number of arguments to function snippet()";
@@ -180117,13 +184234,13 @@ static void fts5SnippetFunction(
return;
}
+ nCol = pApi->xColumnCount(pFts);
memset(&ctx, 0, sizeof(HighlightContext));
iCol = sqlite3_value_int(apVal[0]);
ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
zEllips = (const char*)sqlite3_value_text(apVal[3]);
nToken = sqlite3_value_int(apVal[4]);
- iBestLast = nToken-1;
iBestCol = (iCol>=0 ? iCol : 0);
nPhrase = pApi->xPhraseCount(pFts);
@@ -180131,65 +184248,94 @@ static void fts5SnippetFunction(
if( aSeen==0 ){
rc = SQLITE_NOMEM;
}
-
if( rc==SQLITE_OK ){
rc = pApi->xInstCount(pFts, &nInst);
}
- for(i=0; rc==SQLITE_OK && i<nInst; i++){
- int ip, iSnippetCol, iStart;
- memset(aSeen, 0, nPhrase);
- rc = pApi->xInst(pFts, i, &ip, &iSnippetCol, &iStart);
- if( rc==SQLITE_OK && (iCol<0 || iSnippetCol==iCol) ){
- int nScore = 1000;
- int iLast = iStart - 1 + pApi->xPhraseSize(pFts, ip);
- int j;
- aSeen[ip] = 1;
- for(j=i+1; rc==SQLITE_OK && j<nInst; j++){
- int ic; int io; int iFinal;
- rc = pApi->xInst(pFts, j, &ip, &ic, &io);
- iFinal = io + pApi->xPhraseSize(pFts, ip) - 1;
- if( rc==SQLITE_OK && ic==iSnippetCol && iLast<iStart+nToken ){
- nScore += aSeen[ip] ? 1000 : 1;
- aSeen[ip] = 1;
- if( iFinal>iLast ) iLast = iFinal;
+ memset(&sFinder, 0, sizeof(Fts5SFinder));
+ for(i=0; i<nCol; i++){
+ if( iCol<0 || iCol==i ){
+ int nDoc;
+ int nDocsize;
+ int ii;
+ sFinder.iPos = 0;
+ sFinder.nFirst = 0;
+ rc = pApi->xColumnText(pFts, i, &sFinder.zDoc, &nDoc);
+ if( rc!=SQLITE_OK ) break;
+ rc = pApi->xTokenize(pFts,
+ sFinder.zDoc, nDoc, (void*)&sFinder,fts5SentenceFinderCb
+ );
+ if( rc!=SQLITE_OK ) break;
+ rc = pApi->xColumnSize(pFts, i, &nDocsize);
+ if( rc!=SQLITE_OK ) break;
+
+ for(ii=0; rc==SQLITE_OK && ii<nInst; ii++){
+ int ip, ic, io;
+ int iAdj;
+ int nScore;
+ int jj;
+
+ rc = pApi->xInst(pFts, ii, &ip, &ic, &io);
+ if( ic!=i || rc!=SQLITE_OK ) continue;
+ memset(aSeen, 0, nPhrase);
+ rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
+ io, nToken, &nScore, &iAdj
+ );
+ if( rc==SQLITE_OK && nScore>nBestScore ){
+ nBestScore = nScore;
+ iBestCol = i;
+ iBestStart = iAdj;
+ nColSize = nDocsize;
}
- }
- if( rc==SQLITE_OK && nScore>nBestScore ){
- iBestCol = iSnippetCol;
- iBestStart = iStart;
- iBestLast = iLast;
- nBestScore = nScore;
+ if( rc==SQLITE_OK && sFinder.nFirst && nDocsize>nToken ){
+ for(jj=0; jj<(sFinder.nFirst-1); jj++){
+ if( sFinder.aFirst[jj+1]>io ) break;
+ }
+
+ if( sFinder.aFirst[jj]<io ){
+ memset(aSeen, 0, nPhrase);
+ rc = fts5SnippetScore(pApi, pFts, nDocsize, aSeen, i,
+ sFinder.aFirst[jj], nToken, &nScore, 0
+ );
+
+ nScore += (sFinder.aFirst[jj]==0 ? 120 : 100);
+ if( rc==SQLITE_OK && nScore>nBestScore ){
+ nBestScore = nScore;
+ iBestCol = i;
+ iBestStart = sFinder.aFirst[jj];
+ nColSize = nDocsize;
+ }
+ }
+ }
}
}
}
if( rc==SQLITE_OK ){
- rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
- }
- if( rc==SQLITE_OK ){
rc = pApi->xColumnText(pFts, iBestCol, &ctx.zIn, &ctx.nIn);
}
+ if( rc==SQLITE_OK && nColSize==0 ){
+ rc = pApi->xColumnSize(pFts, iBestCol, &nColSize);
+ }
if( ctx.zIn ){
if( rc==SQLITE_OK ){
rc = fts5CInstIterInit(pApi, pFts, iBestCol, &ctx.iter);
}
- if( (iBestStart+nToken-1)>iBestLast ){
- iBestStart -= (iBestStart+nToken-1-iBestLast) / 2;
- }
- if( iBestStart+nToken>nColSize ){
- iBestStart = nColSize - nToken;
- }
- if( iBestStart<0 ) iBestStart = 0;
-
ctx.iRangeStart = iBestStart;
ctx.iRangeEnd = iBestStart + nToken - 1;
if( iBestStart>0 ){
fts5HighlightAppend(&rc, &ctx, zEllips, -1);
}
+
+ /* Advance iterator ctx.iter so that it points to the first coalesced
+ ** phrase instance at or following position iBestStart. */
+ while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
+ rc = fts5CInstIterNext(&ctx.iter);
+ }
+
if( rc==SQLITE_OK ){
rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
}
@@ -180198,15 +184344,15 @@ static void fts5SnippetFunction(
}else{
fts5HighlightAppend(&rc, &ctx, zEllips, -1);
}
-
- if( rc==SQLITE_OK ){
- sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
- }else{
- sqlite3_result_error_code(pCtx, rc);
- }
- sqlite3_free(ctx.zOut);
}
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(pCtx, rc);
+ }
+ sqlite3_free(ctx.zOut);
sqlite3_free(aSeen);
+ sqlite3_free(sFinder.aFirst);
}
/************************************************************************/
@@ -181925,6 +186071,7 @@ static int fts5ExprGetToken(
case ',': tok = FTS5_COMMA; break;
case '+': tok = FTS5_PLUS; break;
case '*': tok = FTS5_STAR; break;
+ case '-': tok = FTS5_MINUS; break;
case '\0': tok = FTS5_EOF; break;
case '"': {
@@ -182503,49 +186650,61 @@ static int fts5ExprNearTest(
** Initialize all term iterators in the pNear object. If any term is found
** to match no documents at all, return immediately without initializing any
** further iterators.
+**
+** If an error occurs, return an SQLite error code. Otherwise, return
+** SQLITE_OK. It is not considered an error if some term matches zero
+** documents.
*/
static int fts5ExprNearInitAll(
Fts5Expr *pExpr,
Fts5ExprNode *pNode
){
Fts5ExprNearset *pNear = pNode->pNear;
- int i, j;
- int rc = SQLITE_OK;
+ int i;
assert( pNode->bNomatch==0 );
- for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
+ for(i=0; i<pNear->nPhrase; i++){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- for(j=0; j<pPhrase->nTerm; j++){
- Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
- Fts5ExprTerm *p;
- int bEof = 1;
-
- for(p=pTerm; p && rc==SQLITE_OK; p=p->pSynonym){
- if( p->pIter ){
- sqlite3Fts5IterClose(p->pIter);
- p->pIter = 0;
- }
- rc = sqlite3Fts5IndexQuery(
- pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
- (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
- (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
- pNear->pColset,
- &p->pIter
- );
- assert( rc==SQLITE_OK || p->pIter==0 );
- if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){
- bEof = 0;
+ if( pPhrase->nTerm==0 ){
+ pNode->bEof = 1;
+ return SQLITE_OK;
+ }else{
+ int j;
+ for(j=0; j<pPhrase->nTerm; j++){
+ Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
+ Fts5ExprTerm *p;
+ int bHit = 0;
+
+ for(p=pTerm; p; p=p->pSynonym){
+ int rc;
+ if( p->pIter ){
+ sqlite3Fts5IterClose(p->pIter);
+ p->pIter = 0;
+ }
+ rc = sqlite3Fts5IndexQuery(
+ pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm),
+ (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
+ (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
+ pNear->pColset,
+ &p->pIter
+ );
+ assert( (rc==SQLITE_OK)==(p->pIter!=0) );
+ if( rc!=SQLITE_OK ) return rc;
+ if( 0==sqlite3Fts5IterEof(p->pIter) ){
+ bHit = 1;
+ }
}
- }
- if( bEof ){
- pNode->bEof = 1;
- return rc;
+ if( bHit==0 ){
+ pNode->bEof = 1;
+ return SQLITE_OK;
+ }
}
}
}
- return rc;
+ pNode->bEof = 0;
+ return SQLITE_OK;
}
/*
@@ -182678,7 +186837,7 @@ static int fts5ExprNodeTest_STRING(
}
}else{
Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
- if( pIter->iRowid==iLast ) continue;
+ if( pIter->iRowid==iLast || pIter->bEof ) continue;
bMatch = 0;
if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){
return rc;
@@ -182855,7 +187014,10 @@ static int fts5ExprNodeNext_OR(
|| (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0)
){
int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom);
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ){
+ pNode->bNomatch = 0;
+ return rc;
+ }
}
}
}
@@ -182886,7 +187048,10 @@ static int fts5ExprNodeTest_AND(
if( cmp>0 ){
/* Advance pChild until it points to iLast or laster */
rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast);
- if( rc!=SQLITE_OK ) return rc;
+ if( rc!=SQLITE_OK ){
+ pAnd->bNomatch = 0;
+ return rc;
+ }
}
/* If the child node is now at EOF, so is the parent AND node. Otherwise,
@@ -182925,6 +187090,8 @@ static int fts5ExprNodeNext_AND(
int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom);
if( rc==SQLITE_OK ){
rc = fts5ExprNodeTest_AND(pExpr, pNode);
+ }else{
+ pNode->bNomatch = 0;
}
return rc;
}
@@ -182967,6 +187134,9 @@ static int fts5ExprNodeNext_NOT(
if( rc==SQLITE_OK ){
rc = fts5ExprNodeTest_NOT(pExpr, pNode);
}
+ if( rc!=SQLITE_OK ){
+ pNode->bNomatch = 0;
+ }
return rc;
}
@@ -183089,7 +187259,10 @@ static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bD
/* If not at EOF but the current rowid occurs earlier than iFirst in
** the iteration order, move to document iFirst or later. */
- if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
+ if( rc==SQLITE_OK
+ && 0==pRoot->bEof
+ && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0
+ ){
rc = fts5ExprNodeNext(p, pRoot, 1, iFirst);
}
@@ -183343,7 +187516,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
rc = fts5ParseStringFromToken(pToken, &z);
if( rc==SQLITE_OK ){
- int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_QUERY : 0);
+ int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0);
int n;
sqlite3Fts5Dequote(z);
n = (int)strlen(z);
@@ -183395,7 +187568,6 @@ static int sqlite3Fts5ExprClonePhrase(
){
int rc = SQLITE_OK; /* Return code */
Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */
- int i; /* Used to iterate through phrase terms */
Fts5Expr *pNew = 0; /* Expression to return via *ppNew */
TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */
@@ -183416,7 +187588,7 @@ static int sqlite3Fts5ExprClonePhrase(
if( rc==SQLITE_OK ){
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
if( pColsetOrig ){
- int nByte = sizeof(Fts5Colset) + pColsetOrig->nCol * sizeof(int);
+ int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
if( pColset ){
memcpy(pColset, pColsetOrig, nByte);
@@ -183425,18 +187597,25 @@ static int sqlite3Fts5ExprClonePhrase(
}
}
- for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
- int tflags = 0;
- Fts5ExprTerm *p;
- for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
- const char *zTerm = p->zTerm;
- rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
- 0, 0);
- tflags = FTS5_TOKEN_COLOCATED;
- }
- if( rc==SQLITE_OK ){
- sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
+ if( pOrig->nTerm ){
+ int i; /* Used to iterate through phrase terms */
+ for(i=0; rc==SQLITE_OK && i<pOrig->nTerm; i++){
+ int tflags = 0;
+ Fts5ExprTerm *p;
+ for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){
+ const char *zTerm = p->zTerm;
+ rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
+ 0, 0);
+ tflags = FTS5_TOKEN_COLOCATED;
+ }
+ if( rc==SQLITE_OK ){
+ sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
+ }
}
+ }else{
+ /* This happens when parsing a token or quoted phrase that contains
+ ** no token characters at all. (e.g ... MATCH '""'). */
+ sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
}
if( rc==SQLITE_OK ){
@@ -183551,6 +187730,34 @@ static Fts5Colset *fts5ParseColset(
return pNew;
}
+/*
+** Allocate and return an Fts5Colset object specifying the inverse of
+** the colset passed as the second argument. Free the colset passed
+** as the second argument before returning.
+*/
+static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
+ Fts5Colset *pRet;
+ int nCol = pParse->pConfig->nCol;
+
+ pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc,
+ sizeof(Fts5Colset) + sizeof(int)*nCol
+ );
+ if( pRet ){
+ int i;
+ int iOld = 0;
+ for(i=0; i<nCol; i++){
+ if( iOld>=p->nCol || p->aiCol[iOld]!=i ){
+ pRet->aiCol[pRet->nCol++] = i;
+ }else{
+ iOld++;
+ }
+ }
+ }
+
+ sqlite3_free(p);
+ return pRet;
+}
+
static Fts5Colset *sqlite3Fts5ParseColset(
Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
Fts5Colset *pColset, /* Existing colset object */
@@ -185646,7 +189853,6 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
return pRet;
}
-
/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().
@@ -185655,6 +189861,18 @@ static void fts5DataRelease(Fts5Data *pData){
sqlite3_free(pData);
}
+static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
+ Fts5Data *pRet = fts5DataRead(p, iRowid);
+ if( pRet ){
+ if( pRet->szLeaf>pRet->nn ){
+ p->rc = FTS5_CORRUPT;
+ fts5DataRelease(pRet);
+ pRet = 0;
+ }
+ }
+ return pRet;
+}
+
static int fts5IndexPrepareStmt(
Fts5Index *p,
sqlite3_stmt **ppStmt,
@@ -186463,7 +190681,7 @@ static void fts5SegIterNextPage(
pIter->pLeaf = pIter->pNextLeaf;
pIter->pNextLeaf = 0;
}else if( pIter->iLeafPgno<=pSeg->pgnoLast ){
- pIter->pLeaf = fts5DataRead(p,
+ pIter->pLeaf = fts5LeafRead(p,
FTS5_SEGMENT_ROWID(pSeg->iSegid, pIter->iLeafPgno)
);
}else{
@@ -186966,14 +191184,13 @@ static void fts5SegIterNext(
if( pLeaf->nn>pLeaf->szLeaf ){
pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
&pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist
- );
+ );
}
-
}
else if( pLeaf->nn>pLeaf->szLeaf ){
pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
&pLeaf->p[pLeaf->szLeaf], iOff
- );
+ );
pIter->iLeafOffset = iOff;
pIter->iEndofDoclist = iOff;
bNewTerm = 1;
@@ -187007,6 +191224,7 @@ static void fts5SegIterNext(
*/
int nSz;
assert( p->rc==SQLITE_OK );
+ assert( pIter->iLeafOffset<=pIter->pLeaf->nn );
fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz);
pIter->bDel = (nSz & 0x0001);
pIter->nPos = nSz>>1;
@@ -187213,6 +191431,11 @@ static void fts5LeafSeek(
iTermOff += nKeep;
iOff = iTermOff;
+ if( iOff>=n ){
+ p->rc = FTS5_CORRUPT;
+ return;
+ }
+
/* Read the nKeep field of the next term. */
fts5FastGetVarint32(a, iOff, nKeep);
}
@@ -187769,6 +191992,7 @@ static void fts5MultiIterNext(
i64 iFrom /* Advance at least as far as this */
){
int bUseFrom = bFrom;
+ assert( pIter->base.bEof==0 );
while( p->rc==SQLITE_OK ){
int iFirst = pIter->aFirst[1].iFirst;
int bNewTerm = 0;
@@ -187995,7 +192219,7 @@ static void fts5ChunkIterate(
break;
}else{
pgno++;
- pData = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
+ pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno));
if( pData==0 ) break;
pChunk = &pData->p[4];
nChunk = MIN(nRem, pData->szLeaf - 4);
@@ -188140,6 +192364,15 @@ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){
}
/*
+** xSetOutputs callback used when the Fts5Colset object has nCol==0 (match
+** against no columns at all).
+*/
+static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){
+ UNUSED_PARAM(pSeg);
+ pIter->base.nData = 0;
+}
+
+/*
** xSetOutputs callback used by detail=col when there is a column filter
** and there are 100 or more columns. Also called as a fallback from
** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
@@ -188244,6 +192477,10 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
}
+ else if( pIter->pColset->nCol==0 ){
+ pIter->xSetOutputs = fts5IterSetOutputs_ZeroColset;
+ }
+
else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
pIter->xSetOutputs = fts5IterSetOutputs_Full;
}
@@ -190744,7 +194981,7 @@ static void fts5IndexIntegrityCheckSegment(
** ignore this b-tree entry. Otherwise, load it into memory. */
if( iIdxLeaf<pSeg->pgnoFirst ) continue;
iRow = FTS5_SEGMENT_ROWID(pSeg->iSegid, iIdxLeaf);
- pLeaf = fts5DataRead(p, iRow);
+ pLeaf = fts5LeafRead(p, iRow);
if( pLeaf==0 ) break;
/* Check that the leaf contains at least one term, and that it is equal
@@ -194020,7 +198257,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2016-08-11 18:53:32 a12d8059770df4bca59e321c266410344242bf7b", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37", -1, SQLITE_TRANSIENT);
}
static int fts5Init(sqlite3 *db){
@@ -194108,7 +198345,7 @@ static int fts5Init(sqlite3 *db){
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_fts_init(
+SQLITE_API int sqlite3_fts_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -194121,7 +198358,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_fts_init(
#ifdef _WIN32
__declspec(dllexport)
#endif
-SQLITE_API int SQLITE_STDCALL sqlite3_fts5_init(
+SQLITE_API int sqlite3_fts5_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
@@ -194683,11 +198920,6 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **ap
}
}
- /* Write the averages record */
- if( rc==SQLITE_OK ){
- rc = fts5StorageSaveTotals(p);
- }
-
return rc;
}
@@ -194891,11 +199123,6 @@ static int sqlite3Fts5StorageIndexInsert(
}
sqlite3_free(buf.p);
- /* Write the averages record */
- if( rc==SQLITE_OK ){
- rc = fts5StorageSaveTotals(p);
- }
-
return rc;
}
@@ -195230,12 +199457,17 @@ static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){
** Flush any data currently held in-memory to disk.
*/
static int sqlite3Fts5StorageSync(Fts5Storage *p, int bCommit){
- if( bCommit && p->bTotalsValid ){
- int rc = fts5StorageSaveTotals(p);
- p->bTotalsValid = 0;
- if( rc!=SQLITE_OK ) return rc;
+ int rc = SQLITE_OK;
+ i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db);
+ if( p->bTotalsValid ){
+ rc = fts5StorageSaveTotals(p);
+ if( bCommit ) p->bTotalsValid = 0;
+ }
+ if( rc==SQLITE_OK ){
+ rc = sqlite3Fts5IndexSync(p->pIndex, bCommit);
}
- return sqlite3Fts5IndexSync(p->pIndex, bCommit);
+ sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid);
+ return rc;
}
static int sqlite3Fts5StorageRollback(Fts5Storage *p){
@@ -197502,8 +201734,19 @@ static int fts5VocabBestIndexMethod(
}
}
- pInfo->idxNum = idxNum;
+ /* This virtual table always delivers results in ascending order of
+ ** the "term" column (column 0). So if the user has requested this
+ ** specifically - "ORDER BY term" or "ORDER BY term ASC" - set the
+ ** sqlite3_index_info.orderByConsumed flag to tell the core the results
+ ** are already in sorted order. */
+ if( pInfo->nOrderBy==1
+ && pInfo->aOrderBy[0].iColumn==0
+ && pInfo->aOrderBy[0].desc==0
+ ){
+ pInfo->orderByConsumed = 1;
+ }
+ pInfo->idxNum = idxNum;
return SQLITE_OK;
}
diff --git a/libsqlite3/sqlite3.h b/libsqlite3/sqlite3.h
index 3b6b07c..7e6afcb 100644
--- a/libsqlite3/sqlite3.h
+++ b/libsqlite3/sqlite3.h
@@ -108,25 +108,26 @@ extern "C" {
** be held constant and Z will be incremented or else Y will be incremented
** and Z will be reset to zero.
**
-** Since version 3.6.18, SQLite source code has been stored in the
+** Since [version 3.6.18] ([dateof:3.6.18]),
+** SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">Fossil configuration management
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
** within its configuration management system. ^The SQLITE_SOURCE_ID
-** string contains the date and time of the check-in (UTC) and an SHA1
-** hash of the entire source tree.
+** string contains the date and time of the check-in (UTC) and a SHA1
+** or SHA3-256 hash of the entire source tree.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.14.1"
-#define SQLITE_VERSION_NUMBER 3014001
-#define SQLITE_SOURCE_ID "2016-08-11 18:53:32 a12d8059770df4bca59e321c266410344242bf7b"
+#define SQLITE_VERSION "3.18.0"
+#define SQLITE_VERSION_NUMBER 3018000
+#define SQLITE_SOURCE_ID "2017-03-28 18:48:43 424a0d380332858ee55bdebc4af3789f74e70a2b3ba1cf29d84b9b4bcf3e2e37"
/*
** CAPI3REF: Run-Time Library Version Numbers
-** KEYWORDS: sqlite3_version, sqlite3_sourceid
+** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
@@ -155,9 +156,9 @@ extern "C" {
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
-SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
+SQLITE_API const char *sqlite3_libversion(void);
+SQLITE_API const char *sqlite3_sourceid(void);
+SQLITE_API int sqlite3_libversion_number(void);
/*
** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -182,8 +183,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
** [sqlite_compileoption_get()] and the [compile_options pragma].
*/
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
+SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *sqlite3_compileoption_get(int N);
#endif
/*
@@ -222,7 +223,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
**
** See the [threading mode] documentation for additional information.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
+SQLITE_API int sqlite3_threadsafe(void);
/*
** CAPI3REF: Database Connection Handle
@@ -258,7 +259,11 @@ typedef struct sqlite3 sqlite3;
*/
#ifdef SQLITE_INT64_TYPE
typedef SQLITE_INT64_TYPE sqlite_int64;
- typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+# ifdef SQLITE_UINT64_TYPE
+ typedef SQLITE_UINT64_TYPE sqlite_uint64;
+# else
+ typedef unsigned SQLITE_INT64_TYPE sqlite_uint64;
+# endif
#elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef __int64 sqlite_int64;
typedef unsigned __int64 sqlite_uint64;
@@ -319,8 +324,8 @@ typedef sqlite_uint64 sqlite3_uint64;
** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
** argument is a harmless no-op.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
-SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
+SQLITE_API int sqlite3_close(sqlite3*);
+SQLITE_API int sqlite3_close_v2(sqlite3*);
/*
** The type for a callback function.
@@ -391,7 +396,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
** </ul>
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_exec(
+SQLITE_API int sqlite3_exec(
sqlite3*, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
@@ -452,7 +457,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
** [result codes]. However, experience has shown that many of
** these result codes are too coarse-grained. They do not provide as
** much information about problems as programmers might like. In an effort to
-** address this, newer versions of SQLite (version 3.3.8 and later) include
+** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
+** and later) include
** support for additional result codes that provide more detailed information
** about errors. These [extended result codes] are enabled or disabled
** on a per database connection basis using the
@@ -570,7 +576,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_exec(
** file that were written at the application level might have changed
** and that adjacent bytes, even bytes within the same sector are
** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
-** flag indicate that a file cannot be deleted when open. The
+** flag indicates that a file cannot be deleted when open. The
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
** read-only media and cannot be changed even by processes with
** elevated privileges.
@@ -720,6 +726,9 @@ struct sqlite3_file {
** <li> [SQLITE_IOCAP_ATOMIC64K]
** <li> [SQLITE_IOCAP_SAFE_APPEND]
** <li> [SQLITE_IOCAP_SEQUENTIAL]
+** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
+** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
+** <li> [SQLITE_IOCAP_IMMUTABLE]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -976,6 +985,12 @@ struct sqlite3_io_methods {
** on whether or not the file has been renamed, moved, or deleted since it
** was first opened.
**
+** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
+** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
+** underlying native file handle associated with a file handle. This file
+** control interprets its argument as a pointer to a native file handle and
+** writes the resulting value there.
+**
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
** opcode causes the xFileControl method to swap the file handle with the one
@@ -1026,6 +1041,8 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_RBU 26
#define SQLITE_FCNTL_VFS_POINTER 27
#define SQLITE_FCNTL_JOURNAL_POINTER 28
+#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
+#define SQLITE_FCNTL_PDB 30
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1390,10 +1407,10 @@ struct sqlite3_vfs {
** must return [SQLITE_OK] on success and some other [error code] upon
** failure.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
+SQLITE_API int sqlite3_initialize(void);
+SQLITE_API int sqlite3_shutdown(void);
+SQLITE_API int sqlite3_os_init(void);
+SQLITE_API int sqlite3_os_end(void);
/*
** CAPI3REF: Configuring The SQLite Library
@@ -1426,7 +1443,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
*/
-SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
+SQLITE_API int sqlite3_config(int, ...);
/*
** CAPI3REF: Configure database connections
@@ -1445,7 +1462,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
** the call is considered successful.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Memory Allocation Routines
@@ -1969,13 +1986,36 @@ struct sqlite3_mem_methods {
** be a NULL pointer, in which case the new setting is not reported back.
** </dd>
**
+** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
+** <dd> ^This option is used to change the name of the "main" database
+** schema. ^The sole argument is a pointer to a constant UTF8 string
+** which will become the new schema name in place of "main". ^SQLite
+** does not make a copy of the new main schema name string, so the application
+** must ensure that the argument passed into this DBCONFIG option is unchanged
+** until after the database connection closes.
+** </dd>
+**
+** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt>
+** <dd> Usually, when a database in wal mode is closed or detached from a
+** database handle, SQLite checks if this will mean that there are now no
+** connections at all to the database. If so, it performs a checkpoint
+** operation before closing the connection. This option may be used to
+** override this behaviour. The first parameter passed to this operation
+** is an integer - non-zero to disable checkpoints-on-close, or zero (the
+** default) to enable them. The second parameter is a pointer to an integer
+** into which is written 0 or 1 to indicate whether checkpoints-on-close
+** have been disabled - 0 if they are not disabled, 1 if they are.
+** </dd>
+**
** </dl>
*/
+#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
+#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
/*
@@ -1986,7 +2026,7 @@ struct sqlite3_mem_methods {
** [extended result codes] feature of SQLite. ^The extended result
** codes are disabled by default for historical compatibility.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
/*
** CAPI3REF: Last Insert Rowid
@@ -2000,20 +2040,30 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff)
** the table has a column of type [INTEGER PRIMARY KEY] then that column
** is another alias for the rowid.
**
-** ^The sqlite3_last_insert_rowid(D) interface returns the [rowid] of the
-** most recent successful [INSERT] into a rowid table or [virtual table]
-** on database connection D.
-** ^Inserts into [WITHOUT ROWID] tables are not recorded.
-** ^If no successful [INSERT]s into rowid tables
-** have ever occurred on the database connection D,
-** then sqlite3_last_insert_rowid(D) returns zero.
-**
-** ^(If an [INSERT] occurs within a trigger or within a [virtual table]
-** method, then this routine will return the [rowid] of the inserted
-** row as long as the trigger or virtual table method is running.
-** But once the trigger or virtual table method ends, the value returned
-** by this routine reverts to what it was before the trigger or virtual
-** table method began.)^
+** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of
+** the most recent successful [INSERT] into a rowid table or [virtual table]
+** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not
+** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred
+** on the database connection D, then sqlite3_last_insert_rowid(D) returns
+** zero.
+**
+** As well as being set automatically as rows are inserted into database
+** tables, the value returned by this function may be set explicitly by
+** [sqlite3_set_last_insert_rowid()]
+**
+** Some virtual table implementations may INSERT rows into rowid tables as
+** part of committing a transaction (e.g. to flush data accumulated in memory
+** to disk). In this case subsequent calls to this function return the rowid
+** associated with these internal INSERT operations, which leads to
+** unintuitive results. Virtual table implementations that do write to rowid
+** tables in this way can avoid this problem by restoring the original
+** rowid value using [sqlite3_set_last_insert_rowid()] before returning
+** control to the user.
+**
+** ^(If an [INSERT] occurs within a trigger then this routine will
+** return the [rowid] of the inserted row as long as the trigger is
+** running. Once the trigger program ends, the value returned
+** by this routine reverts to what it was before the trigger was fired.)^
**
** ^An [INSERT] that fails due to a constraint violation is not a
** successful [INSERT] and does not change the value returned by this
@@ -2038,7 +2088,17 @@ SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff)
** unpredictable and might not equal either the old or the new
** last insert [rowid].
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+
+/*
+** CAPI3REF: Set the Last Insert Rowid value.
+** METHOD: sqlite3
+**
+** The sqlite3_set_last_insert_rowid(D, R) method allows the application to
+** set the value returned by calling sqlite3_last_insert_rowid(D) to R
+** without inserting a row into the database.
+*/
+SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
/*
** CAPI3REF: Count The Number Of Rows Modified
@@ -2091,7 +2151,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
** while [sqlite3_changes()] is running then the value returned
** is unpredictable and not meaningful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
+SQLITE_API int sqlite3_changes(sqlite3*);
/*
** CAPI3REF: Total Number Of Rows Modified
@@ -2115,7 +2175,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
** while [sqlite3_total_changes()] is running then the value
** returned is unpredictable and not meaningful.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
+SQLITE_API int sqlite3_total_changes(sqlite3*);
/*
** CAPI3REF: Interrupt A Long-Running Query
@@ -2155,7 +2215,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
** If the database connection closes while [sqlite3_interrupt()]
** is running then bad things will likely happen.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
+SQLITE_API void sqlite3_interrupt(sqlite3*);
/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2190,8 +2250,8 @@ SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
** The input to [sqlite3_complete16()] must be a zero-terminated
** UTF-16 string in native byte order.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
-SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
+SQLITE_API int sqlite3_complete(const char *sql);
+SQLITE_API int sqlite3_complete16(const void *sql);
/*
** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
@@ -2252,7 +2312,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
** A busy handler must not close the database connection
** or [prepared statement] that invoked the busy handler.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
+SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*);
/*
** CAPI3REF: Set A Busy Timeout
@@ -2275,7 +2335,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*,int(*)(void*,int),vo
**
** See also: [PRAGMA busy_timeout]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
/*
** CAPI3REF: Convenience Routines For Running Queries
@@ -2350,7 +2410,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
** reflected in subsequent calls to [sqlite3_errcode()] or
** [sqlite3_errmsg()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
+SQLITE_API int sqlite3_get_table(
sqlite3 *db, /* An open database */
const char *zSql, /* SQL to be evaluated */
char ***pazResult, /* Results of the query */
@@ -2358,7 +2418,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
int *pnColumn, /* Number of result columns written here */
char **pzErrmsg /* Error msg written here */
);
-SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
+SQLITE_API void sqlite3_free_table(char **result);
/*
** CAPI3REF: Formatted String Printing Functions
@@ -2464,10 +2524,10 @@ SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
*/
-SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
-SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *sqlite3_mprintf(const char*,...);
+SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
/*
** CAPI3REF: Memory Allocation Subsystem
@@ -2557,12 +2617,12 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list
** a block of memory after it has been released using
** [sqlite3_free()] or [sqlite3_realloc()].
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
-SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
-SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
-SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
-SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
+SQLITE_API void *sqlite3_malloc(int);
+SQLITE_API void *sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *sqlite3_realloc(void*, int);
+SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 sqlite3_msize(void*);
/*
** CAPI3REF: Memory Allocator Statistics
@@ -2587,8 +2647,8 @@ SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
** by [sqlite3_memory_highwater(1)] is the high-water mark
** prior to the reset.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
/*
** CAPI3REF: Pseudo-Random Number Generator
@@ -2611,7 +2671,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
+SQLITE_API void sqlite3_randomness(int N, void *P);
/*
** CAPI3REF: Compile-Time Authorization Callbacks
@@ -2694,7 +2754,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
** as stated in the previous paragraph, sqlite3_step() invokes
** sqlite3_prepare_v2() to reprepare a statement after a schema change.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
+SQLITE_API int sqlite3_set_authorizer(
sqlite3*,
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pUserData
@@ -2802,9 +2862,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
** sqlite3_profile() function is considered experimental and is
** subject to change in future versions of SQLite.
*/
-SQLITE_API SQLITE_DEPRECATED void *SQLITE_STDCALL sqlite3_trace(sqlite3*,
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_DEPRECATED void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
+SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
@@ -2893,7 +2953,7 @@ SQLITE_API SQLITE_DEPRECATED void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
** are deprecated.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_trace_v2(
+SQLITE_API int sqlite3_trace_v2(
sqlite3*,
unsigned uMask,
int(*xCallback)(unsigned,void*,void*,void*),
@@ -2932,7 +2992,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_trace_v2(
** database connections for the meaning of "modify" in this paragraph.
**
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
/*
** CAPI3REF: Opening A New Database Connection
@@ -3161,15 +3221,15 @@ SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(vo
**
** See also: [sqlite3_temp_directory]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_open(
+SQLITE_API int sqlite3_open(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_open16(
+SQLITE_API int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb /* OUT: SQLite db handle */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
+SQLITE_API int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
@@ -3215,9 +3275,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
** VFS method, then the behavior of this routine is undefined and probably
** undesirable.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+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);
/*
@@ -3261,11 +3321,11 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const cha
** was invoked incorrectly by the application. In that case, the
** error code and message may or may not be set.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
-SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
+SQLITE_API int sqlite3_errcode(sqlite3 *db);
+SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *sqlite3_errstr(int);
/*
** CAPI3REF: Prepared Statement Object
@@ -3333,7 +3393,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
**
** New run-time limit categories may be added in future releases.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
/*
** CAPI3REF: Run-Time Limit Categories
@@ -3364,9 +3424,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
**
** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt>
** <dd>The maximum number of instructions in a virtual machine program
-** used to implement an SQL statement. This limit is not currently
-** enforced, though that might be added in some future release of
-** SQLite.</dd>)^
+** used to implement an SQL statement. If [sqlite3_prepare_v2()] or
+** the equivalent tries to allocate space for more than this many opcodes
+** in a single prepared statement, an SQLITE_NOMEM error is returned.</dd>)^
**
** [[SQLITE_LIMIT_FUNCTION_ARG]] ^(<dt>SQLITE_LIMIT_FUNCTION_ARG</dt>
** <dd>The maximum number of arguments on a function.</dd>)^
@@ -3404,6 +3464,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
#define SQLITE_LIMIT_TRIGGER_DEPTH 10
#define SQLITE_LIMIT_WORKER_THREADS 11
+
/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
@@ -3485,28 +3546,28 @@ SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
** </li>
** </ol>
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
+SQLITE_API int sqlite3_prepare(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
+SQLITE_API int sqlite3_prepare_v2(
sqlite3 *db, /* Database handle */
const char *zSql, /* SQL statement, UTF-8 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const char **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
+SQLITE_API int sqlite3_prepare16(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
sqlite3_stmt **ppStmt, /* OUT: Statement handle */
const void **pzTail /* OUT: Pointer to unused portion of zSql */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
+SQLITE_API int sqlite3_prepare16_v2(
sqlite3 *db, /* Database handle */
const void *zSql, /* SQL statement, UTF-16 encoded */
int nByte, /* Maximum length of zSql in bytes. */
@@ -3545,8 +3606,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
** is obtained from [sqlite3_malloc()] and must be free by the application
** by passing it to [sqlite3_free()].
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
-SQLITE_API char *SQLITE_STDCALL sqlite3_expanded_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
@@ -3577,8 +3638,12 @@ SQLITE_API char *SQLITE_STDCALL sqlite3_expanded_sql(sqlite3_stmt *pStmt);
** sqlite3_stmt_readonly() to return true since, while those statements
** change the configuration of a database connection, they do not make
** changes to the content of the database files on disk.
+** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since
+** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
+** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
+** sqlite3_stmt_readonly() returns false for those commands.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Determine If A Prepared Statement Has Been Reset
@@ -3599,7 +3664,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
** for example, in diagnostic routines to search for prepared
** statements that are holding a transaction open.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
/*
** CAPI3REF: Dynamically Typed Value Object
@@ -3763,20 +3828,20 @@ typedef struct sqlite3_context sqlite3_context;
** See also: [sqlite3_bind_parameter_count()],
** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
+SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
/*
** CAPI3REF: Number Of SQL Parameters
@@ -3797,7 +3862,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite
** [sqlite3_bind_parameter_name()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
/*
** CAPI3REF: Name Of A Host Parameter
@@ -3825,7 +3890,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_index()].
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
/*
** CAPI3REF: Index Of A Parameter With A Given Name
@@ -3842,7 +3907,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*,
** [sqlite3_bind_parameter_count()], and
** [sqlite3_bind_parameter_name()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
/*
** CAPI3REF: Reset All Bindings On A Prepared Statement
@@ -3852,19 +3917,23 @@ SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const
** the [sqlite3_bind_blob | bindings] on a [prepared statement].
** ^Use this routine to reset all host parameters to NULL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
/*
** CAPI3REF: Number Of Columns In A Result Set
** METHOD: sqlite3_stmt
**
** ^Return the number of columns in the result set returned by the
-** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
-** statement that does not return data (for example an [UPDATE]).
+** [prepared statement]. ^If this routine returns 0, that means the
+** [prepared statement] returns no data (for example an [UPDATE]).
+** ^However, just because this routine returns a positive number does not
+** mean that one or more rows of data will be returned. ^A SELECT statement
+** will always have a positive sqlite3_column_count() but depending on the
+** WHERE clause constraints and the table content, it might return no rows.
**
** See also: [sqlite3_data_count()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Column Names In A Result Set
@@ -3893,8 +3962,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
** then the name of the column is unspecified and may change from
** one release of SQLite to the next.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
/*
** CAPI3REF: Source Of Data In A Query Result
@@ -3942,12 +4011,12 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N
** for the same [prepared statement] and result column
** at the same time then the results are undefined.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
/*
** CAPI3REF: Declared Datatype Of A Query Result
@@ -3979,8 +4048,8 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*
** is associated with individual values, not with the containers
** used to hold those values.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
/*
** CAPI3REF: Evaluate An SQL Statement
@@ -4041,7 +4110,8 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,in
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began
+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
+** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
** break because any application that ever receives an SQLITE_MISUSE error
@@ -4060,7 +4130,7 @@ SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,in
** then the more specific [error codes] are returned directly
** by sqlite3_step(). The use of the "v2" interface is recommended.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
+SQLITE_API int sqlite3_step(sqlite3_stmt*);
/*
** CAPI3REF: Number of columns in a result set
@@ -4081,7 +4151,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
**
** See also: [sqlite3_column_count()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Fundamental Datatypes
@@ -4271,16 +4341,16 @@ SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
** pointer. Subsequent calls to [sqlite3_errcode()] will return
** [SQLITE_NOMEM].)^
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
/*
** CAPI3REF: Destroy A Prepared Statement Object
@@ -4308,7 +4378,7 @@ SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int
** statement after it has been finalized can result in undefined and
** undesirable behavior such as segfaults and heap corruption.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Reset A Prepared Statement Object
@@ -4335,7 +4405,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
** ^The [sqlite3_reset(S)] interface does not change the values
** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
+SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
/*
** CAPI3REF: Create Or Redefine SQL Functions
@@ -4435,7 +4505,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
** close the database connection nor finalize or reset the prepared
** statement in which the function is running.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
+SQLITE_API int sqlite3_create_function(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4445,7 +4515,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
+SQLITE_API int sqlite3_create_function16(
sqlite3 *db,
const void *zFunctionName,
int nArg,
@@ -4455,7 +4525,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
+SQLITE_API int sqlite3_create_function_v2(
sqlite3 *db,
const char *zFunctionName,
int nArg,
@@ -4501,12 +4571,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
** these functions, we will not explain what they do.
*/
#ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
void*,sqlite3_int64);
#endif
@@ -4556,18 +4626,18 @@ SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(voi
** These routines must be called from the same thread as
** the SQL function that supplied the [sqlite3_value*] parameters.
*/
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
-SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API double sqlite3_value_double(sqlite3_value*);
+SQLITE_API int sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
+SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int sqlite3_value_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -4583,7 +4653,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
** from the result of one [application-defined SQL function] into the
** input of another.
*/
-SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
+SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
/*
** CAPI3REF: Copy And Free SQL Values
@@ -4599,8 +4669,8 @@ SQLITE_API unsigned int SQLITE_STDCALL sqlite3_value_subtype(sqlite3_value*);
** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
** then sqlite3_value_free(V) is a harmless no-op.
*/
-SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
-SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
+SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*);
+SQLITE_API void sqlite3_value_free(sqlite3_value*);
/*
** CAPI3REF: Obtain Aggregate Function Context
@@ -4645,7 +4715,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
** This routine must be called from the same thread in which
** the aggregate SQL function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** CAPI3REF: User Data For Functions
@@ -4660,7 +4730,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int
** This routine must be called from the same thread in which
** the application-defined function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *sqlite3_user_data(sqlite3_context*);
/*
** CAPI3REF: Database Connection For Functions
@@ -4672,7 +4742,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
** and [sqlite3_create_function16()] routines that originally
** registered the application defined function.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
/*
** CAPI3REF: Function Auxiliary Data
@@ -4726,8 +4796,8 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
** These routines must be called from the same thread in which
** the SQL function is running.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
/*
@@ -4863,27 +4933,27 @@ typedef void (*sqlite3_destructor_type)(void*);
** than the one containing the application-defined function that received
** the [sqlite3_context] pointer, the results are undefined.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
+SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*,
sqlite3_uint64,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void sqlite3_result_null(sqlite3_context*);
+SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
void(*)(void*), unsigned char encoding);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
-SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
+SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
/*
@@ -4898,7 +4968,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_result_zeroblob64(sqlite3_context*, sqlite
** The number of subtype bytes preserved by SQLite might increase
** in future releases of SQLite.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context*,unsigned int);
+SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int);
/*
** CAPI3REF: Define New Collating Sequences
@@ -4980,14 +5050,14 @@ SQLITE_API void SQLITE_STDCALL sqlite3_result_subtype(sqlite3_context*,unsigned
**
** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
+SQLITE_API int sqlite3_create_collation(
sqlite3*,
const char *zName,
int eTextRep,
void *pArg,
int(*xCompare)(void*,int,const void*,int,const void*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
+SQLITE_API int sqlite3_create_collation_v2(
sqlite3*,
const char *zName,
int eTextRep,
@@ -4995,7 +5065,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
int(*xCompare)(void*,int,const void*,int,const void*),
void(*xDestroy)(void*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
+SQLITE_API int sqlite3_create_collation16(
sqlite3*,
const void *zName,
int eTextRep,
@@ -5030,12 +5100,12 @@ SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
** [sqlite3_create_collation_v2()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
+SQLITE_API int sqlite3_collation_needed(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const char*)
);
-SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
+SQLITE_API int sqlite3_collation_needed16(
sqlite3*,
void*,
void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -5049,11 +5119,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_key(
+SQLITE_API int sqlite3_key(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The key */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
+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 */
@@ -5067,11 +5137,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
** The code to implement this API is not available in the public release
** of SQLite.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
+SQLITE_API int sqlite3_rekey(
sqlite3 *db, /* Database to be rekeyed */
const void *pKey, int nKey /* The new key */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
+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 */
@@ -5081,7 +5151,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
** Specify the activation key for a SEE database. Unless
** activated, none of the SEE routines will work.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
+SQLITE_API void sqlite3_activate_see(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5091,7 +5161,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
** Specify the activation key for a CEROD database. Unless
** activated, none of the CEROD routines will work.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
+SQLITE_API void sqlite3_activate_cerod(
const char *zPassPhrase /* Activation phrase */
);
#endif
@@ -5113,7 +5183,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
+SQLITE_API int sqlite3_sleep(int);
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -5232,7 +5302,7 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
** connection while this routine is running, then the return value
** is undefined.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int sqlite3_get_autocommit(sqlite3*);
/*
** CAPI3REF: Find The Database Handle Of A Prepared Statement
@@ -5245,7 +5315,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
** create the statement in the first place.
*/
-SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
/*
** CAPI3REF: Return The Filename For A Database Connection
@@ -5262,7 +5332,7 @@ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
** will be an absolute pathname, even if the filename used
** to open the database originally was a URI or relative pathname.
*/
-SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Determine if a database is read-only
@@ -5272,7 +5342,7 @@ SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const cha
** of connection D is read-only, 0 if it is read/write, or -1 if N is not
** the name of a database on connection D.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
/*
** CAPI3REF: Find the next prepared statement
@@ -5288,7 +5358,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbNa
** [sqlite3_next_stmt(D,S)] must refer to an open database
** connection and in particular must not be a NULL pointer.
*/
-SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
/*
** CAPI3REF: Commit And Rollback Notification Callbacks
@@ -5337,8 +5407,8 @@ SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_
**
** See also the [sqlite3_update_hook()] interface.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Data Change Notification Callbacks
@@ -5368,7 +5438,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
** ^The update hook is not invoked when [WITHOUT ROWID] tables are modified.
**
** ^In the current implementation, the update hook
-** is not invoked when duplication rows are deleted because of an
+** is not invoked when conflicting rows are deleted because of an
** [ON CONFLICT | ON CONFLICT REPLACE] clause. ^Nor is the update hook
** invoked when rows are deleted using the [truncate optimization].
** The exceptions defined in this paragraph might change in a future
@@ -5389,7 +5459,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *),
** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()],
** and [sqlite3_preupdate_hook()] interfaces.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
+SQLITE_API void *sqlite3_update_hook(
sqlite3*,
void(*)(void *,int ,char const *,char const *,sqlite3_int64),
void*
@@ -5404,7 +5474,8 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
** and disabled if the argument is false.)^
**
** ^Cache sharing is enabled and disabled for an entire process.
-** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
+** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
+** In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** ^(The cache sharing mode set by this interface effects all subsequent
@@ -5429,7 +5500,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
**
** See Also: [SQLite Shared-Cache Mode]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
+SQLITE_API int sqlite3_enable_shared_cache(int);
/*
** CAPI3REF: Attempt To Free Heap Memory
@@ -5445,7 +5516,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
**
** See also: [sqlite3_db_release_memory()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
+SQLITE_API int sqlite3_release_memory(int);
/*
** CAPI3REF: Free Memory Used By A Database Connection
@@ -5459,7 +5530,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
**
** See also: [sqlite3_release_memory()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int sqlite3_db_release_memory(sqlite3*);
/*
** CAPI3REF: Impose A Limit On Heap Size
@@ -5498,7 +5569,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
** from the heap.
** </ul>)^
**
-** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
+** 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
@@ -5511,7 +5583,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
** The circumstances under which SQLite will enforce the soft heap limit may
** changes in future releases of SQLite.
*/
-SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
/*
** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -5522,7 +5594,7 @@ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64
** only. All new applications should use the
** [sqlite3_soft_heap_limit64()] interface rather than this one.
*/
-SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
+SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
/*
@@ -5592,7 +5664,7 @@ SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
** parsed, if that has not already been done, and returns an error if
** any errors are encountered while loading the schema.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
+SQLITE_API int sqlite3_table_column_metadata(
sqlite3 *db, /* Connection handle */
const char *zDbName, /* Database name or NULL */
const char *zTableName, /* Table name */
@@ -5648,7 +5720,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
**
** See also the [load_extension() SQL function].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
+SQLITE_API int sqlite3_load_extension(
sqlite3 *db, /* Load the extension into this database connection */
const char *zFile, /* Name of the shared library containing extension */
const char *zProc, /* Entry point. Derived from zFile if 0 */
@@ -5680,7 +5752,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
** remains disabled. This will prevent SQL injections from giving attackers
** access to extension loading capabilities.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
/*
** CAPI3REF: Automatically Load Statically Linked Extensions
@@ -5718,7 +5790,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int ono
** See also: [sqlite3_reset_auto_extension()]
** and [sqlite3_cancel_auto_extension()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Cancel Automatic Extension Loading
@@ -5730,7 +5802,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void(*xEntryPoint)(void));
** unregistered and it returns 0 if X was not on the list of initialization
** routines.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
+SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
/*
** CAPI3REF: Reset Automatic Extension Loading
@@ -5738,7 +5810,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void(*xEntryPoint)(v
** ^This interface disables all automatic extensions previously
** registered using [sqlite3_auto_extension()].
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
+SQLITE_API void sqlite3_reset_auto_extension(void);
/*
** The interface to the virtual-table mechanism is currently considered
@@ -5892,13 +5964,15 @@ struct sqlite3_module {
** the xUpdate method are automatically rolled back by SQLite.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
-** structure for SQLite version 3.8.2. If a virtual table extension is
+** structure for SQLite [version 3.8.2] ([dateof:3.8.2]).
+** 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
** 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. It may therefore only be used if
+** was added for [version 3.9.0] ([dateof:3.9.0]).
+** It may therefore only be used if
** sqlite3_libversion_number() returns a value greater than or equal to
** 3009000.
*/
@@ -5983,13 +6057,13 @@ struct sqlite3_index_info {
** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
+SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
void *pClientData /* Client data for xCreate/xConnect */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
+SQLITE_API int sqlite3_create_module_v2(
sqlite3 *db, /* SQLite connection to register module with */
const char *zName, /* Name of the module */
const sqlite3_module *p, /* Methods for the module */
@@ -6052,7 +6126,7 @@ struct sqlite3_vtab_cursor {
** to declare the format (the names and datatypes of the columns) of
** the virtual tables they implement.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
/*
** CAPI3REF: Overload A Function For A Virtual Table
@@ -6071,7 +6145,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
** purpose is to be a placeholder function that can be overloaded
** by a [virtual table].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
/*
** The interface to the virtual-table mechanism defined above (back up
@@ -6146,6 +6220,12 @@ typedef struct sqlite3_blob sqlite3_blob;
** [database connection] error code and message accessible via
** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions.
**
+** A BLOB referenced by sqlite3_blob_open() may be read using the
+** [sqlite3_blob_read()] interface and modified by using
+** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a
+** different row of the same table using the [sqlite3_blob_reopen()]
+** interface. However, the column, table, or database of a [BLOB handle]
+** cannot be changed after the [BLOB handle] is opened.
**
** ^(If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -6169,8 +6249,12 @@ typedef struct sqlite3_blob sqlite3_blob;
**
** To avoid a resource leak, every open [BLOB handle] should eventually
** be released by a call to [sqlite3_blob_close()].
+**
+** See also: [sqlite3_blob_close()],
+** [sqlite3_blob_reopen()], [sqlite3_blob_read()],
+** [sqlite3_blob_bytes()], [sqlite3_blob_write()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
+SQLITE_API int sqlite3_blob_open(
sqlite3*,
const char *zDb,
const char *zTable,
@@ -6184,11 +6268,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
** CAPI3REF: Move a BLOB Handle to a New Row
** METHOD: sqlite3_blob
**
-** ^This function is used to move an existing blob handle so that it points
+** ^This function is used to move an existing [BLOB handle] so that it points
** to a different row of the same database table. ^The new row is identified
** by the rowid value passed as the second argument. Only the row can be
** changed. ^The database, table and column on which the blob handle is open
-** remain the same. Moving an existing blob handle to a new row can be
+** remain the same. Moving an existing [BLOB handle] to a new row is
** faster than closing the existing handle and opening a new one.
**
** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] -
@@ -6203,7 +6287,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
**
** ^This function sets the database handle error code and message.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
/*
** CAPI3REF: Close A BLOB Handle
@@ -6226,7 +6310,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64)
** is passed a valid open blob handle, the values returned by the
** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB
@@ -6242,7 +6326,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
** been closed by [sqlite3_blob_close()]. Passing any other pointer in
** to this routine results in undefined and probably undesirable behavior.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
+SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
/*
** CAPI3REF: Read Data From A BLOB Incrementally
@@ -6271,7 +6355,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
**
** See also: [sqlite3_blob_write()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
/*
** CAPI3REF: Write Data Into A BLOB Incrementally
@@ -6313,7 +6397,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N,
**
** See also: [sqlite3_blob_read()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
/*
** CAPI3REF: Virtual File System Objects
@@ -6344,9 +6428,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z,
** ^(If the default VFS is unregistered, another VFS is chosen as
** the default. The choice for the new VFS is arbitrary.)^
*/
-SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
/*
** CAPI3REF: Mutexes
@@ -6462,11 +6546,11 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
+SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
/*
** CAPI3REF: Mutex Methods Object
@@ -6576,8 +6660,8 @@ struct sqlite3_mutex_methods {
** interface should also return 1 when given a NULL pointer.
*/
#ifndef NDEBUG
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#endif
/*
@@ -6596,7 +6680,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
-#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
+#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
@@ -6617,7 +6701,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
** ^If the [threading mode] is Single-thread or Multi-thread then this
** routine returns a NULL pointer.
*/
-SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
/*
** CAPI3REF: Low-Level Control Of Database Files
@@ -6652,7 +6736,7 @@ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
**
** See also: [SQLITE_FCNTL_LOCKSTATE]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
/*
** CAPI3REF: Testing Interface
@@ -6671,7 +6755,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName
** Unlike most of the SQLite API, this function is not guaranteed to
** operate consistently from one release to the next.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
+SQLITE_API int sqlite3_test_control(int op, ...);
/*
** CAPI3REF: Testing Interface Operation Codes
@@ -6700,6 +6784,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
+#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_BYTEORDER 22
@@ -6734,8 +6819,8 @@ SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
**
** See also: [sqlite3_db_status()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int sqlite3_status64(
int op,
sqlite3_int64 *pCurrent,
sqlite3_int64 *pHighwater,
@@ -6860,7 +6945,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_status64(
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
@@ -7003,7 +7088,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int
**
** See also: [sqlite3_status()] and [sqlite3_db_status()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
/*
** CAPI3REF: Status Parameters for prepared statements
@@ -7472,16 +7557,16 @@ typedef struct sqlite3_backup sqlite3_backup;
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
-SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
+SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
sqlite3 *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
@@ -7598,7 +7683,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
** the special "DROP TABLE/INDEX" case, the extended error code is just
** SQLITE_LOCKED.)^
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
+SQLITE_API int sqlite3_unlock_notify(
sqlite3 *pBlocked, /* Waiting connection */
void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */
void *pNotifyArg /* Argument to pass to xNotify */
@@ -7613,8 +7698,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
** strings in a case-independent fashion, using the same definition of "case
** independence" that SQLite uses internally when comparing identifiers.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
-SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
+SQLITE_API int sqlite3_stricmp(const char *, const char *);
+SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
/*
** CAPI3REF: String Globbing
@@ -7631,7 +7716,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
**
** See also: [sqlite3_strlike()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
+SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
/*
** CAPI3REF: String LIKE Matching
@@ -7654,7 +7739,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zSt
**
** See also: [sqlite3_strglob()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
+SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc);
/*
** CAPI3REF: Error Logging Interface
@@ -7677,7 +7762,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_strlike(const char *zGlob, const char *zSt
** a few hundred characters, it will be truncated to the length of the
** buffer.
*/
-SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
/*
** CAPI3REF: Write-Ahead Log Commit Hook
@@ -7713,7 +7798,7 @@ SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...)
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
** overwrite any prior [sqlite3_wal_hook()] settings.
*/
-SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
+SQLITE_API void *sqlite3_wal_hook(
sqlite3*,
int(*)(void *,sqlite3*,const char*,int),
void*
@@ -7748,7 +7833,7 @@ SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
** is only necessary if the default setting is found to be suboptimal
** for a particular application.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
/*
** CAPI3REF: Checkpoint a database
@@ -7770,7 +7855,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
** start a callback but which do not need the full power (and corresponding
** complication) of [sqlite3_wal_checkpoint_v2()].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
/*
** CAPI3REF: Checkpoint a database
@@ -7864,7 +7949,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zD
** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
** from SQL.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
+SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
@@ -7900,7 +7985,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].) Further options
** may be added in the future.
*/
-SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
/*
** CAPI3REF: Virtual Table Configuration Options
@@ -7953,7 +8038,7 @@ SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
** of the SQL statement that triggered the call to the [xUpdate] method of the
** [virtual table].
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
** CAPI3REF: Conflict resolution modes
@@ -8058,7 +8143,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+SQLITE_API int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
@@ -8074,7 +8159,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
** This API is only available if the library is built with pre-processor
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
-SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
+SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
/*
** CAPI3REF: Flush caches to disk mid-transaction
@@ -8106,7 +8191,7 @@ SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
** ^This function does not set the database handle error code or message
** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
+SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
/*
** CAPI3REF: The pre-update hook.
@@ -8116,7 +8201,7 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
**
** ^The [sqlite3_preupdate_hook()] interface registers a callback function
** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation
-** on a [rowid table].
+** on a database table.
** ^At most one preupdate hook may be registered at a time on a single
** [database connection]; each call to [sqlite3_preupdate_hook()] overrides
** the previous setting.
@@ -8125,9 +8210,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as
** the first parameter to callbacks.
**
-** ^The preupdate hook only fires for changes to [rowid tables]; the preupdate
-** hook is not invoked for changes to [virtual tables] or [WITHOUT ROWID]
-** tables.
+** ^The preupdate hook only fires for changes to real database tables; the
+** preupdate hook is not invoked for changes to [virtual tables] or to
+** system tables like sqlite_master or sqlite_stat1.
**
** ^The second parameter to the preupdate callback is a pointer to
** the [database connection] that registered the preupdate hook.
@@ -8141,12 +8226,16 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
** databases.)^
** ^The fifth parameter to the preupdate callback is the name of the
** table that is being modified.
-** ^The sixth parameter to the preupdate callback is the initial [rowid] of the
-** row being changes for SQLITE_UPDATE and SQLITE_DELETE changes and is
-** undefined for SQLITE_INSERT changes.
-** ^The seventh parameter to the preupdate callback is the final [rowid] of
-** the row being changed for SQLITE_UPDATE and SQLITE_INSERT changes and is
-** undefined for SQLITE_DELETE changes.
+**
+** For an UPDATE or DELETE operation on a [rowid table], the sixth
+** parameter passed to the preupdate callback is the initial [rowid] of the
+** row being modified or deleted. For an INSERT operation on a rowid table,
+** or any operation on a WITHOUT ROWID table, the value of the sixth
+** parameter is undefined. For an INSERT or UPDATE on a rowid table the
+** seventh parameter is the final rowid value of the row being inserted
+** or updated. The value of the seventh parameter passed to the callback
+** function is not defined for operations on WITHOUT ROWID tables, or for
+** INSERT operations on rowid tables.
**
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
@@ -8186,7 +8275,8 @@ SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*);
**
** See also: [sqlite3_update_hook()]
*/
-SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_preupdate_hook(
+#if defined(SQLITE_ENABLE_PREUPDATE_HOOK)
+SQLITE_API void *sqlite3_preupdate_hook(
sqlite3 *db,
void(*xPreUpdate)(
void *pCtx, /* Copy of third arg to preupdate_hook() */
@@ -8199,10 +8289,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_preupdate_hook(
),
void*
);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_count(sqlite3 *);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_depth(sqlite3 *);
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **);
+SQLITE_API int sqlite3_preupdate_count(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_depth(sqlite3 *);
+SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **);
+#endif
/*
** CAPI3REF: Low-level system error code
@@ -8214,11 +8305,11 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_preupdate_new(sqlite3
** called to get back the underlying "errno" that caused the problem, such
** as ENOSPC, EAUTH, EISDIR, and so forth.
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*);
+SQLITE_API int sqlite3_system_errno(sqlite3*);
/*
** CAPI3REF: Database Snapshot
-** KEYWORDS: {snapshot}
+** KEYWORDS: {snapshot} {sqlite3_snapshot}
** EXPERIMENTAL
**
** An instance of the snapshot object records the state of a [WAL mode]
@@ -8242,7 +8333,9 @@ SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*);
** to an historical snapshot (if possible). The destructor for
** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
*/
-typedef struct sqlite3_snapshot sqlite3_snapshot;
+typedef struct sqlite3_snapshot {
+ unsigned char hidden[48];
+} sqlite3_snapshot;
/*
** CAPI3REF: Record A Database Snapshot
@@ -8253,9 +8346,32 @@ typedef struct sqlite3_snapshot sqlite3_snapshot;
** schema S in database connection D. ^On success, the
** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly
** created [sqlite3_snapshot] object into *P and returns SQLITE_OK.
-** ^If schema S of [database connection] D is not a [WAL mode] database
-** that is in a read transaction, then [sqlite3_snapshot_get(D,S,P)]
-** leaves the *P value unchanged and returns an appropriate [error code].
+** If there is not already a read-transaction open on schema S when
+** this function is called, one is opened automatically.
+**
+** The following must be true for this function to succeed. If any of
+** the following statements are false when sqlite3_snapshot_get() is
+** called, SQLITE_ERROR is returned. The final value of *P is undefined
+** in this case.
+**
+** <ul>
+** <li> The database handle must be in [autocommit mode].
+**
+** <li> Schema S of [database connection] D must be a [WAL mode] database.
+**
+** <li> There must not be a write transaction open on schema S of database
+** connection D.
+**
+** <li> One or more transactions must have been written to the current wal
+** file since it was created on disk (by any connection). This means
+** that a snapshot cannot be taken on a wal mode database with no wal
+** file immediately after it is first opened. At least one transaction
+** must be written to it first.
+** </ul>
+**
+** This function may also return SQLITE_NOMEM. If it is called with the
+** database handle in autocommit mode but fails for some other reason,
+** whether or not a read transaction is opened on schema S is undefined.
**
** The [sqlite3_snapshot] object returned from a successful call to
** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()]
@@ -8264,7 +8380,7 @@ typedef struct sqlite3_snapshot sqlite3_snapshot;
** The [sqlite3_snapshot_get()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot **ppSnapshot
@@ -8302,7 +8418,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_get(
** The [sqlite3_snapshot_open()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
sqlite3 *db,
const char *zSchema,
sqlite3_snapshot *pSnapshot
@@ -8319,7 +8435,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_open(
** The [sqlite3_snapshot_free()] interface is only available when the
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
*/
-SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3_snapshot*);
+SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
/*
** CAPI3REF: Compare the ages of two snapshot handles.
@@ -8343,12 +8459,34 @@ SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_snapshot_free(sqlite3
** snapshot than P2, zero if the two handles refer to the same database
** snapshot, and a positive value if P1 is a newer snapshot than P2.
*/
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_snapshot_cmp(
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
sqlite3_snapshot *p1,
sqlite3_snapshot *p2
);
/*
+** CAPI3REF: Recover snapshots from a wal file
+** EXPERIMENTAL
+**
+** If all connections disconnect from a database file but do not perform
+** a checkpoint, the existing wal file is opened along with the database
+** file the next time the database is opened. At this point it is only
+** possible to successfully call sqlite3_snapshot_open() to open the most
+** recent snapshot of the database (the one at the head of the wal file),
+** even though the wal file may contain other valid snapshots for which
+** clients have sqlite3_snapshot handles.
+**
+** This function attempts to scan the wal file associated with database zDb
+** of database handle db and make all valid snapshots available to
+** sqlite3_snapshot_open(). It is an error if there is already a read
+** transaction open on the database, or if the database is not a wal mode
+** database.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
+
+/*
** Undo the hack that converts floating point types to integer for
** builds on processors without floating point support.
*/
@@ -8401,7 +8539,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
+SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
@@ -8427,7 +8565,7 @@ struct sqlite3_rtree_geometry {
**
** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
*/
-SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
+SQLITE_API int sqlite3_rtree_query_callback(
sqlite3 *db,
const char *zQueryFunc,
int (*xQueryFunc)(sqlite3_rtree_query_info*),
@@ -8533,7 +8671,7 @@ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
** attached database. It is not an error if database zDb is not attached
** to the database when the session object is created.
*/
-int sqlite3session_create(
+SQLITE_API int sqlite3session_create(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of db (e.g. "main") */
sqlite3_session **ppSession /* OUT: New session object */
@@ -8551,7 +8689,7 @@ int sqlite3session_create(
** are attached is closed. Refer to the documentation for
** [sqlite3session_create()] for details.
*/
-void sqlite3session_delete(sqlite3_session *pSession);
+SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
/*
@@ -8571,7 +8709,7 @@ void sqlite3session_delete(sqlite3_session *pSession);
** The return value indicates the final state of the session object: 0 if
** the session is disabled, or 1 if it is enabled.
*/
-int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
+SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
/*
** CAPI3REF: Set Or Clear the Indirect Change Flag
@@ -8600,7 +8738,7 @@ int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
** The return value indicates the final state of the indirect flag: 0 if
** it is clear, or 1 if it is set.
*/
-int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
+SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
/*
** CAPI3REF: Attach A Table To A Session Object
@@ -8630,7 +8768,7 @@ int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
** SQLITE_OK is returned if the call completes without error. Or, if an error
** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
*/
-int sqlite3session_attach(
+SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
const char *zTab /* Table name */
);
@@ -8639,12 +8777,12 @@ int sqlite3session_attach(
** CAPI3REF: Set a table filter on a Session Object.
**
** The second argument (xFilter) is the "filter callback". For changes to rows
-** in tables that are not attached to the Session oject, the filter is called
+** 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
** attached, xFilter will not be called again.
*/
-void sqlite3session_table_filter(
+SQLITE_API void sqlite3session_table_filter(
sqlite3_session *pSession, /* Session object */
int(*xFilter)(
void *pCtx, /* Copy of third arg to _filter_table() */
@@ -8757,7 +8895,7 @@ void sqlite3session_table_filter(
** another field of the same row is updated while the session is enabled, the
** resulting changeset will contain an UPDATE change that updates both fields.
*/
-int sqlite3session_changeset(
+SQLITE_API int sqlite3session_changeset(
sqlite3_session *pSession, /* Session object */
int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
void **ppChangeset /* OUT: Buffer containing changeset */
@@ -8801,7 +8939,8 @@ int sqlite3session_changeset(
** the from-table, a DELETE record is added to the session object.
**
** <li> For each row (primary key) that exists in both tables, but features
-** different in each, an UPDATE record is added to the session.
+** different non-PK values in each, an UPDATE record is added to the
+** session.
** </ul>
**
** To clarify, if this function is called and then a changeset constructed
@@ -8818,7 +8957,7 @@ int sqlite3session_changeset(
** message. It is the responsibility of the caller to free this buffer using
** sqlite3_free().
*/
-int sqlite3session_diff(
+SQLITE_API int sqlite3session_diff(
sqlite3_session *pSession,
const char *zFromDb,
const char *zTbl,
@@ -8854,7 +8993,7 @@ int sqlite3session_diff(
** a single table are grouped together, tables appear in the order in which
** they were attached to the session object).
*/
-int sqlite3session_patchset(
+SQLITE_API int sqlite3session_patchset(
sqlite3_session *pSession, /* Session object */
int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
void **ppPatchset /* OUT: Buffer containing changeset */
@@ -8875,7 +9014,7 @@ int sqlite3session_patchset(
** guaranteed that a call to sqlite3session_changeset() will return a
** changeset containing zero changes.
*/
-int sqlite3session_isempty(sqlite3_session *pSession);
+SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession);
/*
** CAPI3REF: Create An Iterator To Traverse A Changeset
@@ -8905,12 +9044,12 @@ int sqlite3session_isempty(sqlite3_session *pSession);
** [sqlite3changeset_invert()] functions, all changes within the changeset
** that apply to a single table are grouped together. This means that when
** an application iterates through a changeset using an iterator created by
-** this function, all changes that relate to a single table are visted
+** this function, all changes that relate to a single table are visited
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
** another change for table X.
*/
-int sqlite3changeset_start(
+SQLITE_API int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset /* Pointer to blob containing changeset */
@@ -8939,7 +9078,7 @@ int sqlite3changeset_start(
** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or
** SQLITE_NOMEM.
*/
-int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
+SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Obtain The Current Operation From A Changeset Iterator
@@ -8967,7 +9106,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
** SQLite error code is returned. The values of the output variables may not
** be trusted in this case.
*/
-int sqlite3changeset_op(
+SQLITE_API int sqlite3changeset_op(
sqlite3_changeset_iter *pIter, /* Iterator object */
const char **pzTab, /* OUT: Pointer to table name */
int *pnCol, /* OUT: Number of columns in table */
@@ -8992,7 +9131,7 @@ int sqlite3changeset_op(
** 0x01 if the corresponding column is part of the tables primary key, or
** 0x00 if it is not.
**
-** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
+** If argument pnCol is not NULL, then *pnCol is set to the number of columns
** in the table.
**
** If this function is called when the iterator does not point to a valid
@@ -9000,7 +9139,7 @@ int sqlite3changeset_op(
** SQLITE_OK is returned and the output variables populated as described
** above.
*/
-int sqlite3changeset_pk(
+SQLITE_API int sqlite3changeset_pk(
sqlite3_changeset_iter *pIter, /* Iterator object */
unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
int *pnCol /* OUT: Number of entries in output array */
@@ -9030,7 +9169,7 @@ int sqlite3changeset_pk(
** If some other error occurs (e.g. an OOM condition), an SQLite error code
** is returned and *ppValue is set to NULL.
*/
-int sqlite3changeset_old(
+SQLITE_API int sqlite3changeset_old(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
@@ -9063,7 +9202,7 @@ int sqlite3changeset_old(
** If some other error occurs (e.g. an OOM condition), an SQLite error code
** is returned and *ppValue is set to NULL.
*/
-int sqlite3changeset_new(
+SQLITE_API int sqlite3changeset_new(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
@@ -9090,7 +9229,7 @@ int sqlite3changeset_new(
** If some other error occurs (e.g. an OOM condition), an SQLite error code
** is returned and *ppValue is set to NULL.
*/
-int sqlite3changeset_conflict(
+SQLITE_API int sqlite3changeset_conflict(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: Value from conflicting row */
@@ -9106,7 +9245,7 @@ int sqlite3changeset_conflict(
**
** In all other cases this function returns SQLITE_MISUSE.
*/
-int sqlite3changeset_fk_conflicts(
+SQLITE_API int sqlite3changeset_fk_conflicts(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int *pnOut /* OUT: Number of FK violations */
);
@@ -9139,7 +9278,7 @@ int sqlite3changeset_fk_conflicts(
** // An error has occurred
** }
*/
-int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
+SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
/*
** CAPI3REF: Invert A Changeset
@@ -9169,7 +9308,7 @@ int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
** WARNING/TODO: This function currently assumes that the input is a valid
** changeset. If it is not, the results are undefined.
*/
-int sqlite3changeset_invert(
+SQLITE_API int sqlite3changeset_invert(
int nIn, const void *pIn, /* Input changeset */
int *pnOut, void **ppOut /* OUT: Inverse of input */
);
@@ -9198,7 +9337,7 @@ int sqlite3changeset_invert(
**
** Refer to the sqlite3_changegroup documentation below for details.
*/
-int sqlite3changeset_concat(
+SQLITE_API int sqlite3changeset_concat(
int nA, /* Number of bytes in buffer pA */
void *pA, /* Pointer to buffer containing changeset A */
int nB, /* Number of bytes in buffer pB */
@@ -9209,12 +9348,12 @@ int sqlite3changeset_concat(
/*
-** Changegroup handle.
+** CAPI3REF: Changegroup Handle
*/
typedef struct sqlite3_changegroup sqlite3_changegroup;
/*
-** CAPI3REF: Combine two or more changesets into a single changeset.
+** CAPI3REF: Create A New Changegroup Object
**
** An sqlite3_changegroup object is used to combine two or more changesets
** (or patchsets) into a single changeset (or patchset). A single changegroup
@@ -9251,6 +9390,8 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
+** CAPI3REF: Add A Changeset To A Changegroup
+**
** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
**
@@ -9265,7 +9406,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
** apply to the same row as a change already present in the changegroup if
** the two rows have the same primary key.
**
-** Changes to rows that that do not already appear in the changegroup are
+** Changes to rows that do not already appear in the changegroup are
** simply copied into it. Or, if both the new changeset and the changegroup
** contain changes that apply to a single row, the final contents of the
** changegroup depends on the type of each change, as follows:
@@ -9326,6 +9467,8 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
+** CAPI3REF: Obtain A Composite Changeset From A Changegroup
+**
** Obtain a buffer containing a changeset (or patchset) representing the
** current contents of the changegroup. If the inputs to the changegroup
** were themselves changesets, the output is a changeset. Or, if the
@@ -9354,7 +9497,7 @@ int sqlite3changegroup_output(
);
/*
-** Delete a changegroup object.
+** CAPI3REF: Delete A Changegroup Object
*/
void sqlite3changegroup_delete(sqlite3_changegroup*);
@@ -9382,7 +9525,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** <ul>
** <li> The table has the same name as the name recorded in the
** changeset, and
-** <li> The table has the same number of columns as recorded in the
+** <li> The table has at least as many columns as recorded in the
** changeset, and
** <li> The table has primary key columns in the same position as
** recorded in the changeset.
@@ -9427,7 +9570,11 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** If a row with matching primary key values is found, but one or more of
** the non-primary key fields contains a value different from the original
** row value stored in the changeset, the conflict-handler function is
-** invoked with [SQLITE_CHANGESET_DATA] as the second argument.
+** invoked with [SQLITE_CHANGESET_DATA] as the second argument. If the
+** database table has more columns than are recorded in the changeset,
+** only the values of those non-primary key fields are compared against
+** the current database contents - any trailing database table columns
+** are ignored.
**
** If no row with matching primary key values is found in the database,
** the conflict-handler function is invoked with [SQLITE_CHANGESET_NOTFOUND]
@@ -9442,7 +9589,9 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
**
** <dt>INSERT Changes<dd>
** For each INSERT change, an attempt is made to insert the new row into
-** the database.
+** the database. If the changeset row contains fewer fields than the
+** database table, the trailing fields are populated with their default
+** values.
**
** If the attempt to insert the row fails because the database already
** contains a row with the same primary key values, the conflict handler
@@ -9460,13 +9609,13 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** For each UPDATE change, this function checks if the target database
** contains a row with the same primary key value (or values) as the
** original row values stored in the changeset. If it does, and the values
-** stored in all non-primary key columns also match the values stored in
-** the changeset the row is updated within the target database.
+** stored in all modified non-primary key columns also match the values
+** stored in the changeset the row is updated within the target database.
**
** If a row with matching primary key values is found, but one or more of
-** the non-primary key fields contains a value different from an original
-** row value stored in the changeset, the conflict-handler function is
-** invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
+** the modified non-primary key fields contains a value different from an
+** original row value stored in the changeset, the conflict-handler function
+** is invoked with [SQLITE_CHANGESET_DATA] as the second argument. Since
** UPDATE changes only contain values for non-primary key fields that are
** to be modified, only those fields need to match the original values to
** avoid the SQLITE_CHANGESET_DATA conflict-handler callback.
@@ -9494,7 +9643,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
** rolled back, restoring the target database to its original state, and an
** SQLite error code returned.
*/
-int sqlite3changeset_apply(
+SQLITE_API int sqlite3changeset_apply(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
@@ -9695,7 +9844,7 @@ int sqlite3changeset_apply(
** parameter set to a value less than or equal to zero. Other than this,
** no guarantees are made as to the size of the chunks of data returned.
*/
-int sqlite3changeset_apply_strm(
+SQLITE_API int sqlite3changeset_apply_strm(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
@@ -9710,7 +9859,7 @@ int sqlite3changeset_apply_strm(
),
void *pCtx /* First argument passed to xConflict */
);
-int sqlite3changeset_concat_strm(
+SQLITE_API int sqlite3changeset_concat_strm(
int (*xInputA)(void *pIn, void *pData, int *pnData),
void *pInA,
int (*xInputB)(void *pIn, void *pData, int *pnData),
@@ -9718,23 +9867,23 @@ int sqlite3changeset_concat_strm(
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3changeset_invert_strm(
+SQLITE_API int sqlite3changeset_invert_strm(
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3changeset_start_strm(
+SQLITE_API int sqlite3changeset_start_strm(
sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData),
void *pIn
);
-int sqlite3session_changeset_strm(
+SQLITE_API int sqlite3session_changeset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
);
-int sqlite3session_patchset_strm(
+SQLITE_API int sqlite3session_patchset_strm(
sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData),
void *pOut
diff --git a/libsqlite3/sqlite3ext.h b/libsqlite3/sqlite3ext.h
index ce87e74..f25084a 100644
--- a/libsqlite3/sqlite3ext.h
+++ b/libsqlite3/sqlite3ext.h
@@ -282,6 +282,8 @@ struct sqlite3_api_routines {
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
+ /* Version 3.18.0 and later */
+ void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
};
/*
@@ -540,6 +542,8 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
+/* Version 3.18.0 and later */
+#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)