summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/sqlite
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2018-01-24 16:50:33 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2018-02-07 12:23:18 +0000
commit3d355015917ff2991b7d01deed2a1abfa15020b7 (patch)
treea6e236a3bfaba91ad55c5ca71e22286a2f2ed8af /src/3rdparty/sqlite
parent2cb1db64370989fffeec313c196fe573c479e6aa (diff)
Update bundled sqlite to 3.22.0
[ChangeLog][Third-Party Code] Sqlite was updated to version 3.22.0 Change-Id: I341c1cabfdd43fac45406c00c33c193ef4bcf402 Reviewed-by: Jesus Fernandez <Jesus.Fernandez@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/3rdparty/sqlite')
-rw-r--r--src/3rdparty/sqlite/sqlite3.c13650
-rw-r--r--src/3rdparty/sqlite/sqlite3.h321
2 files changed, 8640 insertions, 5331 deletions
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index ea5ba16b6f..73c69efbd5 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.20.1. By combining all the individual C code files into this
+** version 3.22.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
@@ -209,6 +209,9 @@ static const char * const sqlite3azCompileOpt[] = {
#if SQLITE_ENABLE_ATOMIC_WRITE
"ENABLE_ATOMIC_WRITE",
#endif
+#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ "ENABLE_BATCH_ATOMIC_WRITE",
+#endif
#if SQLITE_ENABLE_CEROD
"ENABLE_CEROD",
#endif
@@ -828,14 +831,6 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
#endif
/*
-** Make sure that rand_s() is available on Windows systems with MSVC 2005
-** or higher.
-*/
-#if defined(_MSC_VER) && _MSC_VER>=1400
-# define _CRT_RAND_S
-#endif
-
-/*
** Include the header file used to customize the compiler options for MSVC.
** This should be done first so that it can successfully prevent spurious
** compiler warnings due to subsequent content in this file and other files
@@ -1144,15 +1139,17 @@ extern "C" {
** 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 a SHA1
-** or SHA3-256 hash of the entire source tree.
+** or SHA3-256 hash of the entire source tree. If the source code has
+** been edited in any way since it was last checked in, then the last
+** four hexadecimal digits of the hash may be modified.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.20.1"
-#define SQLITE_VERSION_NUMBER 3020001
-#define SQLITE_SOURCE_ID "2017-08-24 16:21:36 8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34"
+#define SQLITE_VERSION "3.22.0"
+#define SQLITE_VERSION_NUMBER 3022000
+#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1168,7 +1165,7 @@ extern "C" {
**
** <blockquote><pre>
** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
** </pre></blockquote>)^
**
@@ -1178,9 +1175,11 @@ extern "C" {
** function is provided for use in DLLs since DLL users usually do not have
** direct access to string constants within the DLL. ^The
** sqlite3_libversion_number() function returns an integer equal to
-** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns
+** [SQLITE_VERSION_NUMBER]. ^(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_SOURCE_ID] C preprocessor macro. Except if SQLite is built
+** using an edited copy of [the amalgamation], then the last four characters
+** of the hash might be different from [SQLITE_SOURCE_ID].)^
**
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
@@ -1461,7 +1460,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Not used */
+#define SQLITE_EMPTY 16 /* Internal use only */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
@@ -1495,6 +1494,8 @@ SQLITE_API int sqlite3_exec(
** the most recent error can be obtained using
** [sqlite3_extended_errcode()].
*/
+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
@@ -1523,6 +1524,9 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
+#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
+#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
+#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
@@ -1535,6 +1539,8 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -1609,6 +1615,11 @@ SQLITE_API int sqlite3_exec(
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
** read-only media and cannot be changed even by processes with
** elevated privileges.
+**
+** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
+** filesystem supports doing multiple write operations atomically when those
+** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
+** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -1624,6 +1635,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
+#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
/*
** CAPI3REF: File Locking Levels
@@ -1758,6 +1770,7 @@ struct sqlite3_file {
** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
** <li> [SQLITE_IOCAP_IMMUTABLE]
+** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -2041,6 +2054,40 @@ struct sqlite3_io_methods {
** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for
** this opcode.
+**
+** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
+** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
+** the file descriptor is placed in "batch write mode", which
+** means all subsequent write operations will be deferred and done
+** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems
+** that do not support batch atomic writes will return SQLITE_NOTFOUND.
+** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
+** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
+** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
+** no VFS interface calls on the same [sqlite3_file] file descriptor
+** except for calls to the xWrite method and the xFileControl method
+** with [SQLITE_FCNTL_SIZE_HINT].
+**
+** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
+** operations since the previous successful call to
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
+** This file control returns [SQLITE_OK] if and only if the writes were
+** all performed successfully and have been committed to persistent storage.
+** ^Regardless of whether or not it is successful, this file control takes
+** the file descriptor out of batch write mode so that all subsequent
+** write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
+** operations since the previous successful call to
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
+** ^This file control takes the file descriptor out of batch write mode
+** so that all subsequent write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -2072,6 +2119,9 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_JOURNAL_POINTER 28
#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
#define SQLITE_FCNTL_PDB 30
+#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
+#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
+#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -2109,12 +2159,18 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
+** The VFS interface is sometimes extended by adding new methods onto
+** the end. Each time such an extension occurs, the iVersion field
+** is incremented. The iVersion value started out as 1 in
+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
+** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
+** may be appended to the sqlite3_vfs object and the iVersion value
+** may increase again in future versions of SQLite.
+** Note that the structure
+** of the sqlite3_vfs object changes in the transition from
+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
+** and yet the iVersion field was not modified.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS. mxPathname is the maximum length of
@@ -2642,6 +2698,16 @@ struct sqlite3_mem_methods {
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
+** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
+** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
+** type int, interpreted as a boolean, which if true provides a hint to
+** SQLite that it should avoid large memory allocations if possible.
+** SQLite will run faster if it is free to make large memory allocations,
+** but some application might prefer to run slower in exchange for
+** guarantees about memory fragmentation that are possible if large
+** allocations are avoided. This hint is normally off.
+** </dd>
+**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
@@ -2659,25 +2725,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
-** that SQLite can use for scratch memory. ^(There are three arguments
-** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte
-** aligned memory buffer from which the scratch allocations will be
-** drawn, the size of each scratch allocation (sz),
-** and the maximum number of scratch allocations (N).)^
-** The first argument must be a pointer to an 8-byte aligned buffer
-** of at least sz*N bytes of memory.
-** ^SQLite will not use more than one scratch buffers per thread.
-** ^SQLite will never request a scratch buffer that is more than 6
-** times the database page size.
-** ^If SQLite needs needs additional
-** scratch memory beyond what is provided by this configuration option, then
-** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
-** ^When the application provides any amount of scratch memory using
-** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
-** [sqlite3_malloc|heap allocations].
-** This can help [Robson proof|prevent memory allocation failures] due to heap
-** fragmentation in low-memory embedded systems.
+** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
@@ -2713,8 +2761,7 @@ struct sqlite3_mem_methods {
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
** that SQLite will use for all of its dynamic memory allocation needs
-** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
-** [SQLITE_CONFIG_PAGECACHE].
+** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
@@ -2907,7 +2954,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */
+#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */
#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
@@ -2928,6 +2975,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
+#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -3035,7 +3083,6 @@ struct sqlite3_mem_methods {
** 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>
-**
** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
@@ -3046,7 +3093,16 @@ struct sqlite3_mem_methods {
** the QPSG active, SQLite will always use the same query plan in the field as
** was used during testing in the lab.
** </dd>
-**
+** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
+** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
+** include output for any operations performed by trigger programs. This
+** option is used to set or clear (the default) a flag that governs this
+** behavior. The first parameter passed to this operation is an integer -
+** non-zero to enable output for trigger programs, or zero to disable it.
+** The second parameter is a pointer to an integer into which is written
+** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
+** it is not disabled, 1 if it is.
+** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -3057,7 +3113,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
-
+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1008 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -3918,8 +3975,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** KEYWORDS: SQLITE_TRACE
**
** These constants identify classes of events that can be monitored
-** using the [sqlite3_trace_v2()] tracing logic. The third argument
-** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
+** using the [sqlite3_trace_v2()] tracing logic. The M argument
+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
** the following constants. ^The first argument to the trace callback
** is one of the following constants.
**
@@ -4128,10 +4185,10 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** ^If [URI filename] interpretation is enabled, and the filename argument
** begins with "file:", then the filename is interpreted as a URI. ^URI
** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
-** set in the fourth argument to sqlite3_open_v2(), or if it has
+** set in the third argument to sqlite3_open_v2(), or if it has
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
-** As of SQLite version 3.7.7, URI filename interpretation is turned off
+** URI filename interpretation is turned off
** by default, but future releases of SQLite might enable URI filename
** interpretation by default. See "[URI filenames]" for additional
** information.
@@ -4805,8 +4862,9 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** implementation of [application-defined SQL functions] are protected.
** ^The sqlite3_value object returned by
** [sqlite3_column_value()] is unprotected.
-** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].
+** Unprotected sqlite3_value objects may only be used as arguments
+** to [sqlite3_result_value()], [sqlite3_bind_value()], and
+** [sqlite3_value_dup()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
@@ -5228,7 +5286,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]),
+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
@@ -5764,6 +5822,9 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** datatype of the value
** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+** against a virtual table.
** </table></blockquote>
**
** <b>Details:</b>
@@ -5812,6 +5873,19 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
+** ^Within the [xUpdate] method of a [virtual table], the
+** sqlite3_value_nochange(X) interface returns true if and only if
+** the column corresponding to X is unchanged by the UPDATE operation
+** that the xUpdate method call was invoked to implement and if
+** and the prior [xColumn] method call that was invoked to extracted
+** the value for that column returned without setting a result (probably
+** because it queried [sqlite3_vtab_nochange()] and found that the column
+** was unchanging). ^Within an [xUpdate] method, any value for which
+** sqlite3_value_nochange(X) is true will in all other respects appear
+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
+** than within an [xUpdate] method call for an UPDATE statement, then
+** the return value is arbitrary and meaningless.
+**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@@ -5834,6 +5908,7 @@ SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -7232,15 +7307,20 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
+#define SQLITE_INDEX_CONSTRAINT_GT 4
+#define SQLITE_INDEX_CONSTRAINT_LE 8
+#define SQLITE_INDEX_CONSTRAINT_LT 16
+#define SQLITE_INDEX_CONSTRAINT_GE 32
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+#define SQLITE_INDEX_CONSTRAINT_NE 68
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
+#define SQLITE_INDEX_CONSTRAINT_IS 72
/*
** CAPI3REF: Register A Virtual Table Implementation
@@ -7931,9 +8011,9 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** the xFileControl method. ^The return value of the xFileControl
** method becomes the return value of this routine.
**
-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
-** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER
+** the space pointed to by the 4th parameter. ^The [SQLITE_FCNTL_FILE_POINTER]
** case is a short-circuit path which does not actually invoke the
** underlying sqlite3_io_methods.xFileControl method.
**
@@ -7945,7 +8025,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
+** See also: [file control opcodes]
*/
SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
@@ -7992,7 +8072,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16
-#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
+#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -8002,7 +8082,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
-#define SQLITE_TESTCTRL_LAST 25
+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
+#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
/*
** CAPI3REF: SQLite Runtime Status
@@ -8051,8 +8132,7 @@ SQLITE_API int sqlite3_status64(
** <dd>This parameter is the current amount of memory checked out
** using [sqlite3_malloc()], either directly or indirectly. The
** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Scratch memory
-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
+** and internal memory usage by the SQLite library. Auxiliary page-cache
** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
@@ -8090,29 +8170,14 @@ SQLITE_API int sqlite3_status64(
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
-** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>This parameter returns the number of allocations used out of the
-** [scratch memory allocator] configured using
-** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one scratch allocation
-** outstanding at time, this parameter also reports the number of threads
-** using scratch memory at the same time.</dd>)^
+** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of scratch memory
-** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The values
-** returned include overflows because the requested allocation was too
-** larger (that is, because the requested allocation was larger than the
-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
-** slots were available.
-** </dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [scratch memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
+** <dd>No longer used.</dd>
+**
+** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>The *pHighwater parameter records the deepest parser stack.
@@ -8125,12 +8190,12 @@ SQLITE_API int sqlite3_status64(
#define SQLITE_STATUS_MEMORY_USED 0
#define SQLITE_STATUS_PAGECACHE_USED 1
#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
+#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */
#define SQLITE_STATUS_MALLOC_SIZE 5
#define SQLITE_STATUS_PARSER_STACK 6
#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8
+#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
@@ -9273,6 +9338,40 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+**
+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+** method of a [virtual table], then it returns true if and only if the
+** column is being fetched as part of an UPDATE operation during which the
+** column value will not change. Applications might use this to substitute
+** a lighter-weight value to return that the corresponding [xUpdate] method
+** understands as a "no-change" value.
+**
+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+** the column is not changed by the UPDATE statement, they the xColumn
+** method can optionally return without setting a result, without calling
+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+** In that case, [sqlite3_value_nochange(X)] will return true for the
+** same column in the [xUpdate] method.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
+
+/*
+** CAPI3REF: Determine The Collation For a Virtual Table Constraint
+**
+** This function may only be called from within a call to the [xBestIndex]
+** method of a [virtual table].
+**
+** The first argument must be the sqlite3_index_info object that is the
+** first parameter to the xBestIndex() method. The second argument must be
+** an index into the aConstraint[] array belonging to the sqlite3_index_info
+** structure passed to xBestIndex. This function returns a pointer to a buffer
+** containing the name of the collation sequence for the corresponding
+** constraint.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
+/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
@@ -9999,6 +10098,35 @@ SQLITE_API 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.
+**
+** <h3>Special sqlite_stat1 Handling</h3>
+**
+** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
+** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
+** <pre>
+** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
+** </pre>
+**
+** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
+** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
+** are recorded for rows for which (idx IS NULL) is true. However, for such
+** rows a zero-length blob (SQL value X'') is stored in the changeset or
+** patchset instead of a NULL value. This allows such changesets to be
+** manipulated by legacy implementations of sqlite3changeset_invert(),
+** concat() and similar.
+**
+** The sqlite3changeset_apply() function automatically converts the
+** zero-length blob back to a NULL value when updating the sqlite_stat1
+** table. However, if the application calls sqlite3changeset_new(),
+** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
+** iterator directly (including on a changeset iterator passed to a
+** conflict-handler callback) then the X'' value is returned. The application
+** must translate X'' to NULL itself if required.
+**
+** Legacy (older than 3.22.0) versions of the sessions module cannot capture
+** changes made to the sqlite_stat1 table. Legacy versions of the
+** sqlite3changeset_apply() function silently ignore any modifications to the
+** sqlite_stat1 table that are part of a changeset or patchset.
*/
SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
@@ -10227,8 +10355,8 @@ SQLITE_API int sqlite3session_diff(
*/
SQLITE_API int sqlite3session_patchset(
sqlite3_session *pSession, /* Session object */
- int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
- void **ppPatchset /* OUT: Buffer containing changeset */
+ int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
+ void **ppPatchset /* OUT: Buffer containing patchset */
);
/*
@@ -10995,12 +11123,12 @@ SQLITE_API int sqlite3changeset_apply(
**
** <table border=1 style="margin-left:8ex;margin-right:8ex">
** <tr><th>Streaming function<th>Non-streaming equivalent</th>
-** <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply]
-** <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat]
-** <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert]
-** <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start]
-** <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset]
-** <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset]
+** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
+** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
+** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert]
+** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
+** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset]
+** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset]
** </table>
**
** Non-streaming functions that accept changesets (or patchsets) as input
@@ -12221,6 +12349,21 @@ SQLITE_PRIVATE void sqlite3Coverage(int);
#endif
/*
+** Some conditionals are optimizations only. In other words, if the
+** conditionals are replaced with a constant 1 (true) or 0 (false) then
+** the correct answer is still obtained, though perhaps not as quickly.
+**
+** The following macros mark these optimizations conditionals.
+*/
+#if defined(SQLITE_MUTATION_TEST)
+# define OK_IF_ALWAYS_TRUE(X) (1)
+# define OK_IF_ALWAYS_FALSE(X) (0)
+#else
+# define OK_IF_ALWAYS_TRUE(X) (X)
+# define OK_IF_ALWAYS_FALSE(X) (X)
+#endif
+
+/*
** Some malloc failures are only possible if SQLITE_TEST_REALLOC_STRESS is
** defined. We need to defend against those failures when testing with
** SQLITE_TEST_REALLOC_STRESS, but we don't want the unreachable branches
@@ -12414,63 +12557,63 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_AS 24
#define TK_WITHOUT 25
#define TK_COMMA 26
-#define TK_ID 27
-#define TK_ABORT 28
-#define TK_ACTION 29
-#define TK_AFTER 30
-#define TK_ANALYZE 31
-#define TK_ASC 32
-#define TK_ATTACH 33
-#define TK_BEFORE 34
-#define TK_BY 35
-#define TK_CASCADE 36
-#define TK_CAST 37
-#define TK_COLUMNKW 38
-#define TK_CONFLICT 39
-#define TK_DATABASE 40
-#define TK_DESC 41
-#define TK_DETACH 42
-#define TK_EACH 43
-#define TK_FAIL 44
-#define TK_FOR 45
-#define TK_IGNORE 46
-#define TK_INITIALLY 47
-#define TK_INSTEAD 48
-#define TK_LIKE_KW 49
-#define TK_MATCH 50
-#define TK_NO 51
-#define TK_KEY 52
-#define TK_OF 53
-#define TK_OFFSET 54
-#define TK_PRAGMA 55
-#define TK_RAISE 56
-#define TK_RECURSIVE 57
-#define TK_REPLACE 58
-#define TK_RESTRICT 59
-#define TK_ROW 60
-#define TK_TRIGGER 61
-#define TK_VACUUM 62
-#define TK_VIEW 63
-#define TK_VIRTUAL 64
-#define TK_WITH 65
-#define TK_REINDEX 66
-#define TK_RENAME 67
-#define TK_CTIME_KW 68
-#define TK_ANY 69
-#define TK_OR 70
-#define TK_AND 71
-#define TK_IS 72
-#define TK_BETWEEN 73
-#define TK_IN 74
-#define TK_ISNULL 75
-#define TK_NOTNULL 76
-#define TK_NE 77
-#define TK_EQ 78
-#define TK_GT 79
-#define TK_LE 80
-#define TK_LT 81
-#define TK_GE 82
-#define TK_ESCAPE 83
+#define TK_ABORT 27
+#define TK_ACTION 28
+#define TK_AFTER 29
+#define TK_ANALYZE 30
+#define TK_ASC 31
+#define TK_ATTACH 32
+#define TK_BEFORE 33
+#define TK_BY 34
+#define TK_CASCADE 35
+#define TK_CAST 36
+#define TK_CONFLICT 37
+#define TK_DATABASE 38
+#define TK_DESC 39
+#define TK_DETACH 40
+#define TK_EACH 41
+#define TK_FAIL 42
+#define TK_OR 43
+#define TK_AND 44
+#define TK_IS 45
+#define TK_MATCH 46
+#define TK_LIKE_KW 47
+#define TK_BETWEEN 48
+#define TK_IN 49
+#define TK_ISNULL 50
+#define TK_NOTNULL 51
+#define TK_NE 52
+#define TK_EQ 53
+#define TK_GT 54
+#define TK_LE 55
+#define TK_LT 56
+#define TK_GE 57
+#define TK_ESCAPE 58
+#define TK_ID 59
+#define TK_COLUMNKW 60
+#define TK_FOR 61
+#define TK_IGNORE 62
+#define TK_INITIALLY 63
+#define TK_INSTEAD 64
+#define TK_NO 65
+#define TK_KEY 66
+#define TK_OF 67
+#define TK_OFFSET 68
+#define TK_PRAGMA 69
+#define TK_RAISE 70
+#define TK_RECURSIVE 71
+#define TK_REPLACE 72
+#define TK_RESTRICT 73
+#define TK_ROW 74
+#define TK_TRIGGER 75
+#define TK_VACUUM 76
+#define TK_VIEW 77
+#define TK_VIRTUAL 78
+#define TK_WITH 79
+#define TK_REINDEX 80
+#define TK_RENAME 81
+#define TK_CTIME_KW 82
+#define TK_ANY 83
#define TK_BITAND 84
#define TK_BITOR 85
#define TK_LSHIFT 86
@@ -12530,28 +12673,23 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#define TK_INDEX 140
#define TK_ALTER 141
#define TK_ADD 142
-#define TK_TO_TEXT 143
-#define TK_TO_BLOB 144
-#define TK_TO_NUMERIC 145
-#define TK_TO_INT 146
-#define TK_TO_REAL 147
-#define TK_ISNOT 148
-#define TK_END_OF_FILE 149
-#define TK_UNCLOSED_STRING 150
-#define TK_FUNCTION 151
-#define TK_COLUMN 152
-#define TK_AGG_FUNCTION 153
-#define TK_AGG_COLUMN 154
-#define TK_UMINUS 155
-#define TK_UPLUS 156
-#define TK_REGISTER 157
-#define TK_VECTOR 158
-#define TK_SELECT_COLUMN 159
-#define TK_IF_NULL_ROW 160
-#define TK_ASTERISK 161
-#define TK_SPAN 162
-#define TK_SPACE 163
-#define TK_ILLEGAL 164
+#define TK_ISNOT 143
+#define TK_FUNCTION 144
+#define TK_COLUMN 145
+#define TK_AGG_FUNCTION 146
+#define TK_AGG_COLUMN 147
+#define TK_UMINUS 148
+#define TK_UPLUS 149
+#define TK_REGISTER 150
+#define TK_VECTOR 151
+#define TK_SELECT_COLUMN 152
+#define TK_IF_NULL_ROW 153
+#define TK_ASTERISK 154
+#define TK_SPAN 155
+#define TK_END_OF_FILE 156
+#define TK_UNCLOSED_STRING 157
+#define TK_SPACE 158
+#define TK_ILLEGAL 159
/* The token codes above must all fit in 8 bits */
#define TKFLG_MASK 0xff
@@ -12672,6 +12810,15 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
#endif
/*
+** The compile-time options SQLITE_MMAP_READWRITE and
+** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another.
+** You must choose one or the other (or neither) but not both.
+*/
+#if defined(SQLITE_MMAP_READWRITE) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+#error Cannot use both SQLITE_MMAP_READWRITE and SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+#endif
+
+/*
** GCC does not define the offsetof() macro so we'll have to do it
** ourselves.
*/
@@ -12969,7 +13116,7 @@ typedef INT16_TYPE LogEst;
** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
** the Select query generator tracing logic is turned on.
*/
-#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE)
+#if defined(SQLITE_ENABLE_SELECTTRACE)
# define SELECTTRACE_ENABLED 1
#else
# define SELECTTRACE_ENABLED 0
@@ -13088,7 +13235,6 @@ typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
-typedef struct ExprSpan ExprSpan;
typedef struct FKey FKey;
typedef struct FuncDestructor FuncDestructor;
typedef struct FuncDef FuncDef;
@@ -13373,6 +13519,7 @@ SQLITE_PRIVATE int sqlite3BtreeCursor(
struct KeyInfo*, /* First argument to compare function */
BtCursor *pCursor /* Space to write cursor structure */
);
+SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void);
SQLITE_PRIVATE int sqlite3BtreeCursorSize(void);
SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*);
SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned);
@@ -13433,6 +13580,9 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags);
SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags);
SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*);
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*);
+#endif
SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*);
SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
@@ -13646,6 +13796,7 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_INT64 (-14) /* P4 is a 64-bit signed integer */
#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */
+#define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */
/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
@@ -13691,87 +13842,87 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Savepoint 0
#define OP_AutoCommit 1
#define OP_Transaction 2
-#define OP_SorterNext 3
-#define OP_PrevIfOpen 4
-#define OP_NextIfOpen 5
-#define OP_Prev 6
-#define OP_Next 7
+#define OP_SorterNext 3 /* jump */
+#define OP_PrevIfOpen 4 /* jump */
+#define OP_NextIfOpen 5 /* jump */
+#define OP_Prev 6 /* jump */
+#define OP_Next 7 /* jump */
#define OP_Checkpoint 8
#define OP_JournalMode 9
#define OP_Vacuum 10
-#define OP_VFilter 11 /* synopsis: iplan=r[P3] zplan='P4' */
+#define OP_VFilter 11 /* jump, synopsis: iplan=r[P3] zplan='P4' */
#define OP_VUpdate 12 /* synopsis: data=r[P3@P2] */
-#define OP_Goto 13
-#define OP_Gosub 14
-#define OP_InitCoroutine 15
-#define OP_Yield 16
-#define OP_MustBeInt 17
-#define OP_Jump 18
+#define OP_Goto 13 /* jump */
+#define OP_Gosub 14 /* jump */
+#define OP_InitCoroutine 15 /* jump */
+#define OP_Yield 16 /* jump */
+#define OP_MustBeInt 17 /* jump */
+#define OP_Jump 18 /* jump */
#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
-#define OP_Once 20
-#define OP_If 21
-#define OP_IfNot 22
-#define OP_IfNullRow 23 /* synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
-#define OP_SeekLT 24 /* synopsis: key=r[P3@P4] */
-#define OP_SeekLE 25 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGE 26 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGT 27 /* synopsis: key=r[P3@P4] */
-#define OP_NoConflict 28 /* synopsis: key=r[P3@P4] */
-#define OP_NotFound 29 /* synopsis: key=r[P3@P4] */
-#define OP_Found 30 /* synopsis: key=r[P3@P4] */
-#define OP_SeekRowid 31 /* synopsis: intkey=r[P3] */
-#define OP_NotExists 32 /* synopsis: intkey=r[P3] */
-#define OP_Last 33
-#define OP_IfSmaller 34
-#define OP_SorterSort 35
-#define OP_Sort 36
-#define OP_Rewind 37
-#define OP_IdxLE 38 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGT 39 /* synopsis: key=r[P3@P4] */
-#define OP_IdxLT 40 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGE 41 /* synopsis: key=r[P3@P4] */
-#define OP_RowSetRead 42 /* synopsis: r[P3]=rowset(P1) */
-#define OP_RowSetTest 43 /* synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 44
-#define OP_FkIfZero 45 /* synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_IfPos 46 /* synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
-#define OP_IfNotZero 47 /* synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
-#define OP_DecrJumpZero 48 /* synopsis: if (--r[P1])==0 goto P2 */
-#define OP_IncrVacuum 49
-#define OP_VNext 50
-#define OP_Init 51 /* synopsis: Start at P2 */
-#define OP_Return 52
-#define OP_EndCoroutine 53
-#define OP_HaltIfNull 54 /* synopsis: if r[P3]=null halt */
-#define OP_Halt 55
-#define OP_Integer 56 /* synopsis: r[P2]=P1 */
-#define OP_Int64 57 /* synopsis: r[P2]=P4 */
-#define OP_String 58 /* synopsis: r[P2]='P4' (len=P1) */
-#define OP_Null 59 /* synopsis: r[P2..P3]=NULL */
-#define OP_SoftNull 60 /* synopsis: r[P1]=NULL */
-#define OP_Blob 61 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 62 /* synopsis: r[P2]=parameter(P1,P4) */
-#define OP_Move 63 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_Copy 64 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
-#define OP_SCopy 65 /* synopsis: r[P2]=r[P1] */
-#define OP_IntCopy 66 /* synopsis: r[P2]=r[P1] */
-#define OP_ResultRow 67 /* synopsis: output=r[P1@P2] */
-#define OP_CollSeq 68
-#define OP_AddImm 69 /* synopsis: r[P1]=r[P1]+P2 */
-#define OP_Or 70 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
-#define OP_And 71 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_RealAffinity 72
-#define OP_Cast 73 /* synopsis: affinity(r[P1]) */
-#define OP_Permutation 74
-#define OP_IsNull 75 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 76 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 77 /* same as TK_NE, synopsis: IF r[P3]!=r[P1] */
-#define OP_Eq 78 /* same as TK_EQ, synopsis: IF r[P3]==r[P1] */
-#define OP_Gt 79 /* same as TK_GT, synopsis: IF r[P3]>r[P1] */
-#define OP_Le 80 /* same as TK_LE, synopsis: IF r[P3]<=r[P1] */
-#define OP_Lt 81 /* same as TK_LT, synopsis: IF r[P3]<r[P1] */
-#define OP_Ge 82 /* same as TK_GE, synopsis: IF r[P3]>=r[P1] */
-#define OP_ElseNotEq 83 /* same as TK_ESCAPE */
+#define OP_Once 20 /* jump */
+#define OP_If 21 /* jump */
+#define OP_IfNot 22 /* jump */
+#define OP_IfNullRow 23 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
+#define OP_SeekLT 24 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekLE 25 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekGE 26 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekGT 27 /* jump, synopsis: key=r[P3@P4] */
+#define OP_NoConflict 28 /* jump, synopsis: key=r[P3@P4] */
+#define OP_NotFound 29 /* jump, synopsis: key=r[P3@P4] */
+#define OP_Found 30 /* jump, synopsis: key=r[P3@P4] */
+#define OP_SeekRowid 31 /* jump, synopsis: intkey=r[P3] */
+#define OP_NotExists 32 /* jump, synopsis: intkey=r[P3] */
+#define OP_Last 33 /* jump */
+#define OP_IfSmaller 34 /* jump */
+#define OP_SorterSort 35 /* jump */
+#define OP_Sort 36 /* jump */
+#define OP_Rewind 37 /* jump */
+#define OP_IdxLE 38 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxGT 39 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxLT 40 /* jump, synopsis: key=r[P3@P4] */
+#define OP_IdxGE 41 /* jump, synopsis: key=r[P3@P4] */
+#define OP_RowSetRead 42 /* jump, synopsis: r[P3]=rowset(P1) */
+#define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 46 /* jump */
+#define OP_FkIfZero 47 /* jump, synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_IfPos 48 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */
+#define OP_IfNotZero 49 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
+#define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */
+#define OP_Eq 53 /* jump, same as TK_EQ, synopsis: IF r[P3]==r[P1] */
+#define OP_Gt 54 /* jump, same as TK_GT, synopsis: IF r[P3]>r[P1] */
+#define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */
+#define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]<r[P1] */
+#define OP_Ge 57 /* jump, same as TK_GE, synopsis: IF r[P3]>=r[P1] */
+#define OP_ElseNotEq 58 /* jump, same as TK_ESCAPE */
+#define OP_DecrJumpZero 59 /* jump, synopsis: if (--r[P1])==0 goto P2 */
+#define OP_IncrVacuum 60 /* jump */
+#define OP_VNext 61 /* jump */
+#define OP_Init 62 /* jump, synopsis: Start at P2 */
+#define OP_Return 63
+#define OP_EndCoroutine 64
+#define OP_HaltIfNull 65 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 66
+#define OP_Integer 67 /* synopsis: r[P2]=P1 */
+#define OP_Int64 68 /* synopsis: r[P2]=P4 */
+#define OP_String 69 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 70 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 71 /* synopsis: r[P1]=NULL */
+#define OP_Blob 72 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 73 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 74 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 75 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 76 /* synopsis: r[P2]=r[P1] */
+#define OP_IntCopy 77 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 78 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 79
+#define OP_AddImm 80 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_RealAffinity 81
+#define OP_Cast 82 /* synopsis: affinity(r[P1]) */
+#define OP_Permutation 83
#define OP_BitAnd 84 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
#define OP_BitOr 85 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
#define OP_ShiftLeft 86 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
@@ -13784,78 +13935,80 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Concat 93 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
#define OP_Compare 94 /* synopsis: r[P1@P3] <-> r[P2@P3] */
#define OP_BitNot 95 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
-#define OP_Column 96 /* synopsis: r[P3]=PX */
+#define OP_Offset 96 /* synopsis: r[P3] = sqlite_offset(P1) */
#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_Affinity 98 /* synopsis: affinity(r[P1@P2]) */
-#define OP_MakeRecord 99 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_Count 100 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 101
-#define OP_SetCookie 102
-#define OP_ReopenIdx 103 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenRead 104 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 105 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenDup 106
-#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_DeferredSeek 128 /* synopsis: Move P3 to P1.rowid if needed */
-#define OP_IdxRowid 129 /* synopsis: r[P2]=rowid */
-#define OP_Destroy 130
-#define OP_Clear 131
+#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_OpenDup 107
+#define OP_OpenAutoindex 108 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 109 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 110
+#define OP_SequenceTest 111 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
+#define OP_OpenPseudo 112 /* synopsis: P3 columns in r[P2] */
+#define OP_Close 113
+#define OP_ColumnsUsed 114
+#define OP_Sequence 115 /* synopsis: r[P2]=cursor[P1].ctr++ */
+#define OP_NewRowid 116 /* synopsis: r[P2]=rowid */
+#define OP_Insert 117 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_InsertInt 118 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 119
+#define OP_ResetCount 120
+#define OP_SorterCompare 121 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData 122 /* synopsis: r[P2]=data */
+#define OP_RowData 123 /* synopsis: r[P2]=data */
+#define OP_Rowid 124 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 125
+#define OP_SeekEnd 126
+#define OP_SorterInsert 127 /* synopsis: key=r[P2] */
+#define OP_IdxInsert 128 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 129 /* synopsis: key=r[P2@P3] */
+#define OP_DeferredSeek 130 /* synopsis: Move P3 to P1.rowid if needed */
+#define OP_IdxRowid 131 /* synopsis: r[P2]=rowid */
#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_PureFunc0 161
-#define OP_Function0 162 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_PureFunc 163
-#define OP_Function 164 /* synopsis: r[P3]=func(r[P2@P5]) */
-#define OP_CursorHint 165
-#define OP_Noop 166
-#define OP_Explain 167
+#define OP_Destroy 133
+#define OP_Clear 134
+#define OP_ResetSorter 135
+#define OP_CreateBtree 136 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
+#define OP_SqlExec 137
+#define OP_ParseSchema 138
+#define OP_LoadAnalysis 139
+#define OP_DropTable 140
+#define OP_DropIndex 141
+#define OP_DropTrigger 142
+#define OP_IntegrityCk 143
+#define OP_RowSetAdd 144 /* synopsis: rowset(P1)=r[P2] */
+#define OP_Param 145
+#define OP_FkCounter 146 /* synopsis: fkctr[P1]+=P2 */
+#define OP_MemMax 147 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_OffsetLimit 148 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+#define OP_AggStep0 149 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggStep 150 /* synopsis: accum=r[P3] step(r[P2@P5]) */
+#define OP_AggFinal 151 /* synopsis: accum=r[P1] N=P2 */
+#define OP_Expire 152
+#define OP_TableLock 153 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 154
+#define OP_VCreate 155
+#define OP_VDestroy 156
+#define OP_VOpen 157
+#define OP_VColumn 158 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VRename 159
+#define OP_Pagecount 160
+#define OP_MaxPgcnt 161
+#define OP_PureFunc0 162
+#define OP_Function0 163 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_PureFunc 164
+#define OP_Function 165 /* synopsis: r[P3]=func(r[P2@P5]) */
+#define OP_Trace 166
+#define OP_CursorHint 167
+#define OP_Noop 168
+#define OP_Explain 169
/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
@@ -13873,23 +14026,23 @@ typedef struct VdbeOpList VdbeOpList;
/* 16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x03, 0x03, 0x01,\
/* 24 */ 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
-/* 40 */ 0x01, 0x01, 0x23, 0x0b, 0x01, 0x01, 0x03, 0x03,\
-/* 48 */ 0x03, 0x01, 0x01, 0x01, 0x02, 0x02, 0x08, 0x00,\
-/* 56 */ 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00,\
-/* 64 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x02, 0x26, 0x26,\
-/* 72 */ 0x02, 0x02, 0x00, 0x03, 0x03, 0x0b, 0x0b, 0x0b,\
-/* 80 */ 0x0b, 0x0b, 0x0b, 0x01, 0x26, 0x26, 0x26, 0x26,\
+/* 40 */ 0x01, 0x01, 0x23, 0x26, 0x26, 0x0b, 0x01, 0x01,\
+/* 48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
+/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x01, 0x01, 0x01, 0x02,\
+/* 64 */ 0x02, 0x08, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00,\
+/* 72 */ 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 80 */ 0x02, 0x02, 0x02, 0x00, 0x26, 0x26, 0x26, 0x26,\
/* 88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\
-/* 96 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
+/* 96 */ 0x20, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
/* 104 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00, 0x00,\
-}
+/* 112 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\
+/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x04,\
+/* 128 */ 0x04, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00,\
+/* 136 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 144 */ 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00,\
+/* 152 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 160 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 168 */ 0x00, 0x00,}
/* The sqlite3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode. The smaller the maximum
@@ -13897,7 +14050,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 83 /* Maximum JUMP opcode */
+#define SQLITE_MX_JUMP_OPCODE 62 /* Maximum JUMP opcode */
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -14215,6 +14368,7 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*);
+SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage*);
/* Operations on page references. */
SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
@@ -14351,6 +14505,8 @@ struct PgHdr {
i16 nRef; /* Number of users of this page */
PgHdr *pDirtyNext; /* Next element in list of dirty pages */
PgHdr *pDirtyPrev; /* Previous element in list of dirty pages */
+ /* NB: pDirtyNext and pDirtyPrev are undefined if the
+ ** PgHdr object is not dirty */
};
/* Bit values for PgHdr.flags */
@@ -14732,10 +14888,12 @@ SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*);
#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id);
SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
+#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **);
SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int);
SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id);
SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int);
+#endif /* SQLITE_OMIT_WAL */
SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **);
SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *);
@@ -14944,6 +15102,7 @@ struct Schema {
#define DB_SchemaLoaded 0x0001 /* The schema has been loaded */
#define DB_UnresetViews 0x0002 /* Some views have defined column names */
#define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */
+#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */
/*
** The number of different kinds of things that can be limited
@@ -14975,9 +15134,9 @@ struct Lookaside {
u32 bDisable; /* Only operate the lookaside when zero */
u16 sz; /* Size of each buffer in bytes */
u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */
- int nOut; /* Number of buffers currently checked out */
- int mxOut; /* Highwater mark for nOut */
- int anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
+ u32 nSlot; /* Number of lookaside slots allocated */
+ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */
+ LookasideSlot *pInit; /* List of buffers not previously used */
LookasideSlot *pFree; /* List of available buffers */
void *pStart; /* First byte of available memory space */
void *pEnd; /* First byte past end of available space */
@@ -15056,9 +15215,11 @@ struct sqlite3 {
sqlite3_mutex *mutex; /* Connection mutex */
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
- int flags; /* Miscellaneous flags. See below */
+ u32 mDbFlags; /* flags recording internal state */
+ u32 flags; /* flags settable by pragmas. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
i64 szMmap; /* Default mmap_size setting */
+ u32 nSchemaLock; /* Do not reset the schema when non-zero */
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
int errCode; /* Most recent error code (SQLITE_*) */
int errMask; /* & result codes with this before returning */
@@ -15141,7 +15302,7 @@ struct sqlite3 {
Hash aModule; /* populated by sqlite3_create_module() */
VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
VTable **aVTrans; /* Virtual tables with open transactions */
- VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
+ VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
#endif
Hash aFunc; /* Hash table of connection functions */
Hash aCollSeq; /* All collating sequences */
@@ -15210,18 +15371,15 @@ struct sqlite3 {
#define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */
#define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */
-#define SQLITE_EnableTrigger 0x00020000 /* True to enable triggers */
-#define SQLITE_DeferFKs 0x00040000 /* Defer all FK constraints */
-#define SQLITE_QueryOnly 0x00080000 /* Disable database changes */
-#define SQLITE_CellSizeCk 0x00100000 /* Check btree cell sizes on load */
-#define SQLITE_Fts3Tokenizer 0x00200000 /* Enable fts3_tokenizer(2) */
-#define SQLITE_EnableQPSG 0x00400000 /* Query Planner Stability Guarantee */
-/* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and
-** could be factored out into a separate bit vector of the sqlite3 object. */
-#define SQLITE_InternChanges 0x00800000 /* Uncommitted Hash table changes */
-#define SQLITE_LoadExtFunc 0x01000000 /* Enable load_extension() SQL func */
-#define SQLITE_PreferBuiltin 0x02000000 /* Preference to built-in funcs */
-#define SQLITE_Vacuum 0x04000000 /* Currently in a VACUUM */
+#define SQLITE_LoadExtFunc 0x00020000 /* Enable load_extension() SQL func */
+#define SQLITE_EnableTrigger 0x00040000 /* True to enable triggers */
+#define SQLITE_DeferFKs 0x00080000 /* Defer all FK constraints */
+#define SQLITE_QueryOnly 0x00100000 /* Disable database changes */
+#define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */
+#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
+#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee*/
+#define SQLITE_TriggerEQP 0x01000000 /* Show trigger EXPLAIN QUERY PLAN */
+
/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
@@ -15231,6 +15389,12 @@ struct sqlite3 {
#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
#endif
+/*
+** Allowed values for sqlite3.mDbFlags
+*/
+#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */
+#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */
+#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
@@ -15241,16 +15405,15 @@ struct sqlite3 {
#define SQLITE_ColumnCache 0x0002 /* Column cache */
#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
-/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */
-#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */
-#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */
-#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */
-#define SQLITE_SubqCoroutine 0x0100 /* Evaluate subqueries as coroutines */
-#define SQLITE_Transitive 0x0200 /* Transitive constraints */
-#define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */
+#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */
+#define SQLITE_CoverIdxScan 0x0020 /* Covering index scans */
+#define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */
+#define SQLITE_Transitive 0x0080 /* Transitive constraints */
+#define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */
+#define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */
+#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
-#define SQLITE_CountOfView 0x1000 /* The count-of-view optimization */
-#define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */
+ /* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */
#define SQLITE_AllOpts 0xffff /* All optimizations */
/*
@@ -15349,6 +15512,7 @@ struct FuncDestructor {
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
+#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -15781,8 +15945,8 @@ struct FKey {
struct KeyInfo {
u32 nRef; /* Number of references to this KeyInfo object */
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
- u16 nField; /* Number of key columns in the index */
- u16 nXField; /* Number of columns beyond the key columns */
+ u16 nKeyField; /* Number of key columns in the index */
+ u16 nAllField; /* Total columns, including key plus others */
sqlite3 *db; /* The database connection */
u8 *aSortOrder; /* Sort order for each column. */
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
@@ -15829,8 +15993,8 @@ struct UnpackedRecord {
u16 nField; /* Number of entries in apMem[] */
i8 default_rc; /* Comparison result if keys are equal */
u8 errCode; /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
- i8 r1; /* Value to return if (lhs > rhs) */
- i8 r2; /* Value to return if (rhs < lhs) */
+ i8 r1; /* Value to return if (lhs < rhs) */
+ i8 r2; /* Value to return if (lhs > rhs) */
u8 eqSeen; /* True if an equality comparison has been seen */
};
@@ -15893,6 +16057,7 @@ struct Index {
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 */
+ unsigned bNoQuery:1; /* Do not use this index to optimize queries */
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
int nSample; /* Number of elements in aSample[] */
int nSampleCol; /* Size of IndexSample.anEq[] and so on */
@@ -16114,7 +16279,8 @@ struct Expr {
** TK_COLUMN: the value of p5 for OP_Column
** TK_AGG_FUNCTION: nesting depth */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
- Table *pTab; /* Table for TK_COLUMN expressions. */
+ Table *pTab; /* Table for TK_COLUMN expressions. Can be NULL
+ ** for a column of an index on an expression */
};
/*
@@ -16122,7 +16288,7 @@ struct Expr {
*/
#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */
#define EP_Agg 0x000002 /* Contains one or more aggregate functions */
- /* 0x000004 // available for use */
+#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */
/* 0x000008 // available for use */
#define EP_Distinct 0x000010 /* Aggregate function with DISTINCT keyword */
#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
@@ -16146,9 +16312,10 @@ struct Expr {
#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
/*
-** Combinations of two or more EP_* flags
+** The EP_Propagate mask is a set of properties that automatically propagate
+** upwards into parent nodes.
*/
-#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
+#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
/*
** These macros can be used to test, set, or clear bits in the
@@ -16202,7 +16369,6 @@ struct Expr {
*/
struct ExprList {
int nExpr; /* Number of expressions on the list */
- int nAlloc; /* Number of a[] slots allocated */
struct ExprList_item { /* For each expression in the list */
Expr *pExpr; /* The parse tree for this expression */
char *zName; /* Token associated with this expression */
@@ -16222,17 +16388,6 @@ struct ExprList {
};
/*
-** An instance of this structure is used by the parser to record both
-** the parse tree for an expression and the span of input text for an
-** expression.
-*/
-struct ExprSpan {
- Expr *pExpr; /* The expression parse tree */
- const char *zStart; /* First character of input text */
- const char *zEnd; /* One character past the end of input text */
-};
-
-/*
** An instance of this structure can hold a simple list of identifiers,
** such as the list "a,b,c" in the following statements:
**
@@ -16429,6 +16584,7 @@ struct NameContext {
#define NC_IdxExpr 0x0020 /* True if resolving columns of CREATE INDEX */
#define NC_VarSelect 0x0040 /* A correlated subquery has been seen */
#define NC_MinMaxAgg 0x1000 /* min/max aggregates seen. See note above */
+#define NC_Complex 0x2000 /* True if a function or subquery seen */
/*
** An instance of the following structure contains all information
@@ -16468,7 +16624,6 @@ struct Select {
Select *pPrior; /* Prior select in a compound select statement */
Select *pNext; /* Next select to the left in a compound */
Expr *pLimit; /* LIMIT expression. NULL means not used. */
- Expr *pOffset; /* OFFSET expression. NULL means not used. */
With *pWith; /* WITH clause attached to this select. Or NULL. */
};
@@ -16499,6 +16654,7 @@ struct Select {
#define SF_MaybeConvert 0x08000 /* Need convertCompoundSelectToSubquery() */
#define SF_Converted 0x10000 /* By convertCompoundSelectToSubquery() */
#define SF_IncludeHidden 0x20000 /* Include hidden columns in output */
+#define SF_ComplexResult 0x40000 /* Result set contains subquery or function */
/*
@@ -16703,7 +16859,7 @@ struct Parse {
int nMem; /* Number of memory cells used so far */
int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
- int iSelfTab; /* Table for associated with an index on expr, or negative
+ int iSelfTab; /* Table associated with an index on expr, or negative
** of the base register during check-constraint eval */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
@@ -16727,7 +16883,7 @@ struct Parse {
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
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 */
+ int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
u32 newmask; /* Mask of new.* columns referenced */
@@ -16844,6 +17000,7 @@ struct AuthContext {
#define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */
#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */
#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */
+#define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */
/*
* Each trigger present in the database schema is stored as an instance of
@@ -16931,6 +17088,7 @@ struct TriggerStep {
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
ExprList *pExprList; /* SET clause for UPDATE. */
IdList *pIdList; /* Column names for INSERT */
+ char *zSpan; /* Original SQL text of this command */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
};
@@ -16956,11 +17114,10 @@ struct DbFixer {
*/
struct StrAccum {
sqlite3 *db; /* Optional database for lookaside. Can be NULL */
- char *zBase; /* A base allocation. Not from malloc. */
char *zText; /* The string collected so far */
- u32 nChar; /* Length of the string so far */
u32 nAlloc; /* Amount of space allocated in zText */
u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */
+ u32 nChar; /* Length of the string so far */
u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
u8 printfFlags; /* SQLITE_PRINTF flags below */
};
@@ -16995,6 +17152,7 @@ struct Sqlite3Config {
int bFullMutex; /* True to enable full mutexing */
int bOpenUri; /* True to interpret filenames as URIs */
int bUseCis; /* Use covering indices for full-scans */
+ int bSmallMalloc; /* Avoid large memory allocations if true */
int mxStrlen; /* Maximum string length */
int neverCorrupt; /* Database is always well-formed */
int szLookaside; /* Default lookaside buffer size */
@@ -17008,9 +17166,6 @@ struct Sqlite3Config {
int mnReq, mxReq; /* Min and max heap requests sizes */
sqlite3_int64 szMmap; /* mmap() space per open file */
sqlite3_int64 mxMmap; /* Maximum value for szMmap */
- void *pScratch; /* Scratch memory */
- int szScratch; /* Size of each scratch buffer */
- int nScratch; /* Number of scratch buffers */
void *pPage; /* Page cache memory */
int szPage; /* Size of each page in pPage[] */
int nPage; /* Number of pages in pPage[] */
@@ -17097,6 +17252,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*);
SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*);
SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*);
+SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*);
#endif
@@ -17152,6 +17308,7 @@ struct TreeView {
** using sqlite3_log(). The routines also provide a convenient place
** to set a debugger breakpoint.
*/
+SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType);
SQLITE_PRIVATE int sqlite3CorruptError(int);
SQLITE_PRIVATE int sqlite3MisuseError(int);
SQLITE_PRIVATE int sqlite3CantopenError(int);
@@ -17242,6 +17399,7 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64);
SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64);
SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
@@ -17249,8 +17407,6 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*);
SQLITE_PRIVATE int sqlite3MallocSize(void*);
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
-SQLITE_PRIVATE void sqlite3ScratchFree(void*);
SQLITE_PRIVATE void *sqlite3PageMalloc(int);
SQLITE_PRIVATE void sqlite3PageFree(void*);
SQLITE_PRIVATE void sqlite3MemSetDefault(void);
@@ -17306,11 +17462,18 @@ SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int);
SQLITE_PRIVATE void sqlite3StatusUp(int, int);
SQLITE_PRIVATE void sqlite3StatusDown(int, int);
SQLITE_PRIVATE void sqlite3StatusHighwater(int, int);
+SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*);
/* Access to mutexes used by sqlite3_status() */
SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void);
+#if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT)
+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*);
+#else
+# define sqlite3MutexWarnOnContention(x)
+#endif
+
#ifndef SQLITE_OMIT_FLOATING_POINT
SQLITE_PRIVATE int sqlite3IsNaN(double);
#else
@@ -17375,7 +17538,7 @@ 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*);
+SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
@@ -17405,7 +17568,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*,Token*);
SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
@@ -17477,16 +17640,16 @@ SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,i
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
- Expr*,ExprList*,u32,Expr*,Expr*);
+ Expr*,ExprList*,u32,Expr*);
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
-SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,Expr*,char*);
+SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
#endif
-SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
-SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
+SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
+SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*);
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*);
@@ -17610,7 +17773,7 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
-SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
+SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int);
#endif
#ifndef SQLITE_OMIT_TRIGGER
@@ -17626,11 +17789,14 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, i
SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int);
void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*,
+ const char*,const char*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
- Select*,u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
+ Select*,u8,const char*,const char*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8,
+ const char*,const char*);
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*,
+ const char*,const char*);
SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*);
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
@@ -17742,6 +17908,8 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr);
+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
@@ -18025,7 +18193,8 @@ 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 *);
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *);
#endif
@@ -18057,6 +18226,9 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *);
#endif
+#if defined(YYCOVERAGE)
+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE*);
+#endif
/*
** If the SQLITE_ENABLE IOTRACE exists then the global variable
@@ -18111,8 +18283,7 @@ SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8);
#endif
#define MEMTYPE_HEAP 0x01 /* General heap allocations */
#define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */
-#define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */
-#define MEMTYPE_PCACHE 0x08 /* Page cache allocations */
+#define MEMTYPE_PCACHE 0x04 /* Page cache allocations */
/*
** Threading interface
@@ -18122,6 +18293,9 @@ SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
#endif
+#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*);
+#endif
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
#endif
@@ -18341,6 +18515,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
SQLITE_THREADSAFE==1, /* bFullMutex */
SQLITE_USE_URI, /* bOpenUri */
SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */
+ 0, /* bSmallMalloc */
0x7ffffffe, /* mxStrlen */
0, /* neverCorrupt */
SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */
@@ -18353,9 +18528,6 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
0, 0, /* mnHeap, mxHeap */
SQLITE_DEFAULT_MMAP_SIZE, /* szMmap */
SQLITE_MAX_MMAP_SIZE, /* mxMmap */
- (void*)0, /* pScratch */
- 0, /* szScratch */
- 0, /* nScratch */
(void*)0, /* pPage */
0, /* szPage */
SQLITE_DEFAULT_PCACHE_INITSZ, /* nPage */
@@ -18557,18 +18729,18 @@ struct VdbeCursor {
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". */
+ /* seekResult does not distinguish between "no seeks have ever occurred
+ ** on this cursor" and "the most recent seek was an exact match".
+ ** For CURTYPE_PSEUDO, seekResult is the register holding the record */
/* 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 */
+ BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */
+ sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */
+ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */
} uc;
KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */
u32 iHdrOffset; /* Offset to next unparsed byte of the header */
@@ -18685,6 +18857,8 @@ struct sqlite3_value {
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** For a pointer type created using sqlite3_bind_pointer() or
** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
+** If both MEM_Null and MEM_Zero are set, that means that the value is
+** an unchanging column value from VColumn.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.
** Usually this is encoded in the same unicode encoding as the main
@@ -19126,7 +19300,6 @@ SQLITE_PRIVATE void sqlite3StatusHighwater(int op, int X){
: sqlite3MallocMutex()) );
assert( op==SQLITE_STATUS_MALLOC_SIZE
|| op==SQLITE_STATUS_PAGECACHE_SIZE
- || op==SQLITE_STATUS_SCRATCH_SIZE
|| op==SQLITE_STATUS_PARSER_STACK );
if( newValue>wsdStat.mxValue[op] ){
wsdStat.mxValue[op] = newValue;
@@ -19176,6 +19349,28 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
}
/*
+** Return the number of LookasideSlot elements on the linked list
+*/
+static u32 countLookasideSlots(LookasideSlot *p){
+ u32 cnt = 0;
+ while( p ){
+ p = p->pNext;
+ cnt++;
+ }
+ return cnt;
+}
+
+/*
+** Count the number of slots of lookaside memory that are outstanding
+*/
+SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){
+ u32 nInit = countLookasideSlots(db->lookaside.pInit);
+ u32 nFree = countLookasideSlots(db->lookaside.pFree);
+ if( pHighwater ) *pHighwater = db->lookaside.nSlot - nInit;
+ return db->lookaside.nSlot - (nInit+nFree);
+}
+
+/*
** Query status information for a single database connection
*/
SQLITE_API int sqlite3_db_status(
@@ -19194,10 +19389,15 @@ SQLITE_API int sqlite3_db_status(
sqlite3_mutex_enter(db->mutex);
switch( op ){
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
- *pCurrent = db->lookaside.nOut;
- *pHighwater = db->lookaside.mxOut;
+ *pCurrent = sqlite3LookasideUsed(db, pHighwater);
if( resetFlag ){
- db->lookaside.mxOut = db->lookaside.nOut;
+ LookasideSlot *p = db->lookaside.pFree;
+ if( p ){
+ while( p->pNext ) p = p->pNext;
+ p->pNext = db->lookaside.pInit;
+ db->lookaside.pInit = db->lookaside.pFree;
+ db->lookaside.pFree = 0;
+ }
}
break;
}
@@ -19397,7 +19597,7 @@ SQLITE_API int sqlite3_db_status(
**
** Jean Meeus
** Astronomical Algorithms, 2nd Edition, 1998
-** ISBM 0-943396-61-1
+** ISBN 0-943396-61-1
** Willmann-Bell, Inc
** Richmond, Virginia (USA)
*/
@@ -20708,7 +20908,7 @@ SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
}
SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
DO_OS_MALLOC_TEST(id);
- return id->pMethods->xSync(id, flags);
+ return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK;
}
SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
DO_OS_MALLOC_TEST(id);
@@ -20763,6 +20963,7 @@ SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
return id->pMethods->xDeviceCharacteristics(id);
}
+#ifndef SQLITE_OMIT_WAL
SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
return id->pMethods->xShmLock(id, offset, n, flags);
}
@@ -20782,6 +20983,7 @@ SQLITE_PRIVATE int sqlite3OsShmMap(
DO_OS_MALLOC_TEST(id);
return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
}
+#endif /* SQLITE_OMIT_WAL */
#if SQLITE_MAX_MMAP_SIZE>0
/* The real implementation of xFetch and xUnfetch */
@@ -23300,6 +23502,193 @@ static SQLITE_WSD int mutexIsInit = 0;
#ifndef SQLITE_MUTEX_OMIT
+
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+/*
+** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains
+** the implementation of a wrapper around the system default mutex
+** implementation (sqlite3DefaultMutex()).
+**
+** Most calls are passed directly through to the underlying default
+** mutex implementation. Except, if a mutex is configured by calling
+** sqlite3MutexWarnOnContention() on it, then if contention is ever
+** encountered within xMutexEnter() a warning is emitted via sqlite3_log().
+**
+** This type of mutex is used as the database handle mutex when testing
+** apps that usually use SQLITE_CONFIG_MULTITHREAD mode.
+*/
+
+/*
+** Type for all mutexes used when SQLITE_ENABLE_MULTITHREADED_CHECKS
+** is defined. Variable CheckMutex.mutex is a pointer to the real mutex
+** allocated by the system mutex implementation. Variable iType is usually set
+** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST
+** or one of the static mutex identifiers. Or, if this is a recursive mutex
+** that has been configured using sqlite3MutexWarnOnContention(), it is
+** set to SQLITE_MUTEX_WARNONCONTENTION.
+*/
+typedef struct CheckMutex CheckMutex;
+struct CheckMutex {
+ int iType;
+ sqlite3_mutex *mutex;
+};
+
+#define SQLITE_MUTEX_WARNONCONTENTION (-1)
+
+/*
+** Pointer to real mutex methods object used by the CheckMutex
+** implementation. Set by checkMutexInit().
+*/
+static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods;
+
+#ifdef SQLITE_DEBUG
+static int checkMutexHeld(sqlite3_mutex *p){
+ return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex);
+}
+static int checkMutexNotheld(sqlite3_mutex *p){
+ return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex);
+}
+#endif
+
+/*
+** Initialize and deinitialize the mutex subsystem.
+*/
+static int checkMutexInit(void){
+ pGlobalMutexMethods = sqlite3DefaultMutex();
+ return SQLITE_OK;
+}
+static int checkMutexEnd(void){
+ pGlobalMutexMethods = 0;
+ return SQLITE_OK;
+}
+
+/*
+** Allocate a mutex.
+*/
+static sqlite3_mutex *checkMutexAlloc(int iType){
+ static CheckMutex staticMutexes[] = {
+ {2, 0}, {3, 0}, {4, 0}, {5, 0},
+ {6, 0}, {7, 0}, {8, 0}, {9, 0},
+ {10, 0}, {11, 0}, {12, 0}, {13, 0}
+ };
+ CheckMutex *p = 0;
+
+ assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 );
+ if( iType<2 ){
+ p = sqlite3MallocZero(sizeof(CheckMutex));
+ if( p==0 ) return 0;
+ p->iType = iType;
+ }else{
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( iType-2>=ArraySize(staticMutexes) ){
+ (void)SQLITE_MISUSE_BKPT;
+ return 0;
+ }
+#endif
+ p = &staticMutexes[iType-2];
+ }
+
+ if( p->mutex==0 ){
+ p->mutex = pGlobalMutexMethods->xMutexAlloc(iType);
+ if( p->mutex==0 ){
+ if( iType<2 ){
+ sqlite3_free(p);
+ }
+ p = 0;
+ }
+ }
+
+ return (sqlite3_mutex*)p;
+}
+
+/*
+** Free a mutex.
+*/
+static void checkMutexFree(sqlite3_mutex *p){
+ assert( SQLITE_MUTEX_RECURSIVE<2 );
+ assert( SQLITE_MUTEX_FAST<2 );
+ assert( SQLITE_MUTEX_WARNONCONTENTION<2 );
+
+#if SQLITE_ENABLE_API_ARMOR
+ if( ((CheckMutex*)p)->iType<2 )
+#endif
+ {
+ CheckMutex *pCheck = (CheckMutex*)p;
+ pGlobalMutexMethods->xMutexFree(pCheck->mutex);
+ sqlite3_free(pCheck);
+ }
+#ifdef SQLITE_ENABLE_API_ARMOR
+ else{
+ (void)SQLITE_MISUSE_BKPT;
+ }
+#endif
+}
+
+/*
+** Enter the mutex.
+*/
+static void checkMutexEnter(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){
+ if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){
+ return;
+ }
+ sqlite3_log(SQLITE_MISUSE,
+ "illegal multi-threaded access to database connection"
+ );
+ }
+ pGlobalMutexMethods->xMutexEnter(pCheck->mutex);
+}
+
+/*
+** Enter the mutex (do not block).
+*/
+static int checkMutexTry(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ return pGlobalMutexMethods->xMutexTry(pCheck->mutex);
+}
+
+/*
+** Leave the mutex.
+*/
+static void checkMutexLeave(sqlite3_mutex *p){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ pGlobalMutexMethods->xMutexLeave(pCheck->mutex);
+}
+
+sqlite3_mutex_methods const *multiThreadedCheckMutex(void){
+ static const sqlite3_mutex_methods sMutex = {
+ checkMutexInit,
+ checkMutexEnd,
+ checkMutexAlloc,
+ checkMutexFree,
+ checkMutexEnter,
+ checkMutexTry,
+ checkMutexLeave,
+#ifdef SQLITE_DEBUG
+ checkMutexHeld,
+ checkMutexNotheld
+#else
+ 0,
+ 0
+#endif
+ };
+ return &sMutex;
+}
+
+/*
+** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as
+** one on which there should be no contention.
+*/
+SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){
+ if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){
+ CheckMutex *pCheck = (CheckMutex*)p;
+ assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE );
+ pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION;
+ }
+}
+#endif /* ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS */
+
/*
** Initialize the mutex system.
*/
@@ -23315,7 +23704,11 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){
sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex;
if( sqlite3GlobalConfig.bCoreMutex ){
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+ pFrom = multiThreadedCheckMutex();
+#else
pFrom = sqlite3DefaultMutex();
+#endif
}else{
pFrom = sqlite3NoopMutex();
}
@@ -23442,6 +23835,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
#endif /* !defined(SQLITE_MUTEX_OMIT) */
+
/************** End of mutex.c ***********************************************/
/************** Begin file mutex_noop.c **************************************/
/*
@@ -24779,14 +25173,6 @@ SQLITE_API int sqlite3_release_memory(int n){
}
/*
-** An instance of the following object records the location of
-** each unused scratch buffer.
-*/
-typedef struct ScratchFreeslot {
- struct ScratchFreeslot *pNext; /* Next unused scratch buffer */
-} ScratchFreeslot;
-
-/*
** State information local to the memory allocation subsystem.
*/
static SQLITE_WSD struct Mem0Global {
@@ -24794,21 +25180,11 @@ static SQLITE_WSD struct Mem0Global {
sqlite3_int64 alarmThreshold; /* The soft heap limit */
/*
- ** Pointers to the end of sqlite3GlobalConfig.pScratch memory
- ** (so that a range test can be used to determine if an allocation
- ** being freed came from pScratch) and a pointer to the list of
- ** unused scratch allocations.
- */
- void *pScratchEnd;
- ScratchFreeslot *pScratchFree;
- u32 nScratchFree;
-
- /*
** True if heap is nearly "full" where "full" is defined by the
** sqlite3_soft_heap_limit() setting.
*/
int nearlyFull;
-} mem0 = { 0, 0, 0, 0, 0, 0 };
+} mem0 = { 0, 0, 0 };
#define mem0 GLOBAL(struct Mem0Global, mem0)
@@ -24878,28 +25254,6 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){
}
memset(&mem0, 0, sizeof(mem0));
mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
- if( sqlite3GlobalConfig.pScratch && sqlite3GlobalConfig.szScratch>=100
- && sqlite3GlobalConfig.nScratch>0 ){
- int i, n, sz;
- ScratchFreeslot *pSlot;
- sz = ROUNDDOWN8(sqlite3GlobalConfig.szScratch);
- sqlite3GlobalConfig.szScratch = sz;
- pSlot = (ScratchFreeslot*)sqlite3GlobalConfig.pScratch;
- n = sqlite3GlobalConfig.nScratch;
- mem0.pScratchFree = pSlot;
- mem0.nScratchFree = n;
- for(i=0; i<n-1; i++){
- pSlot->pNext = (ScratchFreeslot*)(sz+(char*)pSlot);
- pSlot = pSlot->pNext;
- }
- pSlot->pNext = 0;
- mem0.pScratchEnd = (void*)&pSlot[1];
- }else{
- mem0.pScratchEnd = 0;
- sqlite3GlobalConfig.pScratch = 0;
- sqlite3GlobalConfig.szScratch = 0;
- sqlite3GlobalConfig.nScratch = 0;
- }
if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512
|| sqlite3GlobalConfig.nPage<=0 ){
sqlite3GlobalConfig.pPage = 0;
@@ -25051,105 +25405,6 @@ SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){
}
/*
-** Each thread may only have a single outstanding allocation from
-** xScratchMalloc(). We verify this constraint in the single-threaded
-** case by setting scratchAllocOut to 1 when an allocation
-** is outstanding clearing it when the allocation is freed.
-*/
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-static int scratchAllocOut = 0;
-#endif
-
-
-/*
-** Allocate memory that is to be used and released right away.
-** This routine is similar to alloca() in that it is not intended
-** for situations where the memory might be held long-term. This
-** routine is intended to get memory to old large transient data
-** structures that would not normally fit on the stack of an
-** embedded processor.
-*/
-SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
- void *p;
- assert( n>0 );
-
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusHighwater(SQLITE_STATUS_SCRATCH_SIZE, n);
- if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
- p = mem0.pScratchFree;
- mem0.pScratchFree = mem0.pScratchFree->pNext;
- mem0.nScratchFree--;
- sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3_mutex_leave(mem0.mutex);
- p = sqlite3Malloc(n);
- if( sqlite3GlobalConfig.bMemstat && p ){
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
- sqlite3_mutex_leave(mem0.mutex);
- }
- sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
- }
- assert( sqlite3_mutex_notheld(mem0.mutex) );
-
-
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
- ** buffers per thread.
- **
- ** This can only be checked in single-threaded mode.
- */
- assert( scratchAllocOut==0 );
- if( p ) scratchAllocOut++;
-#endif
-
- return p;
-}
-SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
- if( p ){
-
-#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
- /* Verify that no more than two scratch allocation per thread
- ** is outstanding at one time. (This is only checked in the
- ** single-threaded case since checking in the multi-threaded case
- ** would be much more complicated.) */
- assert( scratchAllocOut>=1 && scratchAllocOut<=2 );
- scratchAllocOut--;
-#endif
-
- if( SQLITE_WITHIN(p, sqlite3GlobalConfig.pScratch, mem0.pScratchEnd) ){
- /* Release memory from the SQLITE_CONFIG_SCRATCH allocation */
- ScratchFreeslot *pSlot;
- pSlot = (ScratchFreeslot*)p;
- sqlite3_mutex_enter(mem0.mutex);
- pSlot->pNext = mem0.pScratchFree;
- mem0.pScratchFree = pSlot;
- mem0.nScratchFree++;
- assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
- sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- /* Release memory back to the heap */
- assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
- assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
- sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
- if( sqlite3GlobalConfig.bMemstat ){
- int iSize = sqlite3MallocSize(p);
- sqlite3_mutex_enter(mem0.mutex);
- sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
- sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
- sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
- sqlite3GlobalConfig.m.xFree(p);
- sqlite3_mutex_leave(mem0.mutex);
- }else{
- sqlite3GlobalConfig.m.xFree(p);
- }
- }
- }
-}
-
-/*
** TRUE if p is a lookaside memory allocation from db
*/
#ifndef SQLITE_OMIT_LOOKASIDE
@@ -25239,7 +25494,6 @@ SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){
#endif
pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf;
- db->lookaside.nOut--;
return;
}
}
@@ -25400,16 +25654,16 @@ SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){
assert( db->mallocFailed==0 );
if( n>db->lookaside.sz ){
db->lookaside.anStat[1]++;
- }else if( (pBuf = db->lookaside.pFree)==0 ){
- db->lookaside.anStat[2]++;
- }else{
+ }else if( (pBuf = db->lookaside.pFree)!=0 ){
db->lookaside.pFree = pBuf->pNext;
- db->lookaside.nOut++;
db->lookaside.anStat[0]++;
- if( db->lookaside.nOut>db->lookaside.mxOut ){
- db->lookaside.mxOut = db->lookaside.nOut;
- }
return (void*)pBuf;
+ }else if( (pBuf = db->lookaside.pInit)!=0 ){
+ db->lookaside.pInit = pBuf->pNext;
+ db->lookaside.anStat[0]++;
+ return (void*)pBuf;
+ }else{
+ db->lookaside.anStat[2]++;
}
}else if( db->mallocFailed ){
return 0;
@@ -25514,6 +25768,19 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
}
/*
+** The text between zStart and zEnd represents a phrase within a larger
+** SQL statement. Make a copy of this phrase in space obtained form
+** sqlite3DbMalloc(). Omit leading and trailing whitespace.
+*/
+SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
+ int n;
+ while( sqlite3Isspace(zStart[0]) ) zStart++;
+ n = (int)(zEnd - zStart);
+ while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--;
+ return sqlite3DbStrNDup(db, zStart, n);
+}
+
+/*
** Free any prior content in *pz and replace it with a copy of zNew.
*/
SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
@@ -26247,7 +26514,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( precision>=0 ){
for(length=0; length<precision && bufpt[length]; length++){}
}else{
- length = sqlite3Strlen30(bufpt);
+ length = 0x7fffffff & (int)strlen(bufpt);
}
break;
case etSQLESCAPE: /* Escape ' characters */
@@ -26373,7 +26640,6 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
}else{
char *zOld = isMalloced(p) ? p->zText : 0;
i64 szNew = p->nChar;
- assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
szNew += N + 1;
if( szNew+p->nChar<=p->mxAlloc ){
/* Force exponential buffer size growth as long as it does not overflow,
@@ -26415,7 +26681,6 @@ SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
return;
}
- assert( (p->zText==p->zBase)==!isMalloced(p) );
while( (N--)>0 ) p->zText[p->nChar++] = c;
}
@@ -26433,7 +26698,6 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
- assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
}
/*
@@ -26468,19 +26732,20 @@ SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
** pointer if any kind of error was encountered.
*/
static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
+ char *zText;
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);
+ zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
+ if( zText ){
+ memcpy(zText, p->zText, p->nChar+1);
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{
setStrAccumError(p, STRACCUM_NOMEM);
}
- return p->zText;
+ p->zText = zText;
+ return 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) ){
return strAccumFinishRealloc(p);
@@ -26493,7 +26758,6 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
** Reset an StrAccum string. Reclaim all malloced memory.
*/
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
- assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
if( isMalloced(p) ){
sqlite3DbFree(p->db, p->zText);
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
@@ -26516,11 +26780,11 @@ SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
** allocations will ever occur.
*/
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
- p->zText = p->zBase = zBase;
+ p->zText = zBase;
p->db = db;
- p->nChar = 0;
p->nAlloc = n;
p->mxAlloc = mx;
+ p->nChar = 0;
p->accError = 0;
p->printfFlags = 0;
}
@@ -26686,8 +26950,15 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
sqlite3VXPrintf(&acc, zFormat, ap);
va_end(ap);
sqlite3StrAccumFinish(&acc);
+#ifdef SQLITE_OS_TRACE_PROC
+ {
+ extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf);
+ SQLITE_OS_TRACE_PROC(zBuf, sizeof(zBuf));
+ }
+#else
fprintf(stdout,"%s", zBuf);
fflush(stdout);
+#endif
}
#endif
@@ -26860,7 +27131,6 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
if( p->pHaving ) n++;
if( p->pOrderBy ) n++;
if( p->pLimit ) n++;
- if( p->pOffset ) n++;
}
sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
if( p->pSrc && p->pSrc->nSrc ){
@@ -26917,12 +27187,12 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
}
if( p->pLimit ){
sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pLimit, 0);
- sqlite3TreeViewPop(pView);
- }
- if( p->pOffset ){
- sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
- sqlite3TreeViewExpr(pView, p->pOffset, 0);
+ sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0);
+ if( p->pLimit->pRight ){
+ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+ sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
+ sqlite3TreeViewPop(pView);
+ }
sqlite3TreeViewPop(pView);
}
if( p->pPrior ){
@@ -27215,12 +27485,20 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nExpr; i++){
int j = pList->a[i].u.x.iOrderByCol;
- if( j ){
+ char *zName = pList->a[i].zName;
+ if( j || zName ){
sqlite3TreeViewPush(pView, 0);
+ }
+ if( zName ){
+ sqlite3TreeViewLine(pView, "AS %s", zName);
+ }
+ if( j ){
sqlite3TreeViewLine(pView, "iOrderByCol=%d", j);
}
sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
- if( j ) sqlite3TreeViewPop(pView);
+ if( j || zName ){
+ sqlite3TreeViewPop(pView);
+ }
}
}
}
@@ -28511,6 +28789,45 @@ SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
}
/*
+** Compute 10 to the E-th power. Examples: E==1 results in 10.
+** E==2 results in 100. E==50 results in 1.0e50.
+**
+** This routine only works for values of E between 1 and 341.
+*/
+static LONGDOUBLE_TYPE sqlite3Pow10(int E){
+#if defined(_MSC_VER)
+ static const LONGDOUBLE_TYPE x[] = {
+ 1.0e+001,
+ 1.0e+002,
+ 1.0e+004,
+ 1.0e+008,
+ 1.0e+016,
+ 1.0e+032,
+ 1.0e+064,
+ 1.0e+128,
+ 1.0e+256
+ };
+ LONGDOUBLE_TYPE r = 1.0;
+ int i;
+ assert( E>=0 && E<=307 );
+ for(i=0; E!=0; i++, E >>=1){
+ if( E & 1 ) r *= x[i];
+ }
+ return r;
+#else
+ LONGDOUBLE_TYPE x = 10.0;
+ LONGDOUBLE_TYPE r = 1.0;
+ while(1){
+ if( E & 1 ) r *= x;
+ E >>= 1;
+ if( E==0 ) break;
+ x *= x;
+ }
+ return r;
+#endif
+}
+
+/*
** The string z[] is an text representation of a real number.
** Convert this string to a double and write it into *pResult.
**
@@ -28577,12 +28894,12 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
/* copy max significant digits to significand */
while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
s = s*10 + (*z - '0');
- z+=incr, nDigits++;
+ z+=incr; nDigits++;
}
/* skip non-significant significand digits
** (increase exponent by d to shift decimal left) */
- while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
+ while( z<zEnd && sqlite3Isdigit(*z) ){ z+=incr; nDigits++; d++; }
if( z>=zEnd ) goto do_atof_calc;
/* if decimal point is present */
@@ -28595,7 +28912,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en
s = s*10 + (*z - '0');
d--;
}
- z+=incr, nDigits++;
+ z+=incr; nDigits++;
}
}
if( z>=zEnd ) goto do_atof_calc;
@@ -28665,11 +28982,10 @@ do_atof_calc:
if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/
result = (double)s;
}else{
- LONGDOUBLE_TYPE scale = 1.0;
/* attempt to handle extremely small/large numbers better */
if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/
if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/
- while( e%308 ) { scale *= 1.0e+1; e -= 1; }
+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308);
if( esign<0 ){
result = s / scale;
result /= 1.0e+308;
@@ -28681,14 +28997,15 @@ do_atof_calc:
if( esign<0 ){
result = 0.0*s;
}else{
+#ifdef INFINITY
+ result = INFINITY*s;
+#else
result = 1e308*1e308*s; /* Infinity */
+#endif
}
}
}else{
- /* 1.0e+22 is the largest power of 10 than can be
- ** represented exactly. */
- while( e%22 ) { scale *= 1.0e+1; e -= 1; }
- while( e>0 ) { scale *= 1.0e+22; e -= 22; }
+ LONGDOUBLE_TYPE scale = sqlite3Pow10(e);
if( esign<0 ){
result = s / scale;
}else{
@@ -28743,16 +29060,12 @@ static int compare2pow63(const char *zNum, int incr){
** Convert zNum to a 64-bit signed integer. zNum must be decimal. This
** routine does *not* accept hexadecimal notation.
**
-** If the zNum value is representable as a 64-bit twos-complement
-** integer, then write that value into *pNum and return 0.
-**
-** If zNum is exactly 9223372036854775808, return 2. This special
-** case is broken out because while 9223372036854775808 cannot be a
-** signed 64-bit integer, its negative -9223372036854775808 can be.
+** Returns:
**
-** If zNum is too big for a 64-bit integer and is not
-** 9223372036854775808 or if zNum contains any non-numeric text,
-** then return 1.
+** 0 Successful transformation. Fits in a 64-bit signed integer.
+** 1 Excess text after the integer value
+** 2 Integer too large for a 64-bit signed integer or is malformed
+** 3 Special case of 9223372036854775808
**
** length is the number of bytes in the string (bytes, not characters).
** The string is not necessarily zero-terminated. The encoding is
@@ -28765,6 +29078,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
int i;
int c = 0;
int nonNum = 0; /* True if input contains UTF16 with high byte non-zero */
+ int rc; /* Baseline return code */
const char *zStart;
const char *zEnd = zNum + length;
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
@@ -28804,31 +29118,35 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
testcase( i==20 );
if( &zNum[i]<zEnd /* Extra bytes at the end */
|| (i==0 && zStart==zNum) /* No digits */
- || i>19*incr /* Too many digits */
|| nonNum /* UTF16 with high-order bytes non-zero */
){
+ rc = 1;
+ }else{
+ rc = 0;
+ }
+ if( i>19*incr ){ /* Too many digits */
/* zNum is empty or contains non-numeric text or is longer
** than 19 digits (thus guaranteeing that it is too large) */
- return 1;
+ return 2;
}else if( i<19*incr ){
/* Less than 19 digits, so we know that it fits in 64 bits */
assert( u<=LARGEST_INT64 );
- return 0;
+ return rc;
}else{
/* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
c = compare2pow63(zNum, incr);
if( c<0 ){
/* zNum is less than 9223372036854775808 so it fits */
assert( u<=LARGEST_INT64 );
- return 0;
+ return rc;
}else if( c>0 ){
/* zNum is greater than 9223372036854775808 so it overflows */
- return 1;
+ return 2;
}else{
/* zNum is exactly 9223372036854775808. Fits if negative. The
** special case 2 overflow if positive */
assert( u-1==LARGEST_INT64 );
- return neg ? 0 : 2;
+ return neg ? rc : 3;
}
}
}
@@ -28841,8 +29159,9 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc
** Returns:
**
** 0 Successful transformation. Fits in a 64-bit signed integer.
-** 1 Integer too large for a 64-bit signed integer or is malformed
-** 2 Special case of 9223372036854775808
+** 1 Excess text after the integer value
+** 2 Integer too large for a 64-bit signed integer or is malformed
+** 3 Special case of 9223372036854775808
*/
SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
#ifndef SQLITE_OMIT_HEX_INTEGER
@@ -28856,7 +29175,7 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
u = u*16 + sqlite3HexToInt(z[k]);
}
memcpy(pOut, &u, 8);
- return (z[k]==0 && k-i<=16) ? 0 : 1;
+ return (z[k]==0 && k-i<=16) ? 0 : 2;
}else
#endif /* SQLITE_OMIT_HEX_INTEGER */
{
@@ -29466,7 +29785,7 @@ 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
+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
return __builtin_add_overflow(*pA, iB, pA);
#else
i64 iA = *pA;
@@ -29486,7 +29805,7 @@ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
#endif
}
SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
-#if GCC_VERSION>=5004000
+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
return __builtin_sub_overflow(*pA, iB, pA);
#else
testcase( iB==SMALLEST_INT64+1 );
@@ -29501,7 +29820,7 @@ SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
#endif
}
SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
-#if GCC_VERSION>=5004000
+#if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER)
return __builtin_mul_overflow(*pA, iB, pA);
#else
i64 iA = *pA;
@@ -29603,8 +29922,14 @@ SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){
if( x<2 ) return 0;
while( x<8 ){ y -= 10; x <<= 1; }
}else{
+#if GCC_VERSION>=5004000
+ int i = 60 - __builtin_clzll(x);
+ y += i*10;
+ x >>= i;
+#else
while( x>255 ){ y += 40; x >>= 4; } /*OPTIMIZATION-IF-TRUE*/
while( x>15 ){ y += 10; x >>= 1; }
+#endif
}
return a[x&7] + y - 10;
}
@@ -30085,47 +30410,47 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"),
/* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"),
/* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
- /* 43 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
- /* 44 */ "Program" OpHelp(""),
- /* 45 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 46 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
- /* 47 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
- /* 48 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
- /* 49 */ "IncrVacuum" OpHelp(""),
- /* 50 */ "VNext" OpHelp(""),
- /* 51 */ "Init" OpHelp("Start at P2"),
- /* 52 */ "Return" OpHelp(""),
- /* 53 */ "EndCoroutine" OpHelp(""),
- /* 54 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
- /* 55 */ "Halt" OpHelp(""),
- /* 56 */ "Integer" OpHelp("r[P2]=P1"),
- /* 57 */ "Int64" OpHelp("r[P2]=P4"),
- /* 58 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
- /* 59 */ "Null" OpHelp("r[P2..P3]=NULL"),
- /* 60 */ "SoftNull" OpHelp("r[P1]=NULL"),
- /* 61 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 62 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
- /* 63 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 64 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
- /* 65 */ "SCopy" OpHelp("r[P2]=r[P1]"),
- /* 66 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
- /* 67 */ "ResultRow" OpHelp("output=r[P1@P2]"),
- /* 68 */ "CollSeq" OpHelp(""),
- /* 69 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
- /* 70 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
- /* 71 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
- /* 72 */ "RealAffinity" OpHelp(""),
- /* 73 */ "Cast" OpHelp("affinity(r[P1])"),
- /* 74 */ "Permutation" OpHelp(""),
- /* 75 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 76 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 77 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
- /* 78 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
- /* 79 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
- /* 80 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
- /* 81 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
- /* 82 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
- /* 83 */ "ElseNotEq" OpHelp(""),
+ /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 45 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 46 */ "Program" OpHelp(""),
+ /* 47 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 48 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"),
+ /* 49 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
+ /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"),
+ /* 53 */ "Eq" OpHelp("IF r[P3]==r[P1]"),
+ /* 54 */ "Gt" OpHelp("IF r[P3]>r[P1]"),
+ /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"),
+ /* 56 */ "Lt" OpHelp("IF r[P3]<r[P1]"),
+ /* 57 */ "Ge" OpHelp("IF r[P3]>=r[P1]"),
+ /* 58 */ "ElseNotEq" OpHelp(""),
+ /* 59 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
+ /* 60 */ "IncrVacuum" OpHelp(""),
+ /* 61 */ "VNext" OpHelp(""),
+ /* 62 */ "Init" OpHelp("Start at P2"),
+ /* 63 */ "Return" OpHelp(""),
+ /* 64 */ "EndCoroutine" OpHelp(""),
+ /* 65 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 66 */ "Halt" OpHelp(""),
+ /* 67 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 68 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 69 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 70 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 71 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 72 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 73 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 74 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 75 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 76 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 77 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
+ /* 78 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 79 */ "CollSeq" OpHelp(""),
+ /* 80 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 81 */ "RealAffinity" OpHelp(""),
+ /* 82 */ "Cast" OpHelp("affinity(r[P1])"),
+ /* 83 */ "Permutation" OpHelp(""),
/* 84 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
/* 85 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
/* 86 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
@@ -30138,78 +30463,80 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 93 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
/* 94 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
/* 95 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
- /* 96 */ "Column" OpHelp("r[P3]=PX"),
+ /* 96 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
/* 97 */ "String8" OpHelp("r[P2]='P4'"),
- /* 98 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
- /* 99 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 100 */ "Count" OpHelp("r[P2]=count()"),
- /* 101 */ "ReadCookie" OpHelp(""),
- /* 102 */ "SetCookie" OpHelp(""),
- /* 103 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
- /* 104 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 105 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 106 */ "OpenDup" OpHelp(""),
- /* 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 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
- /* 129 */ "IdxRowid" OpHelp("r[P2]=rowid"),
- /* 130 */ "Destroy" OpHelp(""),
- /* 131 */ "Clear" 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 */ "OpenDup" OpHelp(""),
+ /* 108 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 109 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 110 */ "SorterOpen" OpHelp(""),
+ /* 111 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+ /* 112 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 113 */ "Close" OpHelp(""),
+ /* 114 */ "ColumnsUsed" OpHelp(""),
+ /* 115 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
+ /* 116 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 117 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 118 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 119 */ "Delete" OpHelp(""),
+ /* 120 */ "ResetCount" OpHelp(""),
+ /* 121 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+ /* 122 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 123 */ "RowData" OpHelp("r[P2]=data"),
+ /* 124 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 125 */ "NullRow" OpHelp(""),
+ /* 126 */ "SeekEnd" OpHelp(""),
+ /* 127 */ "SorterInsert" OpHelp("key=r[P2]"),
+ /* 128 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 129 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 130 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
+ /* 131 */ "IdxRowid" OpHelp("r[P2]=rowid"),
/* 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 */ "PureFunc0" OpHelp(""),
- /* 162 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 163 */ "PureFunc" OpHelp(""),
- /* 164 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
- /* 165 */ "CursorHint" OpHelp(""),
- /* 166 */ "Noop" OpHelp(""),
- /* 167 */ "Explain" OpHelp(""),
+ /* 133 */ "Destroy" OpHelp(""),
+ /* 134 */ "Clear" OpHelp(""),
+ /* 135 */ "ResetSorter" OpHelp(""),
+ /* 136 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
+ /* 137 */ "SqlExec" OpHelp(""),
+ /* 138 */ "ParseSchema" OpHelp(""),
+ /* 139 */ "LoadAnalysis" OpHelp(""),
+ /* 140 */ "DropTable" OpHelp(""),
+ /* 141 */ "DropIndex" OpHelp(""),
+ /* 142 */ "DropTrigger" OpHelp(""),
+ /* 143 */ "IntegrityCk" OpHelp(""),
+ /* 144 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 145 */ "Param" OpHelp(""),
+ /* 146 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 147 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 148 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+ /* 149 */ "AggStep0" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 150 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
+ /* 151 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 152 */ "Expire" OpHelp(""),
+ /* 153 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 154 */ "VBegin" OpHelp(""),
+ /* 155 */ "VCreate" OpHelp(""),
+ /* 156 */ "VDestroy" OpHelp(""),
+ /* 157 */ "VOpen" OpHelp(""),
+ /* 158 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 159 */ "VRename" OpHelp(""),
+ /* 160 */ "Pagecount" OpHelp(""),
+ /* 161 */ "MaxPgcnt" OpHelp(""),
+ /* 162 */ "PureFunc0" OpHelp(""),
+ /* 163 */ "Function0" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 164 */ "PureFunc" OpHelp(""),
+ /* 165 */ "Function" OpHelp("r[P3]=func(r[P2@P5])"),
+ /* 166 */ "Trace" OpHelp(""),
+ /* 167 */ "CursorHint" OpHelp(""),
+ /* 168 */ "Noop" OpHelp(""),
+ /* 169 */ "Explain" OpHelp(""),
};
return azName[i];
}
@@ -30309,6 +30636,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/ioctl.h>
#include <unistd.h>
/* #include <time.h> */
#include <sys/time.h>
@@ -30318,7 +30646,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
-# include <sys/ioctl.h>
+/* # include <sys/ioctl.h> */
# include <sys/file.h>
# include <sys/param.h>
#endif /* SQLITE_ENABLE_LOCKING_STYLE */
@@ -30428,7 +30756,7 @@ struct unixFile {
unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
int lastErrno; /* The unix errno from last I/O error */
void *lockingContext; /* Locking style specific state */
- UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */
+ UnixUnusedFd *pPreallocatedUnused; /* Pre-allocated UnixUnusedFd */
const char *zPath; /* Name of the file */
unixShm *pShm; /* Shared memory segment information */
int szChunk; /* Configured by FCNTL_CHUNK_SIZE */
@@ -30439,10 +30767,8 @@ struct unixFile {
sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */
void *pMapRegion; /* Memory mapped region */
#endif
-#ifdef __QNXNTO__
int sectorSize; /* Device sector size */
int deviceCharacteristics; /* Precomputed device characteristics */
-#endif
#if SQLITE_ENABLE_LOCKING_STYLE
int openFlags; /* The flags specified at open() */
#endif
@@ -30745,6 +31071,20 @@ SQLITE_API extern int sqlite3_open_file_count;
# define lseek lseek64
#endif
+#ifdef __linux__
+/*
+** Linux-specific IOCTL magic numbers used for controlling F2FS
+*/
+#define F2FS_IOCTL_MAGIC 0xf5
+#define F2FS_IOC_START_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 1)
+#define F2FS_IOC_COMMIT_ATOMIC_WRITE _IO(F2FS_IOCTL_MAGIC, 2)
+#define F2FS_IOC_START_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 3)
+#define F2FS_IOC_ABORT_VOLATILE_WRITE _IO(F2FS_IOCTL_MAGIC, 5)
+#define F2FS_IOC_GET_FEATURES _IOR(F2FS_IOCTL_MAGIC, 12, u32)
+#define F2FS_FEATURE_ATOMIC_WRITE 0x0004
+#endif /* __linux__ */
+
+
/*
** Different Unix systems declare open() in different ways. Same use
** open(const char*,int,mode_t). Others use open(const char*,int,...).
@@ -30887,7 +31227,7 @@ static struct unix_syscall {
#else
{ "munmap", (sqlite3_syscall_ptr)0, 0 },
#endif
-#define osMunmap ((void*(*)(void*,size_t))aSyscall[23].pCurrent)
+#define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent)
#if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
@@ -30917,6 +31257,13 @@ static struct unix_syscall {
#endif
#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 },
+#else
+ { "ioctl", (sqlite3_syscall_ptr)0, 0 },
+#endif
+#define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent)
+
}; /* End of the overrideable system calls */
@@ -31521,7 +31868,8 @@ struct unixInodeInfo {
/*
** A lists of all unixInodeInfo objects.
*/
-static unixInodeInfo *inodeList = 0;
+static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */
+static unsigned int nUnusedFd = 0; /* Total unused file descriptors */
/*
**
@@ -31631,6 +31979,7 @@ static void closePendingFds(unixFile *pFile){
pNext = p->pNext;
robust_close(pFile, p->fd, __LINE__);
sqlite3_free(p);
+ nUnusedFd--;
}
pInode->pUnused = 0;
}
@@ -31663,6 +32012,7 @@ static void releaseInodeInfo(unixFile *pFile){
sqlite3_free(pInode);
}
}
+ assert( inodeList!=0 || nUnusedFd==0 );
}
/*
@@ -31732,6 +32082,7 @@ static int findInodeInfo(
#else
fileId.ino = (u64)statbuf.st_ino;
#endif
+ assert( inodeList!=0 || nUnusedFd==0 );
pInode = inodeList;
while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
pInode = pInode->pNext;
@@ -32151,11 +32502,12 @@ end_lock:
*/
static void setPendingFd(unixFile *pFile){
unixInodeInfo *pInode = pFile->pInode;
- UnixUnusedFd *p = pFile->pUnused;
+ UnixUnusedFd *p = pFile->pPreallocatedUnused;
p->pNext = pInode->pUnused;
pInode->pUnused = p;
pFile->h = -1;
- pFile->pUnused = 0;
+ pFile->pPreallocatedUnused = 0;
+ nUnusedFd++;
}
/*
@@ -32380,7 +32732,7 @@ static int closeUnixFile(sqlite3_file *id){
#endif
OSTRACE(("CLOSE %-3d\n", pFile->h));
OpenCounter(-1);
- sqlite3_free(pFile->pUnused);
+ sqlite3_free(pFile->pPreallocatedUnused);
memset(pFile, 0, sizeof(unixFile));
return SQLITE_OK;
}
@@ -32717,7 +33069,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
OSTRACE(("TEST WR-LOCK %d %d %d (flock)\n", pFile->h, rc, reserved));
#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
+ if( (rc & 0xff) == SQLITE_IOERR ){
rc = SQLITE_OK;
reserved=1;
}
@@ -32784,7 +33136,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock),
rc==SQLITE_OK ? "ok" : "failed"));
#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
- if( (rc & SQLITE_IOERR) == SQLITE_IOERR ){
+ if( (rc & 0xff) == SQLITE_IOERR ){
rc = SQLITE_BUSY;
}
#endif /* SQLITE_IGNORE_FLOCK_LOCK_ERRORS */
@@ -33321,7 +33673,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
/* Can't reestablish the shared lock. Sqlite can't deal, this is
** a critical I/O error
*/
- rc = ((failed & SQLITE_IOERR) == SQLITE_IOERR) ? failed2 :
+ rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 :
SQLITE_IOERR_LOCK;
goto afp_end_lock;
}
@@ -33601,7 +33953,7 @@ static int unixRead(
/* If this is a database file (not a journal, master-journal or temp
** file), the bytes in the locking range should never be read or written. */
#if 0
- assert( pFile->pUnused==0
+ assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
@@ -33714,7 +34066,7 @@ static int unixWrite(
/* If this is a database file (not a journal, master-journal or temp
** file), the bytes in the locking range should never be read or written. */
#if 0
- assert( pFile->pUnused==0
+ assert( pFile->pPreallocatedUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
@@ -34194,6 +34546,21 @@ static int unixGetTempname(int nBuf, char *zBuf);
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: {
+ int rc = osIoctl(pFile->h, F2FS_IOC_START_ATOMIC_WRITE);
+ return rc ? SQLITE_IOERR_BEGIN_ATOMIC : SQLITE_OK;
+ }
+ case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: {
+ int rc = osIoctl(pFile->h, F2FS_IOC_COMMIT_ATOMIC_WRITE);
+ return rc ? SQLITE_IOERR_COMMIT_ATOMIC : SQLITE_OK;
+ }
+ case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: {
+ int rc = osIoctl(pFile->h, F2FS_IOC_ABORT_VOLATILE_WRITE);
+ return rc ? SQLITE_IOERR_ROLLBACK_ATOMIC : SQLITE_OK;
+ }
+#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
+
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;
@@ -34244,6 +34611,14 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
if( newLimit>sqlite3GlobalConfig.mxMmap ){
newLimit = sqlite3GlobalConfig.mxMmap;
}
+
+ /* The value of newLimit may be eventually cast to (size_t) and passed
+ ** to mmap(). Restrict its value to 2GB if (size_t) is not at least a
+ ** 64-bit type. */
+ if( newLimit>0 && sizeof(size_t)<8 ){
+ newLimit = (newLimit & 0x7FFFFFFF);
+ }
+
*(i64*)pArg = pFile->mmapSizeMax;
if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
pFile->mmapSizeMax = newLimit;
@@ -34277,30 +34652,41 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
/*
-** Return the sector size in bytes of the underlying block device for
-** the specified file. This is almost always 512 bytes, but may be
-** larger for some devices.
+** If pFd->sectorSize is non-zero when this function is called, it is a
+** no-op. Otherwise, the values of pFd->sectorSize and
+** pFd->deviceCharacteristics are set according to the file-system
+** characteristics.
**
-** SQLite code assumes this function cannot fail. It also assumes that
-** if two files are created in the same file-system directory (i.e.
-** a database and its journal file) that the sector size will be the
-** same for both.
+** There are two versions of this function. One for QNX and one for all
+** other systems.
*/
-#ifndef __QNXNTO__
-static int unixSectorSize(sqlite3_file *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- return SQLITE_DEFAULT_SECTOR_SIZE;
-}
-#endif
+#ifndef __QNXNTO__
+static void setDeviceCharacteristics(unixFile *pFd){
+ assert( pFd->deviceCharacteristics==0 || pFd->sectorSize!=0 );
+ if( pFd->sectorSize==0 ){
+#if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ int res;
+ u32 f = 0;
-/*
-** The following version of unixSectorSize() is optimized for QNX.
-*/
-#ifdef __QNXNTO__
+ /* Check for support for F2FS atomic batch writes. */
+ res = osIoctl(pFd->h, F2FS_IOC_GET_FEATURES, &f);
+ if( res==0 && (f & F2FS_FEATURE_ATOMIC_WRITE) ){
+ pFd->deviceCharacteristics = SQLITE_IOCAP_BATCH_ATOMIC;
+ }
+#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
+
+ /* Set the POWERSAFE_OVERWRITE flag if requested. */
+ if( pFd->ctrlFlags & UNIXFILE_PSOW ){
+ pFd->deviceCharacteristics |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
+ }
+
+ pFd->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
+ }
+}
+#else
#include <sys/dcmd_blk.h>
#include <sys/statvfs.h>
-static int unixSectorSize(sqlite3_file *id){
- unixFile *pFile = (unixFile*)id;
+static void setDeviceCharacteristics(unixFile *pFile){
if( pFile->sectorSize == 0 ){
struct statvfs fsInfo;
@@ -34308,7 +34694,7 @@ static int unixSectorSize(sqlite3_file *id){
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
pFile->deviceCharacteristics = 0;
if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
- return pFile->sectorSize;
+ return;
}
if( !strcmp(fsInfo.f_basetype, "tmp") ) {
@@ -34369,9 +34755,24 @@ static int unixSectorSize(sqlite3_file *id){
pFile->deviceCharacteristics = 0;
pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
}
- return pFile->sectorSize;
}
-#endif /* __QNXNTO__ */
+#endif
+
+/*
+** Return the sector size in bytes of the underlying block device for
+** the specified file. This is almost always 512 bytes, but may be
+** larger for some devices.
+**
+** SQLite code assumes this function cannot fail. It also assumes that
+** if two files are created in the same file-system directory (i.e.
+** a database and its journal file) that the sector size will be the
+** same for both.
+*/
+static int unixSectorSize(sqlite3_file *id){
+ unixFile *pFd = (unixFile*)id;
+ setDeviceCharacteristics(pFd);
+ return pFd->sectorSize;
+}
/*
** Return the device characteristics for the file.
@@ -34387,16 +34788,9 @@ static int unixSectorSize(sqlite3_file *id){
** available to turn it off and URI query parameter available to turn it off.
*/
static int unixDeviceCharacteristics(sqlite3_file *id){
- unixFile *p = (unixFile*)id;
- int rc = 0;
-#ifdef __QNXNTO__
- if( p->sectorSize==0 ) unixSectorSize(id);
- rc = p->deviceCharacteristics;
-#endif
- if( p->ctrlFlags & UNIXFILE_PSOW ){
- rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
- }
- return rc;
+ unixFile *pFd = (unixFile*)id;
+ setDeviceCharacteristics(pFd);
+ return pFd->deviceCharacteristics;
}
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
@@ -34458,6 +34852,7 @@ struct unixShmNode {
int szRegion; /* Size of shared-memory regions */
u16 nRegion; /* Size of array apRegion */
u8 isReadonly; /* True if read-only */
+ u8 isUnlocked; /* True if no DMS lock held */
char **apRegion; /* Array of mapped shared-memory regions */
int nRef; /* Number of unixShm objects pointing to this */
unixShm *pFirst; /* All unixShm objects pointing to this */
@@ -34514,7 +34909,7 @@ static int unixShmSystemLock(
/* Access to the unixShmNode object is serialized by the caller */
pShmNode = pFile->pInode->pShmNode;
- assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
+ assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
@@ -34621,6 +35016,64 @@ static void unixShmPurge(unixFile *pFd){
}
/*
+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
+** take it now. Return SQLITE_OK if successful, or an SQLite error
+** code otherwise.
+**
+** If the DMS cannot be locked because this is a readonly_shm=1
+** connection and no other process already holds a lock, return
+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
+*/
+static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){
+ struct flock lock;
+ int rc = SQLITE_OK;
+
+ /* Use F_GETLK to determine the locks other processes are holding
+ ** on the DMS byte. If it indicates that another process is holding
+ ** a SHARED lock, then this process may also take a SHARED lock
+ ** and proceed with opening the *-shm file.
+ **
+ ** Or, if no other process is holding any lock, then this process
+ ** is the first to open it. In this case take an EXCLUSIVE lock on the
+ ** DMS byte and truncate the *-shm file to zero bytes in size. Then
+ ** downgrade to a SHARED lock on the DMS byte.
+ **
+ ** If another process is holding an EXCLUSIVE lock on the DMS byte,
+ ** return SQLITE_BUSY to the caller (it will try again). An earlier
+ ** version of this code attempted the SHARED lock at this point. But
+ ** this introduced a subtle race condition: if the process holding
+ ** EXCLUSIVE failed just before truncating the *-shm file, then this
+ ** process might open and use the *-shm file without truncating it.
+ ** And if the *-shm file has been corrupted by a power failure or
+ ** system crash, the database itself may also become corrupt. */
+ lock.l_whence = SEEK_SET;
+ lock.l_start = UNIX_SHM_DMS;
+ lock.l_len = 1;
+ lock.l_type = F_WRLCK;
+ if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
+ rc = SQLITE_IOERR_LOCK;
+ }else if( lock.l_type==F_UNLCK ){
+ if( pShmNode->isReadonly ){
+ pShmNode->isUnlocked = 1;
+ rc = SQLITE_READONLY_CANTINIT;
+ }else{
+ rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1);
+ if( rc==SQLITE_OK && robust_ftruncate(pShmNode->h, 0) ){
+ rc = unixLogError(SQLITE_IOERR_SHMOPEN,"ftruncate",pShmNode->zFilename);
+ }
+ }
+ }else if( lock.l_type==F_WRLCK ){
+ rc = SQLITE_BUSY;
+ }
+
+ if( rc==SQLITE_OK ){
+ assert( lock.l_type==F_UNLCK || lock.l_type==F_RDLCK );
+ rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
+ }
+ return rc;
+}
+
+/*
** Open a shared-memory area associated with open database file pDbFd.
** This particular implementation uses mmapped files.
**
@@ -34658,9 +35111,9 @@ static void unixShmPurge(unixFile *pFd){
static int unixOpenSharedMemory(unixFile *pDbFd){
struct unixShm *p = 0; /* The connection to be opened */
struct unixShmNode *pShmNode; /* The underlying mmapped file */
- int rc; /* Result code */
+ int rc = SQLITE_OK; /* Result code */
unixInodeInfo *pInode; /* The inode of fd */
- char *zShmFilename; /* Name of the file used for SHM */
+ char *zShm; /* Name of the file used for SHM */
int nShmFilename; /* Size of the SHM filename in bytes */
/* Allocate space for the new unixShm object. */
@@ -34701,14 +35154,14 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
goto shm_open_err;
}
memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
- zShmFilename = pShmNode->zFilename = (char*)&pShmNode[1];
+ zShm = pShmNode->zFilename = (char*)&pShmNode[1];
#ifdef SQLITE_SHM_DIRECTORY
- sqlite3_snprintf(nShmFilename, zShmFilename,
+ sqlite3_snprintf(nShmFilename, zShm,
SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
(u32)sStat.st_ino, (u32)sStat.st_dev);
#else
- sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
- sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
+ sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
+ sqlite3FileSuffix3(pDbFd->zPath, zShm);
#endif
pShmNode->h = -1;
pDbFd->pInode->pShmNode = pShmNode;
@@ -34722,15 +35175,16 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
}
if( pInode->bProcessLock==0 ){
- int openFlags = O_RDWR | O_CREAT;
- if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
- openFlags = O_RDONLY;
- pShmNode->isReadonly = 1;
+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+ pShmNode->h = robust_open(zShm, O_RDWR|O_CREAT, (sStat.st_mode&0777));
}
- pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
if( pShmNode->h<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
- goto shm_open_err;
+ pShmNode->h = robust_open(zShm, O_RDONLY, (sStat.st_mode&0777));
+ if( pShmNode->h<0 ){
+ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShm);
+ goto shm_open_err;
+ }
+ pShmNode->isReadonly = 1;
}
/* If this process is running as root, make sure that the SHM file
@@ -34738,20 +35192,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
** the original owner will not be able to connect.
*/
robustFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
-
- /* Check to see if another process is holding the dead-man switch.
- ** If not, truncate the file to zero length.
- */
- rc = SQLITE_OK;
- if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
- if( robust_ftruncate(pShmNode->h, 0) ){
- rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
- }
- }
- if( rc==SQLITE_OK ){
- rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
- }
- if( rc ) goto shm_open_err;
+
+ rc = unixLockSharedMemory(pDbFd, pShmNode);
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
}
}
@@ -34775,7 +35218,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
sqlite3_mutex_leave(pShmNode->mutex);
- return SQLITE_OK;
+ return rc;
/* Jump here on any error */
shm_open_err:
@@ -34827,6 +35270,11 @@ static int unixShmMap(
p = pDbFd->pShm;
pShmNode = p->pShmNode;
sqlite3_mutex_enter(pShmNode->mutex);
+ if( pShmNode->isUnlocked ){
+ rc = unixLockSharedMemory(pDbFd, pShmNode);
+ if( rc!=SQLITE_OK ) goto shmpage_out;
+ pShmNode->isUnlocked = 0;
+ }
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
assert( pShmNode->pInode==pDbFd->pInode );
assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
@@ -35654,17 +36102,6 @@ static int fillInUnixFile(
assert( pNew->pInode==NULL );
- /* Usually the path zFilename should not be a relative pathname. The
- ** exception is when opening the proxy "conch" file in builds that
- ** include the special Apple locking styles.
- */
-#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
- assert( zFilename==0 || zFilename[0]=='/'
- || pVfs->pAppData==(void*)&autolockIoFinder );
-#else
- assert( zFilename==0 || zFilename[0]=='/' );
-#endif
-
/* No locking occurs in temporary files */
assert( zFilename!=0 || (ctrlFlags & UNIXFILE_NOLOCK)!=0 );
@@ -35923,6 +36360,8 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
#if !OS_VXWORKS
struct stat sStat; /* Results of stat() call */
+ unixEnterMutex();
+
/* A stat() call may fail for various reasons. If this happens, it is
** almost certain that an open() call on the same path will also fail.
** For this reason, if an error occurs in the stat() call here, it is
@@ -35931,10 +36370,9 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
**
** Even if a subsequent open() call does succeed, the consequences of
** not searching for a reusable file descriptor are not dire. */
- if( 0==osStat(zPath, &sStat) ){
+ if( nUnusedFd>0 && 0==osStat(zPath, &sStat) ){
unixInodeInfo *pInode;
- unixEnterMutex();
pInode = inodeList;
while( pInode && (pInode->fileId.dev!=sStat.st_dev
|| pInode->fileId.ino!=(u64)sStat.st_ino) ){
@@ -35945,11 +36383,12 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext));
pUnused = *pp;
if( pUnused ){
+ nUnusedFd--;
*pp = pUnused->pNext;
}
}
- unixLeaveMutex();
}
+ unixLeaveMutex();
#endif /* if !OS_VXWORKS */
return pUnused;
}
@@ -36025,16 +36464,11 @@ static int findCreateFileMode(
*/
nDb = sqlite3Strlen30(zPath) - 1;
while( zPath[nDb]!='-' ){
-#ifndef SQLITE_ENABLE_8_3_NAMES
- /* In the normal case (8+3 filenames disabled) the journal filename
- ** is guaranteed to contain a '-' character. */
- assert( nDb>0 );
- assert( sqlite3Isalnum(zPath[nDb]) );
-#else
- /* If 8+3 names are possible, then the journal file might not contain
- ** a '-' character. So check for that case and return early. */
+ /* In normal operation, the journal file name will always contain
+ ** a '-' character. However in 8+3 filename mode, or if a corrupt
+ ** rollback journal specifies a master journal with a goofy name, then
+ ** the '-' might be missing. */
if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
-#endif
nDb--;
}
memcpy(zDb, zPath, nDb);
@@ -36109,7 +36543,7 @@ static int unixOpen(
** a file-descriptor on the directory too. The first time unixSync()
** is called the directory file descriptor will be fsync()ed and close()d.
*/
- int syncDir = (isCreate && (
+ int isNewJrnl = (isCreate && (
eType==SQLITE_OPEN_MASTER_JOURNAL
|| eType==SQLITE_OPEN_MAIN_JOURNAL
|| eType==SQLITE_OPEN_WAL
@@ -36170,7 +36604,7 @@ static int unixOpen(
return SQLITE_NOMEM_BKPT;
}
}
- p->pUnused = pUnused;
+ p->pPreallocatedUnused = pUnused;
/* Database filenames are double-zero terminated if they are not
** URIs with parameters. Hence, they can always be passed into
@@ -36179,7 +36613,7 @@ static int unixOpen(
}else if( !zName ){
/* If zName is NULL, the upper layer is requesting a temp file. */
- assert(isDelete && !syncDir);
+ assert(isDelete && !isNewJrnl);
rc = unixGetTempname(pVfs->mxPathname, zTmpname);
if( rc!=SQLITE_OK ){
return rc;
@@ -36207,24 +36641,31 @@ static int unixOpen(
gid_t gid; /* Groupid for the file */
rc = findCreateFileMode(zName, flags, &openMode, &uid, &gid);
if( rc!=SQLITE_OK ){
- assert( !p->pUnused );
+ assert( !p->pPreallocatedUnused );
assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
return rc;
}
fd = robust_open(zName, openFlags, openMode);
OSTRACE(("OPENX %-3d %s 0%o\n", fd, zName, openFlags));
assert( !isExclusive || (openFlags & O_CREAT)!=0 );
- if( fd<0 && errno!=EISDIR && isReadWrite ){
- /* Failed to open the file for read/write access. Try read-only. */
- flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
- openFlags &= ~(O_RDWR|O_CREAT);
- flags |= SQLITE_OPEN_READONLY;
- openFlags |= O_RDONLY;
- isReadonly = 1;
- fd = robust_open(zName, openFlags, openMode);
+ if( fd<0 ){
+ if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
+ /* If unable to create a journal because the directory is not
+ ** writable, change the error code to indicate that. */
+ rc = SQLITE_READONLY_DIRECTORY;
+ }else if( errno!=EISDIR && isReadWrite ){
+ /* Failed to open the file for read/write access. Try read-only. */
+ flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
+ openFlags &= ~(O_RDWR|O_CREAT);
+ flags |= SQLITE_OPEN_READONLY;
+ openFlags |= O_RDONLY;
+ isReadonly = 1;
+ fd = robust_open(zName, openFlags, openMode);
+ }
}
if( fd<0 ){
- rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
+ int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
+ if( rc==SQLITE_OK ) rc = rc2;
goto open_finished;
}
@@ -36241,9 +36682,9 @@ static int unixOpen(
*pOutFlags = flags;
}
- if( p->pUnused ){
- p->pUnused->fd = fd;
- p->pUnused->flags = flags;
+ if( p->pPreallocatedUnused ){
+ p->pPreallocatedUnused->fd = fd;
+ p->pPreallocatedUnused->flags = flags;
}
if( isDelete ){
@@ -36284,7 +36725,7 @@ static int unixOpen(
if( isReadonly ) ctrlFlags |= UNIXFILE_RDONLY;
noLock = eType!=SQLITE_OPEN_MAIN_DB;
if( noLock ) ctrlFlags |= UNIXFILE_NOLOCK;
- if( syncDir ) ctrlFlags |= UNIXFILE_DIRSYNC;
+ if( isNewJrnl ) ctrlFlags |= UNIXFILE_DIRSYNC;
if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
#if SQLITE_ENABLE_LOCKING_STYLE
@@ -36320,11 +36761,14 @@ static int unixOpen(
}
#endif
+ assert( zPath==0 || zPath[0]=='/'
+ || eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL
+ );
rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags);
open_finished:
if( rc!=SQLITE_OK ){
- sqlite3_free(p->pUnused);
+ sqlite3_free(p->pPreallocatedUnused);
}
return rc;
}
@@ -37065,7 +37509,7 @@ static int proxyCreateUnixFile(
dummyVfs.zName = "dummy";
pUnused->fd = fd;
pUnused->flags = openFlags;
- pNew->pUnused = pUnused;
+ pNew->pPreallocatedUnused = pUnused;
rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0);
if( rc==SQLITE_OK ){
@@ -38015,7 +38459,7 @@ SQLITE_API int sqlite3_os_init(void){
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
- assert( ArraySize(aSyscall)==28 );
+ assert( ArraySize(aSyscall)==29 );
/* Register all VFSes defined in the aVfs[] array */
for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
@@ -41798,6 +42242,14 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
if( newLimit>sqlite3GlobalConfig.mxMmap ){
newLimit = sqlite3GlobalConfig.mxMmap;
}
+
+ /* The value of newLimit may be eventually cast to (SIZE_T) and passed
+ ** to MapViewOfFile(). Restrict its value to 2GB if (SIZE_T) is not at
+ ** least a 64-bit type. */
+ if( newLimit>0 && sizeof(SIZE_T)<8 ){
+ newLimit = (newLimit & 0x7FFFFFFF);
+ }
+
*(i64*)pArg = pFile->mmapSizeMax;
if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
pFile->mmapSizeMax = newLimit;
@@ -41904,6 +42356,9 @@ struct winShmNode {
int szRegion; /* Size of shared-memory regions */
int nRegion; /* Size of array apRegion */
+ u8 isReadonly; /* True if read-only */
+ u8 isUnlocked; /* True if no DMS lock held */
+
struct ShmRegion {
HANDLE hMap; /* File handle from CreateFileMapping */
void *pMap;
@@ -41970,7 +42425,7 @@ static int winShmSystemLock(
int rc = 0; /* Result code form Lock/UnlockFileEx() */
/* Access to the winShmNode object is serialized by the caller */
- assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
+ assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) );
OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
pFile->hFile.h, lockType, ofst, nByte));
@@ -42052,6 +42507,37 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
}
/*
+** The DMS lock has not yet been taken on shm file pShmNode. Attempt to
+** take it now. Return SQLITE_OK if successful, or an SQLite error
+** code otherwise.
+**
+** If the DMS cannot be locked because this is a readonly_shm=1
+** connection and no other process already holds a lock, return
+** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1.
+*/
+static int winLockSharedMemory(winShmNode *pShmNode){
+ int rc = winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1);
+
+ if( rc==SQLITE_OK ){
+ if( pShmNode->isReadonly ){
+ pShmNode->isUnlocked = 1;
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ return SQLITE_READONLY_CANTINIT;
+ }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
+ "winLockSharedMemory", pShmNode->zFilename);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
+ }
+
+ return winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
+}
+
+/*
** Open the shared-memory area associated with database file pDbFd.
**
** When opening a new shared-memory file, if no other instances of that
@@ -42060,9 +42546,9 @@ static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
*/
static int winOpenSharedMemory(winFile *pDbFd){
struct winShm *p; /* The connection to be opened */
- struct winShmNode *pShmNode = 0; /* The underlying mmapped file */
- int rc; /* Result code */
- struct winShmNode *pNew; /* Newly allocated winShmNode */
+ winShmNode *pShmNode = 0; /* The underlying mmapped file */
+ int rc = SQLITE_OK; /* Result code */
+ winShmNode *pNew; /* Newly allocated winShmNode */
int nName; /* Size of zName in bytes */
assert( pDbFd->pShm==0 ); /* Not previously opened */
@@ -42095,6 +42581,9 @@ static int winOpenSharedMemory(winFile *pDbFd){
if( pShmNode ){
sqlite3_free(pNew);
}else{
+ int inFlags = SQLITE_OPEN_WAL;
+ int outFlags = 0;
+
pShmNode = pNew;
pNew = 0;
((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
@@ -42109,30 +42598,23 @@ static int winOpenSharedMemory(winFile *pDbFd){
}
}
- rc = winOpen(pDbFd->pVfs,
- pShmNode->zFilename, /* Name of the file (UTF-8) */
- (sqlite3_file*)&pShmNode->hFile, /* File handle here */
- SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
- 0);
- if( SQLITE_OK!=rc ){
+ if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+ inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+ }else{
+ inFlags |= SQLITE_OPEN_READONLY;
+ }
+ rc = winOpen(pDbFd->pVfs, pShmNode->zFilename,
+ (sqlite3_file*)&pShmNode->hFile,
+ inFlags, &outFlags);
+ if( rc!=SQLITE_OK ){
+ rc = winLogError(rc, osGetLastError(), "winOpenShm",
+ pShmNode->zFilename);
goto shm_open_err;
}
+ if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1;
- /* Check to see if another process is holding the dead-man switch.
- ** If not, truncate the file to zero length.
- */
- if( winShmSystemLock(pShmNode, WINSHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
- rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
- if( rc!=SQLITE_OK ){
- rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
- "winOpenShm", pDbFd->zPath);
- }
- }
- if( rc==SQLITE_OK ){
- winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1);
- rc = winShmSystemLock(pShmNode, WINSHM_RDLCK, WIN_SHM_DMS, 1);
- }
- if( rc ) goto shm_open_err;
+ rc = winLockSharedMemory(pShmNode);
+ if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
}
/* Make the new connection a child of the winShmNode */
@@ -42155,7 +42637,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
p->pNext = pShmNode->pFirst;
pShmNode->pFirst = p;
sqlite3_mutex_leave(pShmNode->mutex);
- return SQLITE_OK;
+ return rc;
/* Jump here on any error */
shm_open_err:
@@ -42359,6 +42841,8 @@ static int winShmMap(
winFile *pDbFd = (winFile*)fd;
winShm *pShm = pDbFd->pShm;
winShmNode *pShmNode;
+ DWORD protect = PAGE_READWRITE;
+ DWORD flags = FILE_MAP_WRITE | FILE_MAP_READ;
int rc = SQLITE_OK;
if( !pShm ){
@@ -42369,6 +42853,11 @@ static int winShmMap(
pShmNode = pShm->pShmNode;
sqlite3_mutex_enter(pShmNode->mutex);
+ if( pShmNode->isUnlocked ){
+ rc = winLockSharedMemory(pShmNode);
+ if( rc!=SQLITE_OK ) goto shmpage_out;
+ pShmNode->isUnlocked = 0;
+ }
assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
if( pShmNode->nRegion<=iRegion ){
@@ -42415,21 +42904,26 @@ static int winShmMap(
}
pShmNode->aRegion = apNew;
+ if( pShmNode->isReadonly ){
+ protect = PAGE_READONLY;
+ flags = FILE_MAP_READ;
+ }
+
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap = NULL; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, nByte, NULL
+ NULL, protect, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_WIDE)
hMap = osCreateFileMappingW(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, 0, nByte, NULL
+ NULL, protect, 0, nByte, NULL
);
#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
hMap = osCreateFileMappingA(pShmNode->hFile.h,
- NULL, PAGE_READWRITE, 0, nByte, NULL
+ NULL, protect, 0, nByte, NULL
);
#endif
OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
@@ -42439,11 +42933,11 @@ static int winShmMap(
int iOffset = pShmNode->nRegion*szRegion;
int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
#if SQLITE_OS_WINRT
- pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
+ pMap = osMapViewOfFileFromApp(hMap, flags,
iOffset - iOffsetShift, szRegion + iOffsetShift
);
#else
- pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
+ pMap = osMapViewOfFile(hMap, flags,
0, iOffset - iOffsetShift, szRegion + iOffsetShift
);
#endif
@@ -42474,6 +42968,7 @@ shmpage_out:
}else{
*pp = 0;
}
+ if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
sqlite3_mutex_leave(pShmNode->mutex);
return rc;
}
@@ -43110,6 +43605,14 @@ static int winIsDir(const void *zConverted){
return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
}
+/* forward reference */
+static int winAccess(
+ sqlite3_vfs *pVfs, /* Not used on win32 */
+ const char *zFilename, /* Name of file to check */
+ int flags, /* Type of test to make on this file */
+ int *pResOut /* OUT: Result */
+);
+
/*
** Open a file.
*/
@@ -43286,37 +43789,58 @@ static int winOpen(
extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParameters.lpSecurityAttributes = NULL;
extendedParameters.hTemplateFile = NULL;
- while( (h = osCreateFile2((LPCWSTR)zConverted,
- dwDesiredAccess,
- dwShareMode,
- dwCreationDisposition,
- &extendedParameters))==INVALID_HANDLE_VALUE &&
- winRetryIoerr(&cnt, &lastErrno) ){
- /* Noop */
- }
+ do{
+ h = osCreateFile2((LPCWSTR)zConverted,
+ dwDesiredAccess,
+ dwShareMode,
+ dwCreationDisposition,
+ &extendedParameters);
+ if( h!=INVALID_HANDLE_VALUE ) break;
+ if( isReadWrite ){
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
+ if( rc2==SQLITE_OK && isRO ) break;
+ }
+ }while( winRetryIoerr(&cnt, &lastErrno) );
#else
- while( (h = osCreateFileW((LPCWSTR)zConverted,
- dwDesiredAccess,
- dwShareMode, NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL))==INVALID_HANDLE_VALUE &&
- winRetryIoerr(&cnt, &lastErrno) ){
- /* Noop */
- }
+ do{
+ h = osCreateFileW((LPCWSTR)zConverted,
+ dwDesiredAccess,
+ dwShareMode, NULL,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ NULL);
+ if( h!=INVALID_HANDLE_VALUE ) break;
+ if( isReadWrite ){
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
+ if( rc2==SQLITE_OK && isRO ) break;
+ }
+ }while( winRetryIoerr(&cnt, &lastErrno) );
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
- while( (h = osCreateFileA((LPCSTR)zConverted,
- dwDesiredAccess,
- dwShareMode, NULL,
- dwCreationDisposition,
- dwFlagsAndAttributes,
- NULL))==INVALID_HANDLE_VALUE &&
- winRetryIoerr(&cnt, &lastErrno) ){
- /* Noop */
- }
+ do{
+ h = osCreateFileA((LPCSTR)zConverted,
+ dwDesiredAccess,
+ dwShareMode, NULL,
+ dwCreationDisposition,
+ dwFlagsAndAttributes,
+ NULL);
+ if( h!=INVALID_HANDLE_VALUE ) break;
+ if( isReadWrite ){
+ int rc2, isRO = 0;
+ sqlite3BeginBenignMalloc();
+ rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+ sqlite3EndBenignMalloc();
+ if( rc2==SQLITE_OK && isRO ) break;
+ }
+ }while( winRetryIoerr(&cnt, &lastErrno) );
}
#endif
winLogIoerr(cnt, __LINE__);
@@ -43325,8 +43849,6 @@ static int winOpen(
dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
if( h==INVALID_HANDLE_VALUE ){
- pFile->lastErrno = lastErrno;
- winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
sqlite3_free(zConverted);
sqlite3_free(zTmpname);
if( isReadWrite && !isExclusive ){
@@ -43335,6 +43857,8 @@ static int winOpen(
~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
pOutFlags);
}else{
+ pFile->lastErrno = lastErrno;
+ winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
return SQLITE_CANTOPEN_BKPT;
}
}
@@ -43927,9 +44451,6 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
EntropyGatherer e;
UNUSED_PARAMETER(pVfs);
memset(zBuf, 0, nBuf);
-#if defined(_MSC_VER) && _MSC_VER>=1400 && !SQLITE_OS_WINCE
- rand_s((unsigned int*)zBuf); /* rand_s() is not available with MinGW */
-#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
e.a = (unsigned char*)zBuf;
e.na = nBuf;
e.nXor = 0;
@@ -44848,12 +45369,9 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
p->eCreate = 2;
}
}
- pPage->pDirtyNext = 0;
- pPage->pDirtyPrev = 0;
}
if( addRemove & PCACHE_DIRTYLIST_ADD ){
- assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
-
+ pPage->pDirtyPrev = 0;
pPage->pDirtyNext = p->pDirty;
if( pPage->pDirtyNext ){
assert( pPage->pDirtyNext->pDirtyPrev==0 );
@@ -45170,11 +45688,7 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
if( (--p->nRef)==0 ){
if( p->flags&PGHDR_CLEAN ){
pcacheUnpin(p);
- }else if( p->pDirtyPrev!=0 ){ /*OPTIMIZATION-IF-FALSE*/
- /* Move the page to the head of the dirty list. If p->pDirtyPrev==0,
- ** then page p is already at the head of the dirty list and the
- ** following call would be a no-op. Hence the OPTIMIZATION-IF-FALSE
- ** tag above. */
+ }else{
pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
}
}
@@ -45230,16 +45744,15 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
*/
SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
assert( sqlite3PcachePageSanity(p) );
- if( ALWAYS((p->flags & PGHDR_DIRTY)!=0) ){
- assert( (p->flags & PGHDR_CLEAN)==0 );
- pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
- p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
- p->flags |= PGHDR_CLEAN;
- pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
- assert( sqlite3PcachePageSanity(p) );
- if( p->nRef==0 ){
- pcacheUnpin(p);
- }
+ assert( (p->flags & PGHDR_DIRTY)!=0 );
+ assert( (p->flags & PGHDR_CLEAN)==0 );
+ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+ p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+ p->flags |= PGHDR_CLEAN;
+ pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno));
+ assert( sqlite3PcachePageSanity(p) );
+ if( p->nRef==0 ){
+ pcacheUnpin(p);
}
}
@@ -45635,7 +46148,6 @@ typedef struct PGroup PGroup;
struct PgHdr1 {
sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */
unsigned int iKey; /* Key value (page number) */
- u8 isPinned; /* Page in use, not on the LRU list */
u8 isBulkLocal; /* This page from bulk local storage */
u8 isAnchor; /* This is the PGroup.lru element */
PgHdr1 *pNext; /* Next in hash table chain */
@@ -45644,6 +46156,12 @@ struct PgHdr1 {
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
};
+/*
+** A page is pinned if it is no on the LRU list
+*/
+#define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
+#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
+
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
** of one or more PCaches that are able to recycle each other's unpinned
** pages when they are under memory pressure. A PGroup is an instance of
@@ -45671,7 +46189,7 @@ struct PGroup {
unsigned int nMaxPage; /* Sum of nMax for purgeable caches */
unsigned int nMinPage; /* Sum of nMin for purgeable caches */
unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */
- unsigned int nCurrentPage; /* Number of purgeable pages allocated */
+ unsigned int nPurgeable; /* Number of purgeable pages allocated */
PgHdr1 lru; /* The beginning and end of the LRU list */
};
@@ -45685,11 +46203,13 @@ struct PGroup {
*/
struct PCache1 {
/* Cache configuration parameters. Page size (szPage) and the purgeable
- ** flag (bPurgeable) are set when the cache is created. nMax may be
+ ** flag (bPurgeable) and the pnPurgeable pointer are all set when the
+ ** cache is created and are never changed thereafter. nMax may be
** modified at any time by a call to the pcache1Cachesize() method.
** The PGroup mutex must be held when accessing nMax.
*/
PGroup *pGroup; /* PGroup this cache belongs to */
+ unsigned int *pnPurgeable; /* Pointer to pGroup->nPurgeable */
int szPage; /* Size of database content section */
int szExtra; /* sizeof(MemPage)+sizeof(PgHdr) */
int szAlloc; /* Total size of one pcache line */
@@ -45784,6 +46304,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
if( pcache1.isInit ){
PgFreeslot *p;
if( pBuf==0 ) sz = n = 0;
+ if( n==0 ) sz = 0;
sz = ROUNDDOWN8(sz);
pcache1.szSlot = sz;
pcache1.nSlot = pcache1.nFreeSlot = n;
@@ -45976,9 +46497,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){
p->isBulkLocal = 0;
p->isAnchor = 0;
}
- if( pCache->bPurgeable ){
- pCache->pGroup->nCurrentPage++;
- }
+ (*pCache->pnPurgeable)++;
return p;
}
@@ -45999,9 +46518,7 @@ static void pcache1FreePage(PgHdr1 *p){
sqlite3_free(p);
#endif
}
- if( pCache->bPurgeable ){
- pCache->pGroup->nCurrentPage--;
- }
+ (*pCache->pnPurgeable)--;
}
/*
@@ -46096,22 +46613,18 @@ static void pcache1ResizeHash(PCache1 *p){
** The PGroup mutex must be held when this function is called.
*/
static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){
- PCache1 *pCache;
-
assert( pPage!=0 );
- assert( pPage->isPinned==0 );
- pCache = pPage->pCache;
+ assert( PAGE_IS_UNPINNED(pPage) );
assert( pPage->pLruNext );
assert( pPage->pLruPrev );
- assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
+ assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) );
pPage->pLruPrev->pLruNext = pPage->pLruNext;
pPage->pLruNext->pLruPrev = pPage->pLruPrev;
pPage->pLruNext = 0;
pPage->pLruPrev = 0;
- pPage->isPinned = 1;
assert( pPage->isAnchor==0 );
- assert( pCache->pGroup->lru.isAnchor==1 );
- pCache->nRecyclable--;
+ assert( pPage->pCache->pGroup->lru.isAnchor==1 );
+ pPage->pCache->nRecyclable--;
return pPage;
}
@@ -46145,11 +46658,11 @@ static void pcache1EnforceMaxPage(PCache1 *pCache){
PGroup *pGroup = pCache->pGroup;
PgHdr1 *p;
assert( sqlite3_mutex_held(pGroup->mutex) );
- while( pGroup->nCurrentPage>pGroup->nMaxPage
+ while( pGroup->nPurgeable>pGroup->nMaxPage
&& (p=pGroup->lru.pLruPrev)->isAnchor==0
){
assert( p->pCache->pGroup==pGroup );
- assert( p->isPinned==0 );
+ assert( PAGE_IS_UNPINNED(p) );
pcache1PinPage(p);
pcache1RemoveFromHash(p, 1);
}
@@ -46198,7 +46711,7 @@ static void pcache1TruncateUnsafe(
if( pPage->iKey>=iLimit ){
pCache->nPage--;
*pp = pPage->pNext;
- if( !pPage->isPinned ) pcache1PinPage(pPage);
+ if( PAGE_IS_UNPINNED(pPage) ) pcache1PinPage(pPage);
pcache1FreePage(pPage);
}else{
pp = &pPage->pNext;
@@ -46316,6 +46829,10 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
pCache->nMin = 10;
pGroup->nMinPage += pCache->nMin;
pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
+ pCache->pnPurgeable = &pGroup->nPurgeable;
+ }else{
+ static unsigned int dummyCurrentPage;
+ pCache->pnPurgeable = &dummyCurrentPage;
}
pcache1LeaveMutex(pGroup);
if( pCache->nHash==0 ){
@@ -46417,7 +46934,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
){
PCache1 *pOther;
pPage = pGroup->lru.pLruPrev;
- assert( pPage->isPinned==0 );
+ assert( PAGE_IS_UNPINNED(pPage) );
pcache1RemoveFromHash(pPage, 0);
pcache1PinPage(pPage);
pOther = pPage->pCache;
@@ -46425,7 +46942,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
pcache1FreePage(pPage);
pPage = 0;
}else{
- pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
+ pGroup->nPurgeable -= (pOther->bPurgeable - pCache->bPurgeable);
}
}
@@ -46444,7 +46961,6 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
pPage->pCache = pCache;
pPage->pLruPrev = 0;
pPage->pLruNext = 0;
- pPage->isPinned = 1;
*(void **)pPage->page.pExtra = 0;
pCache->apHash[h] = pPage;
if( iKey>pCache->iMaxKey ){
@@ -46530,7 +47046,7 @@ static PgHdr1 *pcache1FetchNoMutex(
** Otherwise (page not in hash and createFlag!=0) continue with
** subsequent steps to try to create the page. */
if( pPage ){
- if( !pPage->isPinned ){
+ if( PAGE_IS_UNPINNED(pPage) ){
return pcache1PinPage(pPage);
}else{
return pPage;
@@ -46605,9 +47121,9 @@ static void pcache1Unpin(
** part of the PGroup LRU list.
*/
assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
- assert( pPage->isPinned==1 );
+ assert( PAGE_IS_PINNED(pPage) );
- if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
+ if( reuseUnlikely || pGroup->nPurgeable>pGroup->nMaxPage ){
pcache1RemoveFromHash(pPage, 1);
}else{
/* Add the page to the PGroup LRU list. */
@@ -46616,7 +47132,6 @@ static void pcache1Unpin(
(pPage->pLruNext = *ppFirst)->pLruPrev = pPage;
*ppFirst = pPage;
pCache->nRecyclable++;
- pPage->isPinned = 0;
}
pcache1LeaveMutex(pCache->pGroup);
@@ -46760,7 +47275,7 @@ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
nFree += sqlite3MemSize(p);
#endif
- assert( p->isPinned==0 );
+ assert( PAGE_IS_UNPINNED(p) );
pcache1PinPage(p);
pcache1RemoveFromHash(p, 1);
}
@@ -46784,10 +47299,10 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
PgHdr1 *p;
int nRecyclable = 0;
for(p=pcache1.grp.lru.pLruNext; p && !p->isAnchor; p=p->pLruNext){
- assert( p->isPinned==0 );
+ assert( PAGE_IS_UNPINNED(p) );
nRecyclable++;
}
- *pnCurrent = pcache1.grp.nCurrentPage;
+ *pnCurrent = pcache1.grp.nPurgeable;
*pnMax = (int)pcache1.grp.nMaxPage;
*pnMin = (int)pcache1.grp.nMinPage;
*pnRecyclable = nRecyclable;
@@ -47342,11 +47857,11 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64
/* #include "sqliteInt.h" */
-/* Additional values that can be added to the sync_flags argument of
-** sqlite3WalFrames():
+/* Macros for extracting appropriate sync flags for either transaction
+** commits (WAL_SYNC_FLAGS(X)) or for checkpoint ops (CKPT_SYNC_FLAGS(X)):
*/
-#define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */
-#define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */
+#define WAL_SYNC_FLAGS(X) ((X)&0x03)
+#define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03)
#ifdef SQLITE_OMIT_WAL
# define sqlite3WalOpen(x,y,z) 0
@@ -47579,8 +48094,8 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
** struct as its argument.
*/
-#define PAGERID(p) ((int)(p->fd))
-#define FILEHANDLEID(fd) ((int)fd)
+#define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd))
+#define FILEHANDLEID(fd) (SQLITE_PTR_TO_INT(fd))
/*
** The Pager.eState variable stores the current 'state' of a pager. A
@@ -48067,6 +48582,18 @@ struct PagerSavepoint {
** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode
** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX
** sub-codes.
+**
+** syncFlags, walSyncFlags
+**
+** syncFlags is either SQLITE_SYNC_NORMAL (0x02) or SQLITE_SYNC_FULL (0x03).
+** syncFlags is used for rollback mode. walSyncFlags is used for WAL mode
+** and contains the flags used to sync the checkpoint operations in the
+** lower two bits, and sync flags used for transaction commits in the WAL
+** file in bits 0x04 and 0x08. In other words, to get the correct sync flags
+** for checkpoint operations, use (walSyncFlags&0x03) and to get the correct
+** sync flags for transaction commit, use ((walSyncFlags>>2)&0x03). Note
+** that with synchronous=NORMAL in WAL mode, transaction commit is not synced
+** meaning that the 0x04 and 0x08 bits are both zero.
*/
struct Pager {
sqlite3_vfs *pVfs; /* OS functions to use for IO */
@@ -48076,9 +48603,8 @@ struct Pager {
u8 noSync; /* Do not sync the journal if true */
u8 fullSync; /* Do extra syncs of the journal for robustness */
u8 extraSync; /* sync directory after journal delete */
- u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */
- u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */
u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */
+ u8 walSyncFlags; /* See description above */
u8 tempFile; /* zFilename is a temporary or immutable file */
u8 noLock; /* Do not lock (except in WAL mode) */
u8 readOnly; /* True for a read-only database */
@@ -48398,6 +48924,7 @@ static int assert_pager_state(Pager *p){
assert( isOpen(p->jfd)
|| p->journalMode==PAGER_JOURNALMODE_OFF
|| p->journalMode==PAGER_JOURNALMODE_WAL
+ || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
);
assert( pPager->dbOrigSize<=pPager->dbHintSize );
break;
@@ -48409,6 +48936,7 @@ static int assert_pager_state(Pager *p){
assert( isOpen(p->jfd)
|| p->journalMode==PAGER_JOURNALMODE_OFF
|| p->journalMode==PAGER_JOURNALMODE_WAL
+ || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
);
break;
@@ -48619,34 +49147,47 @@ static int pagerLockDb(Pager *pPager, int eLock){
}
/*
-** This function determines whether or not the atomic-write optimization
-** can be used with this pager. The optimization can be used if:
+** This function determines whether or not the atomic-write or
+** atomic-batch-write optimizations can be used with this pager. The
+** atomic-write optimization can be used if:
**
** (a) the value returned by OsDeviceCharacteristics() indicates that
** a database page may be written atomically, and
** (b) the value returned by OsSectorSize() is less than or equal
** to the page size.
**
-** The optimization is also always enabled for temporary files. It is
-** an error to call this function if pPager is opened on an in-memory
-** database.
+** If it can be used, then the value returned is the size of the journal
+** file when it contains rollback data for exactly one page.
**
-** If the optimization cannot be used, 0 is returned. If it can be used,
-** then the value returned is the size of the journal file when it
-** contains rollback data for exactly one page.
+** The atomic-batch-write optimization can be used if OsDeviceCharacteristics()
+** returns a value with the SQLITE_IOCAP_BATCH_ATOMIC bit set. -1 is
+** returned in this case.
+**
+** If neither optimization can be used, 0 is returned.
*/
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
static int jrnlBufferSize(Pager *pPager){
assert( !MEMDB );
- if( !pPager->tempFile ){
- int dc; /* Device characteristics */
- int nSector; /* Sector size */
- int szPage; /* Page size */
- assert( isOpen(pPager->fd) );
- dc = sqlite3OsDeviceCharacteristics(pPager->fd);
- nSector = pPager->sectorSize;
- szPage = pPager->pageSize;
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
+ int dc; /* Device characteristics */
+
+ assert( isOpen(pPager->fd) );
+ dc = sqlite3OsDeviceCharacteristics(pPager->fd);
+#else
+ UNUSED_PARAMETER(pPager);
+#endif
+
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ if( dc&SQLITE_IOCAP_BATCH_ATOMIC ){
+ return -1;
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ {
+ int nSector = pPager->sectorSize;
+ int szPage = pPager->pageSize;
assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
@@ -48656,11 +49197,11 @@ static int jrnlBufferSize(Pager *pPager){
}
return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
-}
-#else
-# define jrnlBufferSize(x) 0
#endif
+ return 0;
+}
+
/*
** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
** on the cache using a hash function. This is used for testing
@@ -48742,6 +49283,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
|| szJ<16
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
|| len>=nMaster
+ || len>szJ-16
|| len==0
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
|| SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
@@ -49463,7 +50005,9 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
}
releaseAllSavepoints(pPager);
- assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
+ assert( isOpen(pPager->jfd) || pPager->pInJournal==0
+ || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC)
+ );
if( isOpen(pPager->jfd) ){
assert( !pagerUseWal(pPager) );
@@ -50231,6 +50775,7 @@ static int pager_playback(Pager *pPager, int isHot){
char *zMaster = 0; /* Name of master journal file if any */
int needPagerReset; /* True to reset page prior to first page rollback */
int nPlayback = 0; /* Total number of pages restored from journal */
+ u32 savedPageSize = pPager->pageSize;
/* Figure out how many records are in the journal. Abort early if
** the journal is empty.
@@ -50360,6 +50905,9 @@ static int pager_playback(Pager *pPager, int isHot){
assert( 0 );
end_playback:
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1);
+ }
/* Following a rollback, the database file should be back in its original
** state prior to the start of the transaction, so invoke the
** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
@@ -50418,7 +50966,8 @@ end_playback:
/*
-** Read the content for page pPg out of the database file and into
+** Read the content for page pPg out of the database file (or out of
+** the WAL if that is where the most recent copy if found) into
** pPg->pData. A shared lock or greater must be held on the database
** file before this function is called.
**
@@ -50428,30 +50977,33 @@ end_playback:
** If an IO error occurs, then the IO error is returned to the caller.
** Otherwise, SQLITE_OK is returned.
*/
-static int readDbPage(PgHdr *pPg, u32 iFrame){
+static int readDbPage(PgHdr *pPg){
Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
- Pgno pgno = pPg->pgno; /* Page number to read */
int rc = SQLITE_OK; /* Return code */
- int pgsz = pPager->pageSize; /* Number of bytes to read */
+
+#ifndef SQLITE_OMIT_WAL
+ u32 iFrame = 0; /* Frame of WAL containing pgno */
assert( pPager->eState>=PAGER_READER && !MEMDB );
assert( isOpen(pPager->fd) );
-#ifndef SQLITE_OMIT_WAL
+ if( pagerUseWal(pPager) ){
+ rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
+ if( rc ) return rc;
+ }
if( iFrame ){
- /* Try to pull the page from the write-ahead log. */
- rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
+ rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData);
}else
#endif
{
- i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
- rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
+ i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize;
+ rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset);
if( rc==SQLITE_IOERR_SHORT_READ ){
rc = SQLITE_OK;
}
}
- if( pgno==1 ){
+ if( pPg->pgno==1 ){
if( rc ){
/* If the read is unsuccessful, set the dbFileVers[] to something
** that will never be a valid file version. dbFileVers[] is a copy
@@ -50471,13 +51023,13 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
}
}
- CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT);
+ CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT);
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
- IOTRACE(("PGIN %p %d\n", pPager, pgno));
+ IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
- PAGERID(pPager), pgno, pager_pagehash(pPg)));
+ PAGERID(pPager), pPg->pgno, pager_pagehash(pPg)));
return rc;
}
@@ -50528,11 +51080,7 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){
if( sqlite3PcachePageRefcount(pPg)==1 ){
sqlite3PcacheDrop(pPg);
}else{
- u32 iFrame = 0;
- rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
- if( rc==SQLITE_OK ){
- rc = readDbPage(pPg, iFrame);
- }
+ rc = readDbPage(pPg);
if( rc==SQLITE_OK ){
pPager->xReiniter(pPg);
}
@@ -51038,20 +51586,17 @@ SQLITE_PRIVATE void sqlite3PagerSetFlags(
}
if( pPager->noSync ){
pPager->syncFlags = 0;
- pPager->ckptSyncFlags = 0;
}else if( pgFlags & PAGER_FULLFSYNC ){
pPager->syncFlags = SQLITE_SYNC_FULL;
- pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
- }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
- pPager->syncFlags = SQLITE_SYNC_NORMAL;
- pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
}else{
pPager->syncFlags = SQLITE_SYNC_NORMAL;
- pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
}
- pPager->walSyncFlags = pPager->syncFlags;
+ pPager->walSyncFlags = (pPager->syncFlags<<2);
if( pPager->fullSync ){
- pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
+ pPager->walSyncFlags |= pPager->syncFlags;
+ }
+ if( (pgFlags & PAGER_CKPT_FULLFSYNC) && !pPager->noSync ){
+ pPager->walSyncFlags |= (SQLITE_SYNC_FULL<<2);
}
if( pgFlags & PAGER_CACHESPILL ){
pPager->doNotSpill &= ~SPILLFLAG_OFF;
@@ -51550,7 +52095,7 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
assert( db || pPager->pWal==0 );
- sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize,
+ sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,
(db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp)
);
pPager->pWal = 0;
@@ -52018,6 +52563,13 @@ static int pagerStress(void *p, PgHdr *pPg){
rc = pagerWalFrames(pPager, pPg, 0, 0);
}
}else{
+
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ if( pPager->tempFile==0 ){
+ rc = sqlite3JournalCreate(pPager->jfd);
+ if( rc!=SQLITE_OK ) return pager_error(pPager, rc);
+ }
+#endif
/* Sync the journal file if required. */
if( pPg->flags&PGHDR_NEED_SYNC
@@ -52351,13 +52903,11 @@ act_like_temp_file:
assert( pPager->extraSync==0 );
assert( pPager->syncFlags==0 );
assert( pPager->walSyncFlags==0 );
- assert( pPager->ckptSyncFlags==0 );
}else{
pPager->fullSync = 1;
pPager->extraSync = 0;
pPager->syncFlags = SQLITE_SYNC_NORMAL;
- pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
- pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
+ pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2);
}
/* pPager->pFirst = 0; */
/* pPager->pFirstSynced = 0; */
@@ -52777,7 +53327,8 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
** nothing to rollback, so this routine is a no-op.
*/
static void pagerUnlockIfUnused(Pager *pPager){
- if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
+ if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){
+ assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */
pagerUnlockAndRollback(pPager);
}
}
@@ -52918,14 +53469,9 @@ static int getPageNormal(
memset(pPg->pData, 0, pPager->pageSize);
IOTRACE(("ZERO %p %d\n", pPager, pgno));
}else{
- 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;
- }
assert( pPg->pPager==pPager );
pPager->aStat[PAGER_STAT_MISS]++;
- rc = readDbPage(pPg, iFrame);
+ rc = readDbPage(pPg);
if( rc!=SQLITE_OK ){
goto pager_acquire_err;
}
@@ -52999,7 +53545,7 @@ static int getPageMMap(
}
if( pPg==0 ){
rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
- }else{
+ }else{
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
}
if( pPg ){
@@ -53068,25 +53614,39 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
/*
** Release a page reference.
**
-** If the number of references to the page drop to zero, then the
-** page is added to the LRU list. When all references to all pages
-** are released, a rollback occurs and the lock on the database is
-** removed.
+** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be
+** used if we know that the page being released is not the last page.
+** The btree layer always holds page1 open until the end, so these first
+** to routines can be used to release any page other than BtShared.pPage1.
+**
+** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine
+** checks the total number of outstanding pages and if the number of
+** pages reaches zero it drops the database lock.
*/
SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
- Pager *pPager;
+ TESTONLY( Pager *pPager = pPg->pPager; )
assert( pPg!=0 );
- pPager = pPg->pPager;
if( pPg->flags & PGHDR_MMAP ){
+ assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */
pagerReleaseMapPage(pPg);
}else{
sqlite3PcacheRelease(pPg);
}
- pagerUnlockIfUnused(pPager);
+ /* Do not use this routine to release the last reference to page1 */
+ assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
}
SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
if( pPg ) sqlite3PagerUnrefNotNull(pPg);
}
+SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){
+ Pager *pPager;
+ assert( pPg!=0 );
+ assert( pPg->pgno==1 );
+ assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
+ pPager = pPg->pPager;
+ sqlite3PcacheRelease(pPg);
+ pagerUnlockIfUnused(pPager);
+}
/*
** This function is called at the start of every write transaction.
@@ -53798,6 +54358,21 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
sqlite3PcacheCleanAll(pPager->pPCache);
}
}else{
+ /* The bBatch boolean is true if the batch-atomic-write commit method
+ ** should be used. No rollback journal is created if batch-atomic-write
+ ** is enabled.
+ */
+ sqlite3_file *fd = pPager->fd;
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ const int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */
+ && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC)
+ && !pPager->noSync
+ && sqlite3JournalIsInMemory(pPager->jfd);
+#else
+# define bBatch 0
+#endif
+
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
/* The following block updates the change-counter. Exactly how it
** does this depends on whether or not the atomic-update optimization
** was enabled at compile time, and if this transaction meets the
@@ -53821,33 +54396,40 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
** in 'direct' mode. In this case the journal file will never be
** created for this transaction.
*/
- #ifdef SQLITE_ENABLE_ATOMIC_WRITE
- PgHdr *pPg;
- assert( isOpen(pPager->jfd)
- || pPager->journalMode==PAGER_JOURNALMODE_OFF
- || pPager->journalMode==PAGER_JOURNALMODE_WAL
- );
- if( !zMaster && isOpen(pPager->jfd)
- && pPager->journalOff==jrnlBufferSize(pPager)
- && pPager->dbSize>=pPager->dbOrigSize
- && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
- ){
- /* Update the db file change counter via the direct-write method. The
- ** following call will modify the in-memory representation of page 1
- ** to include the updated change counter and then write page 1
- ** directly to the database file. Because of the atomic-write
- ** property of the host file-system, this is safe.
- */
- rc = pager_incr_changecounter(pPager, 1);
- }else{
- rc = sqlite3JournalCreate(pPager->jfd);
- if( rc==SQLITE_OK ){
- rc = pager_incr_changecounter(pPager, 0);
+ if( bBatch==0 ){
+ PgHdr *pPg;
+ assert( isOpen(pPager->jfd)
+ || pPager->journalMode==PAGER_JOURNALMODE_OFF
+ || pPager->journalMode==PAGER_JOURNALMODE_WAL
+ );
+ if( !zMaster && isOpen(pPager->jfd)
+ && pPager->journalOff==jrnlBufferSize(pPager)
+ && pPager->dbSize>=pPager->dbOrigSize
+ && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
+ ){
+ /* Update the db file change counter via the direct-write method. The
+ ** following call will modify the in-memory representation of page 1
+ ** to include the updated change counter and then write page 1
+ ** directly to the database file. Because of the atomic-write
+ ** property of the host file-system, this is safe.
+ */
+ rc = pager_incr_changecounter(pPager, 1);
+ }else{
+ rc = sqlite3JournalCreate(pPager->jfd);
+ if( rc==SQLITE_OK ){
+ rc = pager_incr_changecounter(pPager, 0);
+ }
}
}
- #else
+#else
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ if( zMaster ){
+ rc = sqlite3JournalCreate(pPager->jfd);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ }
+#endif
rc = pager_incr_changecounter(pPager, 0);
- #endif
+#endif
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
/* Write the master journal name into the journal file. If a master
@@ -53870,8 +54452,24 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
*/
rc = syncJournal(pPager, 0);
if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
-
+
+ if( bBatch ){
+ /* The pager is now in DBMOD state. But regardless of what happens
+ ** next, attempting to play the journal back into the database would
+ ** be unsafe. Close it now to make sure that does not happen. */
+ sqlite3OsClose(pPager->jfd);
+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0);
+ if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+ }
rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
+ if( bBatch ){
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
+ }else{
+ sqlite3OsFileControl(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
+ }
+ }
+
if( rc!=SQLITE_OK ){
assert( rc!=SQLITE_IOERR_BLOCKED );
goto commit_phase_one_exit;
@@ -54772,7 +55370,7 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint(
rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode,
(eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
pPager->pBusyHandlerArg,
- pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
+ pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
pnLog, pnCkpt
);
}
@@ -54929,7 +55527,7 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){
if( rc==SQLITE_OK && pPager->pWal ){
rc = pagerExclusiveLock(pPager);
if( rc==SQLITE_OK ){
- rc = sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags,
+ rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags,
pPager->pageSize, (u8*)pPager->pTmpSpace);
pPager->pWal = 0;
pagerFixMaplimit(pPager);
@@ -55135,6 +55733,10 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
** on a network filesystem. All users of the database must be able to
** share memory.
**
+** In the default unix and windows implementation, the wal-index is a mmapped
+** file whose name is the database name with a "-shm" suffix added. For that
+** reason, the wal-index is sometimes called the "shm" file.
+**
** The wal-index is transient. After a crash, the wal-index can (and should
** be) reconstructed from the original WAL file. In fact, the VFS is required
** to either truncate or zero the header of the wal-index when the last
@@ -55274,9 +55876,18 @@ SQLITE_PRIVATE int sqlite3WalTrace = 0;
#define WALINDEX_MAX_VERSION 3007000
/*
-** Indices of various locking bytes. WAL_NREADER is the number
+** Index numbers for various locking bytes. WAL_NREADER is the number
** of available reader locks and should be at least 3. The default
** is SQLITE_SHM_NLOCK==8 and WAL_NREADER==5.
+**
+** Technically, the various VFSes are free to implement these locks however
+** they see fit. However, compatibility is encouraged so that VFSes can
+** interoperate. The standard implemention used on both unix and windows
+** is for the index number to indicate a byte offset into the
+** WalCkptInfo.aLock[] array in the wal-index header. In other words, all
+** locks are on the shm file. The WALINDEX_LOCK_OFFSET constant (which
+** should be 120) is the location in the shm file for the first locking
+** byte.
*/
#define WAL_WRITE_LOCK 0
#define WAL_ALL_BUT_WRITE 1
@@ -55400,7 +56011,6 @@ struct WalCkptInfo {
#define WAL_FRAME_HDRSIZE 24
/* Size of write ahead log header, including checksum. */
-/* #define WAL_HDRSIZE 24 */
#define WAL_HDRSIZE 32
/* WAL magic value. Either this value, or the same value with the least
@@ -55446,6 +56056,7 @@ struct Wal {
u8 truncateOnCommit; /* True to truncate WAL file on commit */
u8 syncHeader; /* Fsync the WAL header if true */
u8 padToSectorBoundary; /* Pad transactions out to the next sector */
+ u8 bShmUnreliable; /* SHM content is read-only and unreliable */
WalIndexHdr hdr; /* Wal-index header for current transaction */
u32 minFrame; /* Ignore wal frames before this one */
u32 iReCksum; /* On commit, recalculate checksums from here */
@@ -55535,6 +56146,11 @@ struct WalIterator {
** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
** numbered from zero.
**
+** If the wal-index is currently smaller the iPage pages then the size
+** of the wal-index might be increased, but only if it is safe to do
+** so. It is safe to enlarge the wal-index if pWal->writeLock is true
+** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
+**
** If this call is successful, *ppPage is set to point to the wal-index
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
** then an SQLite error code is returned and *ppPage is set to 0.
@@ -55566,9 +56182,13 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
);
- if( rc==SQLITE_READONLY ){
+ assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
+ testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
+ if( (rc&0xff)==SQLITE_READONLY ){
pWal->readOnly |= WAL_SHM_RDONLY;
- rc = SQLITE_OK;
+ if( rc==SQLITE_READONLY ){
+ rc = SQLITE_OK;
+ }
}
}
}
@@ -56090,7 +56710,6 @@ static int walIndexRecover(Wal *pWal){
i64 nSize; /* Size of log file */
u32 aFrameCksum[2] = {0, 0};
int iLock; /* Lock offset to lock for checkpoint */
- int nLock; /* Number of locks to hold */
/* Obtain an exclusive lock on all byte in the locking range not already
** locked by the caller. The caller is guaranteed to have locked the
@@ -56103,11 +56722,17 @@ static int walIndexRecover(Wal *pWal){
assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
assert( pWal->writeLock );
iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
- nLock = SQLITE_SHM_NLOCK - iLock;
- rc = walLockExclusive(pWal, iLock, nLock);
+ rc = walLockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ if( rc==SQLITE_OK ){
+ rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+ if( rc!=SQLITE_OK ){
+ walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ }
+ }
if( rc ){
return rc;
}
+
WALTRACE(("WAL%p: recovery begin...\n", pWal));
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
@@ -56245,7 +56870,8 @@ finished:
recovery_error:
WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
- walUnlockExclusive(pWal, iLock, nLock);
+ walUnlockExclusive(pWal, iLock, WAL_READ_LOCK(0)-iLock);
+ walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
return rc;
}
@@ -56253,13 +56879,14 @@ recovery_error:
** Close an open wal-index.
*/
static void walIndexClose(Wal *pWal, int isDelete){
- if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
+ if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){
int i;
for(i=0; i<pWal->nWiData; i++){
sqlite3_free((void *)pWal->apWiData[i]);
pWal->apWiData[i] = 0;
}
- }else{
+ }
+ if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
}
}
@@ -56801,9 +57428,7 @@ static int walCheckpoint(
pInfo->nBackfillAttempted = mxSafeFrame;
/* Sync the WAL to disk */
- if( sync_flags ){
- rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
- }
+ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
/* If the database may grow as a result of this checkpoint, hint
** about the eventual size of the db file to the VFS layer.
@@ -56844,8 +57469,8 @@ static int walCheckpoint(
i64 szDb = pWal->hdr.nPage*(i64)szPage;
testcase( IS_BIG_INT(szDb) );
rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
- if( rc==SQLITE_OK && sync_flags ){
- rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags));
}
}
if( rc==SQLITE_OK ){
@@ -57055,6 +57680,12 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
}
/*
+** This is the value that walTryBeginRead returns when it needs to
+** be retried.
+*/
+#define WAL_RETRY (-1)
+
+/*
** Read the wal-index header from the wal-index and into pWal->hdr.
** If the wal-header appears to be corrupt, try to reconstruct the
** wal-index from the WAL before returning.
@@ -57077,9 +57708,29 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
assert( pChanged );
rc = walIndexPage(pWal, 0, &page0);
if( rc!=SQLITE_OK ){
- return rc;
- };
- assert( page0 || pWal->writeLock==0 );
+ assert( rc!=SQLITE_READONLY ); /* READONLY changed to OK in walIndexPage */
+ if( rc==SQLITE_READONLY_CANTINIT ){
+ /* The SQLITE_READONLY_CANTINIT return means that the shared-memory
+ ** was openable but is not writable, and this thread is unable to
+ ** confirm that another write-capable connection has the shared-memory
+ ** open, and hence the content of the shared-memory is unreliable,
+ ** since the shared-memory might be inconsistent with the WAL file
+ ** and there is no writer on hand to fix it. */
+ assert( page0==0 );
+ assert( pWal->writeLock==0 );
+ assert( pWal->readOnly & WAL_SHM_RDONLY );
+ pWal->bShmUnreliable = 1;
+ pWal->exclusiveMode = WAL_HEAPMEMORY_MODE;
+ *pChanged = 1;
+ }else{
+ return rc; /* Any other non-OK return is just an error */
+ }
+ }else{
+ /* page0 can be NULL if the SHM is zero bytes in size and pWal->writeLock
+ ** is zero, which prevents the SHM from growing */
+ testcase( page0!=0 );
+ }
+ assert( page0!=0 || pWal->writeLock==0 );
/* If the first page of the wal-index has been mapped, try to read the
** wal-index header immediately, without holding any lock. This usually
@@ -57093,7 +57744,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
*/
assert( badHdr==0 || pWal->writeLock==0 );
if( badHdr ){
- if( pWal->readOnly & WAL_SHM_RDONLY ){
+ if( pWal->bShmUnreliable==0 && (pWal->readOnly & WAL_SHM_RDONLY) ){
if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
walUnlockShared(pWal, WAL_WRITE_LOCK);
rc = SQLITE_READONLY_RECOVERY;
@@ -57123,15 +57774,193 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
rc = SQLITE_CANTOPEN_BKPT;
}
+ if( pWal->bShmUnreliable ){
+ if( rc!=SQLITE_OK ){
+ walIndexClose(pWal, 0);
+ pWal->bShmUnreliable = 0;
+ assert( pWal->nWiData>0 && pWal->apWiData[0]==0 );
+ /* walIndexRecover() might have returned SHORT_READ if a concurrent
+ ** writer truncated the WAL out from under it. If that happens, it
+ ** indicates that a writer has fixed the SHM file for us, so retry */
+ if( rc==SQLITE_IOERR_SHORT_READ ) rc = WAL_RETRY;
+ }
+ pWal->exclusiveMode = WAL_NORMAL_MODE;
+ }
return rc;
}
/*
-** This is the value that walTryBeginRead returns when it needs to
-** be retried.
+** Open a transaction in a connection where the shared-memory is read-only
+** and where we cannot verify that there is a separate write-capable connection
+** on hand to keep the shared-memory up-to-date with the WAL file.
+**
+** This can happen, for example, when the shared-memory is implemented by
+** memory-mapping a *-shm file, where a prior writer has shut down and
+** left the *-shm file on disk, and now the present connection is trying
+** to use that database but lacks write permission on the *-shm file.
+** Other scenarios are also possible, depending on the VFS implementation.
+**
+** Precondition:
+**
+** The *-wal file has been read and an appropriate wal-index has been
+** constructed in pWal->apWiData[] using heap memory instead of shared
+** memory.
+**
+** If this function returns SQLITE_OK, then the read transaction has
+** been successfully opened. In this case output variable (*pChanged)
+** is set to true before returning if the caller should discard the
+** contents of the page cache before proceeding. Or, if it returns
+** WAL_RETRY, then the heap memory wal-index has been discarded and
+** the caller should retry opening the read transaction from the
+** beginning (including attempting to map the *-shm file).
+**
+** If an error occurs, an SQLite error code is returned.
*/
-#define WAL_RETRY (-1)
+static int walBeginShmUnreliable(Wal *pWal, int *pChanged){
+ i64 szWal; /* Size of wal file on disk in bytes */
+ i64 iOffset; /* Current offset when reading wal file */
+ u8 aBuf[WAL_HDRSIZE]; /* Buffer to load WAL header into */
+ u8 *aFrame = 0; /* Malloc'd buffer to load entire frame */
+ int szFrame; /* Number of bytes in buffer aFrame[] */
+ u8 *aData; /* Pointer to data part of aFrame buffer */
+ volatile void *pDummy; /* Dummy argument for xShmMap */
+ int rc; /* Return code */
+ u32 aSaveCksum[2]; /* Saved copy of pWal->hdr.aFrameCksum */
+
+ assert( pWal->bShmUnreliable );
+ assert( pWal->readOnly & WAL_SHM_RDONLY );
+ assert( pWal->nWiData>0 && pWal->apWiData[0] );
+
+ /* Take WAL_READ_LOCK(0). This has the effect of preventing any
+ ** writers from running a checkpoint, but does not stop them
+ ** from running recovery. */
+ rc = walLockShared(pWal, WAL_READ_LOCK(0));
+ if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_BUSY ) rc = WAL_RETRY;
+ goto begin_unreliable_shm_out;
+ }
+ pWal->readLock = 0;
+
+ /* Check to see if a separate writer has attached to the shared-memory area,
+ ** thus making the shared-memory "reliable" again. Do this by invoking
+ ** the xShmMap() routine of the VFS and looking to see if the return
+ ** is SQLITE_READONLY instead of SQLITE_READONLY_CANTINIT.
+ **
+ ** If the shared-memory is now "reliable" return WAL_RETRY, which will
+ ** cause the heap-memory WAL-index to be discarded and the actual
+ ** shared memory to be used in its place.
+ **
+ ** This step is important because, even though this connection is holding
+ ** the WAL_READ_LOCK(0) which prevents a checkpoint, a writer might
+ ** have already checkpointed the WAL file and, while the current
+ ** is active, wrap the WAL and start overwriting frames that this
+ ** process wants to use.
+ **
+ ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has
+ ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY
+ ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations,
+ ** even if some external agent does a "chmod" to make the shared-memory
+ ** writable by us, until sqlite3OsShmUnmap() has been called.
+ ** This is a requirement on the VFS implementation.
+ */
+ rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy);
+ assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */
+ if( rc!=SQLITE_READONLY_CANTINIT ){
+ rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc);
+ goto begin_unreliable_shm_out;
+ }
+
+ /* We reach this point only if the real shared-memory is still unreliable.
+ ** Assume the in-memory WAL-index substitute is correct and load it
+ ** into pWal->hdr.
+ */
+ memcpy(&pWal->hdr, (void*)walIndexHdr(pWal), sizeof(WalIndexHdr));
+
+ /* Make sure some writer hasn't come in and changed the WAL file out
+ ** from under us, then disconnected, while we were not looking.
+ */
+ rc = sqlite3OsFileSize(pWal->pWalFd, &szWal);
+ if( rc!=SQLITE_OK ){
+ goto begin_unreliable_shm_out;
+ }
+ if( szWal<WAL_HDRSIZE ){
+ /* If the wal file is too small to contain a wal-header and the
+ ** wal-index header has mxFrame==0, then it must be safe to proceed
+ ** reading the database file only. However, the page cache cannot
+ ** be trusted, as a read/write connection may have connected, written
+ ** the db, run a checkpoint, truncated the wal file and disconnected
+ ** since this client's last read transaction. */
+ *pChanged = 1;
+ rc = (pWal->hdr.mxFrame==0 ? SQLITE_OK : WAL_RETRY);
+ goto begin_unreliable_shm_out;
+ }
+
+ /* Check the salt keys at the start of the wal file still match. */
+ rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
+ if( rc!=SQLITE_OK ){
+ goto begin_unreliable_shm_out;
+ }
+ if( memcmp(&pWal->hdr.aSalt, &aBuf[16], 8) ){
+ /* Some writer has wrapped the WAL file while we were not looking.
+ ** Return WAL_RETRY which will cause the in-memory WAL-index to be
+ ** rebuilt. */
+ rc = WAL_RETRY;
+ goto begin_unreliable_shm_out;
+ }
+
+ /* Allocate a buffer to read frames into */
+ szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE;
+ aFrame = (u8 *)sqlite3_malloc64(szFrame);
+ if( aFrame==0 ){
+ rc = SQLITE_NOMEM_BKPT;
+ goto begin_unreliable_shm_out;
+ }
+ aData = &aFrame[WAL_FRAME_HDRSIZE];
+
+ /* Check to see if a complete transaction has been appended to the
+ ** wal file since the heap-memory wal-index was created. If so, the
+ ** heap-memory wal-index is discarded and WAL_RETRY returned to
+ ** the caller. */
+ aSaveCksum[0] = pWal->hdr.aFrameCksum[0];
+ aSaveCksum[1] = pWal->hdr.aFrameCksum[1];
+ for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage);
+ iOffset+szFrame<=szWal;
+ iOffset+=szFrame
+ ){
+ u32 pgno; /* Database page number for frame */
+ u32 nTruncate; /* dbsize field from frame header */
+
+ /* Read and decode the next log frame. */
+ rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
+ if( rc!=SQLITE_OK ) break;
+ if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break;
+
+ /* If nTruncate is non-zero, then a complete transaction has been
+ ** appended to this wal file. Set rc to WAL_RETRY and break out of
+ ** the loop. */
+ if( nTruncate ){
+ rc = WAL_RETRY;
+ break;
+ }
+ }
+ pWal->hdr.aFrameCksum[0] = aSaveCksum[0];
+ pWal->hdr.aFrameCksum[1] = aSaveCksum[1];
+
+ begin_unreliable_shm_out:
+ sqlite3_free(aFrame);
+ if( rc!=SQLITE_OK ){
+ int i;
+ for(i=0; i<pWal->nWiData; i++){
+ sqlite3_free((void*)pWal->apWiData[i]);
+ pWal->apWiData[i] = 0;
+ }
+ pWal->bShmUnreliable = 0;
+ sqlite3WalEndReadTransaction(pWal);
+ *pChanged = 1;
+ }
+ return rc;
+}
/*
** Attempt to start a read transaction. This might fail due to a race or
@@ -57147,7 +57976,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
** checkpointed. If useWal==0 then this routine calls walIndexReadHdr()
** to make a copy of the wal-index header into pWal->hdr. If the
** wal-index header has changed, *pChanged is set to 1 (as an indication
-** to the caller that the local paget cache is obsolete and needs to be
+** to the caller that the local page cache is obsolete and needs to be
** flushed.) When useWal==1, the wal-index header is assumed to already
** be loaded and the pChanged parameter is unused.
**
@@ -57193,6 +58022,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
assert( pWal->readLock<0 ); /* Not currently locked */
+ /* useWal may only be set for read/write connections */
+ assert( (pWal->readOnly & WAL_SHM_RDONLY)==0 || useWal==0 );
+
/* Take steps to avoid spinning forever if there is a protocol error.
**
** Circumstances that cause a RETRY should only last for the briefest
@@ -57221,7 +58053,10 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
if( !useWal ){
- rc = walIndexReadHdr(pWal, pChanged);
+ assert( rc==SQLITE_OK );
+ if( pWal->bShmUnreliable==0 ){
+ rc = walIndexReadHdr(pWal, pChanged);
+ }
if( rc==SQLITE_BUSY ){
/* If there is not a recovery running in another thread or process
** then convert BUSY errors to WAL_RETRY. If recovery is known to
@@ -57250,13 +58085,17 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
if( rc!=SQLITE_OK ){
return rc;
}
+ else if( pWal->bShmUnreliable ){
+ return walBeginShmUnreliable(pWal, pChanged);
+ }
}
+ assert( pWal->nWiData>0 );
+ assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
- if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
+ if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
- && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0
- || 0==memcmp(&pWal->hdr, pWal->pSnapshot, sizeof(WalIndexHdr)))
+ && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0)
#endif
){
/* The WAL has been completely backfilled (or it is empty).
@@ -57327,7 +58166,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
}
if( mxI==0 ){
assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
- return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
+ return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
}
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
@@ -57599,7 +58438,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
** then the WAL is ignored by the reader so return early, as if the
** WAL were empty.
*/
- if( iLast==0 || pWal->readLock==0 ){
+ if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){
*piRead = 0;
return SQLITE_OK;
}
@@ -57662,8 +58501,8 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
{
u32 iRead2 = 0;
u32 iTest;
- assert( pWal->minFrame>0 );
- for(iTest=iLast; iTest>=pWal->minFrame; iTest--){
+ assert( pWal->bShmUnreliable || pWal->minFrame>0 );
+ for(iTest=iLast; iTest>=pWal->minFrame && iTest>0; iTest--){
if( walFramePgno(pWal, iTest)==pgno ){
iRead2 = iTest;
break;
@@ -57951,8 +58790,8 @@ static int walWriteToLog(
iOffset += iFirstAmt;
iAmt -= iFirstAmt;
pContent = (void*)(iFirstAmt + (char*)pContent);
- assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
- rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
+ assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 );
+ rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags));
if( iAmt==0 || rc ) return rc;
}
rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
@@ -58122,10 +58961,10 @@ SQLITE_PRIVATE int sqlite3WalFrames(
** an out-of-order write following a WAL restart could result in
** database corruption. See the ticket:
**
- ** http://localhost:591/sqlite/info/ff5be73dee
+ ** https://sqlite.org/src/info/ff5be73dee
*/
- if( pWal->syncHeader && sync_flags ){
- rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
+ if( pWal->syncHeader ){
+ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags));
if( rc ) return rc;
}
}
@@ -58200,7 +59039,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
** sector boundary is synced; the part of the last frame that extends
** past the sector boundary is written after the sync.
*/
- if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
+ if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){
int bSync = 1;
if( pWal->padToSectorBoundary ){
int sectorSize = sqlite3SectorSize(pWal->pWalFd);
@@ -58216,7 +59055,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
}
if( bSync ){
assert( rc==SQLITE_OK );
- rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
+ rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags));
}
}
@@ -58439,24 +59278,24 @@ SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
if( op==0 ){
- if( pWal->exclusiveMode ){
- pWal->exclusiveMode = 0;
+ if( pWal->exclusiveMode!=WAL_NORMAL_MODE ){
+ pWal->exclusiveMode = WAL_NORMAL_MODE;
if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
- pWal->exclusiveMode = 1;
+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
}
- rc = pWal->exclusiveMode==0;
+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
}else{
/* Already in locking_mode=NORMAL */
rc = 0;
}
}else if( op>0 ){
- assert( pWal->exclusiveMode==0 );
+ assert( pWal->exclusiveMode==WAL_NORMAL_MODE );
assert( pWal->readLock>=0 );
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
- pWal->exclusiveMode = 1;
+ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
rc = 1;
}else{
- rc = pWal->exclusiveMode==0;
+ rc = pWal->exclusiveMode==WAL_NORMAL_MODE;
}
return rc;
}
@@ -59063,6 +59902,11 @@ struct CellInfo {
** eState==FAULT: Cursor fault with skipNext as error code.
*/
struct BtCursor {
+ u8 eState; /* One of the CURSOR_XXX constants (see below) */
+ u8 curFlags; /* zero or more BTCF_* flags defined below */
+ u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
+ u8 hints; /* As configured by CursorSetHints() */
+ int nOvflAlloc; /* Allocated size of aOverflow[] array */
Btree *pBtree; /* The Btree to which this cursor belongs */
BtShared *pBt; /* The BtShared this cursor points to */
BtCursor *pNext; /* Forms a linked list of all cursors */
@@ -59071,13 +59915,8 @@ struct BtCursor {
i64 nKey; /* Size of pKey, or last integer key */
void *pKey; /* Saved key that was cursor last known position */
Pgno pgnoRoot; /* The root page of this tree */
- int nOvflAlloc; /* Allocated size of aOverflow[] array */
int skipNext; /* Prev() is noop if negative. Next() is noop if positive.
** Error code if eState==CURSOR_FAULT */
- u8 curFlags; /* zero or more BTCF_* flags defined below */
- u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */
- u8 eState; /* One of the CURSOR_XXX constants (see below) */
- u8 hints; /* As configured by CursorSetHints() */
/* All fields above are zeroed when the cursor is allocated. See
** sqlite3BtreeCursorZero(). Fields that follow must be manually
** initialized. */
@@ -59086,7 +59925,8 @@ struct BtCursor {
u16 ix; /* Current index for apPage[iPage] */
u16 aiIdx[BTCURSOR_MAX_DEPTH-1]; /* Current index in apPage[i] */
struct KeyInfo *pKeyInfo; /* Arg passed to comparison function */
- MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */
+ MemPage *pPage; /* Current page */
+ MemPage *apPage[BTCURSOR_MAX_DEPTH-1]; /* Stack of parents of current page */
};
/*
@@ -59675,6 +60515,34 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){
#define hasReadConflicts(a, b) 0
#endif
+/*
+** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single
+** (MemPage*) as an argument. The (MemPage*) must not be NULL.
+**
+** If SQLITE_DEBUG is not defined, then this macro is equivalent to
+** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message
+** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
+** with the page number and filename associated with the (MemPage*).
+*/
+#ifdef SQLITE_DEBUG
+int corruptPageError(int lineno, MemPage *p){
+ char *zMsg;
+ sqlite3BeginBenignMalloc();
+ zMsg = sqlite3_mprintf("database corruption page %d of %s",
+ (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
+ );
+ sqlite3EndBenignMalloc();
+ if( zMsg ){
+ sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
+ }
+ sqlite3_free(zMsg);
+ return SQLITE_CORRUPT_BKPT;
+}
+# define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage)
+#else
+# define SQLITE_CORRUPT_PAGE(pMemPage) SQLITE_CORRUPT_PGNO(pMemPage->pgno)
+#endif
+
#ifndef SQLITE_OMIT_SHARED_CACHE
#ifdef SQLITE_DEBUG
@@ -60002,7 +60870,9 @@ static void downgradeAllSharedCacheTableLocks(Btree *p){
#endif /* SQLITE_OMIT_SHARED_CACHE */
-static void releasePage(MemPage *pPage); /* Forward reference */
+static void releasePage(MemPage *pPage); /* Forward reference */
+static void releasePageOne(MemPage *pPage); /* Forward reference */
+static void releasePageNotNull(MemPage *pPage); /* Forward reference */
/*
***** This routine is used inside of assert() only ****
@@ -60161,11 +61031,13 @@ static void btreeClearHasContent(BtShared *pBt){
*/
static void btreeReleaseAllCursorPages(BtCursor *pCur){
int i;
- for(i=0; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- pCur->apPage[i] = 0;
+ if( pCur->iPage>=0 ){
+ for(i=0; i<pCur->iPage; i++){
+ releasePageNotNull(pCur->apPage[i]);
+ }
+ releasePageNotNull(pCur->pPage);
+ pCur->iPage = -1;
}
- pCur->iPage = -1;
}
/*
@@ -60294,7 +61166,7 @@ static int SQLITE_NOINLINE saveCursorsOnList(
return rc;
}
}else{
- testcase( p->iPage>0 );
+ testcase( p->iPage>=0 );
btreeReleaseAllCursorPages(p);
}
}
@@ -60334,7 +61206,7 @@ static int btreeMoveto(
if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
if( pIdxKey->nField==0 ){
- rc = SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
+ rc = SQLITE_CORRUPT_BKPT;
goto moveto_done;
}
}else{
@@ -60399,6 +61271,17 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
}
/*
+** Return a pointer to a fake BtCursor object that will always answer
+** false to the sqlite3BtreeCursorHasMoved() routine above. The fake
+** cursor returned must not be used with any other Btree interface.
+*/
+SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){
+ static u8 fakeCursor = CURSOR_VALID;
+ assert( offsetof(BtCursor, eState)==0 );
+ return (BtCursor*)&fakeCursor;
+}
+
+/*
** This routine restores a cursor back to its original position after it
** has been moved by some outside activity (such as a btree rebalance or
** a row having been deleted out from under the cursor).
@@ -60947,8 +61830,11 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
int sz2 = 0;
int sz = get2byte(&data[iFree+2]);
int top = get2byte(&data[hdr+5]);
+ if( top>=iFree ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
if( iFree2 ){
- if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */
sz2 = get2byte(&data[iFree2+2]);
assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
@@ -60979,13 +61865,13 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
** if PRAGMA cell_size_check=ON.
*/
if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( pc>=iCellFirst && pc<=iCellLast );
size = pPage->xCellSize(pPage, &src[pc]);
cbrk -= size;
if( cbrk<iCellFirst || pc+size>usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
testcase( cbrk+size==usableSize );
@@ -61005,7 +61891,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
defragment_out:
if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( cbrk>=iCellFirst );
put2byte(&data[hdr+5], cbrk);
@@ -61037,16 +61923,10 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
int pc = get2byte(&aData[iAddr]);
int x;
int usableSize = pPg->pBt->usableSize;
+ int size; /* Size of the free slot */
assert( pc>0 );
- do{
- int size; /* Size of the free slot */
- /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
- ** increasing offset. */
- if( pc>usableSize-4 || pc<iAddr+4 ){
- *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
- return 0;
- }
+ while( pc<=usableSize-4 ){
/* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
** freeblock form a big-endian integer which is the size of the freeblock
** in bytes, including the 4-byte header. */
@@ -61054,8 +61934,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
if( (x = size - nByte)>=0 ){
testcase( x==4 );
testcase( x==3 );
- if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
- *pRc = SQLITE_CORRUPT_PGNO(pPg->pgno);
+ if( size+pc > usableSize ){
+ *pRc = SQLITE_CORRUPT_PAGE(pPg);
return 0;
}else if( x<4 ){
/* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
@@ -61075,7 +61955,11 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
}
iAddr = pc;
pc = get2byte(&aData[pc]);
- }while( pc );
+ if( pc<iAddr+size ) break;
+ }
+ if( pc ){
+ *pRc = SQLITE_CORRUPT_PAGE(pPg);
+ }
return 0;
}
@@ -61122,7 +62006,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
if( top==0 && pPage->pBt->usableSize==65536 ){
top = 65536;
}else{
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
@@ -61189,7 +62073,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
u8 hdr; /* Page header size. 0 or 100 */
u8 nFrag = 0; /* Reduction in fragmentation */
u16 iOrigSize = iSize; /* Original value of iSize */
- u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
+ u16 x; /* Offset to cell content area */
u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
unsigned char *data = pPage->aData; /* Page content */
@@ -61199,13 +62083,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( iSize>=4 ); /* Minimum cell size is 4 */
- assert( iStart<=iLast );
-
- /* Overwrite deleted information with zeros when the secure_delete
- ** option is enabled */
- if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
- memset(&data[iStart], 0, iSize);
- }
+ assert( iStart<=pPage->pBt->usableSize-4 );
/* The list of freeblocks must be in ascending order. Find the
** spot on the list where iStart should be inserted.
@@ -61218,11 +62096,13 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
while( (iFreeBlk = get2byte(&data[iPtr]))<iStart ){
if( iFreeBlk<iPtr+4 ){
if( iFreeBlk==0 ) break;
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
iPtr = iFreeBlk;
}
- if( iFreeBlk>iLast ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( iFreeBlk>pPage->pBt->usableSize-4 ){
+ return SQLITE_CORRUPT_PAGE(pPage);
+ }
assert( iFreeBlk>iPtr || iFreeBlk==0 );
/* At this point:
@@ -61233,10 +62113,10 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
*/
if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd;
- if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
if( iEnd > pPage->pBt->usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
iSize = iEnd - iStart;
iFreeBlk = get2byte(&data[iFreeBlk]);
@@ -61249,28 +62129,34 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
if( iPtr>hdr+1 ){
int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
if( iPtrEnd+3>=iStart ){
- if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( iPtrEnd>iStart ) return SQLITE_CORRUPT_PAGE(pPage);
nFrag += iStart - iPtrEnd;
iSize = iEnd - iPtr;
iStart = iPtr;
}
}
- if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
data[hdr+7] -= nFrag;
}
- if( iStart==get2byte(&data[hdr+5]) ){
+ x = get2byte(&data[hdr+5]);
+ if( iStart<=x ){
/* The new freeblock is at the beginning of the cell content area,
** so just extend the cell content area rather than create another
** freelist entry */
- if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ if( iStart<x || iPtr!=hdr+1 ) return SQLITE_CORRUPT_PAGE(pPage);
put2byte(&data[hdr+1], iFreeBlk);
put2byte(&data[hdr+5], iEnd);
}else{
/* Insert the new freeblock into the freelist */
put2byte(&data[iPtr], iStart);
- put2byte(&data[iStart], iFreeBlk);
- put2byte(&data[iStart+2], iSize);
}
+ if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
+ /* Overwrite deleted information with zeros when the secure_delete
+ ** option is enabled */
+ memset(&data[iStart], 0, iSize);
+ }
+ put2byte(&data[iStart], iFreeBlk);
+ put2byte(&data[iStart+2], iSize);
pPage->nFree += iOrigSize;
return SQLITE_OK;
}
@@ -61330,7 +62216,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){
}else{
/* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
** an error. */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->max1bytePayload = pBt->max1bytePayload;
return SQLITE_OK;
@@ -61371,7 +62257,7 @@ static int btreeInitPage(MemPage *pPage){
/* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
** the b-tree page type. */
if( decodeFlags(pPage, data[hdr]) ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
pPage->maskPage = (u16)(pBt->pageSize - 1);
@@ -61390,7 +62276,7 @@ static int btreeInitPage(MemPage *pPage){
pPage->nCell = get2byte(&data[hdr+3]);
if( pPage->nCell>MX_CELL(pBt) ){
/* To many cells for a single page. The page must be corrupt */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
testcase( pPage->nCell==MX_CELL(pBt) );
/* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
@@ -61418,12 +62304,12 @@ static int btreeInitPage(MemPage *pPage){
testcase( pc==iCellFirst );
testcase( pc==iCellLast );
if( pc<iCellFirst || pc>iCellLast ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
sz = pPage->xCellSize(pPage, &data[pc]);
testcase( pc+sz==usableSize );
if( pc+sz>usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
if( !pPage->leaf ) iCellLast++;
@@ -61441,12 +62327,12 @@ static int btreeInitPage(MemPage *pPage){
/* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
** always be at least one cell before the first freeblock.
*/
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
while( 1 ){
if( pc>iCellLast ){
/* Freeblock off the end of the page */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
next = get2byte(&data[pc]);
size = get2byte(&data[pc+2]);
@@ -61456,11 +62342,11 @@ static int btreeInitPage(MemPage *pPage){
}
if( next>0 ){
/* Freeblock not in ascending order */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( pc+size>(unsigned int)usableSize ){
/* Last freeblock extends past page end */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
@@ -61472,7 +62358,7 @@ static int btreeInitPage(MemPage *pPage){
** area, according to the page header, lies within the page.
*/
if( nFree>usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
pPage->nFree = (u16)(nFree - iCellFirst);
pPage->isInit = 1;
@@ -61585,7 +62471,7 @@ static Pgno btreePagecount(BtShared *pBt){
}
SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){
assert( sqlite3BtreeHoldsMutex(p) );
- assert( ((p->pBt->nPage)&0x8000000)==0 );
+ assert( ((p->pBt->nPage)&0x80000000)==0 );
return btreePagecount(p->pBt);
}
@@ -61612,7 +62498,7 @@ static int getAndInitPage(
int rc;
DbPage *pDbPage;
assert( sqlite3_mutex_held(pBt->mutex) );
- assert( pCur==0 || ppPage==&pCur->apPage[pCur->iPage] );
+ assert( pCur==0 || ppPage==&pCur->pPage );
assert( pCur==0 || bReadOnly==pCur->curPagerFlags );
assert( pCur==0 || pCur->iPage>0 );
@@ -61646,7 +62532,10 @@ static int getAndInitPage(
return SQLITE_OK;
getAndInitPage_error:
- if( pCur ) pCur->iPage--;
+ if( pCur ){
+ pCur->iPage--;
+ pCur->pPage = pCur->apPage[pCur->iPage];
+ }
testcase( pgno==0 );
assert( pgno!=0 || rc==SQLITE_CORRUPT );
return rc;
@@ -61655,6 +62544,8 @@ getAndInitPage_error:
/*
** Release a MemPage. This should be called once for each prior
** call to btreeGetPage.
+**
+** Page1 is a special case and must be released using releasePageOne().
*/
static void releasePageNotNull(MemPage *pPage){
assert( pPage->aData );
@@ -61668,6 +62559,16 @@ static void releasePageNotNull(MemPage *pPage){
static void releasePage(MemPage *pPage){
if( pPage ) releasePageNotNull(pPage);
}
+static void releasePageOne(MemPage *pPage){
+ assert( pPage!=0 );
+ assert( pPage->aData );
+ assert( pPage->pBt );
+ assert( pPage->pDbPage!=0 );
+ assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
+ assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
+ assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ sqlite3PagerUnrefPageOne(pPage->pDbPage);
+}
/*
** Get an unused page.
@@ -62452,7 +63353,8 @@ SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){
** set to the value passed to this function as the second parameter,
** set it so.
*/
-#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS
+#if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \
+ && !defined(SQLITE_OMIT_WAL)
static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){
sqlite3 *db;
Db *pDb;
@@ -62546,7 +63448,7 @@ static int lockBtree(BtShared *pBt){
}else{
setDefaultSyncFlag(pBt, SQLITE_DEFAULT_WAL_SYNCHRONOUS+1);
if( isOpen==0 ){
- releasePage(pPage1);
+ releasePageOne(pPage1);
return SQLITE_OK;
}
}
@@ -62593,7 +63495,7 @@ static int lockBtree(BtShared *pBt){
** zero and return SQLITE_OK. The caller will call this function
** again with the correct page-size.
*/
- releasePage(pPage1);
+ releasePageOne(pPage1);
pBt->usableSize = usableSize;
pBt->pageSize = pageSize;
freeTempSpace(pBt);
@@ -62647,7 +63549,7 @@ static int lockBtree(BtShared *pBt){
return SQLITE_OK;
page1_init_failed:
- releasePage(pPage1);
+ releasePageOne(pPage1);
pBt->pPage1 = 0;
return rc;
}
@@ -62692,7 +63594,7 @@ static void unlockBtreeIfUnused(BtShared *pBt){
assert( pPage1->aData );
assert( sqlite3PagerRefcount(pBt->pPager)==1 );
pBt->pPage1 = 0;
- releasePageNotNull(pPage1);
+ releasePageOne(pPage1);
}
}
@@ -62987,7 +63889,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( eType==PTRMAP_OVERFLOW2 ){
/* The pointer is always the first 4 bytes of the page in this case. */
if( get4byte(pPage->aData)!=iFrom ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
put4byte(pPage->aData, iTo);
}else{
@@ -63006,7 +63908,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
pPage->xParseCell(pPage, pCell, &info);
if( info.nLocal<info.nPayload ){
if( pCell+info.nSize > pPage->aData+pPage->pBt->usableSize ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
if( iFrom==get4byte(pCell+info.nSize-4) ){
put4byte(pCell+info.nSize-4, iTo);
@@ -63024,7 +63926,7 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){
if( i==nCell ){
if( eType!=PTRMAP_BTREE ||
get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
put4byte(&pPage->aData[pPage->hdrOffset+8], iTo);
}
@@ -63544,7 +64446,6 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr
if( pBtree ){
sqlite3BtreeEnter(pBtree);
for(p=pBtree->pBt->pCursor; p; p=p->pNext){
- int i;
if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
rc = saveCursorPosition(p);
@@ -63558,10 +64459,7 @@ SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int wr
p->eState = CURSOR_FAULT;
p->skipNext = errCode;
}
- for(i=0; i<=p->iPage; i++){
- releasePage(p->apPage[i]);
- p->apPage[i] = 0;
- }
+ btreeReleaseAllCursorPages(p);
}
sqlite3BtreeLeave(pBtree);
}
@@ -63618,7 +64516,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage);
testcase( pBt->nPage!=nPage );
pBt->nPage = nPage;
- releasePage(pPage1);
+ releasePageOne(pPage1);
}
assert( countValidCursors(pBt, 1)==0 );
pBt->inTransaction = TRANS_READ;
@@ -63860,10 +64758,8 @@ SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){
SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
Btree *pBtree = pCur->pBtree;
if( pBtree ){
- int i;
BtShared *pBt = pCur->pBt;
sqlite3BtreeEnter(pBtree);
- sqlite3BtreeClearCursor(pCur);
assert( pBt->pCursor!=0 );
if( pBt->pCursor==pCur ){
pBt->pCursor = pCur->pNext;
@@ -63877,12 +64773,10 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
pPrev = pPrev->pNext;
}while( ALWAYS(pPrev) );
}
- for(i=0; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- }
+ btreeReleaseAllCursorPages(pCur);
unlockBtreeIfUnused(pBt);
sqlite3_free(pCur->aOverflow);
- /* sqlite3_free(pCur); */
+ sqlite3_free(pCur->pKey);
sqlite3BtreeLeave(pBtree);
}
return SQLITE_OK;
@@ -63899,9 +64793,8 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
#ifndef NDEBUG
static void assertCellInfo(BtCursor *pCur){
CellInfo info;
- int iPage = pCur->iPage;
memset(&info, 0, sizeof(info));
- btreeParseCell(pCur->apPage[iPage], pCur->ix, &info);
+ btreeParseCell(pCur->pPage, pCur->ix, &info);
assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
}
#else
@@ -63909,9 +64802,8 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
#endif
static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
if( pCur->info.nSize==0 ){
- int iPage = pCur->iPage;
pCur->curFlags |= BTCF_ValidNKey;
- btreeParseCell(pCur->apPage[iPage],pCur->ix,&pCur->info);
+ btreeParseCell(pCur->pPage,pCur->ix,&pCur->info);
}else{
assertCellInfo(pCur);
}
@@ -63946,6 +64838,20 @@ SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){
return pCur->info.nKey;
}
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+/*
+** Return the offset into the database file for the start of the
+** payload to which the cursor is pointing.
+*/
+SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){
+ assert( cursorHoldsMutex(pCur) );
+ assert( pCur->eState==CURSOR_VALID );
+ getCellInfo(pCur);
+ return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) +
+ (i64)(pCur->info.pPayload - pCur->pPage->aData);
+}
+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
+
/*
** Return the number of bytes of payload for the entry that pCur is
** currently pointing to. For table btrees, this will be the amount
@@ -64109,7 +65015,7 @@ static int accessPayload(
unsigned char *aPayload;
int rc = SQLITE_OK;
int iIdx = 0;
- MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
+ MemPage *pPage = pCur->pPage; /* Btree page of current entry */
BtShared *pBt = pCur->pBt; /* Btree this cursor belongs to */
#ifdef SQLITE_DIRECT_OVERFLOW_READ
unsigned char * const pBufStart = pBuf; /* Start of original out buffer */
@@ -64132,7 +65038,7 @@ static int accessPayload(
** &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
** but is recast into its current form to avoid integer overflow problems
*/
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
/* Check if data must be read/written to/from the btree page itself. */
@@ -64280,7 +65186,7 @@ static int accessPayload(
if( rc==SQLITE_OK && amt>0 ){
/* Overflow chain ends prematurely */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
return rc;
}
@@ -64305,8 +65211,8 @@ static int accessPayload(
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] );
- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->iPage>=0 && pCur->pPage );
+ assert( pCur->ix<pCur->pPage->nCell );
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
}
@@ -64363,18 +65269,23 @@ static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
u32 *pAmt /* Write the number of available bytes here */
){
- u32 amt;
- assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
+ int amt;
+ assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
assert( pCur->eState==CURSOR_VALID );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorOwnsBtShared(pCur) );
- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->ix<pCur->pPage->nCell );
assert( pCur->info.nSize>0 );
- assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
- assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
- amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
- if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
- *pAmt = amt;
+ assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
+ assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
+ amt = pCur->info.nLocal;
+ if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
+ /* There is too little space on the page for the expected amount
+ ** of local content. Database must be corrupt. */
+ assert( CORRUPT_DB );
+ amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload));
+ }
+ *pAmt = (u32)amt;
return (void*)pCur->info.pPayload;
}
@@ -64419,10 +65330,11 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
}
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
- pCur->aiIdx[pCur->iPage++] = pCur->ix;
+ pCur->aiIdx[pCur->iPage] = pCur->ix;
+ pCur->apPage[pCur->iPage] = pCur->pPage;
pCur->ix = 0;
- return getAndInitPage(pBt, newPgno, &pCur->apPage[pCur->iPage],
- pCur, pCur->curPagerFlags);
+ pCur->iPage++;
+ return getAndInitPage(pBt, newPgno, &pCur->pPage, pCur, pCur->curPagerFlags);
}
#ifdef SQLITE_DEBUG
@@ -64456,20 +65368,23 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
** the largest cell index.
*/
static void moveToParent(BtCursor *pCur){
+ MemPage *pLeaf;
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
assert( pCur->iPage>0 );
- assert( pCur->apPage[pCur->iPage] );
+ assert( pCur->pPage );
assertParentIndex(
pCur->apPage[pCur->iPage-1],
pCur->aiIdx[pCur->iPage-1],
- pCur->apPage[pCur->iPage]->pgno
+ pCur->pPage->pgno
);
testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
pCur->ix = pCur->aiIdx[pCur->iPage-1];
- releasePageNotNull(pCur->apPage[pCur->iPage--]);
+ pLeaf = pCur->pPage;
+ pCur->pPage = pCur->apPage[--pCur->iPage];
+ releasePageNotNull(pLeaf);
}
/*
@@ -64481,9 +65396,9 @@ static void moveToParent(BtCursor *pCur){
** single child page. This can only happen with the table rooted at page 1.
**
** If the b-tree structure is empty, the cursor state is set to
-** CURSOR_INVALID. Otherwise, the cursor is set to point to the first
-** cell located on the root (or virtual root) page and the cursor state
-** is set to CURSOR_VALID.
+** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise,
+** the cursor is set to point to the first cell located on the root
+** (or virtual root) page and the cursor state is set to CURSOR_VALID.
**
** If this function returns successfully, it may be assumed that the
** page-header flags indicate that the [virtual] root-page is the expected
@@ -64501,37 +65416,40 @@ static int moveToRoot(BtCursor *pCur){
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
assert( CURSOR_VALID < CURSOR_REQUIRESEEK );
assert( CURSOR_FAULT > CURSOR_REQUIRESEEK );
- if( pCur->eState>=CURSOR_REQUIRESEEK ){
- if( pCur->eState==CURSOR_FAULT ){
- assert( pCur->skipNext!=SQLITE_OK );
- return pCur->skipNext;
- }
- sqlite3BtreeClearCursor(pCur);
- }
+ assert( pCur->eState < CURSOR_REQUIRESEEK || pCur->iPage<0 );
+ assert( pCur->pgnoRoot>0 || pCur->iPage<0 );
if( pCur->iPage>=0 ){
if( pCur->iPage ){
- do{
- assert( pCur->apPage[pCur->iPage]!=0 );
- releasePageNotNull(pCur->apPage[pCur->iPage--]);
- }while( pCur->iPage);
+ releasePageNotNull(pCur->pPage);
+ while( --pCur->iPage ){
+ releasePageNotNull(pCur->apPage[pCur->iPage]);
+ }
+ pCur->pPage = pCur->apPage[0];
goto skip_init;
}
}else if( pCur->pgnoRoot==0 ){
pCur->eState = CURSOR_INVALID;
- return SQLITE_OK;
+ return SQLITE_EMPTY;
}else{
assert( pCur->iPage==(-1) );
- rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
+ if( pCur->eState>=CURSOR_REQUIRESEEK ){
+ if( pCur->eState==CURSOR_FAULT ){
+ assert( pCur->skipNext!=SQLITE_OK );
+ return pCur->skipNext;
+ }
+ sqlite3BtreeClearCursor(pCur);
+ }
+ rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage,
0, pCur->curPagerFlags);
if( rc!=SQLITE_OK ){
pCur->eState = CURSOR_INVALID;
- return rc;
+ return rc;
}
pCur->iPage = 0;
- pCur->curIntKey = pCur->apPage[0]->intKey;
+ pCur->curIntKey = pCur->pPage->intKey;
}
- pRoot = pCur->apPage[0];
+ pRoot = pCur->pPage;
assert( pRoot->pgno==pCur->pgnoRoot );
/* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
@@ -64546,7 +65464,7 @@ static int moveToRoot(BtCursor *pCur){
** (or the freelist). */
assert( pRoot->intKey==1 || pRoot->intKey==0 );
if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
- return SQLITE_CORRUPT_PGNO(pCur->apPage[pCur->iPage]->pgno);
+ return SQLITE_CORRUPT_PAGE(pCur->pPage);
}
skip_init:
@@ -64554,7 +65472,7 @@ skip_init:
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl);
- pRoot = pCur->apPage[0];
+ pRoot = pCur->pPage;
if( pRoot->nCell>0 ){
pCur->eState = CURSOR_VALID;
}else if( !pRoot->leaf ){
@@ -64565,6 +65483,7 @@ skip_init:
rc = moveToChild(pCur, subpage);
}else{
pCur->eState = CURSOR_INVALID;
+ rc = SQLITE_EMPTY;
}
return rc;
}
@@ -64583,7 +65502,7 @@ static int moveToLeftmost(BtCursor *pCur){
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
- while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
+ while( rc==SQLITE_OK && !(pPage = pCur->pPage)->leaf ){
assert( pCur->ix<pPage->nCell );
pgno = get4byte(findCell(pPage, pCur->ix));
rc = moveToChild(pCur, pgno);
@@ -64608,7 +65527,7 @@ static int moveToRightmost(BtCursor *pCur){
assert( cursorOwnsBtShared(pCur) );
assert( pCur->eState==CURSOR_VALID );
- while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
+ while( !(pPage = pCur->pPage)->leaf ){
pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
pCur->ix = pPage->nCell;
rc = moveToChild(pCur, pgno);
@@ -64631,14 +65550,13 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
- if( pCur->eState==CURSOR_INVALID ){
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
- *pRes = 1;
- }else{
- assert( pCur->apPage[pCur->iPage]->nCell>0 );
- *pRes = 0;
- rc = moveToLeftmost(pCur);
- }
+ assert( pCur->pPage->nCell>0 );
+ *pRes = 0;
+ rc = moveToLeftmost(pCur);
+ }else if( rc==SQLITE_EMPTY ){
+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+ *pRes = 1;
+ rc = SQLITE_OK;
}
return rc;
}
@@ -64662,28 +65580,26 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
for(ii=0; ii<pCur->iPage; ii++){
assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell );
}
- assert( pCur->ix==pCur->apPage[pCur->iPage]->nCell-1 );
- assert( pCur->apPage[pCur->iPage]->leaf );
+ assert( pCur->ix==pCur->pPage->nCell-1 );
+ assert( pCur->pPage->leaf );
#endif
return SQLITE_OK;
}
rc = moveToRoot(pCur);
if( rc==SQLITE_OK ){
- if( CURSOR_INVALID==pCur->eState ){
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
- *pRes = 1;
+ assert( pCur->eState==CURSOR_VALID );
+ *pRes = 0;
+ rc = moveToRightmost(pCur);
+ if( rc==SQLITE_OK ){
+ pCur->curFlags |= BTCF_AtLast;
}else{
- assert( pCur->eState==CURSOR_VALID );
- *pRes = 0;
- rc = moveToRightmost(pCur);
- if( rc==SQLITE_OK ){
- pCur->curFlags |= BTCF_AtLast;
- }else{
- pCur->curFlags &= ~BTCF_AtLast;
- }
-
+ pCur->curFlags &= ~BTCF_AtLast;
}
+ }else if( rc==SQLITE_EMPTY ){
+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+ *pRes = 1;
+ rc = SQLITE_OK;
}
return rc;
}
@@ -64782,22 +65698,23 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
rc = moveToRoot(pCur);
if( rc ){
+ if( rc==SQLITE_EMPTY ){
+ assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+ *pRes = -1;
+ return SQLITE_OK;
+ }
return rc;
}
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage] );
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->isInit );
- assert( pCur->eState==CURSOR_INVALID || pCur->apPage[pCur->iPage]->nCell>0 );
- if( pCur->eState==CURSOR_INVALID ){
- *pRes = -1;
- assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
- return SQLITE_OK;
- }
- assert( pCur->apPage[0]->intKey==pCur->curIntKey );
+ assert( pCur->pPage );
+ assert( pCur->pPage->isInit );
+ assert( pCur->eState==CURSOR_VALID );
+ assert( pCur->pPage->nCell > 0 );
+ assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
assert( pCur->curIntKey || pIdxKey );
for(;;){
int lwr, upr, idx, c;
Pgno chldPg;
- MemPage *pPage = pCur->apPage[pCur->iPage];
+ MemPage *pPage = pCur->pPage;
u8 *pCell; /* Pointer to current cell in pPage */
/* pPage->nCell must be greater than zero. If this is the root-page
@@ -64820,7 +65737,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
if( pPage->intKeyLeaf ){
while( 0x80 <= *(pCell++) ){
if( pCell>=pPage->aDataEnd ){
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
}
}
@@ -64894,7 +65811,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
testcase( nCell==2 ); /* Minimum legal index key size */
if( nCell<2 ){
- rc = SQLITE_CORRUPT_PGNO(pPage->pgno);
+ rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_finish;
}
pCellKey = sqlite3Malloc( nCell+18 );
@@ -64925,7 +65842,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
*pRes = 0;
rc = SQLITE_OK;
pCur->ix = (u16)idx;
- if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
+ if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT;
goto moveto_finish;
}
if( lwr>upr ) break;
@@ -64936,7 +65853,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->ix<pCur->pPage->nCell );
pCur->ix = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
@@ -64990,9 +65907,10 @@ SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){
** 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;
+ if( NEVER(pCur->pPage->leaf==0) ) return -1;
- for(n=1, i=0; i<=pCur->iPage; i++){
+ n = pCur->pPage->nCell;
+ for(i=0; i<pCur->iPage; i++){
n *= pCur->apPage[i]->nCell;
}
return n;
@@ -65045,7 +65963,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
}
}
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
idx = ++pCur->ix;
assert( pPage->isInit );
@@ -65068,7 +65986,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){
return SQLITE_DONE;
}
moveToParent(pCur);
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
}while( pCur->ix>=pPage->nCell );
if( pPage->intKey ){
return sqlite3BtreeNext(pCur, 0);
@@ -65091,7 +66009,7 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){
pCur->info.nSize = 0;
pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur);
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
if( (++pCur->ix)>=pPage->nCell ){
pCur->ix--;
return btreeNext(pCur);
@@ -65150,7 +66068,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
}
}
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
assert( pPage->isInit );
if( !pPage->leaf ){
int idx = pCur->ix;
@@ -65169,7 +66087,7 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){
assert( (pCur->curFlags & (BTCF_ValidOvfl))==0 );
pCur->ix--;
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
if( pPage->intKey && !pPage->leaf ){
rc = sqlite3BtreePrevious(pCur, 0);
}else{
@@ -65187,7 +66105,7 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){
pCur->info.nSize = 0;
if( pCur->eState!=CURSOR_VALID
|| pCur->ix==0
- || pCur->apPage[pCur->iPage]->leaf==0
+ || pCur->pPage->leaf==0
){
return btreePrevious(pCur);
}
@@ -65683,7 +66601,7 @@ static int clearCell(
unsigned char *pCell, /* First byte of the Cell */
CellInfo *pInfo /* Size information about the cell */
){
- BtShared *pBt = pPage->pBt;
+ BtShared *pBt;
Pgno ovflPgno;
int rc;
int nOvfl;
@@ -65696,9 +66614,10 @@ static int clearCell(
}
if( pCell+pInfo->nSize-1 > pPage->aData+pPage->maskPage ){
/* Cell extends past end of page */
- return SQLITE_CORRUPT_PGNO(pPage->pgno);
+ return SQLITE_CORRUPT_PAGE(pPage);
}
ovflPgno = get4byte(pCell + pInfo->nSize - 4);
+ pBt = pPage->pBt;
assert( pBt->usableSize > 4 );
ovflPageSize = pBt->usableSize - 4;
nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize;
@@ -65766,21 +66685,20 @@ static int fillInCell(
){
int nPayload;
const u8 *pSrc;
- int nSrc, n, rc;
+ int nSrc, n, rc, mn;
int spaceLeft;
- MemPage *pOvfl = 0;
- MemPage *pToRelease = 0;
+ MemPage *pToRelease;
unsigned char *pPrior;
unsigned char *pPayload;
- BtShared *pBt = pPage->pBt;
- Pgno pgnoOvfl = 0;
+ BtShared *pBt;
+ Pgno pgnoOvfl;
int nHeader;
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
/* pPage is not necessarily writeable since pCell might be auxiliary
** buffer space that is separate from the pPage buffer area */
- assert( pCell<pPage->aData || pCell>=&pPage->aData[pBt->pageSize]
+ assert( pCell<pPage->aData || pCell>=&pPage->aData[pPage->pBt->pageSize]
|| sqlite3PagerIswriteable(pPage->pDbPage) );
/* Fill in the header. */
@@ -65800,25 +66718,36 @@ static int fillInCell(
}
/* Fill in the payload */
+ pPayload = &pCell[nHeader];
if( nPayload<=pPage->maxLocal ){
+ /* This is the common case where everything fits on the btree page
+ ** and no overflow pages are required. */
n = nHeader + nPayload;
testcase( n==3 );
testcase( n==4 );
if( n<4 ) n = 4;
*pnSize = n;
- spaceLeft = nPayload;
- pPrior = pCell;
- }else{
- int mn = pPage->minLocal;
- n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
- testcase( n==pPage->maxLocal );
- testcase( n==pPage->maxLocal+1 );
- if( n > pPage->maxLocal ) n = mn;
- spaceLeft = n;
- *pnSize = n + nHeader + 4;
- pPrior = &pCell[nHeader+n];
+ assert( nSrc<=nPayload );
+ testcase( nSrc<nPayload );
+ memcpy(pPayload, pSrc, nSrc);
+ memset(pPayload+nSrc, 0, nPayload-nSrc);
+ return SQLITE_OK;
}
- pPayload = &pCell[nHeader];
+
+ /* If we reach this point, it means that some of the content will need
+ ** to spill onto overflow pages.
+ */
+ mn = pPage->minLocal;
+ n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
+ testcase( n==pPage->maxLocal );
+ testcase( n==pPage->maxLocal+1 );
+ if( n > pPage->maxLocal ) n = mn;
+ spaceLeft = n;
+ *pnSize = n + nHeader + 4;
+ pPrior = &pCell[nHeader+n];
+ pToRelease = 0;
+ pgnoOvfl = 0;
+ pBt = pPage->pBt;
/* At this point variables should be set as follows:
**
@@ -65844,8 +66773,35 @@ static int fillInCell(
#endif
/* Write the payload into the local Cell and any extra into overflow pages */
- while( nPayload>0 ){
+ while( 1 ){
+ n = nPayload;
+ if( n>spaceLeft ) n = spaceLeft;
+
+ /* If pToRelease is not zero than pPayload points into the data area
+ ** of pToRelease. Make sure pToRelease is still writeable. */
+ assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
+
+ /* If pPayload is part of the data area of pPage, then make sure pPage
+ ** is still writeable */
+ assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
+ || sqlite3PagerIswriteable(pPage->pDbPage) );
+
+ if( nSrc>=n ){
+ memcpy(pPayload, pSrc, n);
+ }else if( nSrc>0 ){
+ n = nSrc;
+ memcpy(pPayload, pSrc, n);
+ }else{
+ memset(pPayload, 0, n);
+ }
+ nPayload -= n;
+ if( nPayload<=0 ) break;
+ pPayload += n;
+ pSrc += n;
+ nSrc -= n;
+ spaceLeft -= n;
if( spaceLeft==0 ){
+ MemPage *pOvfl = 0;
#ifndef SQLITE_OMIT_AUTOVACUUM
Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */
if( pBt->autoVacuum ){
@@ -65898,30 +66854,6 @@ static int fillInCell(
pPayload = &pOvfl->aData[4];
spaceLeft = pBt->usableSize - 4;
}
- n = nPayload;
- if( n>spaceLeft ) n = spaceLeft;
-
- /* If pToRelease is not zero than pPayload points into the data area
- ** of pToRelease. Make sure pToRelease is still writeable. */
- assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) );
-
- /* If pPayload is part of the data area of pPage, then make sure pPage
- ** is still writeable */
- assert( pPayload<pPage->aData || pPayload>=&pPage->aData[pBt->pageSize]
- || sqlite3PagerIswriteable(pPage->pDbPage) );
-
- if( nSrc>0 ){
- if( n>nSrc ) n = nSrc;
- assert( pSrc );
- memcpy(pPayload, pSrc, n);
- }else{
- memset(pPayload, 0, n);
- }
- nPayload -= n;
- pPayload += n;
- pSrc += n;
- nSrc -= n;
- spaceLeft -= n;
}
releasePage(pToRelease);
return SQLITE_OK;
@@ -65953,7 +66885,7 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
hdr = pPage->hdrOffset;
testcase( pc==get2byte(&data[hdr+5]) );
testcase( pc+sz==pPage->pBt->usableSize );
- if( pc < (u32)get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){
+ if( pc+sz > pPage->pBt->usableSize ){
*pRC = SQLITE_CORRUPT_BKPT;
return;
}
@@ -66820,10 +67752,8 @@ static int balance_nonroot(
+ nMaxCells*sizeof(u16) /* b.szCell */
+ pBt->pageSize; /* aSpace1 */
- /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
- ** that is more than 6 times the database page size. */
assert( szScratch<=6*(int)pBt->pageSize );
- b.apCell = sqlite3ScratchMalloc( szScratch );
+ b.apCell = sqlite3StackAllocRaw(0, szScratch );
if( b.apCell==0 ){
rc = SQLITE_NOMEM_BKPT;
goto balance_cleanup;
@@ -67401,7 +68331,7 @@ static int balance_nonroot(
** Cleanup before returning.
*/
balance_cleanup:
- sqlite3ScratchFree(b.apCell);
+ sqlite3StackFree(0, b.apCell);
for(i=0; i<nOld; i++){
releasePage(apOld[i]);
}
@@ -67500,7 +68430,7 @@ static int balance(BtCursor *pCur){
do {
int iPage = pCur->iPage;
- MemPage *pPage = pCur->apPage[iPage];
+ MemPage *pPage = pCur->pPage;
if( iPage==0 ){
if( pPage->nOverflow ){
@@ -67516,7 +68446,9 @@ static int balance(BtCursor *pCur){
pCur->iPage = 1;
pCur->ix = 0;
pCur->aiIdx[0] = 0;
- assert( pCur->apPage[1]->nOverflow );
+ pCur->apPage[0] = pPage;
+ pCur->pPage = pCur->apPage[1];
+ assert( pCur->pPage->nOverflow );
}
}else{
break;
@@ -67596,6 +68528,7 @@ static int balance(BtCursor *pCur){
releasePage(pPage);
pCur->iPage--;
assert( pCur->iPage>=0 );
+ pCur->pPage = pCur->apPage[pCur->iPage];
}
}while( rc==SQLITE_OK );
@@ -67727,7 +68660,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
}
assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) );
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
assert( pPage->intKey || pX->nKey>=0 );
assert( pPage->leaf || !pPage->intKey );
@@ -67814,10 +68747,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** fails. Internal data structure corruption will result otherwise.
** Also, set the cursor state to invalid. This stops saveCursorPosition()
** from trying to save the current position of the cursor. */
- pCur->apPage[pCur->iPage]->nOverflow = 0;
+ pCur->pPage->nOverflow = 0;
pCur->eState = CURSOR_INVALID;
if( (flags & BTREE_SAVEPOSITION) && rc==SQLITE_OK ){
- rc = moveToRoot(pCur);
+ btreeReleaseAllCursorPages(pCur);
if( pCur->pKeyInfo ){
assert( pCur->pKey==0 );
pCur->pKey = sqlite3Malloc( pX->nKey );
@@ -67831,7 +68764,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
pCur->nKey = pX->nKey;
}
}
- assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
+ assert( pCur->iPage<0 || pCur->pPage->nOverflow==0 );
end_insert:
return rc;
@@ -67872,13 +68805,13 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
assert( pCur->curFlags & BTCF_WriteFlag );
assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
assert( !hasReadConflicts(p, pCur->pgnoRoot) );
- assert( pCur->ix<pCur->apPage[pCur->iPage]->nCell );
+ assert( pCur->ix<pCur->pPage->nCell );
assert( pCur->eState==CURSOR_VALID );
assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
iCellDepth = pCur->iPage;
iCellIdx = pCur->ix;
- pPage = pCur->apPage[iCellDepth];
+ pPage = pCur->pPage;
pCell = findCell(pPage, iCellIdx);
/* If the bPreserve flag is set to true, then the cursor position must
@@ -67944,11 +68877,16 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** node. The cell from the leaf node needs to be moved to the internal
** node to replace the deleted cell. */
if( !pPage->leaf ){
- MemPage *pLeaf = pCur->apPage[pCur->iPage];
+ MemPage *pLeaf = pCur->pPage;
int nCell;
- Pgno n = pCur->apPage[iCellDepth+1]->pgno;
+ Pgno n;
unsigned char *pTmp;
+ if( iCellDepth<pCur->iPage-1 ){
+ n = pCur->apPage[iCellDepth+1]->pgno;
+ }else{
+ n = pCur->pPage->pgno;
+ }
pCell = findCell(pLeaf, pLeaf->nCell-1);
if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
nCell = pLeaf->xCellSize(pLeaf, pCell);
@@ -67980,16 +68918,19 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
** well. */
rc = balance(pCur);
if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
+ releasePageNotNull(pCur->pPage);
+ pCur->iPage--;
while( pCur->iPage>iCellDepth ){
releasePage(pCur->apPage[pCur->iPage--]);
}
+ pCur->pPage = pCur->apPage[pCur->iPage];
rc = balance(pCur);
}
if( rc==SQLITE_OK ){
if( bSkipnext ){
assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
- assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB );
+ assert( pPage==pCur->pPage || CORRUPT_DB );
assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
pCur->eState = CURSOR_SKIPNEXT;
if( iCellIdx>=pPage->nCell ){
@@ -68001,8 +68942,10 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
}else{
rc = moveToRoot(pCur);
if( bPreserve ){
+ btreeReleaseAllCursorPages(pCur);
pCur->eState = CURSOR_REQUIRESEEK;
}
+ if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
}
}
return rc;
@@ -68467,11 +69410,11 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
i64 nEntry = 0; /* Value to return in *pnEntry */
int rc; /* Return code */
- if( pCur->pgnoRoot==0 ){
+ rc = moveToRoot(pCur);
+ if( rc==SQLITE_EMPTY ){
*pnEntry = 0;
return SQLITE_OK;
}
- rc = moveToRoot(pCur);
/* Unless an error occurs, the following loop runs one iteration for each
** page in the B-Tree structure (not including overflow pages).
@@ -68484,7 +69427,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
** this page contains countable entries. Increment the entry counter
** accordingly.
*/
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
if( pPage->leaf || !pPage->intKey ){
nEntry += pPage->nCell;
}
@@ -68507,10 +69450,10 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
return moveToRoot(pCur);
}
moveToParent(pCur);
- }while ( pCur->ix>=pCur->apPage[pCur->iPage]->nCell );
+ }while ( pCur->ix>=pCur->pPage->nCell );
pCur->ix++;
- pPage = pCur->apPage[pCur->iPage];
+ pPage = pCur->pPage;
}
/* Descend to the child node of the cell that the cursor currently
@@ -69351,7 +70294,7 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void
&& pCsr->pBt->inTransaction==TRANS_WRITE );
assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) );
assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) );
- assert( pCsr->apPage[pCsr->iPage]->intKey );
+ assert( pCsr->pPage->intKey );
return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1);
}
@@ -70290,7 +71233,7 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
if( p->flags & MEM_Null ){
/* Cannot be both MEM_Null and some other type */
assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
- |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
+ |MEM_RowSet|MEM_Frame|MEM_Agg))==0 );
/* If MEM_Null is set, then either the value is a pure NULL (the usual
** case) or it is a pointer set using sqlite3_bind_pointer() or
@@ -70402,7 +71345,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
assert( pMem->szMalloc==0
|| pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
if( n<32 ) n = 32;
- if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
+ if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
bPreserve = 0;
}else{
@@ -70418,7 +71361,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}
- if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){
+ if( bPreserve && pMem->z ){
+ assert( pMem->z!=pMem->zMalloc );
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
if( (pMem->flags&MEM_Dyn)!=0 ){
@@ -70457,6 +71401,20 @@ SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
}
/*
+** It is already known that pMem contains an unterminated string.
+** Add the zero terminator.
+*/
+static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
+ 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;
+ return SQLITE_OK;
+}
+
+/*
** Change pMem so that its MEM_Str or MEM_Blob value is stored in
** MEM.zMalloc, where it can be safely written.
**
@@ -70468,12 +71426,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
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;
+ int rc = vdbeMemAddTerminator(pMem);
+ if( rc ) return rc;
}
}
pMem->flags &= ~MEM_Ephem;
@@ -70513,20 +71467,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
#endif
/*
-** It is already known that pMem contains an unterminated string.
-** Add the zero terminator.
-*/
-static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
- 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;
- return SQLITE_OK;
-}
-
-/*
** Make sure the given Mem is \u0000 terminated.
*/
SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
@@ -70600,26 +71540,24 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
** otherwise.
*/
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
- int rc = SQLITE_OK;
- if( ALWAYS(pFunc && pFunc->xFinalize) ){
- sqlite3_context ctx;
- Mem t;
- assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
- assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- memset(&ctx, 0, sizeof(ctx));
- memset(&t, 0, sizeof(t));
- t.flags = MEM_Null;
- t.db = pMem->db;
- ctx.pOut = &t;
- ctx.pMem = pMem;
- ctx.pFunc = pFunc;
- pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
- assert( (pMem->flags & MEM_Dyn)==0 );
- if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
- memcpy(pMem, &t, sizeof(t));
- rc = ctx.isError;
- }
- return rc;
+ sqlite3_context ctx;
+ Mem t;
+ assert( pFunc!=0 );
+ assert( pFunc->xFinalize!=0 );
+ assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
+ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+ memset(&ctx, 0, sizeof(ctx));
+ memset(&t, 0, sizeof(t));
+ t.flags = MEM_Null;
+ t.db = pMem->db;
+ ctx.pOut = &t;
+ ctx.pMem = pMem;
+ ctx.pFunc = pFunc;
+ pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
+ assert( (pMem->flags & MEM_Dyn)==0 );
+ if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
+ memcpy(pMem, &t, sizeof(t));
+ return ctx.isError;
}
/*
@@ -70844,14 +71782,21 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
*/
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
+ int rc;
assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
- if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
+ rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
+ if( rc==0 ){
MemSetTypeFlag(pMem, MEM_Int);
}else{
- pMem->u.r = sqlite3VdbeRealValue(pMem);
- MemSetTypeFlag(pMem, MEM_Real);
- sqlite3VdbeIntegerAffinity(pMem);
+ i64 i = pMem->u.i;
+ sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
+ if( rc==1 && pMem->u.r==(double)i ){
+ pMem->u.i = i;
+ MemSetTypeFlag(pMem, MEM_Int);
+ }else{
+ MemSetTypeFlag(pMem, MEM_Real);
+ }
}
}
assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
@@ -71178,7 +72123,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
if( nByte<0 ){
assert( enc!=0 );
if( enc==SQLITE_UTF8 ){
- nByte = sqlite3Strlen30(z);
+ nByte = 0x7fffffff & (int)strlen(z);
if( nByte>iLimit ) nByte = iLimit+1;
}else{
for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
@@ -71256,12 +72201,11 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize(
){
int rc;
pMem->flags = MEM_Null;
- if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
+ if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){
rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z);
if( rc==SQLITE_OK ){
- pMem->z[amt] = 0;
- pMem->z[amt+1] = 0;
- pMem->flags = MEM_Blob|MEM_Term;
+ pMem->z[amt] = 0; /* Overrun area used when reading malformed records */
+ pMem->flags = MEM_Blob;
pMem->n = (int)amt;
}else{
sqlite3VdbeMemRelease(pMem);
@@ -71410,7 +72354,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
if( pRec ){
pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
if( pRec->pKeyInfo ){
- assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
+ assert( pRec->pKeyInfo->nAllField==nCol );
assert( pRec->pKeyInfo->enc==ENC(db) );
pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
for(i=0; i<nCol; i++){
@@ -71567,7 +72511,11 @@ static int valueFromExpr(
assert( pExpr!=0 );
while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
+#if defined(SQLITE_ENABLE_STAT3_OR_STAT4)
+ if( op==TK_REGISTER ) op = pExpr->op2;
+#else
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
+#endif
/* Compressed expressions only appear when parsing the DEFAULT clause
** on a table column definition, and hence only when pCtx==0. This
@@ -71662,7 +72610,10 @@ static int valueFromExpr(
return rc;
no_mem:
- sqlite3OomFault(db);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+ if( pCtx==0 || pCtx->pParse->nErr==0 )
+#endif
+ sqlite3OomFault(db);
sqlite3DbFree(db, zVal);
assert( *ppVal==0 );
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -71946,7 +72897,7 @@ SQLITE_PRIVATE int sqlite3Stat4Column(
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
if( pRec ){
int i;
- int nCol = pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField;
+ int nCol = pRec->pKeyInfo->nAllField;
Mem *aMem = pRec->aMem;
sqlite3 *db = aMem[0].db;
for(i=0; i<nCol; i++){
@@ -72042,10 +72993,12 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
p->pParse = pParse;
+ pParse->pVdbe = p;
assert( pParse->aLabel==0 );
assert( pParse->nLabel==0 );
assert( pParse->nOpAlloc==0 );
assert( pParse->szOpAlloc==0 );
+ sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
return p;
}
@@ -72499,7 +73452,8 @@ static Op *opIterNext(VdbeOpIter *p){
** * OP_VUpdate
** * OP_VRename
** * OP_FkCounter with P2==0 (immediate foreign key constraint)
-** * OP_CreateTable and OP_InitCoroutine (for CREATE TABLE AS SELECT ...)
+** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine
+** (for CREATE TABLE AS SELECT ...)
**
** Then check that the value of Parse.mayAbort is true if an
** ABORT may be thrown, or false otherwise. Return true if it does
@@ -72527,7 +73481,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
hasAbort = 1;
break;
}
- if( opcode==OP_CreateTable ) hasCreateTable = 1;
+ if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
@@ -72606,6 +73560,27 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
p->bIsReader = 1;
break;
}
+ case OP_Next:
+ case OP_NextIfOpen:
+ case OP_SorterNext: {
+ pOp->p4.xAdvance = sqlite3BtreeNext;
+ pOp->p4type = P4_ADVANCE;
+ /* The code generator never codes any of these opcodes as a jump
+ ** to a label. They are always coded as a jump backwards to a
+ ** known address */
+ assert( pOp->p2>=0 );
+ break;
+ }
+ case OP_Prev:
+ case OP_PrevIfOpen: {
+ pOp->p4.xAdvance = sqlite3BtreePrevious;
+ pOp->p4type = P4_ADVANCE;
+ /* The code generator never codes any of these opcodes as a jump
+ ** to a label. They are always coded as a jump backwards to a
+ ** known address */
+ assert( pOp->p2>=0 );
+ break;
+ }
#ifndef SQLITE_OMIT_VIRTUALTABLE
case OP_VUpdate: {
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
@@ -72617,27 +73592,25 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
assert( pOp[-1].opcode==OP_Integer );
n = pOp[-1].p1;
if( n>nMaxArgs ) nMaxArgs = n;
- break;
+ /* Fall through into the default case */
}
#endif
- case OP_Next:
- case OP_NextIfOpen:
- case OP_SorterNext: {
- pOp->p4.xAdvance = sqlite3BtreeNext;
- pOp->p4type = P4_ADVANCE;
- break;
- }
- case OP_Prev:
- case OP_PrevIfOpen: {
- pOp->p4.xAdvance = sqlite3BtreePrevious;
- pOp->p4type = P4_ADVANCE;
+ default: {
+ if( pOp->p2<0 ){
+ /* The mkopcodeh.tcl script has so arranged things that the only
+ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
+ ** have non-negative values for P2. */
+ assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
+ assert( ADDR(pOp->p2)<pParse->nLabel );
+ pOp->p2 = aLabel[ADDR(pOp->p2)];
+ }
break;
}
}
- if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 && pOp->p2<0 ){
- assert( ADDR(pOp->p2)<pParse->nLabel );
- pOp->p2 = aLabel[ADDR(pOp->p2)];
- }
+ /* The mkopcodeh.tcl script has so arranged things that the only
+ ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
+ ** have non-negative values for P2. */
+ assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0);
}
if( pOp==p->aOp ) break;
pOp--;
@@ -72853,6 +73826,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
case P4_REAL:
case P4_INT64:
case P4_DYNAMIC:
+ case P4_DYNBLOB:
case P4_INTARRAY: {
sqlite3DbFree(db, p4);
break;
@@ -73310,8 +74284,8 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
int j;
KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->aSortOrder!=0 );
- sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
- for(j=0; j<pKeyInfo->nField; j++){
+ sqlite3XPrintf(&x, "k(%d", pKeyInfo->nKeyField);
+ for(j=0; j<pKeyInfo->nKeyField; j++){
CollSeq *pColl = pKeyInfo->aColl[j];
const char *zColl = pColl ? pColl->zName : "";
if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
@@ -73383,7 +74357,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
int *ai = pOp->p4.ai;
int n = ai[0]; /* The first element of an INTARRAY is always the
** count of the number of elements to follow */
- for(i=1; i<n; i++){
+ for(i=1; i<=n; i++){
sqlite3XPrintf(&x, ",%d", ai[i]);
}
zTemp[0] = '[';
@@ -73394,6 +74368,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
sqlite3XPrintf(&x, "program");
break;
}
+ case P4_DYNBLOB:
case P4_ADVANCE: {
zTemp[0] = 0;
break;
@@ -73626,6 +74601,8 @@ SQLITE_PRIVATE int sqlite3VdbeList(
int i; /* Loop counter */
int rc = SQLITE_OK; /* Return code */
Mem *pMem = &p->aMem[1]; /* First Mem of result set */
+ int bListSubprogs = (p->explain==1 || (db->flags & SQLITE_TriggerEQP)!=0);
+ Op *pOp = 0;
assert( p->explain );
assert( p->magic==VDBE_MAGIC_RUN );
@@ -73638,7 +74615,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
releaseMemArray(pMem, 8);
p->pResultSet = 0;
- if( p->rc==SQLITE_NOMEM_BKPT ){
+ if( p->rc==SQLITE_NOMEM ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
sqlite3OomFault(db);
@@ -73653,7 +74630,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
** encountered, but p->pc will eventually catch up to nRow.
*/
nRow = p->nOp;
- if( p->explain==1 ){
+ if( bListSubprogs ){
/* The first 8 memory cells are used for the result set. So we will
** commandeer the 9th cell to use as storage for an array of pointers
** to trigger subprograms. The VDBE is guaranteed to have at least 9
@@ -73673,17 +74650,11 @@ SQLITE_PRIVATE int sqlite3VdbeList(
do{
i = p->pc++;
- }while( i<nRow && p->explain==2 && p->aOp[i].opcode!=OP_Explain );
- if( i>=nRow ){
- p->rc = SQLITE_OK;
- rc = SQLITE_DONE;
- }else if( db->u1.isInterrupted ){
- p->rc = SQLITE_INTERRUPT;
- rc = SQLITE_ERROR;
- sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
- }else{
- char *zP4;
- Op *pOp;
+ if( i>=nRow ){
+ p->rc = SQLITE_OK;
+ rc = SQLITE_DONE;
+ break;
+ }
if( i<p->nOp ){
/* The output line number is small enough that we are still in the
** main program. */
@@ -73698,94 +74669,110 @@ SQLITE_PRIVATE int sqlite3VdbeList(
}
pOp = &apSub[j]->aOp[i];
}
- if( p->explain==1 ){
- pMem->flags = MEM_Int;
- pMem->u.i = i; /* Program counter */
- pMem++;
-
- pMem->flags = MEM_Static|MEM_Str|MEM_Term;
- pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- pMem++;
- /* When an OP_Program opcode is encounter (the only opcode that has
- ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
- ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
- ** has not already been seen.
- */
- if( pOp->p4type==P4_SUBPROGRAM ){
- int nByte = (nSub+1)*sizeof(SubProgram*);
- int j;
- for(j=0; j<nSub; j++){
- if( apSub[j]==pOp->p4.pProgram ) break;
- }
- if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, nSub!=0) ){
- apSub = (SubProgram **)pSub->z;
- apSub[nSub++] = pOp->p4.pProgram;
- pSub->flags |= MEM_Blob;
- pSub->n = nSub*sizeof(SubProgram*);
+ /* When an OP_Program opcode is encounter (the only opcode that has
+ ** a P4_SUBPROGRAM argument), expand the size of the array of subprograms
+ ** kept in p->aMem[9].z to hold the new program - assuming this subprogram
+ ** has not already been seen.
+ */
+ if( bListSubprogs && pOp->p4type==P4_SUBPROGRAM ){
+ int nByte = (nSub+1)*sizeof(SubProgram*);
+ int j;
+ for(j=0; j<nSub; j++){
+ if( apSub[j]==pOp->p4.pProgram ) break;
+ }
+ if( j==nSub ){
+ p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0);
+ if( p->rc!=SQLITE_OK ){
+ rc = SQLITE_ERROR;
+ break;
}
+ apSub = (SubProgram **)pSub->z;
+ apSub[nSub++] = pOp->p4.pProgram;
+ pSub->flags |= MEM_Blob;
+ pSub->n = nSub*sizeof(SubProgram*);
+ nRow += pOp->p4.pProgram->nOp;
}
}
+ }while( p->explain==2 && pOp->opcode!=OP_Explain );
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p1; /* P1 */
- pMem++;
+ if( rc==SQLITE_OK ){
+ if( db->u1.isInterrupted ){
+ p->rc = SQLITE_INTERRUPT;
+ rc = SQLITE_ERROR;
+ sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
+ }else{
+ char *zP4;
+ if( p->explain==1 ){
+ pMem->flags = MEM_Int;
+ pMem->u.i = i; /* Program counter */
+ pMem++;
+
+ pMem->flags = MEM_Static|MEM_Str|MEM_Term;
+ pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
+ assert( pMem->z!=0 );
+ pMem->n = sqlite3Strlen30(pMem->z);
+ pMem->enc = SQLITE_UTF8;
+ pMem++;
+ }
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p2; /* P2 */
- pMem++;
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p1; /* P1 */
+ pMem++;
- pMem->flags = MEM_Int;
- pMem->u.i = pOp->p3; /* P3 */
- pMem++;
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p2; /* P2 */
+ pMem++;
- if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Str|MEM_Term;
- zP4 = displayP4(pOp, pMem->z, pMem->szMalloc);
- if( zP4!=pMem->z ){
- pMem->n = 0;
- sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
- }else{
- assert( pMem->z!=0 );
- pMem->n = sqlite3Strlen30(pMem->z);
- pMem->enc = SQLITE_UTF8;
- }
- pMem++;
+ pMem->flags = MEM_Int;
+ pMem->u.i = pOp->p3; /* P3 */
+ pMem++;
- if( p->explain==1 ){
- if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
+ if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
pMem->flags = MEM_Str|MEM_Term;
- pMem->n = 2;
- sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
- pMem->enc = SQLITE_UTF8;
+ 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 );
+ pMem->n = sqlite3Strlen30(pMem->z);
+ pMem->enc = SQLITE_UTF8;
+ }
pMem++;
-
+
+ if( p->explain==1 ){
+ if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
+ }
+ pMem->flags = MEM_Str|MEM_Term;
+ pMem->n = 2;
+ sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
+ pMem->enc = SQLITE_UTF8;
+ pMem++;
+
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
- if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
- assert( p->db->mallocFailed );
- return SQLITE_ERROR;
- }
- pMem->flags = MEM_Str|MEM_Term;
- pMem->n = displayComment(pOp, zP4, pMem->z, 500);
- pMem->enc = SQLITE_UTF8;
+ if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
+ assert( p->db->mallocFailed );
+ return SQLITE_ERROR;
+ }
+ pMem->flags = MEM_Str|MEM_Term;
+ pMem->n = displayComment(pOp, zP4, pMem->z, 500);
+ pMem->enc = SQLITE_UTF8;
#else
- pMem->flags = MEM_Null; /* Comment */
+ pMem->flags = MEM_Null; /* Comment */
#endif
- }
+ }
- p->nResColumn = 8 - 4*(p->explain-1);
- p->pResultSet = &p->aMem[1];
- p->rc = SQLITE_OK;
- rc = SQLITE_ROW;
+ p->nResColumn = 8 - 4*(p->explain-1);
+ p->pResultSet = &p->aMem[1];
+ p->rc = SQLITE_OK;
+ rc = SQLITE_ROW;
+ }
}
return rc;
}
@@ -74148,27 +75135,6 @@ static void closeAllCursors(Vdbe *p){
}
/*
-** Clean up the VM after a single run.
-*/
-static void Cleanup(Vdbe *p){
- sqlite3 *db = p->db;
-
-#ifdef SQLITE_DEBUG
- /* Execute assert() statements to ensure that the Vdbe.apCsr[] and
- ** Vdbe.aMem[] arrays have already been cleaned up. */
- int i;
- if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
- if( p->aMem ){
- for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
- }
-#endif
-
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
- p->pResultSet = 0;
-}
-
-/*
** Set the number of result columns that will be returned by this SQL
** statement. This is now set at compile time, rather than during
** execution of the vdbe program so that sqlite3_column_count() can
@@ -74276,6 +75242,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
pPager = sqlite3BtreePager(pBt);
if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
&& aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
+ && sqlite3PagerIsMemdb(pPager)==0
){
assert( i!=1 );
nTrans++;
@@ -74876,6 +75843,10 @@ static void vdbeInvokeSqllog(Vdbe *v){
** VDBE_MAGIC_INIT.
*/
SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+ int i;
+#endif
+
sqlite3 *db;
db = p->db;
@@ -74893,8 +75864,6 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
if( p->pc>=0 ){
vdbeInvokeSqllog(p);
sqlite3VdbeTransferError(p);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
if( p->runOnlyOnce ) p->expired = 1;
}else if( p->rc && p->expired ){
/* The expired flag was set on the VDBE before the first call
@@ -74902,13 +75871,21 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
** called), set the database error in this case as well.
*/
sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = 0;
}
- /* Reclaim all memory used by the VDBE
+ /* Reset register contents and reclaim error message memory.
*/
- Cleanup(p);
+#ifdef SQLITE_DEBUG
+ /* Execute assert() statements to ensure that the Vdbe.apCsr[] and
+ ** Vdbe.aMem[] arrays have already been cleaned up. */
+ if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
+ if( p->aMem ){
+ for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
+ }
+#endif
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = 0;
+ p->pResultSet = 0;
/* Save profiling information from this VDBE run.
*/
@@ -74916,7 +75893,6 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
{
FILE *out = fopen("vdbe_profile.out", "a");
if( out ){
- int i;
fprintf(out, "---- ");
for(i=0; i<p->nOp; i++){
fprintf(out, "%02x", p->aOp[i].opcode);
@@ -75042,7 +76018,7 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
sqlite3 *db;
- if( NEVER(p==0) ) return;
+ assert( p!=0 );
db = p->db;
assert( sqlite3_mutex_held(db->mutex) );
sqlite3VdbeClearObject(db, p);
@@ -75129,19 +76105,18 @@ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
*/
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
VdbeCursor *p = *pp;
- if( p->eCurType==CURTYPE_BTREE ){
- if( p->deferredMoveto ){
- int iMap;
- if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
- *pp = p->pAltCursor;
- *piCol = iMap - 1;
- return SQLITE_OK;
- }
- return handleDeferredMoveto(p);
- }
- if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
- return handleMovedCursor(p);
+ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
+ if( p->deferredMoveto ){
+ int iMap;
+ if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
+ *pp = p->pAltCursor;
+ *piCol = iMap - 1;
+ return SQLITE_OK;
}
+ return handleDeferredMoveto(p);
+ }
+ if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
+ return handleMovedCursor(p);
}
return SQLITE_OK;
}
@@ -75439,7 +76414,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
Mem *pMem /* Memory cell to write value into */
){
switch( serial_type ){
- case 10: /* Reserved for future use */
+ case 10: { /* Internal use only: NULL with virtual table
+ ** UPDATE no-change flag set */
+ pMem->flags = MEM_Null|MEM_Zero;
+ pMem->n = 0;
+ pMem->u.nZero = 0;
+ break;
+ }
case 11: /* Reserved for future use */
case 0: { /* Null */
/* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
@@ -75537,13 +76518,13 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
){
UnpackedRecord *p; /* Unpacked record to return */
int nByte; /* Number of bytes required for *p */
- nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nField+1);
+ nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
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;
- p->nField = pKeyInfo->nField + 1;
+ p->nField = pKeyInfo->nKeyField + 1;
return p;
}
@@ -75583,7 +76564,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
pMem++;
if( (++u)>=p->nField ) break;
}
- assert( u<=pKeyInfo->nField + 1 );
+ assert( u<=pKeyInfo->nKeyField + 1 );
p->nField = u;
}
@@ -75632,9 +76613,9 @@ static int vdbeRecordCompareDebug(
idx1 = getVarint32(aKey1, szHdr1);
if( szHdr1>98307 ) return SQLITE_CORRUPT;
d1 = szHdr1;
- assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField || CORRUPT_DB );
+ assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB );
assert( pKeyInfo->aSortOrder!=0 );
- assert( pKeyInfo->nField>0 );
+ assert( pKeyInfo->nKeyField>0 );
assert( idx1<=szHdr1 || CORRUPT_DB );
do{
u32 serial_type1;
@@ -75696,12 +76677,12 @@ debugCompareEnd:
/*
** 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
-** limit given by pKeyInfo->nField + pKeyInfo->nXField.
+** limit given by pKeyInfo->nAllField.
**
** If this constraint is not satisfied, it means that the high-speed
** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
** not work correctly. If this assert() ever fires, it probably means
-** that the KeyInfo.nField or KeyInfo.nXField values were computed
+** that the KeyInfo.nKeyField or KeyInfo.nAllField values were computed
** incorrectly.
*/
static void vdbeAssertFieldCountWithinLimits(
@@ -75722,7 +76703,7 @@ static void vdbeAssertFieldCountWithinLimits(
idx += getVarint32(aKey+idx, notUsed);
nField++;
}
- assert( nField <= pKeyInfo->nField+pKeyInfo->nXField );
+ assert( nField <= pKeyInfo->nAllField );
}
#else
# define vdbeAssertFieldCountWithinLimits(A,B,C)
@@ -76027,10 +77008,10 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
}
VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
- assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
+ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField
|| CORRUPT_DB );
assert( pPKey2->pKeyInfo->aSortOrder!=0 );
- assert( pPKey2->pKeyInfo->nField>0 );
+ assert( pPKey2->pKeyInfo->nKeyField>0 );
assert( idx1<=szHdr1 || CORRUPT_DB );
do{
u32 serial_type;
@@ -76363,7 +77344,7 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
** The easiest way to enforce this limit is to consider only records with
** 13 fields or less. If the first field is an integer, the maximum legal
** header size is (12*5 + 1 + 1) bytes. */
- if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
+ if( p->pKeyInfo->nAllField<=13 ){
int flags = p->aMem[0].flags;
if( p->pKeyInfo->aSortOrder[0] ){
p->r1 = 1;
@@ -76698,7 +77679,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
preupdate.iNewReg = iReg;
preupdate.keyinfo.db = db;
preupdate.keyinfo.enc = ENC(db);
- preupdate.keyinfo.nField = pTab->nCol;
+ preupdate.keyinfo.nKeyField = pTab->nCol;
preupdate.keyinfo.aSortOrder = (u8*)&fakeSortOrder;
preupdate.iKey1 = iKey1;
preupdate.iKey2 = iKey2;
@@ -76708,8 +77689,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2);
db->pPreUpdate = 0;
sqlite3DbFree(db, preupdate.aRecord);
- vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pUnpacked);
- vdbeFreeUnpacked(db, preupdate.keyinfo.nField+1, preupdate.pNewUnpacked);
+ vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked);
+ vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked);
if( preupdate.aNew ){
int i;
for(i=0; i<pCsr->nField; i++){
@@ -76992,6 +77973,11 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
return aType[pVal->flags&MEM_AffMask];
}
+/* Return true if a parameter to xUpdate represents an unchanged column */
+SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){
+ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
+}
+
/* Make a copy of an sqlite3_value object
*/
SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
@@ -77248,7 +78234,7 @@ static int doWalCallbacks(sqlite3 *db){
sqlite3BtreeEnter(pBt);
nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
- if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
+ if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
}
}
@@ -77358,7 +78344,7 @@ static int sqlite3Step(Vdbe *p){
if( rc!=SQLITE_ROW ) checkProfileCallback(db, p);
#endif
- if( rc==SQLITE_DONE ){
+ if( rc==SQLITE_DONE && db->autoCommit ){
assert( p->rc==SQLITE_OK );
p->rc = doWalCallbacks(db);
if( p->rc!=SQLITE_OK ){
@@ -77402,7 +78388,6 @@ end_of_step:
*/
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 */
int cnt = 0; /* Counter to prevent infinite loop of reprepares */
sqlite3 *db; /* The database connection */
@@ -77416,32 +78401,31 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
int savedPc = v->pc;
- rc2 = rc = sqlite3Reprepare(v);
- if( rc!=SQLITE_OK) break;
+ rc = sqlite3Reprepare(v);
+ if( rc!=SQLITE_OK ){
+ /* This case occurs after failing to recompile an sql statement.
+ ** The error message from the SQL compiler has already been loaded
+ ** into the database handle. This block copies the error message
+ ** from the database handle into the statement and sets the statement
+ ** program counter to 0 to ensure that when the statement is
+ ** finalized or reset the parser error message is available via
+ ** sqlite3_errmsg() and sqlite3_errcode().
+ */
+ const char *zErr = (const char *)sqlite3_value_text(db->pErr);
+ sqlite3DbFree(db, v->zErrMsg);
+ if( !db->mallocFailed ){
+ v->zErrMsg = sqlite3DbStrDup(db, zErr);
+ v->rc = rc = sqlite3ApiExit(db, rc);
+ } else {
+ v->zErrMsg = 0;
+ v->rc = rc = SQLITE_NOMEM_BKPT;
+ }
+ break;
+ }
sqlite3_reset(pStmt);
if( savedPc>=0 ) v->doingRerun = 1;
assert( v->expired==0 );
}
- if( rc2!=SQLITE_OK ){
- /* This case occurs after failing to recompile an sql statement.
- ** The error message from the SQL compiler has already been loaded
- ** into the database handle. This block copies the error message
- ** from the database handle into the statement and sets the statement
- ** program counter to 0 to ensure that when the statement is
- ** finalized or reset the parser error message is available via
- ** sqlite3_errmsg() and sqlite3_errcode().
- */
- const char *zErr = (const char *)sqlite3_value_text(db->pErr);
- sqlite3DbFree(db, v->zErrMsg);
- if( !db->mallocFailed ){
- v->zErrMsg = sqlite3DbStrDup(db, zErr);
- v->rc = rc2;
- } else {
- v->zErrMsg = 0;
- v->rc = rc = SQLITE_NOMEM_BKPT;
- }
- }
- rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -77472,6 +78456,25 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
}
/*
+** If this routine is invoked from within an xColumn method of a virtual
+** table, then it returns true if and only if the the call is during an
+** UPDATE operation and the value of the column will not be modified
+** by the UPDATE.
+**
+** If this routine is called from any context other than within the
+** xColumn method of a virtual table, then the return value is meaningless
+** and arbitrary.
+**
+** Virtual table implements might use this routine to optimize their
+** performance by substituting a NULL result, or some other light-weight
+** value, as a signal to the xUpdate routine that the column is unchanged.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
+ assert( p );
+ return sqlite3_value_nochange(p->pOut);
+}
+
+/*
** Return the current time for a statement. If the current time
** is requested more than once within the same run of a single prepared
** statement, the exact same time is returned for each invocation regardless
@@ -78447,7 +79450,7 @@ static UnpackedRecord *vdbeUnpackRecord(
pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo);
if( pRet ){
- memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nField+1));
+ memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1));
sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet);
}
return pRet;
@@ -78520,7 +79523,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa
*/
SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){
PreUpdate *p = db->pPreUpdate;
- return (p ? p->keyinfo.nField : 0);
+ return (p ? p->keyinfo.nKeyField : 0);
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
@@ -78773,7 +79776,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
Mem *pVar; /* Value of a host parameter */
StrAccum out; /* Accumulate the output here */
#ifndef SQLITE_OMIT_UTF16
- Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */
+ Mem utf8; /* Used to convert UTF16 into UTF8 for display */
#endif
char zBase[100]; /* Initial working space */
@@ -79242,7 +80245,7 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
return 0;
}
- if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
+ if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==0 ){
return MEM_Int;
}
return MEM_Real;
@@ -79352,7 +80355,7 @@ static void memTracePrint(Mem *p){
if( p->flags & MEM_Undefined ){
printf(" undefined");
}else if( p->flags & MEM_Null ){
- printf(" NULL");
+ printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
}else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
printf(" si:%lld", p->u.i);
}else if( p->flags & MEM_Int ){
@@ -80932,13 +81935,23 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
compare_op:
- switch( pOp->opcode ){
- 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;
+ /* At this point, res is negative, zero, or positive if reg[P1] is
+ ** less than, equal to, or greater than reg[P3], respectively. Compute
+ ** the answer to this operator in res2, depending on what the comparison
+ ** operator actually is. The next block of code depends on the fact
+ ** that the 6 comparison operators are consecutive integers in this
+ ** order: NE, EQ, GT, LE, LT, GE */
+ assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 );
+ assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 );
+ if( res<0 ){ /* ne, eq, gt, le, lt, ge */
+ static const unsigned char aLTb[] = { 1, 0, 0, 1, 1, 0 };
+ res2 = aLTb[pOp->opcode - OP_Ne];
+ }else if( res==0 ){
+ static const unsigned char aEQb[] = { 0, 1, 0, 1, 0, 1 };
+ res2 = aEQb[pOp->opcode - OP_Ne];
+ }else{
+ static const unsigned char aGTb[] = { 1, 0, 1, 0, 0, 1 };
+ res2 = aGTb[pOp->opcode - OP_Ne];
}
/* Undo any changes made by applyAffinity() to the input registers. */
@@ -80950,7 +81963,6 @@ compare_op:
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
@@ -81081,7 +82093,7 @@ case OP_Compare: {
assert( memIsValid(&aMem[p2+idx]) );
REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
- assert( i<pKeyInfo->nField );
+ assert( i<pKeyInfo->nKeyField );
pColl = pKeyInfo->aColl[i];
bRev = pKeyInfo->aSortOrder[i];
iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
@@ -81317,6 +82329,36 @@ case OP_IfNullRow: { /* jump */
break;
}
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+/* Opcode: Offset P1 P2 P3 * *
+** Synopsis: r[P3] = sqlite_offset(P1)
+**
+** Store in register r[P3] the byte offset into the database file that is the
+** start of the payload for the record at which that cursor P1 is currently
+** pointing.
+**
+** P2 is the column number for the argument to the sqlite_offset() function.
+** This opcode does not use P2 itself, but the P2 value is used by the
+** code generator. The P1, P2, and P3 operands to this opcode are the
+** as as for OP_Column.
+**
+** This opcode is only available if SQLite is compiled with the
+** -DSQLITE_ENABLE_OFFSET_SQL_FUNC option.
+*/
+case OP_Offset: { /* out3 */
+ VdbeCursor *pC; /* The VDBE cursor */
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = p->apCsr[pOp->p1];
+ pOut = &p->aMem[pOp->p3];
+ if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){
+ sqlite3VdbeMemSetNull(pOut);
+ }else{
+ sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor));
+ }
+ break;
+}
+#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */
+
/* Opcode: Column P1 P2 P3 P4 P5
** Synopsis: r[P3]=PX
**
@@ -81354,9 +82396,7 @@ case OP_Column: {
const u8 *zData; /* Part of the record being decoded */
const u8 *zHdr; /* Next unparsed byte of the header */
const u8 *zEndHdr; /* Pointer to first byte after the header */
- u32 offset; /* Offset into the data */
u64 offset64; /* 64-bit offset */
- u32 avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
@@ -81383,11 +82423,13 @@ case OP_Column: {
if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/
if( pC->nullRow ){
if( pC->eCurType==CURTYPE_PSEUDO ){
- assert( pC->uc.pseudoTableReg>0 );
- pReg = &aMem[pC->uc.pseudoTableReg];
+ /* For the special case of as pseudo-cursor, the seekResult field
+ ** identifies the register that holds the record */
+ assert( pC->seekResult>0 );
+ pReg = &aMem[pC->seekResult];
assert( pReg->flags & MEM_Blob );
assert( memIsValid(pReg) );
- pC->payloadSize = pC->szRow = avail = pReg->n;
+ pC->payloadSize = pC->szRow = pReg->n;
pC->aRow = (u8*)pReg->z;
}else{
sqlite3VdbeMemSetNull(pDest);
@@ -81399,23 +82441,19 @@ case OP_Column: {
assert( pCrsr );
assert( sqlite3BtreeCursorIsValid(pCrsr) );
pC->payloadSize = sqlite3BtreePayloadSize(pCrsr);
- pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &avail);
- assert( avail<=65536 ); /* Maximum page size is 64KiB */
- if( pC->payloadSize <= (u32)avail ){
- pC->szRow = pC->payloadSize;
- }else if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
+ assert( pC->szRow<=pC->payloadSize );
+ assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */
+ if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
- }else{
- pC->szRow = avail;
}
}
pC->cacheStatus = p->cacheCtr;
- pC->iHdrOffset = getVarint32(pC->aRow, offset);
+ pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
pC->nHdrParsed = 0;
- aOffset[0] = offset;
- if( avail<offset ){ /*OPTIMIZATION-IF-FALSE*/
+ if( pC->szRow<aOffset[0] ){ /*OPTIMIZATION-IF-FALSE*/
/* pC->aRow does not have to hold the entire row, but it does at least
** need to cover the header of the record. If pC->aRow does not contain
** the complete header, then set it to zero, forcing the header to be
@@ -81432,17 +82470,26 @@ case OP_Column: {
** 3-byte type for each of the maximum of 32768 columns plus three
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
*/
- if( offset > 98307 || offset > pC->payloadSize ){
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
+ if( aOffset[0] > 98307 || aOffset[0] > pC->payloadSize ){
+ goto op_column_corrupt;
}
- }else if( offset>0 ){ /*OPTIMIZATION-IF-TRUE*/
- /* The following goto is an optimization. It can be omitted and
- ** everything will still work. But OP_Column is measurably faster
- ** by skipping the subsequent conditional, which is always true.
+ }else{
+ /* This is an optimization. By skipping over the first few tests
+ ** (ex: pC->nHdrParsed<=p2) in the next section, we achieve a
+ ** measurable performance gain.
+ **
+ ** This branch is taken even if aOffset[0]==0. Such a record is never
+ ** generated by SQLite, and could be considered corruption, but we
+ ** accept it for historical reasons. When aOffset[0]==0, the code this
+ ** branch jumps to reads past the end of the record, but never more
+ ** than a few bytes. Even if the record occurs at the end of the page
+ ** content area, the "page header" comes after the page content and so
+ ** this overread is harmless. Similar overreads can occur for a corrupt
+ ** database file.
*/
zData = pC->aRow;
assert( pC->nHdrParsed<=p2 ); /* Conditional skipped */
+ testcase( aOffset[0]==0 );
goto op_column_read_header;
}
}
@@ -81471,6 +82518,7 @@ case OP_Column: {
offset64 = aOffset[i];
zHdr = zData + pC->iHdrOffset;
zEndHdr = zData + aOffset[0];
+ testcase( zHdr>=zEndHdr );
do{
if( (t = zHdr[0])<0x80 ){
zHdr++;
@@ -81491,9 +82539,13 @@ case OP_Column: {
if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset64!=pC->payloadSize))
|| (offset64 > pC->payloadSize)
){
- if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
+ if( aOffset[0]==0 ){
+ i = 0;
+ zHdr = zEndHdr;
+ }else{
+ if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem);
+ goto op_column_corrupt;
+ }
}
pC->nHdrParsed = i;
@@ -81587,6 +82639,15 @@ op_column_out:
UPDATE_MAX_BLOBSIZE(pDest);
REGISTER_TRACE(pOp->p3, pDest);
break;
+
+op_column_corrupt:
+ if( aOp[0].p3>0 ){
+ pOp = &aOp[aOp[0].p3-1];
+ break;
+ }else{
+ rc = SQLITE_CORRUPT_BKPT;
+ goto abort_due_to_error;
+ }
}
/* Opcode: Affinity P1 P2 * P4 *
@@ -81711,9 +82772,18 @@ case OP_MakeRecord: {
pRec = pLast;
do{
assert( memIsValid(pRec) );
- pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
+ serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
if( pRec->flags & MEM_Zero ){
- if( nData ){
+ if( serial_type==0 ){
+ /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
+ ** table methods that never invoke sqlite3_result_xxxxx() while
+ ** computing an unchanging column value in an UPDATE statement.
+ ** Give such values a special internal-use-only serial-type of 10
+ ** so that they can be passed through to xUpdate and have
+ ** a true sqlite3_value_nochange(). */
+ assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
+ serial_type = 10;
+ }else if( nData ){
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
}else{
nZero += pRec->u.nZero;
@@ -81724,6 +82794,7 @@ case OP_MakeRecord: {
testcase( serial_type==127 );
testcase( serial_type==128 );
nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
+ pRec->uTemp = serial_type;
if( pRec==pData0 ) break;
pRec--;
}while(1);
@@ -81927,7 +82998,7 @@ case OP_Savepoint: {
int isSchemaChange;
iSavepoint = db->nSavepoint - iSavepoint - 1;
if( p1==SAVEPOINT_ROLLBACK ){
- isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
+ isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0;
for(ii=0; ii<db->nDb; ii++){
rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
SQLITE_ABORT_ROLLBACK,
@@ -81946,7 +83017,7 @@ case OP_Savepoint: {
if( isSchemaChange ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
- db->flags = (db->flags | SQLITE_InternChanges);
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
}
@@ -82226,7 +83297,7 @@ case OP_SetCookie: {
if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
pDb->pSchema->schema_cookie = pOp->p3;
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
pDb->pSchema->file_format = pOp->p3;
@@ -82365,7 +83436,7 @@ case OP_OpenWrite:
assert( (pIn2->flags & MEM_Int)!=0 );
sqlite3VdbeMemIntegerify(pIn2);
p2 = (int)pIn2->u.i;
- /* The p2 value always comes from a prior OP_CreateTable opcode and
+ /* The p2 value always comes from a prior OP_CreateBtree opcode and
** that opcode will always set the p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
@@ -82375,7 +83446,7 @@ case OP_OpenWrite:
pKeyInfo = pOp->p4.pKeyInfo;
assert( pKeyInfo->enc==ENC(db) );
assert( pKeyInfo->db==db );
- nField = pKeyInfo->nField+pKeyInfo->nXField;
+ nField = pKeyInfo->nAllField;
}else if( pOp->p4type==P4_INT32 ){
nField = pOp->p4.i;
}
@@ -82586,8 +83657,13 @@ case OP_OpenPseudo: {
pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO);
if( pCx==0 ) goto no_mem;
pCx->nullRow = 1;
- pCx->uc.pseudoTableReg = pOp->p2;
+ pCx->seekResult = pOp->p2;
pCx->isTable = 1;
+ /* Give this pseudo-cursor a fake BtCursor pointer so that pCx
+ ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test
+ ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto()
+ ** which is a performance optimization */
+ pCx->uc.pCursor = sqlite3BtreeFakeValidCursor();
assert( pOp->p5==0 );
break;
}
@@ -83329,10 +84405,8 @@ case OP_InsertInt: {
int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
const char *zDb; /* database name - used by the update hook */
Table *pTab; /* Table structure - used by update and pre-update hooks */
- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
BtreePayload x; /* Payload to be inserted */
- op = 0;
pData = &aMem[pOp->p2];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( memIsValid(pData) );
@@ -83360,33 +84434,30 @@ case OP_InsertInt: {
zDb = db->aDb[pC->iDb].zDbSName;
pTab = pOp->p4.pTab;
assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
- op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
}else{
- pTab = 0; /* Not needed. Silence a compiler warning. */
+ pTab = 0;
zDb = 0; /* Not needed. Silence a compiler warning. */
}
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/* Invoke the pre-update hook, if any */
- if( db->xPreUpdateCallback
- && pOp->p4type==P4_TABLE
- && !(pOp->p5 & OPFLAG_ISUPDATE)
- ){
- sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2);
+ if( pTab ){
+ if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
+ sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2);
+ }
+ if( db->xUpdateCallback==0 || pTab->aCol==0 ){
+ /* Prevent post-update hook from running in cases when it should not */
+ pTab = 0;
+ }
}
if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
- if( pData->flags & MEM_Null ){
- x.pData = 0;
- x.nData = 0;
- }else{
- assert( pData->flags & (MEM_Blob|MEM_Str) );
- x.pData = pData->z;
- x.nData = pData->n;
- }
+ assert( pData->flags & (MEM_Blob|MEM_Str) );
+ x.pData = pData->z;
+ x.nData = pData->n;
seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
if( pData->flags & MEM_Zero ){
x.nZero = pData->u.nZero;
@@ -83402,8 +84473,12 @@ case OP_InsertInt: {
/* Invoke the update-hook if required. */
if( rc ) goto abort_due_to_error;
- if( db->xUpdateCallback && op ){
- db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey);
+ if( pTab ){
+ assert( db->xUpdateCallback!=0 );
+ assert( pTab->aCol!=0 );
+ db->xUpdateCallback(db->pUpdateArg,
+ (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
+ zDb, pTab->zName, x.nKey);
}
break;
}
@@ -83753,7 +84828,17 @@ case OP_NullRow: {
break;
}
-/* Opcode: Last P1 P2 P3 * *
+/* Opcode: SeekEnd P1 * * * *
+**
+** Position cursor P1 at the end of the btree for the purpose of
+** appending a new entry onto the btree.
+**
+** 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.
+*/
+/* Opcode: Last P1 P2 * * *
**
** The next use of the Rowid or Column or Prev instruction for P1
** will refer to the last entry in the database table or index.
@@ -83764,14 +84849,8 @@ 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_SeekEnd:
case OP_Last: { /* jump */
VdbeCursor *pC;
BtCursor *pCrsr;
@@ -83784,22 +84863,24 @@ case OP_Last: { /* jump */
pCrsr = pC->uc.pCursor;
res = 0;
assert( pCrsr!=0 );
- pC->seekResult = pOp->p3;
#ifdef SQLITE_DEBUG
- pC->seekOp = OP_Last;
+ pC->seekOp = pOp->opcode;
#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{
+ if( pOp->opcode==OP_SeekEnd ){
assert( pOp->p2==0 );
+ pC->seekResult = -1;
+ if( sqlite3BtreeCursorIsValidNN(pCrsr) ){
+ break;
+ }
+ }
+ 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;
}
break;
}
@@ -84428,50 +85509,28 @@ case OP_ResetSorter: {
break;
}
-/* Opcode: CreateTable P1 P2 * * *
-** Synopsis: r[P2]=root iDb=P1
-**
-** Allocate a new table in the main database file if P1==0 or in the
-** auxiliary database file if P1==1 or in an attached database if
-** P1>1. Write the root page number of the new table into
-** register P2
+/* Opcode: CreateBtree P1 P2 P3 * *
+** Synopsis: r[P2]=root iDb=P1 flags=P3
**
-** The difference between a table and an index is this: A table must
-** have a 4-byte integer key and can have arbitrary data. An index
-** has an arbitrary key but no data.
-**
-** See also: CreateIndex
+** Allocate a new b-tree in the main database file if P1==0 or in the
+** TEMP database file if P1==1 or in an attached database if
+** P1>1. The P3 argument must be 1 (BTREE_INTKEY) for a rowid table
+** it must be 2 (BTREE_BLOBKEY) for a index or WITHOUT ROWID table.
+** The root page number of the new b-tree is stored in register P2.
*/
-/* Opcode: CreateIndex P1 P2 * * *
-** Synopsis: r[P2]=root iDb=P1
-**
-** Allocate a new index in the main database file if P1==0 or in the
-** auxiliary database file if P1==1 or in an attached database if
-** P1>1. Write the root page number of the new table into
-** register P2.
-**
-** See documentation on OP_CreateTable for additional information.
-*/
-case OP_CreateIndex: /* out2 */
-case OP_CreateTable: { /* out2 */
+case OP_CreateBtree: { /* out2 */
int pgno;
- int flags;
Db *pDb;
pOut = out2Prerelease(p, pOp);
pgno = 0;
+ assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 );
- if( pOp->opcode==OP_CreateTable ){
- /* flags = BTREE_INTKEY; */
- flags = BTREE_INTKEY;
- }else{
- flags = BTREE_BLOBKEY;
- }
- rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
+ rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3);
if( rc ) goto abort_due_to_error;
pOut->u.i = pgno;
break;
@@ -84633,7 +85692,7 @@ case OP_IntegrityCk: {
nRoot = pOp->p2;
aRoot = pOp->p4.ai;
assert( nRoot>0 );
- assert( aRoot[nRoot]==0 );
+ assert( aRoot[0]==nRoot );
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
pnErr = &aMem[pOp->p3];
assert( (pnErr->flags & MEM_Int)!=0 );
@@ -84641,7 +85700,7 @@ case OP_IntegrityCk: {
pIn1 = &aMem[pOp->p1];
assert( pOp->p5<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p5) );
- z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
+ z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
(int)pnErr->u.i+1, &nErr);
sqlite3VdbeMemSetNull(pIn1);
if( nErr==0 ){
@@ -85628,12 +86687,18 @@ case OP_VFilter: { /* jump */
#endif /* SQLITE_OMIT_VIRTUALTABLE */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VColumn P1 P2 P3 * *
+/* Opcode: VColumn P1 P2 P3 * P5
** Synopsis: r[P3]=vcolumn(P2)
**
-** Store the value of the P2-th column of
-** the row of the virtual-table that the
-** P1 cursor is pointing to into register P3.
+** Store in register P3 the value of the P2-th column of
+** the current row of the virtual-table of cursor P1.
+**
+** If the VColumn opcode is being used to fetch the value of
+** an unchanging column during an UPDATE operation, then the P5
+** value is 1. Otherwise, P5 is 0. The P5 value is returned
+** by sqlite3_vtab_nochange() routine can can be used
+** by virtual table implementations to return special "no-change"
+** marks which can be more efficient, depending on the virtual table.
*/
case OP_VColumn: {
sqlite3_vtab *pVtab;
@@ -85655,7 +86720,13 @@ case OP_VColumn: {
assert( pModule->xColumn );
memset(&sContext, 0, sizeof(sContext));
sContext.pOut = pDest;
- MemSetTypeFlag(pDest, MEM_Null);
+ if( pOp->p5 ){
+ sqlite3VdbeMemSetNull(pDest);
+ pDest->flags = MEM_Null|MEM_Zero;
+ pDest->u.nZero = 0;
+ }else{
+ MemSetTypeFlag(pDest, MEM_Null);
+ }
rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
sqlite3VtabImportErrmsg(p, pVtab);
if( sContext.isError ){
@@ -85981,8 +87052,14 @@ case OP_Function: {
break;
}
-
-/* Opcode: Init P1 P2 * P4 *
+/* Opcode: Trace P1 P2 * P4 *
+**
+** Write P4 on the statement trace output if statement tracing is
+** enabled.
+**
+** Operand P1 must be 0x7fffffff and P2 must positive.
+*/
+/* Opcode: Init P1 P2 P3 P4 *
** Synopsis: Start at P2
**
** Programs contain a single instance of this opcode as the very first
@@ -85996,7 +87073,11 @@ case OP_Function: {
**
** Increment the value of P1 so that OP_Once opcodes will jump the
** first time they are evaluated for this run.
+**
+** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT
+** error is encountered.
*/
+case OP_Trace:
case OP_Init: { /* jump */
char *zTrace;
int i;
@@ -86011,7 +87092,9 @@ 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 */
+
+ /* OP_Init is always instruction 0 */
+ assert( pOp==p->aOp || pOp->opcode==OP_Trace );
#ifndef SQLITE_OMIT_TRACE
if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
@@ -86054,6 +87137,7 @@ case OP_Init: { /* jump */
#endif /* SQLITE_OMIT_TRACE */
assert( pOp->p2>0 );
if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){
+ if( pOp->opcode==OP_Trace ) break;
for(i=1; i<p->nOp; i++){
if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0;
}
@@ -86270,11 +87354,12 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
v->aMem[1].u.i = iRow;
/* 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
+ ** then back it up to the point where it does the OP_NotExists. 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;
+ if( v->pc>4 ){
+ v->pc = 4;
+ assert( v->aOp[v->pc].opcode==OP_NotExists );
rc = sqlite3VdbeExec(v);
}else{
rc = sqlite3_step(p->pStmt);
@@ -86336,8 +87421,8 @@ SQLITE_API int sqlite3_blob_open(
int rc = SQLITE_OK;
char *zErr = 0;
Table *pTab;
- Parse *pParse = 0;
Incrblob *pBlob = 0;
+ Parse sParse;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppBlob==0 ){
@@ -86355,37 +87440,34 @@ SQLITE_API int sqlite3_blob_open(
sqlite3_mutex_enter(db->mutex);
pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob));
- if( !pBlob ) goto blob_open_out;
- pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
- if( !pParse ) goto blob_open_out;
-
do {
- memset(pParse, 0, sizeof(Parse));
- pParse->db = db;
+ memset(&sParse, 0, sizeof(Parse));
+ if( !pBlob ) goto blob_open_out;
+ sParse.db = db;
sqlite3DbFree(db, zErr);
zErr = 0;
sqlite3BtreeEnterAll(db);
- pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
+ pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
if( pTab && IsVirtual(pTab) ){
pTab = 0;
- sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
+ sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);
}
if( pTab && !HasRowid(pTab) ){
pTab = 0;
- sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable);
+ sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable);
}
#ifndef SQLITE_OMIT_VIEW
if( pTab && pTab->pSelect ){
pTab = 0;
- sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
+ sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
}
#endif
if( !pTab ){
- if( pParse->zErrMsg ){
+ if( sParse.zErrMsg ){
sqlite3DbFree(db, zErr);
- zErr = pParse->zErrMsg;
- pParse->zErrMsg = 0;
+ zErr = sParse.zErrMsg;
+ sParse.zErrMsg = 0;
}
rc = SQLITE_ERROR;
sqlite3BtreeLeaveAll(db);
@@ -86449,7 +87531,7 @@ SQLITE_API int sqlite3_blob_open(
}
}
- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse);
+ pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse);
assert( pBlob->pStmt || db->mallocFailed );
if( pBlob->pStmt ){
@@ -86485,7 +87567,8 @@ SQLITE_API int sqlite3_blob_open(
sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag,
pTab->pSchema->schema_cookie,
pTab->pSchema->iGeneration);
- sqlite3VdbeChangeP5(v, 1);
+ sqlite3VdbeChangeP5(v, 1);
+ assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed );
aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
/* Make sure a mutex is held on the table to be accessed */
@@ -86500,7 +87583,7 @@ SQLITE_API int sqlite3_blob_open(
aOp[0].p1 = iDb;
aOp[0].p2 = pTab->tnum;
aOp[0].p3 = wrFlag;
- sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
+ sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
}
if( db->mallocFailed==0 ){
#endif
@@ -86522,10 +87605,10 @@ SQLITE_API int sqlite3_blob_open(
aOp[1].p4.i = pTab->nCol+1;
aOp[3].p2 = pTab->nCol;
- pParse->nVar = 0;
- pParse->nMem = 1;
- pParse->nTab = 1;
- sqlite3VdbeMakeReady(v, pParse);
+ sParse.nVar = 0;
+ sParse.nMem = 1;
+ sParse.nTab = 1;
+ sqlite3VdbeMakeReady(v, &sParse);
}
}
@@ -86547,8 +87630,7 @@ blob_open_out:
}
sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
- sqlite3ParserReset(pParse);
- sqlite3StackFree(db, pParse);
+ sqlite3ParserReset(&sParse);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -87542,7 +88624,7 @@ static int vdbeSorterCompareText(
}
if( res==0 ){
- if( pTask->pSorter->pKeyInfo->nField>1 ){
+ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
@@ -87611,7 +88693,7 @@ static int vdbeSorterCompareInt(
}
if( res==0 ){
- if( pTask->pSorter->pKeyInfo->nField>1 ){
+ if( pTask->pSorter->pKeyInfo->nKeyField>1 ){
res = vdbeSorterCompareTail(
pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
);
@@ -87626,7 +88708,7 @@ static int vdbeSorterCompareInt(
/*
** Initialize the temporary index cursor just opened as a sorter cursor.
**
-** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
+** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nKeyField)
** to determine the number of fields that should be compared from the
** records being sorted. However, if the value passed as argument nField
** is non-zero and the sorter is able to guarantee a stable sort, nField
@@ -87679,7 +88761,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
assert( pCsr->pKeyInfo && pCsr->pBtx==0 );
assert( pCsr->eCurType==CURTYPE_SORTER );
- szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
+ szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*);
sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
@@ -87691,8 +88773,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
pKeyInfo->db = 0;
if( nField && nWorker==0 ){
- pKeyInfo->nXField += (pKeyInfo->nField - nField);
- pKeyInfo->nField = nField;
+ pKeyInfo->nKeyField = nField;
}
pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
pSorter->nTask = nWorker + 1;
@@ -87720,11 +88801,9 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
- /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
- ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
- ** large heap allocations.
- */
- if( sqlite3GlobalConfig.pScratch==0 ){
+ /* Avoid large memory allocations if the application has requested
+ ** SQLITE_CONFIG_SMALL_MALLOC. */
+ if( sqlite3GlobalConfig.bSmallMalloc==0 ){
assert( pSorter->iMemory==0 );
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
@@ -87732,7 +88811,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
}
}
- if( (pKeyInfo->nField+pKeyInfo->nXField)<13
+ if( pKeyInfo->nAllField<13
&& (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
){
pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
@@ -88047,7 +89126,7 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
if( pTask->pUnpacked==0 ){
pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo);
if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT;
- pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
+ pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField;
pTask->pUnpacked->errCode = 0;
}
return SQLITE_OK;
@@ -89571,7 +90650,8 @@ static int memjrnlRead(
int iChunkOffset;
FileChunk *pChunk;
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
if( (iAmt+iOfst)>p->endpoint.iOffset ){
return SQLITE_IOERR_SHORT_READ;
}
@@ -89690,7 +90770,8 @@ static int memjrnlWrite(
** atomic-write optimization. In this case the first 28 bytes of the
** journal file may be written as part of committing the transaction. */
assert( iOfst==p->endpoint.iOffset || iOfst==0 );
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
if( iOfst==0 && p->pFirst ){
assert( p->nChunkSize>iAmt );
memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt);
@@ -89859,17 +90940,31 @@ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){
sqlite3JournalOpen(0, 0, pJfd, 0, -1);
}
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
+ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
/*
** If the argument p points to a MemJournal structure that is not an
** in-memory-only journal file (i.e. is one that was opened with a +ve
-** nSpill parameter), and the underlying file has not yet been created,
-** create it now.
+** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying
+** file has not yet been created, create it now.
*/
-SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *p){
+SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){
int rc = SQLITE_OK;
- if( p->pMethods==&MemJournalMethods && ((MemJournal*)p)->nSpill>0 ){
- rc = memjrnlCreateFile((MemJournal*)p);
+ MemJournal *p = (MemJournal*)pJfd;
+ if( p->pMethod==&MemJournalMethods && (
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ p->nSpill>0
+#else
+ /* While this appears to not be possible without ATOMIC_WRITE, the
+ ** paths are complex, so it seems prudent to leave the test in as
+ ** a NEVER(), in case our analysis is subtly flawed. */
+ NEVER(p->nSpill>0)
+#endif
+#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
+ || (p->flags & SQLITE_OPEN_MAIN_JOURNAL)
+#endif
+ )){
+ rc = memjrnlCreateFile(p);
}
return rc;
}
@@ -89936,18 +91031,22 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
int rc;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
- rc = pWalker->xExprCallback(pWalker, pExpr);
- if( rc ) return rc & WRC_Abort;
- if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
- if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
- assert( pExpr->x.pList==0 || pExpr->pRight==0 );
- if( pExpr->pRight ){
- if( walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
- }else 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;
+ while(1){
+ rc = pWalker->xExprCallback(pWalker, pExpr);
+ if( rc ) return rc & WRC_Abort;
+ if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
+ if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
+ assert( pExpr->x.pList==0 || pExpr->pRight==0 );
+ if( pExpr->pRight ){
+ pExpr = pExpr->pRight;
+ continue;
+ }else 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;
+ }
}
+ break;
}
return WRC_Continue;
}
@@ -89983,7 +91082,6 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){
if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort;
if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort;
- if( sqlite3WalkExpr(pWalker, p->pOffset) ) return WRC_Abort;
return WRC_Continue;
}
@@ -90000,16 +91098,15 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
struct SrcList_item *pItem;
pSrc = p->pSrc;
- if( ALWAYS(pSrc) ){
- for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
- if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
- return WRC_Abort;
- }
- if( pItem->fg.isTabFunc
- && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
- ){
- return WRC_Abort;
- }
+ assert( pSrc!=0 );
+ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
+ if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){
+ return WRC_Abort;
+ }
+ if( pItem->fg.isTabFunc
+ && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg)
+ ){
+ return WRC_Abort;
}
}
return WRC_Continue;
@@ -90652,7 +91749,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
SrcList *pSrcList = pNC->pSrcList;
struct SrcList_item *pItem;
assert( pSrcList && pSrcList->nSrc==1 );
- pItem = pSrcList->a;
+ pItem = pSrcList->a;
+ assert( HasRowid(pItem->pTab) && pItem->pTab->pSelect==0 );
pExpr->op = TK_COLUMN;
pExpr->pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor;
@@ -91015,12 +92113,10 @@ static int resolveCompoundOrderBy(
pOrderBy = pSelect->pOrderBy;
if( pOrderBy==0 ) return 0;
db = pParse->db;
-#if SQLITE_MAX_COLUMN
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
return 1;
}
-#endif
for(i=0; i<pOrderBy->nExpr; i++){
pOrderBy->a[i].done = 0;
}
@@ -91112,12 +92208,10 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
struct ExprList_item *pItem;
if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
-#if SQLITE_MAX_COLUMN
if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
return 1;
}
-#endif
pEList = pSelect->pEList;
assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */
for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
@@ -91255,8 +92349,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
*/
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
- if( sqlite3ResolveExprNames(&sNC, p->pLimit) ||
- sqlite3ResolveExprNames(&sNC, p->pOffset) ){
+ if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){
return WRC_Abort;
}
@@ -91718,6 +92811,11 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){
** Return the collation sequence for the expression pExpr. If
** there is no defined collating sequence, return NULL.
**
+** See also: sqlite3ExprNNCollSeq()
+**
+** The sqlite3ExprNNCollSeq() works the same exact that it returns the
+** default collation if pExpr has no defined collation.
+**
** The collating sequence might be determined by a COLLATE operator
** or by the presence of a column with a defined collating sequence.
** COLLATE operators take first precedence. Left operands take
@@ -91783,6 +92881,32 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
}
/*
+** Return the collation sequence for the expression pExpr. If
+** there is no defined collating sequence, return a pointer to the
+** defautl collation sequence.
+**
+** See also: sqlite3ExprCollSeq()
+**
+** The sqlite3ExprCollSeq() routine works the same except that it
+** returns NULL if there is no defined collation.
+*/
+SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){
+ CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr);
+ if( p==0 ) p = pParse->db->pDfltColl;
+ assert( p!=0 );
+ return p;
+}
+
+/*
+** Return TRUE if the two expressions have equivalent collating sequences.
+*/
+SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){
+ CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1);
+ CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2);
+ return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0;
+}
+
+/*
** pExpr is an operand of a comparison operator. aff2 is the
** type affinity of the other operand. This routine returns the
** type affinity that should be used for the comparison operator.
@@ -92221,16 +93345,15 @@ static void heightOfExprList(ExprList *p, int *pnHeight){
}
}
}
-static void heightOfSelect(Select *p, int *pnHeight){
- if( p ){
+static void heightOfSelect(Select *pSelect, int *pnHeight){
+ Select *p;
+ for(p=pSelect; p; p=p->pPrior){
heightOfExpr(p->pWhere, pnHeight);
heightOfExpr(p->pHaving, pnHeight);
heightOfExpr(p->pLimit, pnHeight);
- heightOfExpr(p->pOffset, pnHeight);
heightOfExprList(p->pEList, pnHeight);
heightOfExprList(p->pGroupBy, pnHeight);
heightOfExprList(p->pOrderBy, pnHeight);
- heightOfSelect(p->pPrior, pnHeight);
}
}
@@ -92369,7 +93492,7 @@ SQLITE_PRIVATE Expr *sqlite3Expr(
){
Token x;
x.z = zToken;
- x.n = zToken ? sqlite3Strlen30(zToken) : 0;
+ x.n = sqlite3Strlen30(zToken);
return sqlite3ExprAlloc(db, op, &x, 0);
}
@@ -92515,6 +93638,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
return 0;
}
pNew->x.pList = pList;
+ ExprSetProperty(pNew, EP_HasFunc);
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
sqlite3ExprSetHeightAndFlags(pParse, pNew);
return pNew;
@@ -92896,10 +94020,9 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
Expr *pPriorSelectCol = 0;
assert( db!=0 );
if( p==0 ) return 0;
- pNew = sqlite3DbMallocRawNN(db,
- sizeof(*pNew)+sizeof(pNew->a[0])*(p->nExpr-1) );
+ pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
if( pNew==0 ) return 0;
- pNew->nAlloc = pNew->nExpr = p->nExpr;
+ pNew->nExpr = p->nExpr;
pItem = pNew->a;
pOldItem = p->a;
for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
@@ -93025,7 +94148,6 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
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;
@@ -93053,6 +94175,13 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
** Add a new element to the end of an expression list. If pList is
** initially NULL, then create a new expression list.
**
+** The pList argument must be either NULL or a pointer to an ExprList
+** obtained from a prior call to sqlite3ExprListAppend(). This routine
+** may not be used with an ExprList obtained from sqlite3ExprListDup().
+** Reason: This routine assumes that the number of slots in pList->a[]
+** is a power of two. That is true for sqlite3ExprListAppend() returns
+** but is not necessarily true from the return value of sqlite3ExprListDup().
+**
** If a memory allocation error occurs, the entire list is freed and
** NULL is returned. If non-NULL is returned, then it is guaranteed
** that the new entry was successfully appended.
@@ -93071,16 +94200,14 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
goto no_mem;
}
pList->nExpr = 0;
- pList->nAlloc = 1;
- }else if( pList->nExpr==pList->nAlloc ){
+ }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
ExprList *pNew;
pNew = sqlite3DbRealloc(db, pList,
- sizeof(*pList)+(2*pList->nAlloc - 1)*sizeof(pList->a[0]));
+ sizeof(*pList)+(2*pList->nExpr - 1)*sizeof(pList->a[0]));
if( pNew==0 ){
goto no_mem;
}
pList = pNew;
- pList->nAlloc *= 2;
}
pItem = &pList->a[pList->nExpr++];
assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
@@ -93214,17 +94341,16 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(
SQLITE_PRIVATE void sqlite3ExprListSetSpan(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to add the span. */
- ExprSpan *pSpan /* The span to be added */
+ const char *zStart, /* Start of the span */
+ const char *zEnd /* End of the span */
){
sqlite3 *db = pParse->db;
assert( pList!=0 || db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
assert( pList->nExpr>0 );
- assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
sqlite3DbFree(db, pItem->zSpan);
- pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
+ pItem->zSpan = sqlite3DbSpanDup(db, zStart, zEnd);
}
}
@@ -93271,17 +94397,29 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
int i;
u32 m = 0;
- if( pList ){
- for(i=0; i<pList->nExpr; i++){
- Expr *pExpr = pList->a[i].pExpr;
- assert( pExpr!=0 );
- m |= pExpr->flags;
- }
+ assert( pList!=0 );
+ for(i=0; i<pList->nExpr; i++){
+ Expr *pExpr = pList->a[i].pExpr;
+ assert( pExpr!=0 );
+ m |= pExpr->flags;
}
return m;
}
/*
+** This is a SELECT-node callback for the expression walker that
+** always "fails". By "fail" in this case, we mean set
+** pWalker->eCode to zero and abort.
+**
+** This callback is used by multiple expression walkers.
+*/
+SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){
+ UNUSED_PARAMETER(NotUsed);
+ pWalker->eCode = 0;
+ return WRC_Abort;
+}
+
+/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant. The
** Walker.eCode value determines the type of "constant" we are looking
@@ -93357,21 +94495,16 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
}
/* Fall through */
default:
- testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
- testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
+ testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail will disallow */
+ testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail will disallow */
return WRC_Continue;
}
}
-static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
- UNUSED_PARAMETER(NotUsed);
- pWalker->eCode = 0;
- return WRC_Abort;
-}
static int exprIsConst(Expr *p, int initFlag, int iCur){
Walker w;
w.eCode = initFlag;
w.xExprCallback = exprNodeIsConstant;
- w.xSelectCallback = selectNodeIsConstant;
+ w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
@@ -93425,8 +94558,8 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){
for(i=0; i<pGroupBy->nExpr; i++){
Expr *p = pGroupBy->a[i].pExpr;
if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){
- CollSeq *pColl = sqlite3ExprCollSeq(pWalker->pParse, p);
- if( pColl==0 || sqlite3_stricmp("BINARY", pColl->zName)==0 ){
+ CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p);
+ if( sqlite3_stricmp("BINARY", pColl->zName)==0 ){
return WRC_Prune;
}
}
@@ -93494,7 +94627,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){
Walker w;
w.eCode = 1;
w.xExprCallback = sqlite3ExprWalkNoop;
- w.xSelectCallback = selectNodeIsConstant;
+ w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
@@ -93567,8 +94700,8 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
case TK_BLOB:
return 0;
case TK_COLUMN:
- assert( p->pTab!=0 );
return ExprHasProperty(p, EP_CanBeNull) ||
+ p->pTab==0 || /* Reference to column of index on expression */
(p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
default:
return 1;
@@ -93650,7 +94783,6 @@ static Select *isCandidateForInOpt(Expr *pX){
}
assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
if( p->pLimit ) return 0; /* Has no LIMIT clause */
- assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */
if( p->pWhere ) return 0; /* Has no WHERE clause */
pSrc = p->pSrc;
assert( pSrc!=0 );
@@ -93740,16 +94872,15 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** pX->iTable made to point to the ephemeral table instead of an
** existing table.
**
-** The inFlags parameter must contain exactly one of the bits
-** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP. If inFlags contains
-** IN_INDEX_MEMBERSHIP, then the generated table will be used for a
-** fast membership test. When the IN_INDEX_LOOP bit is set, the
-** IN index will be used to loop over all values of the RHS of the
-** IN operator.
+** The inFlags parameter must contain, at a minimum, one of the bits
+** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains
+** IN_INDEX_MEMBERSHIP, then the generated table will be used for a fast
+** membership test. When the IN_INDEX_LOOP bit is set, the IN index will
+** be used to loop over all values of the RHS of the IN operator.
**
** 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 columns are guaranteed
+** An epheremal table will be created 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.
**
@@ -94230,7 +95361,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
/* Loop through each expression in <exprlist>. */
r1 = sqlite3GetTempReg(pParse);
r2 = sqlite3GetTempReg(pParse);
- if( isRowid ) sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
+ if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
Expr *pE2 = pItem->pExpr;
int iValToIns;
@@ -94290,6 +95421,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
Select *pSel; /* SELECT statement to encode */
SelectDest dest; /* How to deal with SELECT result */
int nReg; /* Registers to allocate */
+ Expr *pLimit; /* New limit expression */
testcase( pExpr->op==TK_EXISTS );
testcase( pExpr->op==TK_SELECT );
@@ -94311,11 +95443,14 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
VdbeComment((v, "Init EXISTS result"));
}
- sqlite3ExprDelete(pParse->db, pSel->pLimit);
- pSel->pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,
- &sqlite3IntTokens[1], 0);
+ pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
+ if( pSel->pLimit ){
+ sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
+ pSel->pLimit->pLeft = pLimit;
+ }else{
+ pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
+ }
pSel->iLimit = 0;
- pSel->selFlags &= ~SF_MultiValue;
if( sqlite3Select(pParse, pSel, &dest) ){
return 0;
}
@@ -94658,7 +95793,7 @@ 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==1 || (c==2 && !negFlag) || (negFlag && value==SMALLEST_INT64)){
+ if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){
#ifdef SQLITE_OMIT_FLOATING_POINT
sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
#else
@@ -94672,7 +95807,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
}
#endif
}else{
- if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
+ if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; }
sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64);
}
}
@@ -95421,9 +96556,21 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( !pColl ) pColl = db->pDfltColl;
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
}
- sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
- constMask, r1, target, (char*)pDef, P4_FUNCDEF);
- sqlite3VdbeChangeP5(v, (u8)nFarg);
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){
+ Expr *pArg = pFarg->a[0].pExpr;
+ if( pArg->op==TK_COLUMN ){
+ sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+ }
+ }else
+#endif
+ {
+ sqlite3VdbeAddOp4(v, pParse->iSelfTab ? OP_PureFunc0 : OP_Function0,
+ constMask, r1, target, (char*)pDef, P4_FUNCDEF);
+ sqlite3VdbeChangeP5(v, (u8)nFarg);
+ }
if( nFarg && constMask==0 ){
sqlite3ReleaseTempRange(pParse, r1, nFarg);
}
@@ -95827,7 +96974,9 @@ SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targ
** Generate code that pushes the value of every element of the given
** expression list into a sequence of registers beginning at target.
**
-** Return the number of elements evaluated.
+** Return the number of elements evaluated. The number returned will
+** usually be pList->nExpr but might be reduced if SQLITE_ECEL_OMITREF
+** is defined.
**
** The SQLITE_ECEL_DUP flag prevents the arguments from being
** filled using OP_SCopy. OP_Copy must be used instead.
@@ -95838,6 +96987,8 @@ SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targ
** The SQLITE_ECEL_REF flag means that expressions in the list with
** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored
** in registers at srcReg, and so the value can be copied from there.
+** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0
+** are simply omitted rather than being copied from srcReg.
*/
SQLITE_PRIVATE int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */
@@ -97271,9 +98422,9 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
char *zWhere = 0; /* Where clause to locate temp triggers */
#endif
VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */
- int savedDbFlags; /* Saved value of db->flags */
+ u32 savedDbFlags; /* Saved value of db->mDbFlags */
- savedDbFlags = db->flags;
+ savedDbFlags = db->mDbFlags;
if( NEVER(db->mallocFailed) ) goto exit_rename_table;
assert( pSrc->nSrc==1 );
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
@@ -97282,7 +98433,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
zDb = db->aDb[iDb].zDbSName;
- db->flags |= SQLITE_PreferBuiltin;
+ db->mDbFlags |= DBFLAG_PreferBuiltin;
/* Get a NULL terminated version of the new table name. */
zName = sqlite3NameFromToken(db, pName);
@@ -97447,7 +98598,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
exit_rename_table:
sqlite3SrcListDelete(db, pSrc);
sqlite3DbFree(db, zName);
- db->flags = savedDbFlags;
+ db->mDbFlags = savedDbFlags;
}
/*
@@ -97548,11 +98699,11 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
char *zEnd = &zCol[pColDef->n-1];
- int savedDbFlags = db->flags;
+ u32 savedDbFlags = db->mDbFlags;
while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
*zEnd-- = '\0';
}
- db->flags |= SQLITE_PreferBuiltin;
+ db->mDbFlags |= DBFLAG_PreferBuiltin;
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
@@ -97561,7 +98712,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
zTab
);
sqlite3DbFree(db, zCol);
- db->flags = savedDbFlags;
+ db->mDbFlags = savedDbFlags;
}
/* Make sure the schema version is at least 3. But do not upgrade
@@ -97913,6 +99064,10 @@ static void openStatTable(
"DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zDbSName, zTab, zWhereType, zWhere
);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ }else if( db->xPreUpdateCallback ){
+ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
+#endif
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
@@ -98677,6 +99832,9 @@ static void analyzeOneTable(
int regIdxname = iMem++; /* Register containing index name */
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
int regPrev = iMem; /* MUST BE LAST (see below) */
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ Table *pStat1 = 0;
+#endif
pParse->nMem = MAX(pParse->nMem, iMem);
v = sqlite3GetVdbe(pParse);
@@ -98702,6 +99860,18 @@ static void analyzeOneTable(
}
#endif
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ if( db->xPreUpdateCallback ){
+ pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
+ if( pStat1==0 ) return;
+ pStat1->zName = (char*)&pStat1[1];
+ memcpy(pStat1->zName, "sqlite_stat1", 13);
+ pStat1->nCol = 3;
+ pStat1->iPKey = -1;
+ sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
+ }
+#endif
+
/* Establish a read-lock on the table at the shared-cache level.
** Open a read-only cursor on the table. Also allocate a cursor number
** to use for scanning indexes (iIdxCur). No index cursor is opened at
@@ -98903,6 +100073,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
+#endif
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
/* Add the entries to the stat3 or stat4 table. */
@@ -98966,6 +100139,9 @@ static void analyzeOneTable(
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
+ sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
+#endif
sqlite3VdbeJumpHere(v, jZeroRows);
}
}
@@ -99686,10 +100862,6 @@ static void attachFunc(
);
goto attach_error;
}
- if( !db->autoCommit ){
- zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
- goto attach_error;
- }
for(i=0; i<db->nDb; i++){
char *z = db->aDb[i].zDbSName;
assert( z && zName );
@@ -99881,11 +101053,6 @@ static void detachFunc(
sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
goto detach_error;
}
- if( !db->autoCommit ){
- sqlite3_snprintf(sizeof(zErr), zErr,
- "cannot DETACH database within transaction");
- goto detach_error;
- }
if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
@@ -100106,9 +101273,6 @@ SQLITE_PRIVATE int sqlite3FixSelect(
if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
return 1;
}
- if( sqlite3FixExpr(pFix, pSelect->pOffset) ){
- return 1;
- }
pSelect = pSelect->pPrior;
}
return 0;
@@ -100298,11 +101462,9 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(
#endif
);
if( rc==SQLITE_DENY ){
- if( db->nDb>2 || iDb!=0 ){
- sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
- }else{
- sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol);
- }
+ char *z = sqlite3_mprintf("%s.%s", zTab, zCol);
+ if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z);
+ sqlite3ErrorMsg(pParse, "access to %z is prohibited", z);
pParse->rc = SQLITE_AUTH;
}else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){
sqliteAuthBadReturnCode(pParse);
@@ -100935,7 +102097,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char
}
freeIndex(db, pIndex);
}
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
/*
@@ -100970,28 +102132,26 @@ SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
/*
** Reset the schema for the database at index iDb. Also reset the
-** TEMP schema.
+** TEMP schema. The reset is deferred if db->nSchemaLock is not zero.
+** Deferred resets may be run by calling with iDb<0.
*/
SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
- Db *pDb;
+ int i;
assert( iDb<db->nDb );
- /* Case 1: Reset the single schema identified by iDb */
- pDb = &db->aDb[iDb];
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- assert( pDb->pSchema!=0 );
- sqlite3SchemaClear(pDb->pSchema);
+ if( iDb>=0 ){
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ DbSetProperty(db, iDb, DB_ResetWanted);
+ DbSetProperty(db, 1, DB_ResetWanted);
+ }
- /* If any database other than TEMP is reset, then also reset TEMP
- ** since TEMP might be holding triggers that reference tables in the
- ** other database.
- */
- if( iDb!=1 ){
- pDb = &db->aDb[1];
- assert( pDb->pSchema!=0 );
- sqlite3SchemaClear(pDb->pSchema);
+ if( db->nSchemaLock==0 ){
+ for(i=0; i<db->nDb; i++){
+ if( DbHasProperty(db, i, DB_ResetWanted) ){
+ sqlite3SchemaClear(db->aDb[i].pSchema);
+ }
+ }
}
- return;
}
/*
@@ -101001,13 +102161,14 @@ SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
int i;
sqlite3BtreeEnterAll(db);
+ assert( db->nSchemaLock==0 );
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
sqlite3SchemaClear(pDb->pSchema);
}
}
- db->flags &= ~SQLITE_InternChanges;
+ db->mDbFlags &= ~DBFLAG_SchemaChange;
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
sqlite3CollapseDatabaseArray(db);
@@ -101017,7 +102178,7 @@ SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
** This routine is called when a commit occurs.
*/
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
- db->flags &= ~SQLITE_InternChanges;
+ db->mDbFlags &= ~DBFLAG_SchemaChange;
}
/*
@@ -101055,13 +102216,16 @@ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){
*/
static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
Index *pIndex, *pNext;
- TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
+#ifdef SQLITE_DEBUG
/* Record the number of outstanding lookaside allocations in schema Tables
** prior to doing any free() operations. Since schema Tables do not use
** lookaside, this number should not change. */
- TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ?
- db->lookaside.nOut : 0 );
+ int nLookaside = 0;
+ if( db && (pTable->tabFlags & TF_Ephemeral)==0 ){
+ nLookaside = sqlite3LookasideUsed(db, 0);
+ }
+#endif
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
@@ -101095,7 +102259,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
sqlite3DbFree(db, pTable);
/* Verify that no lookaside memory was used by schema tables */
- assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
+ assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) );
}
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
/* Do not delete the table until the reference count reaches zero. */
@@ -101121,7 +102285,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char
pDb = &db->aDb[iDb];
p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0);
sqlite3DeleteTable(db, p);
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
/*
@@ -101234,7 +102398,8 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
return -1;
}
}else{
- assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
+ assert( db->init.iDb==0 || db->init.busy
+ || (db->mDbFlags & DBFLAG_Vacuum)!=0);
iDb = db->init.iDb;
*pUnqual = pName1;
}
@@ -101466,7 +102631,8 @@ SQLITE_PRIVATE void sqlite3StartTable(
}else
#endif
{
- pParse->addrCrTab = sqlite3VdbeAddOp2(v, OP_CreateTable, iDb, reg2);
+ pParse->addrCrTab =
+ sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
}
sqlite3OpenMasterTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
@@ -101515,12 +102681,10 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
Column *pCol;
sqlite3 *db = pParse->db;
if( (p = pParse->pNewTable)==0 ) return;
-#if SQLITE_MAX_COLUMN
if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
return;
}
-#endif
z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
if( z==0 ) return;
memcpy(z, pName->z, pName->n);
@@ -101675,34 +102839,37 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
+SQLITE_PRIVATE void sqlite3AddDefaultValue(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The parsed expression of the default value */
+ const char *zStart, /* Start of the default value text */
+ const char *zEnd /* First character past end of defaut value text */
+){
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
p = pParse->pNewTable;
if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
+ if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
/* A copy of pExpr is used instead of the original, as pExpr contains
- ** tokens that point to volatile memory. The 'span' of the expression
- ** is required by pragma table_info.
+ ** tokens that point to volatile memory.
*/
Expr x;
sqlite3ExprDelete(db, pCol->pDflt);
memset(&x, 0, sizeof(x));
x.op = TK_SPAN;
- x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
- x.pLeft = pSpan->pExpr;
+ x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd);
+ x.pLeft = pExpr;
x.flags = EP_Skip;
pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
sqlite3DbFree(db, x.u.zToken);
}
}
- sqlite3ExprDelete(db, pSpan->pExpr);
+ sqlite3ExprDelete(db, pExpr);
}
/*
@@ -102126,9 +103293,8 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){
** Changes include:
**
** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL.
-** (2) Convert the OP_CreateTable into an OP_CreateIndex. There is
-** no rowid btree for a WITHOUT ROWID. Instead, the canonical
-** data storage is a covering index btree.
+** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY
+** into BTREE_BLOBKEY.
** (3) Bypass the creation of the sqlite_master table entry
** for the PRIMARY KEY as the primary key index is now
** identified by the sqlite_master table entry of the table itself.
@@ -102136,7 +103302,7 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){
** schema to the rootpage from the main table.
** (5) Add all table columns to the PRIMARY KEY Index object
** so that the PRIMARY KEY is a covering index. The surplus
-** columns are part of KeyInfo.nXField and are not used for
+** columns are part of KeyInfo.nAllField and are not used for
** sorting or lookup or uniqueness checks.
** (6) Replace the rowid tail on all automatically generated UNIQUE
** indices with the PRIMARY KEY columns.
@@ -102165,13 +103331,12 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
** virtual tables */
if( IN_DECLARE_VTAB ) return;
- /* Convert the OP_CreateTable opcode that would normally create the
- ** root-page for the table into an OP_CreateIndex opcode. The index
- ** created will become the PRIMARY KEY index.
+ /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
+ ** into BTREE_BLOBKEY.
*/
if( pParse->addrCrTab ){
assert( v );
- sqlite3VdbeChangeOpcode(v, pParse->addrCrTab, OP_CreateIndex);
+ sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY);
}
/* Locate the PRIMARY KEY index. Or, if this table was originally
@@ -102421,10 +103586,6 @@ SQLITE_PRIVATE void sqlite3EndTable(
pParse->nTab = 2;
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
- sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
- sqlite3Select(pParse, pSelect, &dest);
- sqlite3VdbeEndCoroutine(v, regYield);
- sqlite3VdbeJumpHere(v, addrTop - 1);
if( pParse->nErr ) return;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
if( pSelTab==0 ) return;
@@ -102434,6 +103595,11 @@ SQLITE_PRIVATE void sqlite3EndTable(
pSelTab->nCol = 0;
pSelTab->aCol = 0;
sqlite3DeleteTable(db, pSelTab);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ sqlite3Select(pParse, pSelect, &dest);
+ if( pParse->nErr ) return;
+ sqlite3VdbeEndCoroutine(v, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1);
addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
@@ -102511,7 +103677,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
return;
}
pParse->pNewTable = 0;
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
#ifndef SQLITE_OMIT_ALTERTABLE
if( !p->pSelect ){
@@ -102576,7 +103742,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
** the end.
*/
sEnd = pParse->sLastToken;
- assert( sEnd.z[0]!=0 );
+ assert( sEnd.z[0]!=0 || sEnd.n==0 );
if( sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
@@ -102610,6 +103776,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_VIRTUALTABLE
+ int rc;
+#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
sqlite3_xauth xAuth; /* Saved xAuth pointer */
#endif
@@ -102617,8 +103786,11 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
assert( pTable );
#ifndef SQLITE_OMIT_VIRTUALTABLE
- if( sqlite3VtabCallConnect(pParse, pTable) ){
- return SQLITE_ERROR;
+ db->nSchemaLock++;
+ rc = sqlite3VtabCallConnect(pParse, pTable);
+ db->nSchemaLock--;
+ if( rc ){
+ return 1;
}
if( IsVirtual(pTable) ) return 0;
#endif
@@ -102814,14 +103986,6 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
** is also added (this can happen with an auto-vacuum database).
*/
static void destroyTable(Parse *pParse, Table *pTab){
-#ifdef SQLITE_OMIT_AUTOVACUUM
- Index *pIdx;
- int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
- destroyRootPage(pParse, pTab->tnum, iDb);
- for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- destroyRootPage(pParse, pIdx->tnum, iDb);
- }
-#else
/* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM
** is not defined), then it is important to call OP_Destroy on the
** table and index root-pages in order, starting with the numerically
@@ -102864,7 +104028,6 @@ static void destroyTable(Parse *pParse, Table *pTab){
iDestroyed = iLargest;
}
}
-#endif
}
/*
@@ -103291,7 +104454,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
- sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -103780,7 +104943,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
sqlite3OomFault(db);
goto exit_create_index;
}
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
if( pTblName!=0 ){
pIndex->tnum = db->init.newTnum;
}
@@ -103816,7 +104979,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** that case the convertToWithoutRowidTable() routine will replace
** the Noop with a Goto to jump over the VDBE code generated below. */
pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
- sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
+ sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY);
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
@@ -104311,9 +105474,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
goto append_from_error;
}
p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
- if( p==0 || NEVER(p->nSrc==0) ){
+ if( p==0 ){
goto append_from_error;
}
+ assert( p->nSrc>0 );
pItem = &p->a[p->nSrc-1];
assert( pAlias!=0 );
if( pAlias->n ){
@@ -104338,8 +105502,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
*/
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
assert( pIndexedBy!=0 );
- if( p && ALWAYS(p->nSrc>0) ){
- struct SrcList_item *pItem = &p->a[p->nSrc-1];
+ if( p && pIndexedBy->n>0 ){
+ struct SrcList_item *pItem;
+ assert( p->nSrc>0 );
+ pItem = &p->a[p->nSrc-1];
assert( pItem->fg.notIndexed==0 );
assert( pItem->fg.isIndexedBy==0 );
assert( pItem->fg.isTabFunc==0 );
@@ -104349,7 +105515,7 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI
pItem->fg.notIndexed = 1;
}else{
pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
- pItem->fg.isIndexedBy = (pItem->u1.zIndexedBy!=0);
+ pItem->fg.isIndexedBy = 1;
}
}
}
@@ -104820,6 +105986,18 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
if( pParse->nErr ){
+ assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ );
+ if( pIdx->bNoQuery==0 ){
+ /* Deactivate the index because it contains an unknown collating
+ ** sequence. The only way to reactive the index is to reload the
+ ** schema. Adding the missing collating sequence later does not
+ ** reactive the index. The application had the chance to register
+ ** the missing index using the collation-needed callback. For
+ ** simplicity, SQLite will not give the application a second chance.
+ */
+ pIdx->bNoQuery = 1;
+ pParse->rc = SQLITE_ERROR_RETRY;
+ }
sqlite3KeyInfoUnref(pKey);
pKey = 0;
}
@@ -105005,6 +106183,7 @@ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
assert( !p || p->xCmp );
if( p==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
+ pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ;
}
return p;
}
@@ -105274,7 +106453,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
/* If no match is found, search the built-in functions.
**
- ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
+ ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in
** functions even if a prior app-defined function was found. And give
** priority to built-in functions.
**
@@ -105284,7 +106463,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
** new function. But the FuncDefs for built-in functions are read-only.
** So we must not search for built-ins when creating a new function.
*/
- if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
+ if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
bestScore = 0;
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
p = functionSearch(h, zName);
@@ -105357,8 +106536,8 @@ SQLITE_PRIVATE void sqlite3SchemaClear(void *p){
pSchema->pSeqTab = 0;
if( pSchema->schemaFlags & DB_SchemaLoaded ){
pSchema->iGeneration++;
- pSchema->schemaFlags &= ~DB_SchemaLoaded;
}
+ pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted);
}
/*
@@ -105478,6 +106657,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
Parse *pParse, /* Parsing context */
Table *pView, /* View definition */
Expr *pWhere, /* Optional WHERE clause to be added */
+ ExprList *pOrderBy, /* Optional ORDER BY clause */
+ Expr *pLimit, /* Optional LIMIT clause */
int iCur /* Cursor number for ephemeral table */
){
SelectDest dest;
@@ -105494,8 +106675,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}
- pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
- SF_IncludeHidden, 0, 0);
+ pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
+ SF_IncludeHidden, pLimit);
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pSel, &dest);
sqlite3SelectDelete(db, pSel);
@@ -105517,29 +106698,29 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
Expr *pWhere, /* The WHERE clause. May be null */
ExprList *pOrderBy, /* The ORDER BY clause. May be null */
Expr *pLimit, /* The LIMIT clause. May be null */
- Expr *pOffset, /* The OFFSET clause. May be null */
char *zStmtType /* Either DELETE or UPDATE. For err msgs. */
){
- Expr *pWhereRowid = NULL; /* WHERE rowid .. */
+ sqlite3 *db = pParse->db;
+ Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */
Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */
- Expr *pSelectRowid = NULL; /* SELECT rowid ... */
ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */
SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */
Select *pSelect = NULL; /* Complete SELECT tree */
+ Table *pTab;
/* Check that there isn't an ORDER BY without a LIMIT clause.
*/
- if( pOrderBy && (pLimit == 0) ) {
+ if( pOrderBy && pLimit==0 ) {
sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType);
- goto limit_where_cleanup;
+ sqlite3ExprDelete(pParse->db, pWhere);
+ sqlite3ExprListDelete(pParse->db, pOrderBy);
+ return 0;
}
/* We only need to generate a select expression if there
** is a limit/offset term to enforce.
*/
if( pLimit == 0 ) {
- /* if pLimit is null, pOffset will always be null as well. */
- assert( pOffset == 0 );
return pWhere;
}
@@ -105552,36 +106733,47 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
** );
*/
- 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;
+ pTab = pSrc->a[0].pTab;
+ if( HasRowid(pTab) ){
+ pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0);
+ pEList = sqlite3ExprListAppend(
+ pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0)
+ );
+ }else{
+ Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+ if( pPk->nKeyCol==1 ){
+ const char *zName = pTab->aCol[pPk->aiColumn[0]].zName;
+ pLhs = sqlite3Expr(db, TK_ID, zName);
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName));
+ }else{
+ int i;
+ for(i=0; i<pPk->nKeyCol; i++){
+ Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName);
+ pEList = sqlite3ExprListAppend(pParse, pEList, p);
+ }
+ pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( pLhs ){
+ pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0);
+ }
+ }
+ }
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
** and the SELECT subtree. */
+ pSrc->a[0].pTab = 0;
pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0);
- if( pSelectSrc == 0 ) {
- sqlite3ExprListDelete(pParse->db, pEList);
- goto limit_where_cleanup;
- }
+ pSrc->a[0].pTab = pTab;
+ pSrc->a[0].pIBIndex = 0;
/* generate the SELECT expression tree. */
- pSelect = sqlite3SelectNew(pParse,pEList,pSelectSrc,pWhere,0,0,
- pOrderBy,0,pLimit,pOffset);
- if( pSelect == 0 ) return 0;
+ pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0,
+ pOrderBy,0,pLimit
+ );
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0);
- pInClause = pWhereRowid ? sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0) : 0;
+ pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0);
sqlite3PExprAddSelect(pParse, pInClause, pSelect);
return pInClause;
-
-limit_where_cleanup:
- sqlite3ExprDelete(pParse->db, pWhere);
- sqlite3ExprListDelete(pParse->db, pOrderBy);
- sqlite3ExprDelete(pParse->db, pLimit);
- sqlite3ExprDelete(pParse->db, pOffset);
- return 0;
}
#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */
/* && !defined(SQLITE_OMIT_SUBQUERY) */
@@ -105596,7 +106788,9 @@ limit_where_cleanup:
SQLITE_PRIVATE void sqlite3DeleteFrom(
Parse *pParse, /* The parser context */
SrcList *pTabList, /* The table from which we should delete things */
- Expr *pWhere /* The WHERE clause. May be null */
+ Expr *pWhere, /* The WHERE clause. May be null */
+ ExprList *pOrderBy, /* ORDER BY clause. May be null */
+ Expr *pLimit /* LIMIT clause. May be null */
){
Vdbe *v; /* The virtual database engine */
Table *pTab; /* The table from which records will be deleted */
@@ -105641,6 +106835,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
assert( pTabList->nSrc==1 );
+
/* Locate the table which we want to delete. This table has to be
** put in an SrcList structure because some of the subroutines we
** will be calling are designed to work with multiple tables and expect
@@ -105655,16 +106850,26 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
#ifndef SQLITE_OMIT_TRIGGER
pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0);
isView = pTab->pSelect!=0;
- bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
#else
# define pTrigger 0
# define isView 0
#endif
+ bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0);
#ifdef SQLITE_OMIT_VIEW
# undef isView
# define isView 0
#endif
+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+ if( !isView ){
+ pWhere = sqlite3LimitWhere(
+ pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE"
+ );
+ pOrderBy = 0;
+ pLimit = 0;
+ }
+#endif
+
/* If pTab is really a view, make sure it has been initialized.
*/
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
@@ -105712,8 +106917,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iTabCur);
+ sqlite3MaterializeView(pParse, pTab,
+ pWhere, pOrderBy, pLimit, iTabCur
+ );
iDataCur = iIdxCur = iTabCur;
+ pOrderBy = 0;
+ pLimit = 0;
}
#endif
@@ -105890,7 +107099,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
}
}else if( pPk ){
addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey);
+ if( IsVirtual(pTab) ){
+ sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey);
+ }else{
+ 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);
@@ -105953,6 +107166,10 @@ delete_from_cleanup:
sqlite3AuthContextPop(&sContext);
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprDelete(db, pWhere);
+#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
+ sqlite3ExprListDelete(db, pOrderBy);
+ sqlite3ExprDelete(db, pLimit);
+#endif
sqlite3DbFree(db, aToOpen);
return;
}
@@ -106110,7 +107327,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
u8 p5 = 0;
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
- if( pParse->nested==0 ){
+ if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){
sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
}
if( eMode!=ONEPASS_OFF ){
@@ -106994,16 +108211,20 @@ static int patternCompare(
** c or cx.
*/
if( c<=0x80 ){
- u32 cx;
+ char zStop[3];
int bMatch;
if( noCase ){
- cx = sqlite3Toupper(c);
- c = sqlite3Tolower(c);
+ zStop[0] = sqlite3Toupper(c);
+ zStop[1] = sqlite3Tolower(c);
+ zStop[2] = 0;
}else{
- cx = c;
+ zStop[0] = c;
+ zStop[1] = 0;
}
- while( (c2 = *(zString++))!=0 ){
- if( c2!=c && c2!=cx ) continue;
+ while(1){
+ zString += strcspn((const char*)zString, zStop);
+ if( zString[0]==0 ) break;
+ zString++;
bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
if( bMatch!=SQLITE_NOMATCH ) return bMatch;
}
@@ -107161,7 +108382,8 @@ static void likeFunc(
#ifdef SQLITE_TEST
sqlite3_like_count++;
#endif
- sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
+ sqlite3_result_int(context,
+ patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
}
}
@@ -108002,9 +109224,14 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
/*
** pExpr points to an expression which implements a function. If
** it is appropriate to apply the LIKE optimization to that function
-** then set aWc[0] through aWc[2] to the wildcard characters and
-** return TRUE. If the function is not a LIKE-style function then
-** return FALSE.
+** then set aWc[0] through aWc[2] to the wildcard characters and the
+** escape character and then return TRUE. If the function is not a
+** LIKE-style function then return FALSE.
+**
+** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE
+** operator if c is a string literal that is exactly one byte in length.
+** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is
+** no ESCAPE clause.
**
** *pIsNocase is set to true if uppercase and lowercase are equivalent for
** the function (default for LIKE). If the function makes the distinction
@@ -108013,17 +109240,26 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
*/
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
- if( pExpr->op!=TK_FUNCTION
- || !pExpr->x.pList
- || pExpr->x.pList->nExpr!=2
- ){
+ int nExpr;
+ if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
+ nExpr = pExpr->x.pList->nExpr;
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
+ if( nExpr<3 ){
+ aWc[3] = 0;
+ }else{
+ Expr *pEscape = pExpr->x.pList->a[2].pExpr;
+ char *zEscape;
+ if( pEscape->op!=TK_STRING ) return 0;
+ zEscape = pEscape->u.zToken;
+ if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
+ aWc[3] = zEscape[0];
+ }
/* The memcpy() statement assumes that the wildcard characters are
** the first three statements in the compareInfo structure. The
@@ -108076,6 +109312,10 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
#ifdef SQLITE_DEBUG
FUNCTION2(affinity, 1, 0, 0, noopFunc, SQLITE_FUNC_AFFINITY),
#endif
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET|
+ SQLITE_FUNC_TYPEOF),
+#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
@@ -108898,7 +110138,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
}
pParse->disableTriggers = 1;
- sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0);
+ sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
pParse->disableTriggers = 0;
/* If the DELETE has generated immediate foreign key constraint
@@ -109456,7 +110696,7 @@ static Trigger *fkActionTrigger(
sqlite3ExprListAppend(pParse, 0, pRaise),
sqlite3SrcListAppend(db, 0, &tFrom, 0),
pWhere,
- 0, 0, 0, 0, 0, 0
+ 0, 0, 0, 0, 0
);
pWhere = 0;
}
@@ -109823,7 +111063,7 @@ static int autoIncBegin(
){
int memId = 0; /* Register holding maximum rowid */
if( (pTab->tabFlags & TF_Autoincrement)!=0
- && (pParse->db->flags & SQLITE_Vacuum)==0
+ && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
AutoincInfo *pInfo;
@@ -110081,7 +111321,6 @@ 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 */
int i, j; /* Loop counters */
Vdbe *v; /* Generate code into this virtual machine */
Index *pIdx; /* For looping over indices of the table */
@@ -110137,8 +111376,6 @@ SQLITE_PRIVATE void sqlite3Insert(
/* Locate the table into which we will be inserting new information.
*/
assert( pTabList->nSrc==1 );
- zTab = pTabList->a[0].zName;
- if( NEVER(zTab==0) ) goto insert_cleanup;
pTab = sqlite3SrcListLookup(pParse, pTabList);
if( pTab==0 ){
goto insert_cleanup;
@@ -110509,7 +111746,8 @@ SQLITE_PRIVATE void sqlite3Insert(
VdbeOp *pOp;
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
pOp = sqlite3VdbeGetOp(v, -1);
- if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
+ assert( pOp!=0 );
+ if( pOp->opcode==OP_Null && !IsVirtual(pTab) ){
appendFlag = 1;
pOp->opcode = OP_NewRowid;
pOp->p1 = iDataCur;
@@ -111170,6 +112408,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
/* Check to see if the new index entry will be unique */
+ sqlite3ExprCachePush(pParse);
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
regIdx, pIdx->nKeyCol); VdbeCoverage(v);
@@ -111258,6 +112497,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
}
}
sqlite3VdbeResolveLabel(v, addrUniqueOk);
+ sqlite3ExprCachePop(pParse);
if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField);
}
if( ipkTop ){
@@ -111606,7 +112846,6 @@ static int xferOptimization(
if( pSelect->pLimit ){
return 0; /* SELECT may not have a LIMIT clause */
}
- assert( pSelect->pOffset==0 ); /* Must be so if pLimit==0 */
if( pSelect->pPrior ){
return 0; /* SELECT may not be a compound query */
}
@@ -111656,7 +112895,7 @@ static int xferOptimization(
Column *pDestCol = &pDest->aCol[i];
Column *pSrcCol = &pSrc->aCol[i];
#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
- if( (db->flags & SQLITE_Vacuum)==0
+ if( (db->mDbFlags & DBFLAG_Vacuum)==0
&& (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN
){
return 0; /* Neither table may have __hidden__ columns */
@@ -111732,15 +112971,15 @@ static int xferOptimization(
regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
assert( HasRowid(pDest) || destHasUniqueIdx );
- if( (db->flags & SQLITE_Vacuum)==0 && (
+ if( (db->mDbFlags & DBFLAG_Vacuum)==0 && (
(pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
)){
/* In some circumstances, we are able to run the xfer optimization
** only if the destination table is initially empty. Unless the
- ** SQLITE_Vacuum flag is set, this block generates code to make
- ** that determination. If SQLITE_Vacuum is set, then the destination
+ ** DBFLAG_Vacuum flag is set, this block generates code to make
+ ** that determination. If DBFLAG_Vacuum is set, then the destination
** table is always empty.
**
** Conditions under which the destination must be empty:
@@ -111776,8 +113015,8 @@ static int xferOptimization(
assert( (pDest->tabFlags & TF_Autoincrement)==0 );
}
sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
- if( db->flags & SQLITE_Vacuum ){
- sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+ if( db->mDbFlags & DBFLAG_Vacuum ){
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
}else{
@@ -111808,13 +113047,13 @@ static int xferOptimization(
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
- if( db->flags & SQLITE_Vacuum ){
+ if( db->mDbFlags & DBFLAG_Vacuum ){
/* This INSERT command is part of a VACUUM operation, which guarantees
** that the destination table is empty. If all indexed columns use
** collation sequence BINARY, then it can also be assumed that the
** index will be populated by inserting keys in strictly sorted
** order. In this case, instead of seeking within the b-tree as part
- ** of every OP_IdxInsert opcode, an OP_Last is added before the
+ ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the
** OP_IdxInsert to seek to the point within the b-tree where each key
** should be inserted. This is faster.
**
@@ -111829,7 +113068,7 @@ static int xferOptimization(
}
if( i==pSrcIdx->nColumn ){
idxInsFlags = OPFLAG_USESEEKRESULT;
- sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
}
}
if( !HasRowid(pSrc) && pDestIdx->idxType==2 ){
@@ -112160,7 +113399,7 @@ struct sqlite3_api_routines {
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
const char*,const char*),void*);
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
- char * (*snprintf)(int,char*,const char*,...);
+ char * (*xsnprintf)(int,char*,const char*,...);
int (*step)(sqlite3_stmt*);
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
char const**,char const**,int*,int*,int*);
@@ -112272,7 +113511,7 @@ struct sqlite3_api_routines {
int (*uri_boolean)(const char*,const char*,int);
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
const char *(*uri_parameter)(const char*,const char*);
- char *(*vsnprintf)(int,char*,const char*,va_list);
+ char *(*xvsnprintf)(int,char*,const char*,va_list);
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
/* Version 3.8.7 and later */
int (*auto_extension)(void(*)(void));
@@ -112318,6 +113557,9 @@ struct sqlite3_api_routines {
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
+ int (*vtab_nochange)(sqlite3_context*);
+ int (*value_nochange)(sqlite3_value*);
+ const char *(*vtab_collation)(sqlite3_index_info*,int);
};
/*
@@ -112444,7 +113686,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
-#define sqlite3_snprintf sqlite3_api->snprintf
+#define sqlite3_snprintf sqlite3_api->xsnprintf
#define sqlite3_step sqlite3_api->step
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
@@ -112468,7 +113710,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
-#define sqlite3_vsnprintf sqlite3_api->vsnprintf
+#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_overload_function sqlite3_api->overload_function
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
@@ -112544,7 +113786,7 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
#define sqlite3_uri_int64 sqlite3_api->uri_int64
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
-#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf
+#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
/* Version 3.8.7 and later */
#define sqlite3_auto_extension sqlite3_api->auto_extension
@@ -112584,6 +113826,10 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
#define sqlite3_result_pointer sqlite3_api->result_pointer
#define sqlite3_value_pointer sqlite3_api->value_pointer
+/* Version 3.22.0 and later */
+#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
+#define sqlite3_value_nochange sqltie3_api->value_nochange
+#define sqlite3_vtab_collation sqltie3_api->vtab_collation
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -113018,7 +114264,11 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_prepare16_v3,
sqlite3_bind_pointer,
sqlite3_result_pointer,
- sqlite3_value_pointer
+ sqlite3_value_pointer,
+ /* Version 3.22.0 and later */
+ sqlite3_vtab_nochange,
+ sqlite3_value_nochange,
+ sqlite3_vtab_collation
};
/*
@@ -113084,8 +114334,10 @@ static int sqlite3LoadExtension(
#if SQLITE_OS_UNIX || SQLITE_OS_WIN
for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
+ int bExists = 0;
if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
- handle = sqlite3OsDlOpen(pVfs, zAltFile);
+ sqlite3OsAccess(pVfs, zAltFile, SQLITE_ACCESS_EXISTS, &bExists);
+ if( bExists ) handle = sqlite3OsDlOpen(pVfs, zAltFile);
sqlite3_free(zAltFile);
}
#endif
@@ -114339,16 +115591,16 @@ static const PragmaName *pragmaLocate(const char *zName){
/*
** 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.
+** Generate code to output a single-column result row with a value of the
+** string held in register 3. Decrement the result count in register 1
+** and halt if the maximum number of result rows have been issued.
*/
-static int integrityCheckResultRow(Vdbe *v, int regResult){
+static int integrityCheckResultRow(Vdbe *v){
int addr;
- sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 1);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1);
VdbeCoverage(v);
- sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
+ sqlite3VdbeAddOp0(v, OP_Halt);
return addr;
}
@@ -115121,6 +116373,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** type: Column declaration type.
** notnull: True if 'NOT NULL' is part of column declaration
** dflt_value: The default value for the column, if any.
+ ** pk: Non-zero for PK fields.
*/
case PragTyp_TABLE_INFO: if( zRight ){
Table *pTab;
@@ -115275,13 +116528,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
}
for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
p = (FuncDef*)sqliteHashData(j);
sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 0);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
}
break;
@@ -115293,7 +116544,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){
Module *pMod = (Module*)sqliteHashData(j);
sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}
break;
@@ -115303,7 +116553,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
int i;
for(i=0; i<ArraySize(aPragmaName); i++){
sqlite3VdbeMultiLoad(v, 1, "s", aPragmaName[i].zName);
- sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}
break;
@@ -115529,12 +116778,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Do an integrity check on each database file */
for(i=0; i<db->nDb; i++){
- HashElem *x;
- Hash *pTbls;
- int *aRoot;
- int cnt = 0;
- int mxIdx = 0;
- int nIdx;
+ HashElem *x; /* For looping over tables in the schema */
+ Hash *pTbls; /* Set of all tables in the schema */
+ int *aRoot; /* Array of root page numbers of all btrees */
+ int cnt = 0; /* Number of entries in aRoot[] */
+ int mxIdx = 0; /* Maximum number of indexes for any table */
if( OMIT_TEMPDB && i==1 ) continue;
if( iDb>=0 && i!=iDb ) continue;
@@ -115549,8 +116797,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( sqlite3SchemaMutexHeld(db, i, 0) );
pTbls = &db->aDb[i].pSchema->tblHash;
for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
- Table *pTab = sqliteHashData(x);
- Index *pIdx;
+ Table *pTab = sqliteHashData(x); /* Current table */
+ Index *pIdx; /* An index on pTab */
+ int nIdx; /* Number of indexes on pTab */
if( HasRowid(pTab) ) cnt++;
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; }
if( nIdx>mxIdx ) mxIdx = nIdx;
@@ -115560,12 +116809,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx;
- if( HasRowid(pTab) ) aRoot[cnt++] = pTab->tnum;
+ if( HasRowid(pTab) ) aRoot[++cnt] = pTab->tnum;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
- aRoot[cnt++] = pIdx->tnum;
+ aRoot[++cnt] = pIdx->tnum;
}
}
- aRoot[cnt] = 0;
+ aRoot[0] = cnt;
/* Make sure sufficient number of registers have been allocated */
pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
@@ -115578,9 +116827,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
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);
- integrityCheckResultRow(v, 2);
+ sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3);
+ integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, addr);
/* Make sure all the indices are constructed correctly.
@@ -115594,16 +116842,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
int r1 = -1;
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);
sqlite3ExprCacheClear(pParse);
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
1, 0, &iDataCur, &iIdxCur);
+ /* reg[7] counts the number of entries in the table.
+ ** reg[8+i] counts the number of entries in the i-th index
+ */
sqlite3VdbeAddOp2(v, OP_Integer, 0, 7);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
@@ -115624,7 +116869,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pTab->aCol[j].zName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
- integrityCheckResultRow(v, 3);
+ integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, jmp2);
}
/* Verify CHECK constraints */
@@ -115647,57 +116892,62 @@ SQLITE_PRIVATE void sqlite3Pragma(
zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
pTab->zName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
- integrityCheckResultRow(v, 3);
+ integrityCheckResultRow(v);
sqlite3VdbeResolveLabel(v, addrCkOk);
sqlite3ExprCachePop(pParse);
}
sqlite3ExprListDelete(db, pCheck);
}
- /* Validate index entries for the current row */
- 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;
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
- pPrior, r1);
- pPrior = pIdx;
- sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
- /* Verify that an index entry exists for the current table row */
- jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
- pIdx->nColumn); VdbeCoverage(v);
- 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);
- 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
- ** or (2) the next entry has a different key */
- if( IsUniqueIndex(pIdx) ){
- int uniqOk = sqlite3VdbeMakeLabel(v);
- int jmp6;
- int kk;
- for(kk=0; kk<pIdx->nKeyCol; kk++){
- int iCol = pIdx->aiColumn[kk];
- assert( iCol!=XN_ROWID && iCol<pTab->nCol );
- if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
- sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
- VdbeCoverage(v);
+ if( !isQuick ){ /* Omit the remaining tests for quick_check */
+ /* Sanity check on record header decoding */
+ sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nCol-1, 3);
+ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ /* Validate index entries for the current row */
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int jmp2, jmp3, jmp4, jmp5;
+ int ckUniq = sqlite3VdbeMakeLabel(v);
+ if( pPk==pIdx ) continue;
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
+ pPrior, r1);
+ pPrior = pIdx;
+ sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */
+ /* Verify that an index entry exists for the current table row */
+ jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
+ pIdx->nColumn); VdbeCoverage(v);
+ 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);
+ jmp4 = integrityCheckResultRow(v);
+ 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
+ ** or (2) the next entry has a different key */
+ if( IsUniqueIndex(pIdx) ){
+ int uniqOk = sqlite3VdbeMakeLabel(v);
+ int jmp6;
+ int kk;
+ for(kk=0; kk<pIdx->nKeyCol; kk++){
+ int iCol = pIdx->aiColumn[kk];
+ assert( iCol!=XN_ROWID && iCol<pTab->nCol );
+ if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
+ sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
+ VdbeCoverage(v);
+ }
+ jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
+ sqlite3VdbeGoto(v, uniqOk);
+ sqlite3VdbeJumpHere(v, jmp6);
+ sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
+ pIdx->nKeyCol); VdbeCoverage(v);
+ sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
+ sqlite3VdbeGoto(v, jmp5);
+ sqlite3VdbeResolveLabel(v, uniqOk);
}
- jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
- sqlite3VdbeGoto(v, uniqOk);
- sqlite3VdbeJumpHere(v, jmp6);
- sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
- pIdx->nKeyCol); VdbeCoverage(v);
- sqlite3VdbeLoadString(v, 3, "non-unique entry in index ");
- sqlite3VdbeGoto(v, jmp5);
- sqlite3VdbeResolveLabel(v, uniqOk);
+ sqlite3VdbeJumpHere(v, jmp4);
+ sqlite3ResolvePartIdxLabel(pParse, jmp3);
}
- sqlite3VdbeJumpHere(v, jmp4);
- sqlite3ResolvePartIdxLabel(pParse, jmp3);
}
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
@@ -115709,9 +116959,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
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);
+ sqlite3VdbeLoadString(v, 4, pIdx->zName);
+ sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3);
+ integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, addr);
}
}
@@ -115725,6 +116975,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_IfNotZero, 1, 4, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0}, /* 3 */
+ { OP_Halt, 0, 0, 0}, /* 4 */
+ { OP_String8, 0, 3, 0}, /* 5 */
+ { OP_Goto, 0, 3, 0}, /* 6 */
};
VdbeOp *aOp;
@@ -115733,7 +116986,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
aOp[0].p2 = 1-mxErr;
aOp[2].p4type = P4_STATIC;
aOp[2].p4.z = "ok";
+ aOp[5].p4type = P4_STATIC;
+ aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT);
}
+ sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2);
}
}
break;
@@ -116613,7 +117869,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = saved_iDb;
- assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
+ assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 );
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
assert( iDb==1 );
@@ -116678,6 +117934,8 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
assert( sqlite3_mutex_held(db->mutex) );
assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
+ db->init.busy = 1;
+
/* Construct the in-memory representation schema tables (sqlite_master or
** sqlite_temp_master) by invoking the parser directly. The appropriate
** table name will be inserted automatically by the parser so we can just
@@ -116686,7 +117944,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
azArg[0] = zMasterName = SCHEMA_TABLE(iDb);
azArg[1] = "1";
azArg[2] = "CREATE TABLE x(type text,name text,tbl_name text,"
- "rootpage integer,sql text)";
+ "rootpage int,sql text)";
azArg[3] = 0;
initData.db = db;
initData.iDb = iDb;
@@ -116702,10 +117960,10 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
*/
pDb = &db->aDb[iDb];
if( pDb->pBt==0 ){
- if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){
- DbSetProperty(db, 1, DB_SchemaLoaded);
- }
- return SQLITE_OK;
+ assert( iDb==1 );
+ DbSetProperty(db, 1, DB_SchemaLoaded);
+ rc = SQLITE_OK;
+ goto error_out;
}
/* If there is not already a read-only (or read-write) transaction opened
@@ -116864,9 +118122,13 @@ initone_error_out:
sqlite3BtreeLeave(pDb->pBt);
error_out:
- if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
- sqlite3OomFault(db);
+ if( rc ){
+ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
+ sqlite3OomFault(db);
+ }
+ sqlite3ResetOneSchema(db, iDb);
}
+ db->init.busy = 0;
return rc;
}
@@ -116882,42 +118144,29 @@ error_out:
*/
SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
int i, rc;
- int commit_internal = !(db->flags&SQLITE_InternChanges);
+ int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
assert( sqlite3_mutex_held(db->mutex) );
assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
assert( db->init.busy==0 );
- rc = SQLITE_OK;
- db->init.busy = 1;
ENC(db) = SCHEMA_ENC(db);
- for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
- if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
- rc = sqlite3InitOne(db, i, pzErrMsg);
- if( rc ){
- sqlite3ResetOneSchema(db, i);
- }
+ assert( db->nDb>0 );
+ /* Do the main schema first */
+ if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){
+ rc = sqlite3InitOne(db, 0, pzErrMsg);
+ if( rc ) return rc;
}
-
- /* Once all the other databases have been initialized, load the schema
- ** for the TEMP database. This is loaded last, as the TEMP database
- ** schema may contain references to objects in other databases.
- */
-#ifndef SQLITE_OMIT_TEMPDB
- assert( db->nDb>1 );
- if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
- rc = sqlite3InitOne(db, 1, pzErrMsg);
- if( rc ){
- sqlite3ResetOneSchema(db, 1);
+ /* All other schemas after the main schema. The "temp" schema must be last */
+ for(i=db->nDb-1; i>0; i--){
+ if( !DbHasProperty(db, i, DB_SchemaLoaded) ){
+ rc = sqlite3InitOne(db, i, pzErrMsg);
+ if( rc ) return rc;
}
}
-#endif
-
- db->init.busy = 0;
- if( rc==SQLITE_OK && commit_internal ){
+ if( commit_internal ){
sqlite3CommitInternalChanges(db);
}
-
- return rc;
+ return SQLITE_OK;
}
/*
@@ -117008,7 +118257,8 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
*/
assert( sqlite3_mutex_held(db->mutex) );
if( pSchema ){
- for(i=0; ALWAYS(i<db->nDb); i++){
+ for(i=0; 1; i++){
+ assert( i<db->nDb );
if( db->aDb[i].pSchema==pSchema ){
break;
}
@@ -117022,16 +118272,14 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
** Free all memory allocations in the pParse object
*/
SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
- if( pParse ){
- sqlite3 *db = pParse->db;
- sqlite3DbFree(db, pParse->aLabel);
- sqlite3ExprListDelete(db, pParse->pConstExpr);
- if( db ){
- assert( db->lookaside.bDisable >= pParse->disableLookaside );
- db->lookaside.bDisable -= pParse->disableLookaside;
- }
- pParse->disableLookaside = 0;
+ sqlite3 *db = pParse->db;
+ sqlite3DbFree(db, pParse->aLabel);
+ sqlite3ExprListDelete(db, pParse->pConstExpr);
+ if( db ){
+ assert( db->lookaside.bDisable >= pParse->disableLookaside );
+ db->lookaside.bDisable -= pParse->disableLookaside;
}
+ pParse->disableLookaside = 0;
}
/*
@@ -117191,8 +118439,6 @@ static int sqlite3Prepare(
end_prepare:
sqlite3ParserReset(&sParse);
- rc = sqlite3ApiExit(db, rc);
- assert( (rc&db->errMask)==rc );
return rc;
}
static int sqlite3LockAndPrepare(
@@ -117205,6 +118451,7 @@ static int sqlite3LockAndPrepare(
const char **pzTail /* OUT: End of parsed string */
){
int rc;
+ int cnt = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
@@ -117215,14 +118462,18 @@ static int sqlite3LockAndPrepare(
}
sqlite3_mutex_enter(db->mutex);
sqlite3BtreeEnterAll(db);
- rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
- if( rc==SQLITE_SCHEMA ){
- sqlite3_finalize(*ppStmt);
+ do{
+ /* Make multiple attempts to compile the SQL, until it either succeeds
+ ** or encounters a permanent error. A schema problem after one schema
+ ** reset is considered a permanent error. */
rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
- }
+ assert( rc==SQLITE_OK || *ppStmt==0 );
+ }while( rc==SQLITE_ERROR_RETRY
+ || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
sqlite3BtreeLeaveAll(db);
+ rc = sqlite3ApiExit(db, rc);
+ assert( (rc&db->errMask)==rc );
sqlite3_mutex_leave(db->mutex);
- assert( rc==SQLITE_OK || *ppStmt==0 );
return rc;
}
@@ -117509,8 +118760,7 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){
sqlite3ExprDelete(db, p->pHaving);
sqlite3ExprListDelete(db, p->pOrderBy);
sqlite3ExprDelete(db, p->pLimit);
- sqlite3ExprDelete(db, p->pOffset);
- if( p->pWith ) sqlite3WithDelete(db, p->pWith);
+ if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith);
if( bFree ) sqlite3DbFreeNN(db, p);
p = pPrior;
bFree = 1;
@@ -117542,8 +118792,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
u32 selFlags, /* Flag parameters, such as SF_Distinct */
- Expr *pLimit, /* LIMIT value. NULL means not used */
- Expr *pOffset /* OFFSET value. NULL means no offset */
+ Expr *pLimit /* LIMIT value. NULL means not used */
){
Select *pNew;
Select standin;
@@ -117553,7 +118802,8 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew = &standin;
}
if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0));
+ pEList = sqlite3ExprListAppend(pParse, 0,
+ sqlite3Expr(pParse->db,TK_ASTERISK,0));
}
pNew->pEList = pEList;
pNew->op = TK_SELECT;
@@ -117575,9 +118825,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->pPrior = 0;
pNew->pNext = 0;
pNew->pLimit = pLimit;
- pNew->pOffset = pOffset;
pNew->pWith = 0;
- assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 );
if( pParse->db->mallocFailed ) {
clearSelect(pParse->db, pNew, pNew!=&standin);
pNew = 0;
@@ -117604,7 +118852,7 @@ SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
** Delete the given Select structure and all of its substructures.
*/
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
- if( p ) clearSelect(db, p, 1);
+ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
}
/*
@@ -117845,11 +119093,10 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
pLeft = &pSrc->a[0];
pRight = &pLeft[1];
for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
- Table *pLeftTab = pLeft->pTab;
Table *pRightTab = pRight->pTab;
int isOuter;
- if( NEVER(pLeftTab==0 || pRightTab==0) ) continue;
+ if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
/* When the NATURAL keyword is present, add WHERE clause terms for
@@ -117997,11 +119244,11 @@ static void pushOntoSorter(
if( pParse->db->mallocFailed ) return;
pOp->p2 = nKey + nData;
pKI = pOp->p4.pKeyInfo;
- memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
+ memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
- testcase( pKI->nXField>2 );
+ testcase( pKI->nAllField > pKI->nKeyField+2 );
pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
- pKI->nXField-1);
+ pKI->nAllField-pKI->nKeyField-1);
addrJmp = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
@@ -118099,16 +119346,15 @@ static void codeDistinct(
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
-** If srcTab is negative, then the pEList expressions
+** If srcTab is negative, then the p->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
+** zero or more, then data is pulled from srcTab and p->pEList is used only
** to get the number of columns and the collation sequence for each column.
*/
static void selectInnerLoop(
Parse *pParse, /* The parser context */
Select *p, /* The complete select statement being coded */
- ExprList *pEList, /* List of values being extracted */
- int srcTab, /* Pull data from this table */
+ int srcTab, /* Pull data from this table if non-negative */
SortCtx *pSort, /* If not NULL, info on how to process ORDER BY */
DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
SelectDest *pDest, /* How to dispose of the results */
@@ -118132,7 +119378,7 @@ static void selectInnerLoop(
int regOrig; /* Start of memory holding full result (or 0) */
assert( v );
- assert( pEList!=0 );
+ assert( p->pEList!=0 );
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
if( pSort && pSort->pOrderBy==0 ) pSort = 0;
if( pSort==0 && !hasDistinct ){
@@ -118142,7 +119388,7 @@ static void selectInnerLoop(
/* Pull the requested columns.
*/
- nResultCol = pEList->nExpr;
+ nResultCol = p->pEList->nExpr;
if( pDest->iSdst==0 ){
if( pSort ){
@@ -118165,7 +119411,7 @@ static void selectInnerLoop(
if( srcTab>=0 ){
for(i=0; i<nResultCol; i++){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
- VdbeComment((v, "%s", pEList->a[i].zName));
+ VdbeComment((v, "%s", p->pEList->a[i].zName));
}
}else if( eDest!=SRT_Exists ){
/* If the destination is an EXISTS(...) expression, the actual
@@ -118178,24 +119424,25 @@ static void selectInnerLoop(
ecelFlags = 0;
}
if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){
- /* For each expression in pEList that is a copy of an expression in
+ /* For each expression in p->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,
+ ** This allows the p->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;
+ p->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);
+ nResultCol = sqlite3ExprCodeExprList(pParse,p->pEList,regResult,
+ 0,ecelFlags);
}
/* If the DISTINCT keyword was present on the SELECT statement
@@ -118227,7 +119474,7 @@ static void selectInnerLoop(
iJump = sqlite3VdbeCurrentAddr(v) + nResultCol;
for(i=0; i<nResultCol; i++){
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
+ CollSeq *pColl = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr);
if( i<nResultCol-1 ){
sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
VdbeCoverage(v);
@@ -118470,8 +119717,8 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){
KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra);
if( p ){
p->aSortOrder = (u8*)&p->aColl[N+X];
- p->nField = (u16)N;
- p->nXField = (u16)X;
+ p->nKeyField = (u16)N;
+ p->nAllField = (u16)(N+X);
p->enc = ENC(db);
p->db = db;
p->nRef = 1;
@@ -118545,10 +119792,7 @@ static KeyInfo *keyInfoFromExprList(
if( pInfo ){
assert( sqlite3KeyInfoIsWriteable(pInfo) );
for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
- CollSeq *pColl;
- pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
- if( !pColl ) pColl = db->pDfltColl;
- pInfo->aColl[i-iStart] = pColl;
+ pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
pInfo->aSortOrder[i-iStart] = pItem->sortOrder;
}
}
@@ -118798,23 +120042,23 @@ static void generateSortTail(
** the SQLITE_ENABLE_COLUMN_METADATA compile-time option is used.
*/
#ifdef SQLITE_ENABLE_COLUMN_METADATA
-# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,C,D,E,F)
+# define columnType(A,B,C,D,E) columnTypeImpl(A,B,C,D,E)
#else /* if !defined(SQLITE_ENABLE_COLUMN_METADATA) */
-# define columnType(A,B,C,D,E,F) columnTypeImpl(A,B,F)
+# define columnType(A,B,C,D,E) columnTypeImpl(A,B)
#endif
static const char *columnTypeImpl(
NameContext *pNC,
+#ifndef SQLITE_ENABLE_COLUMN_METADATA
+ Expr *pExpr
+#else
Expr *pExpr,
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
const char **pzOrigDb,
const char **pzOrigTab,
- const char **pzOrigCol,
+ const char **pzOrigCol
#endif
- u8 *pEstWidth
){
char const *zType = 0;
int j;
- u8 estWidth = 1;
#ifdef SQLITE_ENABLE_COLUMN_METADATA
char const *zOrigDb = 0;
char const *zOrigTab = 0;
@@ -118823,8 +120067,9 @@ static const char *columnTypeImpl(
assert( pExpr!=0 );
assert( pNC->pSrcList!=0 );
+ assert( pExpr->op!=TK_AGG_COLUMN ); /* This routine runes before aggregates
+ ** are processed */
switch( pExpr->op ){
- case TK_AGG_COLUMN:
case TK_COLUMN: {
/* The expression is a column. Locate the table the column is being
** extracted from in NameContext.pSrcList. This table may be real
@@ -118833,8 +120078,6 @@ static const char *columnTypeImpl(
Table *pTab = 0; /* Table structure column is extracted from */
Select *pS = 0; /* Select the column is extracted from */
int iCol = pExpr->iColumn; /* Index of column in pTab */
- testcase( pExpr->op==TK_AGG_COLUMN );
- testcase( pExpr->op==TK_COLUMN );
while( pNC && !pTab ){
SrcList *pTabList = pNC->pSrcList;
for(j=0;j<pTabList->nSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++);
@@ -118883,33 +120126,32 @@ static const char *columnTypeImpl(
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth);
+ zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol);
}
- }else if( pTab->pSchema ){
- /* A real table */
+ }else{
+ /* A real table or a CTE table */
assert( !pS );
- if( iCol<0 ) iCol = pTab->iPKey;
- assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
#ifdef SQLITE_ENABLE_COLUMN_METADATA
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
zType = "INTEGER";
zOrigCol = "rowid";
}else{
zOrigCol = pTab->aCol[iCol].zName;
zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
- estWidth = pTab->aCol[iCol].szEst;
}
zOrigTab = pTab->zName;
- if( pNC->pParse ){
+ if( pNC->pParse && pTab->pSchema ){
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
}
#else
+ assert( iCol==XN_ROWID || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
zType = "INTEGER";
}else{
zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
- estWidth = pTab->aCol[iCol].szEst;
}
#endif
}
@@ -118928,7 +120170,7 @@ static const char *columnTypeImpl(
sNC.pSrcList = pS->pSrc;
sNC.pNext = pNC;
sNC.pParse = pNC->pParse;
- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, &estWidth);
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
break;
}
#endif
@@ -118942,7 +120184,6 @@ static const char *columnTypeImpl(
*pzOrigCol = zOrigCol;
}
#endif
- if( pEstWidth ) *pEstWidth = estWidth;
return zType;
}
@@ -118969,7 +120210,7 @@ static void generateColumnTypes(
const char *zOrigDb = 0;
const char *zOrigTab = 0;
const char *zOrigCol = 0;
- zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol, 0);
+ zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
/* The vdbe must make its own copy of the column-type and other
** column specific strings, in case the schema is reset before this
@@ -118979,7 +120220,7 @@ static void generateColumnTypes(
sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT);
sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT);
#else
- zType = columnType(&sNC, p, 0, 0, 0, 0);
+ zType = columnType(&sNC, p, 0, 0, 0);
#endif
sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT);
}
@@ -119009,9 +120250,9 @@ static void generateColumnTypes(
** other words, the zSpan of the result expression.
**
** short=ON, full=OFF: (This is the default setting). If the result
-** refers directly to a table column, then the result
-** column name is just the table column name: COLUMN.
-** Otherwise use zSpan.
+** refers directly to a table column, then the
+** result column name is just the table column
+** name: COLUMN. Otherwise use zSpan.
**
** full=ON, short=ANY: If the result refers directly to a table column,
** then the result column name with the table name
@@ -119040,6 +120281,7 @@ static void generateColumnNames(
if( pParse->colNamesSet || db->mallocFailed ) return;
/* Column names are determined by the left-most term of a compound select */
while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+ SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
pTabList = pSelect->pSrc;
pEList = pSelect->pEList;
assert( v!=0 );
@@ -119052,6 +120294,8 @@ static void generateColumnNames(
Expr *p = pEList->a[i].pExpr;
assert( p!=0 );
+ assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
+ assert( p->op!=TK_COLUMN || p->pTab!=0 ); /* Covering idx not yet coded */
if( pEList->a[i].zName ){
/* An AS clause always takes first priority */
char *zName = pEList->a[i].zName;
@@ -119126,6 +120370,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
nCol = pEList->nExpr;
aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
testcase( aCol==0 );
+ if( nCol>32767 ) nCol = 32767;
}else{
nCol = 0;
aCol = 0;
@@ -119145,10 +120390,12 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
pColExpr = pColExpr->pRight;
assert( pColExpr!=0 );
}
- if( pColExpr->op==TK_COLUMN && pColExpr->pTab!=0 ){
+ assert( pColExpr->op!=TK_AGG_COLUMN );
+ if( pColExpr->op==TK_COLUMN ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
Table *pTab = pColExpr->pTab;
+ assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid";
}else if( pColExpr->op==TK_ID ){
@@ -119220,7 +120467,6 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
int i;
Expr *p;
struct ExprList_item *a;
- u64 szAll = 0;
assert( pSelect!=0 );
assert( (pSelect->selFlags & SF_Resolved)!=0 );
@@ -119233,10 +120479,11 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
const char *zType;
int n, m;
p = a[i].pExpr;
- zType = columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
- szAll += pCol->szEst;
+ zType = columnType(&sNC, p, 0, 0, 0);
+ /* pCol->szEst = ... // Column size est for SELECT tables never used */
pCol->affinity = sqlite3ExprAffinity(p);
- if( zType && (m = sqlite3Strlen30(zType))>0 ){
+ if( zType ){
+ m = sqlite3Strlen30(zType);
n = sqlite3Strlen30(pCol->zName);
pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2);
if( pCol->zName ){
@@ -119250,7 +120497,7 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
}
}
- pTab->szTabRow = sqlite3LogEst(szAll*4);
+ pTab->szTabRow = 1; /* Any non-zero value works */
}
/*
@@ -119293,25 +120540,22 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
** Get a VDBE for the given parser context. Create a new one if necessary.
** If an error occurs, return NULL and leave a message in pParse.
*/
-static SQLITE_NOINLINE Vdbe *allocVdbe(Parse *pParse){
- Vdbe *v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
- if( v ) sqlite3VdbeAddOp2(v, OP_Init, 0, 1);
+SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
+ if( pParse->pVdbe ){
+ return pParse->pVdbe;
+ }
if( pParse->pToplevel==0
&& OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
){
pParse->okConstFactor = 1;
}
- return v;
-}
-SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
- Vdbe *v = pParse->pVdbe;
- return v ? v : allocVdbe(pParse);
+ return sqlite3VdbeCreate(pParse);
}
/*
** Compute the iLimit and iOffset fields of the SELECT based on the
-** pLimit and pOffset expressions. pLimit and pOffset hold the expressions
+** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions
** that appear in the original SQL statement after the LIMIT and OFFSET
** keywords. Or NULL if those keywords are omitted. iLimit and iOffset
** are the integer memory register numbers for counters used to compute
@@ -119319,15 +120563,15 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
** iLimit and iOffset are negative.
**
** This routine changes the values of iLimit and iOffset only if
-** a limit or offset is defined by pLimit and pOffset. iLimit and
-** iOffset should have been preset to appropriate default values (zero)
+** a limit or offset is defined by pLimit->pLeft and pLimit->pRight. iLimit
+** and iOffset should have been preset to appropriate default values (zero)
** prior to calling this routine.
**
** The iOffset register (if it exists) is initialized to the value
** of the OFFSET. The iLimit register is initialized to LIMIT. Register
** iOffset+1 is initialized to LIMIT+OFFSET.
**
-** Only if pLimit!=0 or pOffset!=0 do the limit registers get
+** Only if pLimit->pLeft!=0 do the limit registers get
** redefined. The UNION ALL operator uses this property to force
** the reuse of the same limit and offset registers across multiple
** SELECT statements.
@@ -119337,6 +120581,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
int iLimit = 0;
int iOffset;
int n;
+ Expr *pLimit = p->pLimit;
+
if( p->iLimit ) return;
/*
@@ -119346,12 +120592,13 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
** no rows.
*/
sqlite3ExprCacheClear(pParse);
- assert( p->pOffset==0 || p->pLimit!=0 );
- if( p->pLimit ){
+ if( pLimit ){
+ assert( pLimit->op==TK_LIMIT );
+ assert( pLimit->pLeft!=0 );
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
- if( sqlite3ExprIsInteger(p->pLimit, &n) ){
+ if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
@@ -119361,15 +120608,15 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
p->selFlags |= SF_FixedLimit;
}
}else{
- sqlite3ExprCode(pParse, p->pLimit, iLimit);
+ sqlite3ExprCode(pParse, pLimit->pLeft, iLimit);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
VdbeComment((v, "LIMIT counter"));
sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
}
- if( p->pOffset ){
+ if( pLimit->pRight ){
p->iOffset = iOffset = ++pParse->nMem;
pParse->nMem++; /* Allocate an extra register for limit+offset */
- sqlite3ExprCode(pParse, p->pOffset, iOffset);
+ sqlite3ExprCode(pParse, pLimit->pRight, iOffset);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
VdbeComment((v, "OFFSET counter"));
sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
@@ -119499,7 +120746,7 @@ static void generateWithRecursiveQuery(
int i; /* Loop counter */
int rc; /* Result code */
ExprList *pOrderBy; /* The ORDER BY clause */
- Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */
+ Expr *pLimit; /* Saved LIMIT and OFFSET */
int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
/* Obtain authorization to do a recursive query */
@@ -119510,10 +120757,9 @@ static void generateWithRecursiveQuery(
p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, addrBreak);
pLimit = p->pLimit;
- pOffset = p->pOffset;
regLimit = p->iLimit;
regOffset = p->iOffset;
- p->pLimit = p->pOffset = 0;
+ p->pLimit = 0;
p->iLimit = p->iOffset = 0;
pOrderBy = p->pOrderBy;
@@ -119578,7 +120824,7 @@ static void generateWithRecursiveQuery(
/* Output the single row in Current */
addrCont = sqlite3VdbeMakeLabel(v);
codeOffset(v, regOffset, addrCont);
- selectInnerLoop(pParse, p, p->pEList, iCurrent,
+ selectInnerLoop(pParse, p, iCurrent,
0, 0, pDest, addrCont, addrBreak);
if( regLimit ){
sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
@@ -119606,7 +120852,6 @@ end_of_recursive_query:
sqlite3ExprListDelete(pParse->db, p->pOrderBy);
p->pOrderBy = pOrderBy;
p->pLimit = pLimit;
- p->pOffset = pOffset;
return;
}
#endif /* SQLITE_OMIT_CTE */
@@ -119625,9 +120870,14 @@ static int multiSelectOrderBy(
** on a VALUES clause.
**
** Because the Select object originates from a VALUES clause:
-** (1) It has no LIMIT or OFFSET
+** (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
** (2) All terms are UNION ALL
** (3) There is no ORDER BY clause
+**
+** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
+** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
+** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
+** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
*/
static int multiSelectValues(
Parse *pParse, /* Parsing context */
@@ -119635,14 +120885,13 @@ static int multiSelectValues(
SelectDest *pDest /* What to do with query results */
){
Select *pPrior;
+ Select *pRightmost = p;
int nRow = 1;
int rc = 0;
assert( p->selFlags & SF_MultiValue );
do{
assert( p->selFlags & SF_Values );
assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
- assert( p->pLimit==0 );
- assert( p->pOffset==0 );
assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
if( p->pPrior==0 ) break;
assert( p->pPrior->pNext==p );
@@ -119654,7 +120903,7 @@ static int multiSelectValues(
p->pPrior = 0;
rc = sqlite3Select(pParse, p, pDest);
p->pPrior = pPrior;
- if( rc ) break;
+ if( rc || pRightmost->pLimit ) break;
p->nSelectRow = nRow;
p = p->pNext;
}
@@ -119716,15 +120965,9 @@ static int multiSelect(
db = pParse->db;
pPrior = p->pPrior;
dest = *pDest;
- if( pPrior->pOrderBy ){
- sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
- selectOpName(p->op));
- rc = 1;
- goto multi_select_end;
- }
- if( pPrior->pLimit ){
- sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before",
- selectOpName(p->op));
+ if( pPrior->pOrderBy || pPrior->pLimit ){
+ sqlite3ErrorMsg(pParse,"%s clause should come after %s not before",
+ pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op));
rc = 1;
goto multi_select_end;
}
@@ -119775,11 +121018,9 @@ static int multiSelect(
pPrior->iLimit = p->iLimit;
pPrior->iOffset = p->iOffset;
pPrior->pLimit = p->pLimit;
- pPrior->pOffset = p->pOffset;
explainSetInteger(iSub1, pParse->iNextSelectId);
rc = sqlite3Select(pParse, pPrior, &dest);
p->pLimit = 0;
- p->pOffset = 0;
if( rc ){
goto multi_select_end;
}
@@ -119801,7 +121042,7 @@ static int multiSelect(
p->pPrior = pPrior;
p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
if( pPrior->pLimit
- && sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
+ && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit)
&& nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
){
p->nSelectRow = sqlite3LogEst((u64)nLimit);
@@ -119816,7 +121057,7 @@ static int multiSelect(
int unionTab; /* Cursor number of the temporary table holding result */
u8 op = 0; /* One of the SRT_ operations to apply to self */
int priorOp; /* The SRT_ operation to apply to prior selects */
- Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */
+ Expr *pLimit; /* Saved values of p->nLimit */
int addr;
SelectDest uniondest;
@@ -119828,7 +121069,6 @@ static int multiSelect(
** right.
*/
assert( p->pLimit==0 ); /* Not allowed on leftward elements */
- assert( p->pOffset==0 ); /* Not allowed on leftward elements */
unionTab = dest.iSDParm;
}else{
/* We will need to create our own temporary table to hold the
@@ -119864,8 +121104,6 @@ static int multiSelect(
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
uniondest.eDest = op;
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite3Select(pParse, p, &uniondest);
@@ -119881,7 +121119,6 @@ static int multiSelect(
}
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
- p->pOffset = pOffset;
p->iLimit = 0;
p->iOffset = 0;
@@ -119897,7 +121134,7 @@ static int multiSelect(
computeLimitRegisters(pParse, p, iBreak);
sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
iStart = sqlite3VdbeCurrentAddr(v);
- selectInnerLoop(pParse, p, p->pEList, unionTab,
+ selectInnerLoop(pParse, p, unionTab,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
@@ -119909,7 +121146,7 @@ static int multiSelect(
default: assert( p->op==TK_INTERSECT ); {
int tab1, tab2;
int iCont, iBreak, iStart;
- Expr *pLimit, *pOffset;
+ Expr *pLimit;
int addr;
SelectDest intersectdest;
int r1;
@@ -119945,8 +121182,6 @@ static int multiSelect(
p->pPrior = 0;
pLimit = p->pLimit;
p->pLimit = 0;
- pOffset = p->pOffset;
- p->pOffset = 0;
intersectdest.iSDParm = tab2;
explainSetInteger(iSub2, pParse->iNextSelectId);
rc = sqlite3Select(pParse, p, &intersectdest);
@@ -119956,7 +121191,6 @@ static int multiSelect(
if( p->nSelectRow>pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
- p->pOffset = pOffset;
/* Generate code to take the intersection of the two temporary
** tables.
@@ -119970,7 +121204,7 @@ static int multiSelect(
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,
+ selectInnerLoop(pParse, p, tab1,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
@@ -120435,8 +121669,6 @@ static int multiSelectOrderBy(
}
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = 0;
- sqlite3ExprDelete(db, p->pOffset);
- p->pOffset = 0;
regAddrA = ++pParse->nMem;
regAddrB = ++pParse->nMem;
@@ -120622,7 +121854,9 @@ static Expr *substExpr(
Expr *pExpr /* Expr in which substitution occurs */
){
if( pExpr==0 ) return 0;
- if( ExprHasProperty(pExpr, EP_FromJoin) && pExpr->iRightJoinTable==pSubst->iTable ){
+ if( ExprHasProperty(pExpr, EP_FromJoin)
+ && pExpr->iRightJoinTable==pSubst->iTable
+ ){
pExpr->iRightJoinTable = pSubst->iNewTable;
}
if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable ){
@@ -120735,68 +121969,74 @@ static void substSelect(
** exist on the table t1, a complete scan of the data might be
** avoided.
**
-** Flattening is only attempted if all of the following are true:
+** Flattening is subject to the following constraints:
**
-** (1) The subquery and the outer query do not both use aggregates.
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** The subquery and the outer query cannot both be aggregates.
**
-** (2) The subquery is not an aggregate or (2a) the outer query is not a join
-** and (2b) the outer query does not use subqueries other than the one
-** FROM-clause subquery that is a candidate for flattening. (2b is
-** due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** (2) If the subquery is an aggregate then
+** (2a) the outer query must not be a join and
+** (2b) the outer query must not use subqueries
+** other than the one FROM-clause subquery that is a candidate
+** for flattening. (This is due to ticket [2f7170d73bf9abf80]
+** from 2015-02-09.)
**
-** (3) The subquery is not the right operand of a LEFT JOIN
-** or (a) the subquery is not itself a join and (b) the FROM clause
-** of the subquery does not contain a virtual table and (c) the
-** outer query is not an aggregate.
+** (3) If the subquery is the right operand of a LEFT JOIN then
+** (3a) the subquery may not be a join and
+** (3b) the FROM clause of the subquery may not contain a virtual
+** table and
+** (3c) the outer query may not be an aggregate.
**
-** (4) The subquery is not DISTINCT.
+** (4) The subquery can not be DISTINCT.
**
** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT
** sub-queries that were excluded from this optimization. Restriction
** (4) has since been expanded to exclude all DISTINCT subqueries.
**
-** (6) The subquery does not use aggregates or the outer query is not
-** DISTINCT.
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** If the subquery is aggregate, the outer query may not be DISTINCT.
**
-** (7) The subquery has a FROM clause. TODO: For subqueries without
+** (7) The subquery must have a FROM clause. TODO: For subqueries without
** A FROM clause, consider adding a FROM clause with the special
** table sqlite_once that consists of a single row containing a
** single NULL.
**
-** (8) The subquery does not use LIMIT or the outer query is not a join.
+** (8) If the subquery uses LIMIT then the outer query may not be a join.
**
-** (9) The subquery does not use LIMIT or the outer query does not use
-** aggregates.
+** (9) If the subquery uses LIMIT then the outer query may not be aggregate.
**
** (**) Restriction (10) was removed from the code on 2005-02-05 but we
** accidently carried the comment forward until 2014-09-15. Original
-** text: "The subquery does not use aggregates or the outer query
-** does not use LIMIT."
+** constraint: "If the subquery is aggregate then the outer query
+** may not use LIMIT."
**
-** (11) The subquery and the outer query do not both have ORDER BY clauses.
+** (11) The subquery and the outer query may not both have ORDER BY clauses.
**
** (**) Not implemented. Subsumed into restriction (3). Was previously
** a separate restriction deriving from ticket #350.
**
-** (13) The subquery and outer query do not both use LIMIT.
+** (13) The subquery and outer query may not both use LIMIT.
**
-** (14) The subquery does not use OFFSET.
+** (14) The subquery may not use OFFSET.
**
-** (15) The outer query is not part of a compound select or the
-** subquery does not have a LIMIT clause.
+** (15) If the outer query is part of a compound select, then the
+** subquery may not use LIMIT.
** (See ticket #2339 and ticket [02a8e81d44]).
**
-** (16) The outer query is not an aggregate or the subquery does
-** not contain ORDER BY. (Ticket #2942) This used to not matter
+** (16) If the outer query is aggregate, then the subquery may not
+** use ORDER BY. (Ticket #2942) This used to not matter
** until we introduced the group_concat() function.
**
-** (17) The sub-query is not a compound select, or it is a UNION ALL
-** compound clause made up entirely of non-aggregate queries, and
-** the parent query:
-**
-** * is not itself part of a compound select,
-** * is not an aggregate or DISTINCT query, and
-** * is not a join
+** (17) If the subquery is a compound select, then
+** (17a) all compound operators must be a UNION ALL, and
+** (17b) no terms within the subquery compound may be aggregate
+** or DISTINCT, and
+** (17c) every term within the subquery compound must have a FROM clause
+** (17d) the outer query may not be
+** (17d1) aggregate, or
+** (17d2) DISTINCT, or
+** (17d3) a join.
**
** The parent and sub-query may contain WHERE clauses. Subject to
** rules (11), (13) and (14), they may also contain ORDER BY,
@@ -120812,10 +122052,10 @@ static void substSelect(
** syntax error and return a detailed message.
**
** (18) If the sub-query is a compound select, then all terms of the
-** ORDER by clause of the parent must be simple references to
+** ORDER BY clause of the parent must be simple references to
** columns of the sub-query.
**
-** (19) The subquery does not use LIMIT or the outer query does not
+** (19) If the subquery uses LIMIT then the outer query may not
** have a WHERE clause.
**
** (20) If the sub-query is a compound select, then it must not use
@@ -120824,17 +122064,19 @@ static void substSelect(
** appear as unmodified result columns in the outer query. But we
** have other optimizations in mind to deal with that case.
**
-** (21) The subquery does not use LIMIT or the outer query is not
+** (21) If the subquery uses LIMIT then the outer query may not be
** DISTINCT. (See ticket [752e1646fc]).
**
-** (22) The subquery is not a recursive CTE.
+** (22) The subquery may not be a recursive CTE.
**
-** (23) The parent is not a recursive CTE, or the sub-query is not a
-** compound query. This restriction is because transforming the
+** (**) Subsumed into restriction (17d3). Was: If the outer query is
+** a recursive CTE, then the sub-query may not be a compound query.
+** This restriction is because transforming the
** parent to a compound query confuses the code that handles
** recursive queries in multiSelect().
**
-** (24) The subquery is not an aggregate that uses the built-in min() or
+** (**) We no longer attempt to flatten aggregate subqueries. Was:
+** The subquery may not be an aggregate that uses the built-in min() or
** or max() functions. (Without this restriction, a query like:
** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
** return the value X for which Y was maximal.)
@@ -120842,7 +122084,7 @@ static void substSelect(
**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
-** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
+** uses aggregates.
**
** If flattening is not attempted, this routine is a no-op and returns 0.
** If flattening is attempted this routine returns 1.
@@ -120854,8 +122096,7 @@ static int flattenSubquery(
Parse *pParse, /* Parsing context */
Select *p, /* The parent or outer SELECT statement */
int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
- int isAgg, /* True if outer SELECT uses aggregate functions */
- int subqueryIsAgg /* True if the subquery uses aggregate functions */
+ int isAgg /* True if outer SELECT uses aggregate functions */
){
const char *zSavedAuthContext = pParse->zAuthContext;
Select *pParent; /* Current UNION ALL term of the other query */
@@ -120874,7 +122115,7 @@ static int flattenSubquery(
/* Check to see if flattening is permitted. Return 0 if not.
*/
assert( p!=0 );
- assert( p->pPrior==0 ); /* Unable to flatten compound queries */
+ assert( p->pPrior==0 );
if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
pSrc = p->pSrc;
assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
@@ -120882,16 +122123,6 @@ static int flattenSubquery(
iParent = pSubitem->iCursor;
pSub = pSubitem->pSelect;
assert( pSub!=0 );
- if( subqueryIsAgg ){
- if( isAgg ) return 0; /* Restriction (1) */
- if( pSrc->nSrc>1 ) return 0; /* Restriction (2a) */
- if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
- || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
- || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
- ){
- return 0; /* Restriction (2b) */
- }
- }
pSubSrc = pSub->pSrc;
assert( pSubSrc );
@@ -120901,18 +122132,15 @@ static int flattenSubquery(
** became arbitrary expressions, we were forced to add restrictions (13)
** and (14). */
if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
- if( pSub->pOffset ) return 0; /* Restriction (14) */
+ if( pSub->pLimit && pSub->pLimit->pRight ) return 0; /* Restriction (14) */
if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
return 0; /* Restriction (15) */
}
if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
- if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (5) */
+ if( pSub->selFlags & SF_Distinct ) return 0; /* Restriction (4) */
if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
return 0; /* Restrictions (8)(9) */
}
- if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
- return 0; /* Restriction (6) */
- }
if( p->pOrderBy && pSub->pOrderBy ){
return 0; /* Restriction (11) */
}
@@ -120921,18 +122149,14 @@ static int flattenSubquery(
if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
return 0; /* Restriction (21) */
}
- testcase( pSub->selFlags & SF_Recursive );
- testcase( pSub->selFlags & SF_MinMaxAgg );
- if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){
- return 0; /* Restrictions (22) and (24) */
- }
- if( (p->selFlags & SF_Recursive) && pSub->pPrior ){
- return 0; /* Restriction (23) */
+ if( pSub->selFlags & (SF_Recursive) ){
+ return 0; /* Restrictions (22) */
}
/*
** If the subquery is the right operand of a LEFT JOIN, then the
- ** subquery may not be a join itself. Example of why this is not allowed:
+ ** subquery may not be a join itself (3a). Example of why this is not
+ ** allowed:
**
** t1 LEFT OUTER JOIN (t2 JOIN t3)
**
@@ -120943,54 +122167,56 @@ static int flattenSubquery(
** which is not at all the same thing.
**
** If the subquery is the right operand of a LEFT JOIN, then the outer
- ** query cannot be an aggregate. This is an artifact of the way aggregates
- ** are processed - there is no mechanism to determine if the LEFT JOIN
- ** table should be all-NULL.
+ ** query cannot be an aggregate. (3c) This is an artifact of the way
+ ** aggregates are processed - there is no mechanism to determine if
+ ** the LEFT JOIN table should be all-NULL.
**
** See also tickets #306, #350, and #3300.
*/
if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
isLeftJoin = 1;
if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
- return 0; /* Restriction (3) */
+ /* (3a) (3c) (3b) */
+ return 0;
}
}
#ifdef SQLITE_EXTRA_IFNULLROW
else if( iFrom>0 && !isAgg ){
/* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
- ** every reference to any result column from subquery in a join, even though
- ** they are not necessary. This will stress-test the OP_IfNullRow opcode. */
+ ** every reference to any result column from subquery in a join, even
+ ** though they are not necessary. This will stress-test the OP_IfNullRow
+ ** opcode. */
isLeftJoin = -1;
}
#endif
- /* Restriction 17: If the sub-query is a compound SELECT, then it must
+ /* Restriction (17): If the sub-query is a compound SELECT, then it must
** use only the UNION ALL operator. And none of the simple select queries
** that make up the compound SELECT are allowed to be aggregate or distinct
** queries.
*/
if( pSub->pPrior ){
if( pSub->pOrderBy ){
- return 0; /* Restriction 20 */
+ return 0; /* Restriction (20) */
}
if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
- return 0;
+ return 0; /* (17d1), (17d2), or (17d3) */
}
for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
assert( pSub->pSrc!=0 );
assert( pSub->pEList->nExpr==pSub1->pEList->nExpr );
- if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
- || (pSub1->pPrior && pSub1->op!=TK_ALL)
- || pSub1->pSrc->nSrc<1
+ if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */
+ || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */
+ || pSub1->pSrc->nSrc<1 /* (17c) */
){
return 0;
}
testcase( pSub1->pSrc->nSrc>1 );
}
- /* Restriction 18. */
+ /* Restriction (18). */
if( p->pOrderBy ){
int ii;
for(ii=0; ii<p->pOrderBy->nExpr; ii++){
@@ -120999,6 +122225,14 @@ static int flattenSubquery(
}
}
+ /* Ex-restriction (23):
+ ** The only way that the recursive part of a CTE can contain a compound
+ ** subquery is for the subquery to be one term of a join. But if the
+ ** subquery is a join, then the flattening has already been stopped by
+ ** restriction (17d3)
+ */
+ assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 );
+
/***** If we reach this point, flattening is permitted. *****/
SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
pSub->zSelName, pSub, iFrom));
@@ -121046,16 +122280,13 @@ static int flattenSubquery(
Select *pNew;
ExprList *pOrderBy = p->pOrderBy;
Expr *pLimit = p->pLimit;
- Expr *pOffset = p->pOffset;
Select *pPrior = p->pPrior;
p->pOrderBy = 0;
p->pSrc = 0;
p->pPrior = 0;
p->pLimit = 0;
- p->pOffset = 0;
pNew = sqlite3SelectDup(db, p, 0);
sqlite3SelectSetName(pNew, pSub->zSelName);
- p->pOffset = pOffset;
p->pLimit = pLimit;
p->pOrderBy = pOrderBy;
p->pSrc = pSrc;
@@ -121211,18 +122442,7 @@ static int flattenSubquery(
if( isLeftJoin>0 ){
setJoinExpr(pWhere, iNewParent);
}
- if( subqueryIsAgg ){
- assert( pParent->pHaving==0 );
- pParent->pHaving = pParent->pWhere;
- pParent->pWhere = pWhere;
- 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, pWhere, pParent->pWhere);
- }
+ pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere);
if( db->mallocFailed==0 ){
SubstContext x;
x.pParse = pParse;
@@ -121285,9 +122505,13 @@ static int flattenSubquery(
**
** Do not attempt this optimization if:
**
-** (1) The inner query is an aggregate. (In that case, we'd really want
-** to copy the outer WHERE-clause terms onto the HAVING clause of the
-** inner query. But they probably won't help there so do not bother.)
+** (1) (** This restriction was removed on 2017-09-29. We used to
+** disallow this optimization for aggregate subqueries, but now
+** it is allowed by putting the extra terms on the HAVING clause.
+** The added HAVING clause is pointless if the subquery lacks
+** a GROUP BY clause. But such a HAVING clause is also harmless
+** so there does not appear to be any reason to add extra logic
+** to suppress it. **)
**
** (2) The inner query is the recursive part of a common table expression.
**
@@ -121312,16 +122536,22 @@ static int pushDownWhereTerms(
){
Expr *pNew;
int nChng = 0;
- Select *pX; /* For looping over compound SELECTs in pSubq */
if( pWhere==0 ) return 0;
- for(pX=pSubq; pX; pX=pX->pPrior){
- if( (pX->selFlags & (SF_Aggregate|SF_Recursive))!=0 ){
- testcase( pX->selFlags & SF_Aggregate );
- testcase( pX->selFlags & SF_Recursive );
- testcase( pX!=pSubq );
- return 0; /* restrictions (1) and (2) */
+ if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */
+
+#ifdef SQLITE_DEBUG
+ /* Only the first term of a compound can have a WITH clause. But make
+ ** sure no other terms are marked SF_Recursive in case something changes
+ ** in the future.
+ */
+ {
+ Select *pX;
+ for(pX=pSubq; pX; pX=pX->pPrior){
+ assert( (pX->selFlags & (SF_Recursive))==0 );
}
}
+#endif
+
if( pSubq->pLimit!=0 ){
return 0; /* restriction (3) */
}
@@ -121329,7 +122559,7 @@ static int pushDownWhereTerms(
nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor);
pWhere = pWhere->pLeft;
}
- if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction 5 */
+ if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction (5) */
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
nChng++;
while( pSubq ){
@@ -121341,7 +122571,11 @@ static int pushDownWhereTerms(
x.isLeftJoin = 0;
x.pEList = pSubq->pEList;
pNew = substExpr(&x, pNew);
- pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
+ if( pSubq->selFlags & SF_Aggregate ){
+ pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew);
+ }else{
+ pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew);
+ }
pSubq = pSubq->pPrior;
}
}
@@ -121350,42 +122584,44 @@ static int pushDownWhereTerms(
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
/*
-** Based on the contents of the AggInfo structure indicated by the first
-** argument, this function checks if the following are true:
+** The pFunc is the only aggregate function in the query. Check to see
+** if the query is a candidate for the min/max optimization.
**
-** * the query contains just a single aggregate function,
-** * the aggregate function is either min() or max(), and
-** * the argument to the aggregate function is a column value.
+** If the query is a candidate for the min/max optimization, then set
+** *ppMinMax to be an ORDER BY clause to be used for the optimization
+** and return either WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX depending on
+** whether pFunc is a min() or max() function.
**
-** If all of the above are true, then WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX
-** is returned as appropriate. Also, *ppMinMax is set to point to the
-** list of arguments passed to the aggregate before returning.
+** If the query is not a candidate for the min/max optimization, return
+** WHERE_ORDERBY_NORMAL (which must be zero).
**
-** Or, if the conditions above are not met, *ppMinMax is set to 0 and
-** WHERE_ORDERBY_NORMAL is returned.
+** This routine must be called after aggregate functions have been
+** located but before their arguments have been subjected to aggregate
+** analysis.
*/
-static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
- int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
-
- *ppMinMax = 0;
- if( pAggInfo->nFunc==1 ){
- Expr *pExpr = pAggInfo->aFunc[0].pExpr; /* Aggregate function */
- ExprList *pEList = pExpr->x.pList; /* Arguments to agg function */
-
- assert( pExpr->op==TK_AGG_FUNCTION );
- if( pEList && pEList->nExpr==1 && pEList->a[0].pExpr->op==TK_AGG_COLUMN ){
- const char *zFunc = pExpr->u.zToken;
- if( sqlite3StrICmp(zFunc, "min")==0 ){
- eRet = WHERE_ORDERBY_MIN;
- *ppMinMax = pEList;
- }else if( sqlite3StrICmp(zFunc, "max")==0 ){
- eRet = WHERE_ORDERBY_MAX;
- *ppMinMax = pEList;
- }
- }
- }
-
- assert( *ppMinMax==0 || (*ppMinMax)->nExpr==1 );
+static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
+ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
+ ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
+ const char *zFunc; /* Name of aggregate function pFunc */
+ ExprList *pOrderBy;
+ u8 sortOrder;
+
+ assert( *ppMinMax==0 );
+ assert( pFunc->op==TK_AGG_FUNCTION );
+ if( pEList==0 || pEList->nExpr!=1 ) return eRet;
+ zFunc = pFunc->u.zToken;
+ if( sqlite3StrICmp(zFunc, "min")==0 ){
+ eRet = WHERE_ORDERBY_MIN;
+ sortOrder = SQLITE_SO_ASC;
+ }else if( sqlite3StrICmp(zFunc, "max")==0 ){
+ eRet = WHERE_ORDERBY_MAX;
+ sortOrder = SQLITE_SO_DESC;
+ }else{
+ return eRet;
+ }
+ *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
+ assert( pOrderBy!=0 || db->mallocFailed );
+ if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder;
return eRet;
}
@@ -121516,7 +122752,6 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
assert( pNew->pPrior!=0 );
pNew->pPrior->pNext = pNew;
pNew->pLimit = 0;
- pNew->pOffset = 0;
return WRC_Continue;
}
@@ -121669,7 +122904,8 @@ static int withExpand(
);
return SQLITE_ERROR;
}
- assert( pTab->nTabRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
+ assert( pTab->nTabRef==1 ||
+ ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 ));
pCte->zCteErr = "circular reference: %s";
pSavedWith = pParse->pWith;
@@ -121726,7 +122962,7 @@ static int withExpand(
*/
static void selectPopWith(Walker *pWalker, Select *p){
Parse *pParse = pWalker->pParse;
- if( pParse->pWith && p->pPrior==0 ){
+ if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){
With *pWith = findRightmost(p)->pWith;
if( pWith!=0 ){
assert( pParse->pWith==pWith );
@@ -121771,17 +123007,19 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3 *db = pParse->db;
Expr *pE, *pRight, *pExpr;
u16 selFlags = p->selFlags;
+ u32 elistFlags = 0;
p->selFlags |= SF_Expanded;
if( db->mallocFailed ){
return WRC_Abort;
}
- if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){
+ assert( p->pSrc!=0 );
+ if( (selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
pTabList = p->pSrc;
pEList = p->pEList;
- if( p->pWith ){
+ if( OK_IF_ALWAYS_TRUE(p->pWith) ){
sqlite3WithPush(pParse, p->pWith, 0);
}
@@ -121813,7 +123051,11 @@ static int selectExpander(Walker *pWalker, Select *p){
pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ) return WRC_Abort;
pTab->nTabRef = 1;
- pTab->zName = sqlite3MPrintf(db, "sqlite_sq_%p", (void*)pTab);
+ if( pFrom->zAlias ){
+ pTab->zName = sqlite3DbStrDup(db, pFrom->zAlias);
+ }else{
+ pTab->zName = sqlite3MPrintf(db, "subquery_%p", (void*)pTab);
+ }
while( pSel->pPrior ){ pSel = pSel->pPrior; }
sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
pTab->iPKey = -1;
@@ -121879,6 +123121,7 @@ static int selectExpander(Walker *pWalker, Select *p){
assert( pE->op!=TK_DOT || pE->pRight!=0 );
assert( pE->op!=TK_DOT || (pE->pLeft!=0 && pE->pLeft->op==TK_ID) );
if( pE->op==TK_DOT && pE->pRight->op==TK_ASTERISK ) break;
+ elistFlags |= pE->flags;
}
if( k<pEList->nExpr ){
/*
@@ -121894,6 +123137,7 @@ static int selectExpander(Walker *pWalker, Select *p){
for(k=0; k<pEList->nExpr; k++){
pE = a[k].pExpr;
+ elistFlags |= pE->flags;
pRight = pE->pRight;
assert( pE->op!=TK_DOT || pRight!=0 );
if( pE->op!=TK_ASTERISK
@@ -122023,12 +123267,15 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3ExprListDelete(db, pEList);
p->pEList = pNew;
}
-#if SQLITE_MAX_COLUMN
- if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
- sqlite3ErrorMsg(pParse, "too many columns in result set");
- return WRC_Abort;
+ if( p->pEList ){
+ if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
+ sqlite3ErrorMsg(pParse, "too many columns in result set");
+ return WRC_Abort;
+ }
+ if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){
+ p->selFlags |= SF_ComplexResult;
+ }
}
-#endif
return WRC_Continue;
}
@@ -122082,7 +123329,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
Walker w;
w.xExprCallback = sqlite3ExprWalkNoop;
w.pParse = pParse;
- if( pParse->hasCompound ){
+ if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){
w.xSelectCallback = convertCompoundSelectToSubquery;
w.xSelectCallback2 = 0;
sqlite3WalkSelect(&w, pSelect);
@@ -122170,15 +123417,13 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
Select *p, /* The SELECT statement being coded. */
NameContext *pOuterNC /* Name context for container */
){
- sqlite3 *db;
- if( NEVER(p==0) ) return;
- db = pParse->db;
- if( db->mallocFailed ) return;
+ assert( p!=0 || pParse->db->mallocFailed );
+ if( pParse->db->mallocFailed ) return;
if( p->selFlags & SF_HasTypeInfo ) return;
sqlite3SelectExpand(pParse, p);
- if( pParse->nErr || db->mallocFailed ) return;
+ if( pParse->nErr || pParse->db->mallocFailed ) return;
sqlite3ResolveSelectNames(pParse, p, pOuterNC);
- if( pParse->nErr || db->mallocFailed ) return;
+ if( pParse->nErr || pParse->db->mallocFailed ) return;
sqlite3SelectAddTypeInfo(pParse, p);
}
@@ -122473,24 +123718,24 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
Expr *pExpr;
Expr *pCount;
sqlite3 *db;
- if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate query */
+ if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */
if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
pExpr = p->pEList->a[0].pExpr;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
- if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Must be count() */
+ if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
- if( p->pSrc->nSrc!=1 ) return 0; /* One table in the FROM clause */
+ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
pSub = p->pSrc->a[0].pSelect;
if( pSub==0 ) return 0; /* The FROM is a subquery */
- if( pSub->pPrior==0 ) return 0; /* Must be a compound subquery */
+ if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */
do{
if( pSub->op!=TK_ALL && pSub->pPrior ) return 0; /* Must be UNION ALL */
if( pSub->pWhere ) return 0; /* No WHERE clause */
if( pSub->selFlags & SF_Aggregate ) return 0; /* Not an aggregate */
- pSub = pSub->pPrior; /* Repeat over compound terms */
+ pSub = pSub->pPrior; /* Repeat over compound */
}while( pSub );
- /* If we reach this point, that means it is OK to perform the transformation */
+ /* If we reach this point then it is OK to perform the transformation */
db = pParse->db;
pCount = pExpr;
@@ -122565,6 +123810,8 @@ SQLITE_PRIVATE int sqlite3Select(
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
sqlite3 *db; /* The database connection */
+ ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
+ u8 minMaxFlag; /* Flag for min/max queries */
#ifndef SQLITE_OMIT_EXPLAIN
int iRestoreSelectId = pParse->iSelectId;
@@ -122630,7 +123877,6 @@ SQLITE_PRIVATE int sqlite3Select(
for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
struct SrcList_item *pItem = &pTabList->a[i];
Select *pSub = pItem->pSelect;
- int isAggSub;
Table *pTab = pItem->pTab;
if( pSub==0 ) continue;
@@ -122642,13 +123888,45 @@ SQLITE_PRIVATE int sqlite3Select(
goto select_end;
}
- isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
- if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
+ /* Do not try to flatten an aggregate subquery.
+ **
+ ** Flattening an aggregate subquery is only possible if the outer query
+ ** is not a join. But if the outer query is not a join, then the subquery
+ ** will be implemented as a co-routine and there is no advantage to
+ ** flattening in that case.
+ */
+ if( (pSub->selFlags & SF_Aggregate)!=0 ) continue;
+ assert( pSub->pGroupBy==0 );
+
+ /* If the outer query contains a "complex" result set (that is,
+ ** if the result set of the outer query uses functions or subqueries)
+ ** and if the subquery contains an ORDER BY clause and if
+ ** it will be implemented as a co-routine, then do not flatten. This
+ ** restriction allows SQL constructs like this:
+ **
+ ** SELECT expensive_function(x)
+ ** FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
+ **
+ ** The expensive_function() is only computed on the 10 rows that
+ ** are output, rather than every row of the table.
+ **
+ ** The requirement that the outer query have a complex result set
+ ** means that flattening does occur on simpler SQL constraints without
+ ** the expensive_function() like:
+ **
+ ** SELECT x FROM (SELECT x FROM tab ORDER BY y LIMIT 10);
+ */
+ if( pSub->pOrderBy!=0
+ && i==0
+ && (p->selFlags & SF_ComplexResult)!=0
+ && (pTabList->nSrc==1
+ || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
+ ){
+ continue;
+ }
+
+ if( flattenSubquery(pParse, p, i, isAgg) ){
/* This subquery can be absorbed into its parent. */
- if( isAggSub ){
- isAgg = 1;
- p->selFlags |= SF_Aggregate;
- }
i = -1;
}
pTabList = p->pSrc;
@@ -122682,10 +123960,14 @@ SQLITE_PRIVATE int sqlite3Select(
struct SrcList_item *pItem = &pTabList->a[i];
SelectDest dest;
Select *pSub;
+#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
+ const char *zSavedAuthContext;
+#endif
- /* Issue SQLITE_READ authorizations with a fake column name for any tables that
- ** are referenced but from which no values are extracted. Examples of where these
- ** kinds of null SQLITE_READ authorizations would occur:
+ /* Issue SQLITE_READ authorizations with a fake column name for any
+ ** tables that are referenced but from which no values are extracted.
+ ** Examples of where these kinds of null SQLITE_READ authorizations
+ ** would occur:
**
** SELECT count(*) FROM t1; -- SQLITE_READ t1.""
** SELECT t1.* FROM t1, t2; -- SQLITE_READ t2.""
@@ -122693,10 +123975,10 @@ SQLITE_PRIVATE int sqlite3Select(
** The fake column name is an empty string. It is possible for a table to
** have a column named by the empty string, in which case there is no way to
** distinguish between an unreferenced table and an actual reference to the
- ** "" column. The original design was for the fake column name to be a NULL,
+ ** "" column. The original design was for the fake column name to be a NULL,
** which would be unambiguous. But legacy authorization callbacks might
- ** assume the column name is non-NULL and segfault. The use of an empty string
- ** for the fake column name seems safer.
+ ** assume the column name is non-NULL and segfault. The use of an empty
+ ** string for the fake column name seems safer.
*/
if( pItem->colUsed==0 ){
sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase);
@@ -122748,16 +124030,14 @@ SQLITE_PRIVATE int sqlite3Select(
#endif
}
+ zSavedAuthContext = pParse->zAuthContext;
+ pParse->zAuthContext = pItem->zName;
+
/* Generate code to implement the subquery
**
- ** The subquery is implemented as a co-routine if all of these are true:
- ** (1) The subquery is guaranteed to be the outer loop (so that it
- ** does not need to be computed more than once)
- ** (2) The ALL keyword after SELECT is omitted. (Applications are
- ** allowed to say "SELECT ALL" instead of just "SELECT" to disable
- ** the use of co-routines.)
- ** (3) Co-routines are not disabled using sqlite3_test_control()
- ** with SQLITE_TESTCTRL_OPTIMIZATIONS.
+ ** The subquery is implemented as a co-routine if the subquery is
+ ** guaranteed to be the outer loop (so that it does not need to be
+ ** computed more than once)
**
** TODO: Are there other reasons beside (1) to use a co-routine
** implementation?
@@ -122765,13 +124045,12 @@ SQLITE_PRIVATE int sqlite3Select(
if( i==0
&& (pTabList->nSrc==1
|| (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */
- && (p->selFlags & SF_All)==0 /* (2) */
- && OptimizationEnabled(db, SQLITE_SubqCoroutine) /* (3) */
){
/* Implement a co-routine that will return a single row of the result
** set on each invocation.
*/
int addrTop = sqlite3VdbeCurrentAddr(v)+1;
+
pItem->regReturn = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
VdbeComment((v, "%s", pItem->pTab->zName));
@@ -122829,6 +124108,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
if( db->mallocFailed ) goto select_end;
pParse->nHeight -= sqlite3SelectExprHeight(p);
+ pParse->zAuthContext = zSavedAuthContext;
#endif
}
@@ -122976,7 +124256,8 @@ SQLITE_PRIVATE int sqlite3Select(
}
/* Use the standard inner loop. */
- selectInnerLoop(pParse, p, pEList, -1, &sSort, &sDistinct, pDest,
+ assert( p->pEList==pEList );
+ selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest,
sqlite3WhereContinueLabel(pWInfo),
sqlite3WhereBreakLabel(pWInfo));
@@ -123056,6 +124337,11 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
+ if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){
+ minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy);
+ }else{
+ minMaxFlag = WHERE_ORDERBY_NORMAL;
+ }
for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sNC.ncFlags |= NC_InAggFunc;
@@ -123064,6 +124350,24 @@ SQLITE_PRIVATE int sqlite3Select(
}
sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
+#if SELECTTRACE_ENABLED
+ if( sqlite3SelectTrace & 0x400 ){
+ int ii;
+ SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n"));
+ sqlite3TreeViewSelect(0, p, 0);
+ for(ii=0; ii<sAggInfo.nColumn; ii++){
+ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
+ ii, sAggInfo.aCol[ii].iMem);
+ sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
+ }
+ for(ii=0; ii<sAggInfo.nFunc; ii++){
+ sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
+ ii, sAggInfo.aFunc[ii].iMem);
+ sqlite3TreeViewExpr(0, sAggInfo.aFunc[ii].pExpr, 0);
+ }
+ }
+#endif
+
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
@@ -123279,7 +124583,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, &sAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, -1, &sSort,
+ selectInnerLoop(pParse, p, -1, &sSort,
&sDistinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
@@ -123293,7 +124597,6 @@ SQLITE_PRIVATE int sqlite3Select(
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
- ExprList *pDel = 0;
#ifndef SQLITE_OMIT_BTREECOUNT
Table *pTab;
if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
@@ -123355,67 +124658,31 @@ SQLITE_PRIVATE int sqlite3Select(
}else
#endif /* SQLITE_OMIT_BTREECOUNT */
{
- /* Check if the query is of one of the following forms:
- **
- ** SELECT min(x) FROM ...
- ** SELECT max(x) FROM ...
- **
- ** If it is, then ask the code in where.c to attempt to sort results
- ** as if there was an "ORDER ON x" or "ORDER ON x DESC" clause.
- ** If where.c is able to produce results sorted in this order, then
- ** add vdbe code to break out of the processing loop after the
- ** first iteration (since the first iteration of the loop is
- ** guaranteed to operate on the row with the minimum or maximum
- ** value of x, the only row required).
- **
- ** A special flag must be passed to sqlite3WhereBegin() to slightly
- ** modify behavior as follows:
- **
- ** + If the query is a "SELECT min(x)", then the loop coded by
- ** where.c should not iterate over any values with a NULL value
- ** for x.
- **
- ** + The optimizer code in where.c (the thing that decides which
- ** index or indices to use) should place a different priority on
- ** satisfying the 'ORDER BY' clause than it does in other cases.
- ** Refer to code and comments in where.c for details.
- */
- ExprList *pMinMax = 0;
- u8 flag = WHERE_ORDERBY_NORMAL;
-
- assert( p->pGroupBy==0 );
- assert( flag==0 );
- if( p->pHaving==0 ){
- flag = minMaxQuery(&sAggInfo, &pMinMax);
- }
- assert( flag==0 || (pMinMax!=0 && pMinMax->nExpr==1) );
-
- if( flag ){
- pMinMax = sqlite3ExprListDup(db, pMinMax, 0);
- pDel = pMinMax;
- assert( db->mallocFailed || pMinMax!=0 );
- if( !db->mallocFailed ){
- pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0;
- pMinMax->a[0].pExpr->op = TK_COLUMN;
- }
- }
-
/* This case runs if the aggregate has no GROUP BY clause. The
** processing is much simpler since there is only a single row
** of output.
*/
+ assert( p->pGroupBy==0 );
resetAccumulator(pParse, &sAggInfo);
- pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMax, 0,flag,0);
+
+ /* If this query is a candidate for the min/max optimization, then
+ ** minMaxFlag will have been previously set to either
+ ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will
+ ** be an appropriate ORDER BY expression for the optimization.
+ */
+ assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
+ assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
+
+ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
+ 0, minMaxFlag, 0);
if( pWInfo==0 ){
- sqlite3ExprListDelete(db, pDel);
goto select_end;
}
updateAccumulator(pParse, &sAggInfo);
- assert( pMinMax==0 || pMinMax->nExpr==1 );
if( sqlite3WhereIsOrdered(pWInfo)>0 ){
sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
VdbeComment((v, "%s() by index",
- (flag==WHERE_ORDERBY_MIN?"min":"max")));
+ (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max")));
}
sqlite3WhereEnd(pWInfo);
finalizeAggFunctions(pParse, &sAggInfo);
@@ -123423,9 +124690,8 @@ SQLITE_PRIVATE int sqlite3Select(
sSort.pOrderBy = 0;
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, -1, 0, 0,
+ selectInnerLoop(pParse, p, -1, 0, 0,
pDest, addrEnd, addrEnd);
- sqlite3ExprListDelete(db, pDel);
}
sqlite3VdbeResolveLabel(v, addrEnd);
@@ -123457,7 +124723,7 @@ SQLITE_PRIVATE int sqlite3Select(
*/
select_end:
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
-
+ sqlite3ExprListDelete(db, pMinMaxOrderBy);
sqlite3DbFree(db, sAggInfo.aCol);
sqlite3DbFree(db, sAggInfo.aFunc);
#if SELECTTRACE_ENABLED
@@ -123697,6 +124963,7 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS
sqlite3ExprListDelete(db, pTmp->pExprList);
sqlite3SelectDelete(db, pTmp->pSelect);
sqlite3IdListDelete(db, pTmp->pIdList);
+ sqlite3DbFree(db, pTmp->zSpan);
sqlite3DbFree(db, pTmp);
}
@@ -124012,13 +125279,29 @@ triggerfinish_cleanup:
}
/*
+** Duplicate a range of text from an SQL statement, then convert all
+** whitespace characters into ordinary space characters.
+*/
+static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
+ char *z = sqlite3DbSpanDup(db, zStart, zEnd);
+ int i;
+ if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' ';
+ return z;
+}
+
+/*
** Turn a SELECT statement (that the pSelect parameter points to) into
** a trigger step. Return a pointer to a TriggerStep structure.
**
** The parser calls this routine when it finds a SELECT statement in
** body of a TRIGGER.
*/
-SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelect){
+SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(
+ sqlite3 *db, /* Database connection */
+ Select *pSelect, /* The SELECT statement */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
+){
TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
if( pTriggerStep==0 ) {
sqlite3SelectDelete(db, pSelect);
@@ -124027,6 +125310,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelec
pTriggerStep->op = TK_SELECT;
pTriggerStep->pSelect = pSelect;
pTriggerStep->orconf = OE_Default;
+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
return pTriggerStep;
}
@@ -124039,7 +125323,9 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelec
static TriggerStep *triggerStepAllocate(
sqlite3 *db, /* Database connection */
u8 op, /* Trigger opcode */
- Token *pName /* The target name */
+ Token *pName, /* The target name */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
TriggerStep *pTriggerStep;
@@ -124050,6 +125336,7 @@ static TriggerStep *triggerStepAllocate(
sqlite3Dequote(z);
pTriggerStep->zTarget = z;
pTriggerStep->op = op;
+ pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
}
return pTriggerStep;
}
@@ -124066,13 +125353,15 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
Token *pTableName, /* Name of the table into which we insert */
IdList *pColumn, /* List of columns in pTableName to insert into */
Select *pSelect, /* A SELECT statement that supplies values */
- u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+ u8 orconf, /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
TriggerStep *pTriggerStep;
assert(pSelect != 0 || db->mallocFailed);
- pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
+ pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName, zStart, zEnd);
if( pTriggerStep ){
pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
pTriggerStep->pIdList = pColumn;
@@ -124095,11 +125384,13 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
Token *pTableName, /* Name of the table to be updated */
ExprList *pEList, /* The SET clause: list of column and new values */
Expr *pWhere, /* The WHERE clause */
- u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+ u8 orconf, /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
TriggerStep *pTriggerStep;
- pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
+ pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName, zStart, zEnd);
if( pTriggerStep ){
pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
@@ -124118,11 +125409,13 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
sqlite3 *db, /* Database connection */
Token *pTableName, /* The table from which rows are deleted */
- Expr *pWhere /* The WHERE clause */
+ Expr *pWhere, /* The WHERE clause */
+ const char *zStart, /* Start of SQL text */
+ const char *zEnd /* End of SQL text */
){
TriggerStep *pTriggerStep;
- pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
+ pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName, zStart, zEnd);
if( pTriggerStep ){
pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
pTriggerStep->orconf = OE_Default;
@@ -124257,7 +125550,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const ch
*pp = (*pp)->pNext;
}
sqlite3DeleteTrigger(db, pTrigger);
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
}
@@ -124377,13 +125670,21 @@ static int codeTriggerProgram(
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
assert( pParse->okConstFactor==0 );
+#ifndef SQLITE_OMIT_TRACE
+ if( pStep->zSpan ){
+ sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0,
+ sqlite3MPrintf(db, "-- %s", pStep->zSpan),
+ P4_DYNAMIC);
+ }
+#endif
+
switch( pStep->op ){
case TK_UPDATE: {
sqlite3Update(pParse,
targetSrcList(pParse, pStep),
sqlite3ExprListDup(db, pStep->pExprList, 0),
sqlite3ExprDup(db, pStep->pWhere, 0),
- pParse->eOrconf
+ pParse->eOrconf, 0, 0
);
break;
}
@@ -124399,7 +125700,7 @@ static int codeTriggerProgram(
case TK_DELETE: {
sqlite3DeleteFrom(pParse,
targetSrcList(pParse, pStep),
- sqlite3ExprDup(db, pStep->pWhere, 0)
+ sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0
);
break;
}
@@ -124517,9 +125818,11 @@ static TriggerPrg *codeRowTrigger(
pTab->zName
));
#ifndef SQLITE_OMIT_TRACE
- sqlite3VdbeChangeP4(v, -1,
- sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
- );
+ if( pTrigger->zName ){
+ sqlite3VdbeChangeP4(v, -1,
+ sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC
+ );
+ }
#endif
/* If one was specified, code the WHEN clause. If it evaluates to false
@@ -124547,7 +125850,7 @@ static TriggerPrg *codeRowTrigger(
VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf)));
transferParseError(pParse, pSubParse);
- if( db->mallocFailed==0 ){
+ if( db->mallocFailed==0 && pParse->nErr==0 ){
pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
}
pProgram->nMem = pSubParse->nMem;
@@ -124866,7 +126169,9 @@ SQLITE_PRIVATE void sqlite3Update(
SrcList *pTabList, /* The table in which we should change things */
ExprList *pChanges, /* Things to be changed */
Expr *pWhere, /* The WHERE clause. May be null */
- int onError /* How to handle constraint errors */
+ int onError, /* How to handle constraint errors */
+ ExprList *pOrderBy, /* ORDER BY clause. May be null */
+ Expr *pLimit /* LIMIT clause. May be null */
){
int i, j; /* Loop counters */
Table *pTab; /* The table to be updated */
@@ -124951,6 +126256,16 @@ SQLITE_PRIVATE void sqlite3Update(
# define isView 0
#endif
+#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+ if( !isView ){
+ pWhere = sqlite3LimitWhere(
+ pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE"
+ );
+ pOrderBy = 0;
+ pLimit = 0;
+ }
+#endif
+
if( sqlite3ViewGetColumnNames(pParse, pTab) ){
goto update_cleanup;
}
@@ -125119,7 +126434,11 @@ SQLITE_PRIVATE void sqlite3Update(
*/
#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
if( isView ){
- sqlite3MaterializeView(pParse, pTab, pWhere, iDataCur);
+ sqlite3MaterializeView(pParse, pTab,
+ pWhere, pOrderBy, pLimit, iDataCur
+ );
+ pOrderBy = 0;
+ pLimit = 0;
}
#endif
@@ -125503,6 +126822,10 @@ update_cleanup:
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprListDelete(db, pChanges);
sqlite3ExprDelete(db, pWhere);
+#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
+ sqlite3ExprListDelete(db, pOrderBy);
+ sqlite3ExprDelete(db, pLimit);
+#endif
return;
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
@@ -125562,7 +126885,7 @@ static void updateVirtualTable(
int bOnePass; /* True to use onepass strategy */
int addr; /* Address of OP_OpenEphemeral */
- /* Allocate nArg registers to martial the arguments to VUpdate. Then
+ /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
** create and open the ephemeral table in which the records created from
** these arguments will be temporarily stored. */
assert( v );
@@ -125578,19 +126901,31 @@ static void updateVirtualTable(
if( pWInfo==0 ) return;
/* Populate the argument registers. */
- sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
- if( pRowid ){
- sqlite3ExprCode(pParse, pRowid, regArg+1);
- }else{
- sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
- }
for(i=0; i<pTab->nCol; i++){
if( aXRef[i]>=0 ){
sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
}else{
sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
+ sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
}
}
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
+ if( pRowid ){
+ sqlite3ExprCode(pParse, pRowid, regArg+1);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
+ }
+ }else{
+ Index *pPk; /* PRIMARY KEY index */
+ i16 iPk; /* PRIMARY KEY column */
+ pPk = sqlite3PrimaryKeyIndex(pTab);
+ assert( pPk!=0 );
+ assert( pPk->nKeyCol==1 );
+ iPk = pPk->aiColumn[0];
+ sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg);
+ sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1);
+ }
bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
@@ -125606,6 +126941,11 @@ static void updateVirtualTable(
/* Create a record from the argument register contents and insert it into
** the ephemeral table. */
sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
+#ifdef SQLITE_DEBUG
+ /* Signal an assert() within OP_MakeRecord that it is allowed to
+ ** accept no-change records with serial_type 10 */
+ sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
+#endif
sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
}
@@ -125775,7 +127115,8 @@ 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 */
- int saved_flags; /* Saved value of the db->flags */
+ u16 saved_mDbFlags; /* Saved value of db->mDbFlags */
+ u32 saved_flags; /* Saved value of db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
u8 saved_mTrace; /* Saved trace settings */
@@ -125798,11 +127139,12 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
** restored before returning. Then set the writable-schema flag, and
** disable CHECK and foreign key constraints. */
saved_flags = db->flags;
+ saved_mDbFlags = db->mDbFlags;
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_mTrace = db->mTrace;
- db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
- | SQLITE_PreferBuiltin | SQLITE_Vacuum);
+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
+ db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
db->mTrace = 0;
@@ -125913,8 +127255,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
"WHERE type='table'AND coalesce(rootpage,1)>0",
zDbMain
);
- assert( (db->flags & SQLITE_Vacuum)!=0 );
- db->flags &= ~SQLITE_Vacuum;
+ assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
+ db->mDbFlags &= ~DBFLAG_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy the triggers, views, and virtual tables from the main database
@@ -125982,6 +127324,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
end_of_vacuum:
/* Restore the original value of db->flags */
db->init.iDb = 0;
+ db->mDbFlags = saved_mDbFlags;
db->flags = saved_flags;
db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange;
@@ -126058,8 +127401,10 @@ SQLITE_PRIVATE Module *sqlite3VtabCreateModule(
){
Module *pMod;
int nName = sqlite3Strlen30(zName);
- pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1);
- if( pMod ){
+ pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1);
+ if( pMod==0 ){
+ sqlite3OomFault(db);
+ }else{
Module *pDel;
char *zCopy = (char *)(&pMod[1]);
memcpy(zCopy, zName, nName+1);
@@ -126534,13 +127879,14 @@ static int vtabCallConstructor(
}
}
- zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
+ zModuleName = sqlite3DbStrDup(db, pTab->zName);
if( !zModuleName ){
return SQLITE_NOMEM_BKPT;
}
- pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
+ pVTable = sqlite3MallocZero(sizeof(VTable));
if( !pVTable ){
+ sqlite3OomFault(db);
sqlite3DbFree(db, zModuleName);
return SQLITE_NOMEM_BKPT;
}
@@ -126660,6 +128006,7 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr);
if( rc!=SQLITE_OK ){
sqlite3ErrorMsg(pParse, "%s", zErr);
+ pParse->rc = rc;
}
sqlite3DbFree(db, zErr);
}
@@ -126749,10 +128096,10 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
*/
SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
VtabCtx *pCtx;
- Parse *pParse;
int rc = SQLITE_OK;
Table *pTab;
char *zErr = 0;
+ Parse sParse;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
@@ -126769,55 +128116,55 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
pTab = pCtx->pTab;
assert( IsVirtual(pTab) );
- pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
- if( pParse==0 ){
- rc = SQLITE_NOMEM_BKPT;
- }else{
- pParse->declareVtab = 1;
- pParse->db = db;
- pParse->nQueryLoop = 1;
-
- if( SQLITE_OK==sqlite3RunParser(pParse, zCreateTable, &zErr)
- && pParse->pNewTable
- && !db->mallocFailed
- && !pParse->pNewTable->pSelect
- && !IsVirtual(pParse->pNewTable)
- ){
- if( !pTab->aCol ){
- Table *pNew = pParse->pNewTable;
- Index *pIdx;
- pTab->aCol = pNew->aCol;
- pTab->nCol = pNew->nCol;
- pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
- pNew->nCol = 0;
- pNew->aCol = 0;
- assert( pTab->pIndex==0 );
- if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 ){
- rc = SQLITE_ERROR;
- }
- pIdx = pNew->pIndex;
- if( pIdx ){
- assert( pIdx->pNext==0 );
- pTab->pIndex = pIdx;
- pNew->pIndex = 0;
- pIdx->pTable = pTab;
- }
+ memset(&sParse, 0, sizeof(sParse));
+ sParse.declareVtab = 1;
+ sParse.db = db;
+ sParse.nQueryLoop = 1;
+ if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr)
+ && sParse.pNewTable
+ && !db->mallocFailed
+ && !sParse.pNewTable->pSelect
+ && !IsVirtual(sParse.pNewTable)
+ ){
+ if( !pTab->aCol ){
+ Table *pNew = sParse.pNewTable;
+ Index *pIdx;
+ pTab->aCol = pNew->aCol;
+ pTab->nCol = pNew->nCol;
+ pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid);
+ pNew->nCol = 0;
+ pNew->aCol = 0;
+ assert( pTab->pIndex==0 );
+ assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 );
+ if( !HasRowid(pNew)
+ && pCtx->pVTable->pMod->pModule->xUpdate!=0
+ && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1
+ ){
+ /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0)
+ ** or else must have a single-column PRIMARY KEY */
+ rc = SQLITE_ERROR;
+ }
+ pIdx = pNew->pIndex;
+ if( pIdx ){
+ assert( pIdx->pNext==0 );
+ pTab->pIndex = pIdx;
+ pNew->pIndex = 0;
+ pIdx->pTable = pTab;
}
- pCtx->bDeclared = 1;
- }else{
- sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
- sqlite3DbFree(db, zErr);
- rc = SQLITE_ERROR;
- }
- pParse->declareVtab = 0;
-
- if( pParse->pVdbe ){
- sqlite3VdbeFinalize(pParse->pVdbe);
}
- sqlite3DeleteTable(db, pParse->pNewTable);
- sqlite3ParserReset(pParse);
- sqlite3StackFree(db, pParse);
+ pCtx->bDeclared = 1;
+ }else{
+ sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
+ sqlite3DbFree(db, zErr);
+ rc = SQLITE_ERROR;
}
+ sParse.declareVtab = 0;
+
+ if( sParse.pVdbe ){
+ sqlite3VdbeFinalize(sParse.pVdbe);
+ }
+ sqlite3DeleteTable(db, sParse.pNewTable);
+ sqlite3ParserReset(&sParse);
assert( (rc&0xff)==rc );
rc = sqlite3ApiExit(db, rc);
@@ -127795,7 +129142,6 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
** WO_LE == SQLITE_INDEX_CONSTRAINT_LE
** WO_GT == SQLITE_INDEX_CONSTRAINT_GT
** WO_GE == SQLITE_INDEX_CONSTRAINT_GE
-** WO_MATCH == SQLITE_INDEX_CONSTRAINT_MATCH
*/
#define WO_IN 0x0001
#define WO_EQ 0x0002
@@ -127803,7 +129149,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC
#define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
-#define WO_MATCH 0x0040
+#define WO_AUX 0x0040 /* Op useful to virtual tables only */
#define WO_IS 0x0080
#define WO_ISNULL 0x0100
#define WO_OR 0x0200 /* Two or more OR-connected terms */
@@ -127950,7 +129296,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
){
int ret = 0;
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
- if( pParse->explain==2 )
+ if( sqlite3ParseToplevel(pParse)->explain==2 )
#endif
{
struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
@@ -128116,8 +129462,8 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
int nLoop = 0;
- while( ALWAYS(pTerm!=0)
- && (pTerm->wtFlags & TERM_CODED)==0
+ assert( pTerm!=0 );
+ while( (pTerm->wtFlags & TERM_CODED)==0
&& (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
&& (pLevel->notReady & pTerm->prereqAll)==0
){
@@ -128128,6 +129474,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
}
if( pTerm->iParent<0 ) break;
pTerm = &pTerm->pWC->a[pTerm->iParent];
+ assert( pTerm!=0 );
pTerm->nChild--;
if( pTerm->nChild!=0 ) break;
nLoop++;
@@ -128198,6 +129545,102 @@ static void updateRangeAffinityStr(
}
}
+
+/*
+** pX is an expression of the form: (vector) IN (SELECT ...)
+** In other words, it is a vector IN operator with a SELECT clause on the
+** LHS. But not all terms in the vector are indexable and the terms might
+** not be in the correct order for indexing.
+**
+** This routine makes a copy of the input pX expression and then adjusts
+** the vector on the LHS with corresponding changes to the SELECT so that
+** the vector contains only index terms and those terms are in the correct
+** order. The modified IN expression is returned. The caller is responsible
+** for deleting the returned expression.
+**
+** Example:
+**
+** CREATE TABLE t1(a,b,c,d,e,f);
+** CREATE INDEX t1x1 ON t1(e,c);
+** SELECT * FROM t1 WHERE (a,b,c,d,e) IN (SELECT v,w,x,y,z FROM t2)
+** \_______________________________________/
+** The pX expression
+**
+** Since only columns e and c can be used with the index, in that order,
+** the modified IN expression that is returned will be:
+**
+** (e,c) IN (SELECT z,x FROM t2)
+**
+** The reduced pX is different from the original (obviously) and thus is
+** only used for indexing, to improve performance. The original unaltered
+** IN expression must also be run on each output row for correctness.
+*/
+static Expr *removeUnindexableInClauseTerms(
+ Parse *pParse, /* The parsing context */
+ int iEq, /* Look at loop terms starting here */
+ WhereLoop *pLoop, /* The current loop */
+ Expr *pX /* The IN expression to be reduced */
+){
+ sqlite3 *db = pParse->db;
+ Expr *pNew = sqlite3ExprDup(db, pX, 0);
+ if( db->mallocFailed==0 ){
+ ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */
+ ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */
+ ExprList *pRhs = 0; /* New RHS after modifications */
+ ExprList *pLhs = 0; /* New LHS after mods */
+ int i; /* Loop counter */
+ Select *pSelect; /* Pointer to the SELECT on the RHS */
+
+ for(i=iEq; i<pLoop->nLTerm; i++){
+ if( pLoop->aLTerm[i]->pExpr==pX ){
+ int iField = pLoop->aLTerm[i]->iField - 1;
+ assert( pOrigRhs->a[iField].pExpr!=0 );
+ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
+ pOrigRhs->a[iField].pExpr = 0;
+ assert( pOrigLhs->a[iField].pExpr!=0 );
+ pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
+ pOrigLhs->a[iField].pExpr = 0;
+ }
+ }
+ sqlite3ExprListDelete(db, pOrigRhs);
+ sqlite3ExprListDelete(db, pOrigLhs);
+ pNew->pLeft->x.pList = pLhs;
+ pNew->x.pSelect->pEList = pRhs;
+ if( pLhs && pLhs->nExpr==1 ){
+ /* 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. */
+ Expr *p = pLhs->a[0].pExpr;
+ pLhs->a[0].pExpr = 0;
+ sqlite3ExprDelete(db, pNew->pLeft);
+ pNew->pLeft = p;
+ }
+ pSelect = pNew->x.pSelect;
+ 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;
+ }
+ }
+
+#if 0
+ printf("For indexing, change the IN expr:\n");
+ sqlite3TreeViewExpr(0, pX, 0);
+ printf("Into:\n");
+ sqlite3TreeViewExpr(0, pNew, 0);
+#endif
+ }
+ return pNew;
+}
+
+
/*
** 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
@@ -128260,68 +129703,23 @@ static int codeEqualityTerm(
}
}
for(i=iEq;i<pLoop->nLTerm; i++){
- if( ALWAYS(pLoop->aLTerm[i]) && pLoop->aLTerm[i]->pExpr==pX ) nEq++;
+ assert( pLoop->aLTerm[i]!=0 );
+ if( 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 */
+ pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
- 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;
+ aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
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;
+ pTerm->pExpr->iTable = pX->iTable;
}
- sqlite3ExprListDelete(pParse->db, pLhs);
- sqlite3ExprListDelete(pParse->db, pRhs);
+ sqlite3ExprDelete(db, pX);
+ pX = pTerm->pExpr;
}
if( eType==IN_INDEX_INDEX_DESC ){
@@ -128616,7 +130014,7 @@ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){
pWalker->eCode = 1;
}else if( pExpr->op==TK_FUNCTION ){
int d1;
- char d2[3];
+ char d2[4];
if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){
pWalker->eCode = 1;
}
@@ -128839,7 +130237,7 @@ static void codeDeferredSeek(
*/
static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
assert( nReg>0 );
- if( sqlite3ExprIsVector(p) ){
+ if( p && sqlite3ExprIsVector(p) ){
#ifndef SQLITE_OMIT_SUBQUERY
if( (p->flags & EP_xIsSelect) ){
Vdbe *v = pParse->pVdbe;
@@ -128892,9 +130290,9 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
}
/*
-** For an indexes on expression X, locate every instance of expression X in pExpr
-** and change that subexpression into a reference to the appropriate column of
-** the index.
+** For an indexes on expression X, locate every instance of expression X
+** in pExpr and change that subexpression into a reference to the appropriate
+** column of the index.
*/
static void whereIndexExprTrans(
Index *pIdx, /* The Index */
@@ -129460,6 +130858,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
}
}else if( bStopAtNull ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
+ sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
endEq = 0;
nConstraint++;
}
@@ -130171,12 +131570,12 @@ static int isLikeOrGlob(
int *pisComplete, /* True if the only wildcard is % in the last character */
int *pnoCase /* True if uppercase is equivalent to lowercase */
){
- const char *z = 0; /* String on RHS of LIKE operator */
+ const u8 *z = 0; /* String on RHS of LIKE operator */
Expr *pRight, *pLeft; /* Right and left size of LIKE operator */
ExprList *pList; /* List of operands to the LIKE operator */
int c; /* One character in z[] */
int cnt; /* Number of non-wildcard prefix characters */
- char wc[3]; /* Wildcard characters */
+ char wc[4]; /* Wildcard characters */
sqlite3 *db = pParse->db; /* Database connection */
sqlite3_value *pVal = 0;
int op; /* Opcode of pRight */
@@ -130198,12 +131597,12 @@ static int isLikeOrGlob(
int iCol = pRight->iColumn;
pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB);
if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
- z = (char *)sqlite3_value_text(pVal);
+ z = sqlite3_value_text(pVal);
}
sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
}else if( op==TK_STRING ){
- z = pRight->u.zToken;
+ z = (u8*)pRight->u.zToken;
}
if( z ){
@@ -130223,16 +131622,42 @@ static int isLikeOrGlob(
return 0;
}
}
+
+ /* Count the number of prefix characters prior to the first wildcard */
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
+ if( c==wc[3] && z[cnt]!=0 ) cnt++;
}
+
+ /* The optimization is possible only if (1) the pattern does not begin
+ ** with a wildcard and if (2) the non-wildcard prefix does not end with
+ ** an (illegal 0xff) character. The second condition is necessary so
+ ** that we can increment the prefix key to find an upper bound for the
+ ** range search.
+ */
if( cnt!=0 && 255!=(u8)z[cnt-1] ){
Expr *pPrefix;
+
+ /* A "complete" match if the pattern ends with "*" or "%" */
*pisComplete = c==wc[0] && z[cnt+1]==0;
- pPrefix = sqlite3Expr(db, TK_STRING, z);
- if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
+
+ /* Get the pattern prefix. Remove all escapes from the prefix. */
+ pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
+ if( pPrefix ){
+ int iFrom, iTo;
+ char *zNew = pPrefix->u.zToken;
+ zNew[cnt] = 0;
+ for(iFrom=iTo=0; iFrom<cnt; iFrom++){
+ if( zNew[iFrom]==wc[3] ) iFrom++;
+ zNew[iTo++] = zNew[iFrom];
+ }
+ zNew[iTo] = 0;
+ }
*ppPrefix = pPrefix;
+
+ /* If the RHS pattern is a bound parameter, make arrangements to
+ ** reprepare the statement when that parameter is rebound */
if( op==TK_VARIABLE ){
Vdbe *v = pParse->pVdbe;
sqlite3VdbeSetVarmask(v, pRight->iColumn);
@@ -130263,48 +131688,84 @@ static int isLikeOrGlob(
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
-** Check to see if the given expression is of the form
-**
-** column OP expr
-**
-** where OP is one of MATCH, GLOB, LIKE or REGEXP and "column" is a
-** column of a virtual table.
-**
-** If it is then return TRUE. If not, return FALSE.
-*/
-static int isMatchOfColumn(
+** Check to see if the pExpr expression is a form that needs to be passed
+** to the xBestIndex method of virtual tables. Forms of interest include:
+**
+** Expression Virtual Table Operator
+** ----------------------- ---------------------------------
+** 1. column MATCH expr SQLITE_INDEX_CONSTRAINT_MATCH
+** 2. column GLOB expr SQLITE_INDEX_CONSTRAINT_GLOB
+** 3. column LIKE expr SQLITE_INDEX_CONSTRAINT_LIKE
+** 4. column REGEXP expr SQLITE_INDEX_CONSTRAINT_REGEXP
+** 5. column != expr SQLITE_INDEX_CONSTRAINT_NE
+** 6. expr != column SQLITE_INDEX_CONSTRAINT_NE
+** 7. column IS NOT expr SQLITE_INDEX_CONSTRAINT_ISNOT
+** 8. expr IS NOT column SQLITE_INDEX_CONSTRAINT_ISNOT
+** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL
+**
+** In every case, "column" must be a column of a virtual table. If there
+** is a match, set *ppLeft to the "column" expression, set *ppRight to the
+** "expr" expression (even though in forms (6) and (8) the column is on the
+** right and the expression is on the left). Also set *peOp2 to the
+** appropriate virtual table operator. The return value is 1 or 2 if there
+** is a match. The usual return is 1, but if the RHS is also a column
+** of virtual table in forms (5) or (7) then return 2.
+**
+** If the expression matches none of the patterns above, return 0.
+*/
+static int isAuxiliaryVtabOperator(
Expr *pExpr, /* Test this expression */
- unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
-){
- static const struct Op2 {
- const char *zOp;
- unsigned char eOp2;
- } aOp[] = {
- { "match", SQLITE_INDEX_CONSTRAINT_MATCH },
- { "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
- { "like", SQLITE_INDEX_CONSTRAINT_LIKE },
- { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
- };
- ExprList *pList;
- Expr *pCol; /* Column reference */
- int i;
+ unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */
+ Expr **ppLeft, /* Column expression to left of MATCH/op2 */
+ Expr **ppRight /* Expression to left of MATCH/op2 */
+){
+ if( pExpr->op==TK_FUNCTION ){
+ static const struct Op2 {
+ const char *zOp;
+ unsigned char eOp2;
+ } aOp[] = {
+ { "match", SQLITE_INDEX_CONSTRAINT_MATCH },
+ { "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
+ { "like", SQLITE_INDEX_CONSTRAINT_LIKE },
+ { "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
+ };
+ ExprList *pList;
+ Expr *pCol; /* Column reference */
+ int i;
- if( pExpr->op!=TK_FUNCTION ){
- return 0;
- }
- pList = pExpr->x.pList;
- if( pList==0 || pList->nExpr!=2 ){
- return 0;
- }
- pCol = pList->a[1].pExpr;
- if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
- return 0;
- }
- for(i=0; i<ArraySize(aOp); i++){
- if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
- *peOp2 = aOp[i].eOp2;
- return 1;
+ pList = pExpr->x.pList;
+ if( pList==0 || pList->nExpr!=2 ){
+ return 0;
+ }
+ pCol = pList->a[1].pExpr;
+ if( pCol->op!=TK_COLUMN || !IsVirtual(pCol->pTab) ){
+ return 0;
}
+ for(i=0; i<ArraySize(aOp); i++){
+ if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
+ *peOp2 = aOp[i].eOp2;
+ *ppRight = pList->a[0].pExpr;
+ *ppLeft = pCol;
+ return 1;
+ }
+ }
+ }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
+ int res = 0;
+ Expr *pLeft = pExpr->pLeft;
+ Expr *pRight = pExpr->pRight;
+ if( pLeft->op==TK_COLUMN && IsVirtual(pLeft->pTab) ){
+ res++;
+ }
+ if( pRight && pRight->op==TK_COLUMN && IsVirtual(pRight->pTab) ){
+ res++;
+ SWAP(Expr*, pLeft, pRight);
+ }
+ *ppLeft = pLeft;
+ *ppRight = pRight;
+ if( pExpr->op==TK_NE ) *peOp2 = SQLITE_INDEX_CONSTRAINT_NE;
+ if( pExpr->op==TK_ISNOT ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOT;
+ if( pExpr->op==TK_NOTNULL ) *peOp2 = SQLITE_INDEX_CONSTRAINT_ISNOTNULL;
+ return res;
}
return 0;
}
@@ -130555,7 +132016,7 @@ static void exprAnalyzeOrTerm(
for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
assert( pAndTerm->pExpr );
if( allowedOp(pAndTerm->pExpr->op)
- || pAndTerm->eOperator==WO_MATCH
+ || pAndTerm->eOperator==WO_AUX
){
b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor);
}
@@ -130757,7 +132218,6 @@ static void exprAnalyzeOrTerm(
static int termIsEquivalence(Parse *pParse, Expr *pExpr){
char aff1, aff2;
CollSeq *pColl;
- const char *zColl1, *zColl2;
if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
@@ -130770,11 +132230,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
}
pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
- pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
- zColl1 = pColl ? pColl->zName : 0;
- pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
- zColl2 = pColl ? pColl->zName : 0;
- return sqlite3_stricmp(zColl1, zColl2)==0;
+ return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight);
}
/*
@@ -130903,7 +132359,7 @@ static void exprAnalyze(
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
- unsigned char eOp2; /* op2 value for LIKE/REGEXP/GLOB */
+ unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */
int nLeft; /* Number of elements on left side vector */
if( db->mallocFailed ){
@@ -131137,41 +132593,46 @@ static void exprAnalyze(
#endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
#ifndef SQLITE_OMIT_VIRTUALTABLE
- /* Add a WO_MATCH auxiliary term to the constraint set if the
- ** current expression is of the form: column MATCH expr.
+ /* Add a WO_AUX auxiliary term to the constraint set if the
+ ** current expression is of the form "column OP expr" where OP
+ ** is an operator that gets passed into virtual tables but which is
+ ** not normally optimized for ordinary tables. In other words, OP
+ ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL.
** This information is used by the xBestIndex methods of
** virtual tables. The native query optimizer does not attempt
** to do anything with MATCH functions.
*/
- if( pWC->op==TK_AND && isMatchOfColumn(pExpr, &eOp2) ){
- int idxNew;
- Expr *pRight, *pLeft;
- WhereTerm *pNewTerm;
- Bitmask prereqColumn, prereqExpr;
-
- pRight = pExpr->x.pList->a[0].pExpr;
- pLeft = pExpr->x.pList->a[1].pExpr;
- prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
- prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
- if( (prereqExpr & prereqColumn)==0 ){
- Expr *pNewExpr;
- pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
- 0, sqlite3ExprDup(db, pRight, 0));
- if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
- ExprSetProperty(pNewExpr, EP_FromJoin);
+ if( pWC->op==TK_AND ){
+ Expr *pRight = 0, *pLeft = 0;
+ int res = isAuxiliaryVtabOperator(pExpr, &eOp2, &pLeft, &pRight);
+ while( res-- > 0 ){
+ int idxNew;
+ WhereTerm *pNewTerm;
+ Bitmask prereqColumn, prereqExpr;
+
+ prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight);
+ prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft);
+ if( (prereqExpr & prereqColumn)==0 ){
+ Expr *pNewExpr;
+ pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
+ 0, sqlite3ExprDup(db, pRight, 0));
+ if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
+ ExprSetProperty(pNewExpr, EP_FromJoin);
+ }
+ idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
+ testcase( idxNew==0 );
+ pNewTerm = &pWC->a[idxNew];
+ pNewTerm->prereqRight = prereqExpr;
+ pNewTerm->leftCursor = pLeft->iTable;
+ pNewTerm->u.leftColumn = pLeft->iColumn;
+ pNewTerm->eOperator = WO_AUX;
+ pNewTerm->eMatchOp = eOp2;
+ markTermAsChild(pWC, idxNew, idxTerm);
+ pTerm = &pWC->a[idxTerm];
+ pTerm->wtFlags |= TERM_COPIED;
+ pNewTerm->prereqAll = pTerm->prereqAll;
}
- idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
- testcase( idxNew==0 );
- pNewTerm = &pWC->a[idxNew];
- pNewTerm->prereqRight = prereqExpr;
- pNewTerm->leftCursor = pLeft->iTable;
- pNewTerm->u.leftColumn = pLeft->iColumn;
- pNewTerm->eOperator = WO_MATCH;
- pNewTerm->eMatchOp = eOp2;
- markTermAsChild(pWC, idxNew, idxTerm);
- pTerm = &pWC->a[idxTerm];
- pTerm->wtFlags |= TERM_COPIED;
- pNewTerm->prereqAll = pTerm->prereqAll;
+ SWAP(Expr*, pLeft, pRight);
}
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -131466,6 +132927,21 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
/* #include "sqliteInt.h" */
/* #include "whereInt.h" */
+/*
+** Extra information appended to the end of sqlite3_index_info but not
+** visible to the xBestIndex function, at least not directly. The
+** sqlite3_vtab_collation() interface knows how to reach it, however.
+**
+** This object is not an API and can be changed from one release to the
+** next. As long as allocateIndexInfo() and sqlite3_vtab_collation()
+** agree on the structure, all will be well.
+*/
+typedef struct HiddenIndexInfo HiddenIndexInfo;
+struct HiddenIndexInfo {
+ WhereClause *pWC; /* The Where clause being analyzed */
+ Parse *pParse; /* The parsing context */
+};
+
/* Forward declaration of methods */
static int whereLoopResize(sqlite3*, WhereLoop*, int);
@@ -131850,8 +133326,8 @@ static int findIndexCol(
&& p->iColumn==pIdx->aiColumn[iCol]
&& p->iTable==iBase
){
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
- if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
+ CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr);
+ if( 0==sqlite3StrICmp(pColl->zName, zColl) ){
return i;
}
}
@@ -132288,11 +133764,11 @@ end_auto_index_create:
** by passing the pointer returned by this function to sqlite3_free().
*/
static sqlite3_index_info *allocateIndexInfo(
- Parse *pParse,
- WhereClause *pWC,
+ Parse *pParse, /* The parsing context */
+ WhereClause *pWC, /* The WHERE clause being analyzed */
Bitmask mUnusable, /* Ignore terms with these prereqs */
- struct SrcList_item *pSrc,
- ExprList *pOrderBy,
+ struct SrcList_item *pSrc, /* The FROM clause term that is the vtab */
+ ExprList *pOrderBy, /* The ORDER BY clause */
u16 *pmNoOmit /* Mask of terms not to omit */
){
int i, j;
@@ -132300,6 +133776,7 @@ static sqlite3_index_info *allocateIndexInfo(
struct sqlite3_index_constraint *pIdxCons;
struct sqlite3_index_orderby *pIdxOrderBy;
struct sqlite3_index_constraint_usage *pUsage;
+ struct HiddenIndexInfo *pHidden;
WhereTerm *pTerm;
int nOrderBy;
sqlite3_index_info *pIdxInfo;
@@ -132315,7 +133792,7 @@ static sqlite3_index_info *allocateIndexInfo(
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_IS );
testcase( pTerm->eOperator & WO_ALL );
- if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
+ if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
assert( pTerm->u.leftColumn>=(-1) );
nTerm++;
@@ -132341,7 +133818,7 @@ static sqlite3_index_info *allocateIndexInfo(
*/
pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo)
+ (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm
- + sizeof(*pIdxOrderBy)*nOrderBy );
+ + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) );
if( pIdxInfo==0 ){
sqlite3ErrorMsg(pParse, "out of memory");
return 0;
@@ -132352,7 +133829,8 @@ static sqlite3_index_info *allocateIndexInfo(
** changing them. We have to do some funky casting in order to
** initialize those fields.
*/
- pIdxCons = (struct sqlite3_index_constraint*)&pIdxInfo[1];
+ pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1];
+ pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1];
pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm];
pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy];
*(int*)&pIdxInfo->nConstraint = nTerm;
@@ -132362,8 +133840,10 @@ static sqlite3_index_info *allocateIndexInfo(
*(struct sqlite3_index_constraint_usage**)&pIdxInfo->aConstraintUsage =
pUsage;
+ pHidden->pWC = pWC;
+ pHidden->pParse = pParse;
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
- u8 op;
+ u16 op;
if( pTerm->leftCursor != pSrc->iCursor ) continue;
if( pTerm->prereqRight & mUnusable ) continue;
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
@@ -132371,34 +133851,40 @@ static sqlite3_index_info *allocateIndexInfo(
testcase( pTerm->eOperator & WO_IS );
testcase( pTerm->eOperator & WO_ISNULL );
testcase( pTerm->eOperator & WO_ALL );
- if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
+ if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
assert( pTerm->u.leftColumn>=(-1) );
pIdxCons[j].iColumn = pTerm->u.leftColumn;
pIdxCons[j].iTermOffset = i;
- op = (u8)pTerm->eOperator & WO_ALL;
+ op = pTerm->eOperator & WO_ALL;
if( op==WO_IN ) op = WO_EQ;
- if( op==WO_MATCH ){
- op = pTerm->eMatchOp;
- }
- pIdxCons[j].op = op;
- /* The direct assignment in the previous line is possible only because
- ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
- ** following asserts verify this fact. */
- assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
- assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
- assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
- assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
- 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;
+ if( op==WO_AUX ){
+ pIdxCons[j].op = pTerm->eMatchOp;
+ }else if( op & (WO_ISNULL|WO_IS) ){
+ if( op==WO_ISNULL ){
+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_ISNULL;
+ }else{
+ pIdxCons[j].op = SQLITE_INDEX_CONSTRAINT_IS;
+ }
+ }else{
+ pIdxCons[j].op = (u8)op;
+ /* The direct assignment in the previous line is possible only because
+ ** the WO_ and SQLITE_INDEX_CONSTRAINT_ codes are identical. The
+ ** following asserts verify this fact. */
+ assert( WO_EQ==SQLITE_INDEX_CONSTRAINT_EQ );
+ assert( WO_LT==SQLITE_INDEX_CONSTRAINT_LT );
+ assert( WO_LE==SQLITE_INDEX_CONSTRAINT_LE );
+ assert( WO_GT==SQLITE_INDEX_CONSTRAINT_GT );
+ assert( WO_GE==SQLITE_INDEX_CONSTRAINT_GE );
+ assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) );
+
+ 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++;
@@ -133304,40 +134790,40 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
- if( ALWAYS(pWInfo) ){
- int i;
- for(i=0; i<pWInfo->nLevel; i++){
- WhereLevel *pLevel = &pWInfo->a[i];
- if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
- sqlite3DbFree(db, pLevel->u.in.aInLoop);
- }
- }
- sqlite3WhereClauseClear(&pWInfo->sWC);
- while( pWInfo->pLoops ){
- WhereLoop *p = pWInfo->pLoops;
- pWInfo->pLoops = p->pNextLoop;
- whereLoopDelete(db, p);
+ int i;
+ assert( pWInfo!=0 );
+ for(i=0; i<pWInfo->nLevel; i++){
+ WhereLevel *pLevel = &pWInfo->a[i];
+ if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
+ sqlite3DbFree(db, pLevel->u.in.aInLoop);
}
- sqlite3DbFreeNN(db, pWInfo);
}
+ sqlite3WhereClauseClear(&pWInfo->sWC);
+ while( pWInfo->pLoops ){
+ WhereLoop *p = pWInfo->pLoops;
+ pWInfo->pLoops = p->pNextLoop;
+ whereLoopDelete(db, p);
+ }
+ sqlite3DbFreeNN(db, pWInfo);
}
/*
** Return TRUE if all of the following are true:
**
** (1) X has the same or lower cost that Y
-** (2) X is a proper subset of Y
-** (3) X skips at least as many columns as Y
-**
-** By "proper subset" we mean that X uses fewer WHERE clause terms
-** than Y and that every WHERE clause term used by X is also used
-** by Y.
+** (2) X uses fewer WHERE clause terms than Y
+** (3) Every WHERE clause term used by X is also used by Y
+** (4) X skips at least as many columns as Y
+** (5) If X is a covering index, than Y is too
**
+** Conditions (2) and (3) mean that X is a "proper subset" of Y.
** If X is a proper subset of Y then Y is a better choice and ought
** to have a lower cost. This routine returns TRUE when that cost
-** relationship is inverted and needs to be adjusted. The third rule
+** relationship is inverted and needs to be adjusted. Constraint (4)
** was added because if X uses skip-scan less than Y it still might
-** deserve a lower cost even if it is a proper subset of Y.
+** deserve a lower cost even if it is a proper subset of Y. Constraint (5)
+** was added because a covering index probably deserves to have a lower cost
+** than a non-covering index even if it is a proper subset.
*/
static int whereLoopCheaperProperSubset(
const WhereLoop *pX, /* First WhereLoop to compare */
@@ -133359,6 +134845,10 @@ static int whereLoopCheaperProperSubset(
}
if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */
}
+ if( (pX->wsFlags&WHERE_IDX_ONLY)!=0
+ && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
+ return 0; /* Constraint (5) */
+ }
return 1; /* All conditions meet */
}
@@ -133897,7 +135387,7 @@ static int whereLoopAddBtreeIndex(
pNew->wsFlags |= WHERE_COLUMN_EQ;
assert( saved_nEq==pNew->u.btree.nEq );
if( iCol==XN_ROWID
- || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
+ || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
){
if( iCol>=0 && pProbe->uniqNotNull==0 ){
pNew->wsFlags |= WHERE_UNQ_WANTED;
@@ -134110,7 +135600,7 @@ static int indexMightHelpWithOrderBy(
}else if( (aColExpr = pIndex->aColExpr)!=0 ){
for(jj=0; jj<pIndex->nKeyCol; jj++){
if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
- if( sqlite3ExprCompare(0, pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
+ if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
return 1;
}
}
@@ -134306,14 +135796,17 @@ static int whereLoopAddBtree(
}
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
- /* Loop over all indices
- */
- for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
+ /* Loop over all indices. If there was an INDEXED BY clause, then only
+ ** consider index pProbe. */
+ for(; rc==SQLITE_OK && pProbe;
+ pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++
+ ){
if( pProbe->pPartIdxWhere!=0
&& !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
testcase( pNew->iTab!=pSrc->iCursor ); /* See ticket [98d973b8f5] */
continue; /* Partial index inappropriate for this query */
}
+ if( pProbe->bNoQuery ) continue;
rSize = pProbe->aiRowLogEst[0];
pNew->u.btree.nEq = 0;
pNew->u.btree.nBtm = 0;
@@ -134418,10 +135911,6 @@ static int whereLoopAddBtree(
pBuilder->nRecValid = 0;
pBuilder->pRec = 0;
#endif
-
- /* If there was an INDEXED BY clause, then only that one index is
- ** considered. */
- if( pSrc->pIBIndex ) break;
}
return rc;
}
@@ -134576,6 +136065,27 @@ static int whereLoopAddVirtualOne(
return rc;
}
+/*
+** If this function is invoked from within an xBestIndex() callback, it
+** returns a pointer to a buffer containing the name of the collation
+** sequence associated with element iCons of the sqlite3_index_info.aConstraint
+** array. Or, if iCons is out of range or there is no active xBestIndex
+** call, return NULL.
+*/
+SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){
+ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
+ const char *zRet = 0;
+ if( iCons>=0 && iCons<pIdxInfo->nConstraint ){
+ CollSeq *pC = 0;
+ int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset;
+ Expr *pX = pHidden->pWC->a[iTerm].pExpr;
+ if( pX->pLeft ){
+ pC = sqlite3BinaryCompareCollSeq(pHidden->pParse, pX->pLeft, pX->pRight);
+ }
+ zRet = (pC ? pC->zName : "BINARY");
+ }
+ return zRet;
+}
/*
** Add all WhereLoop objects for a table of the join identified by
@@ -135020,14 +136530,10 @@ static i8 wherePathSatisfiesOrderBy(
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);
- if( !pColl ) pColl = db->pDfltColl;
- z1 = pColl->zName;
- pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
- if( !pColl ) pColl = db->pDfltColl;
- z2 = pColl->zName;
- if( sqlite3StrICmp(z1, z2)!=0 ) continue;
+ if( sqlite3ExprCollSeqMatch(pWInfo->pParse,
+ pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){
+ continue;
+ }
testcase( pTerm->pExpr->op==TK_IS );
}
obSat |= MASKBIT(i);
@@ -135099,7 +136605,7 @@ static i8 wherePathSatisfiesOrderBy(
if( pIndex ){
iColumn = pIndex->aiColumn[j];
revIdx = pIndex->aSortOrder[j];
- if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
+ if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID;
}else{
iColumn = XN_ROWID;
revIdx = 0;
@@ -135126,19 +136632,18 @@ static i8 wherePathSatisfiesOrderBy(
testcase( wctrlFlags & WHERE_GROUPBY );
testcase( wctrlFlags & WHERE_DISTINCTBY );
if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
- if( iColumn>=(-1) ){
+ if( iColumn>=XN_ROWID ){
if( pOBExpr->op!=TK_COLUMN ) continue;
if( pOBExpr->iTable!=iCur ) continue;
if( pOBExpr->iColumn!=iColumn ) continue;
}else{
- if( sqlite3ExprCompare(0,
- pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){
+ Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr;
+ if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){
continue;
}
}
- if( iColumn>=0 ){
- pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
- if( !pColl ) pColl = db->pDfltColl;
+ if( iColumn!=XN_ROWID ){
+ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
}
pLoop->u.btree.nIdxCol = j+1;
@@ -135775,6 +137280,7 @@ static int exprIsDeterministic(Expr *p){
memset(&w, 0, sizeof(w));
w.eCode = 1;
w.xExprCallback = exprNodeIsDeterministic;
+ w.xSelectCallback = sqlite3SelectWalkFail;
sqlite3WalkExpr(&w, p);
return w.eCode;
}
@@ -135984,37 +137490,38 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
if( wctrlFlags & WHERE_WANT_DISTINCT ){
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}
- }
-
- /* Assign a bit from the bitmask to every term in the FROM clause.
- **
- ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
- **
- ** The rule of the previous sentence ensures thta if X is the bitmask for
- ** a table T, then X-1 is the bitmask for all other tables to the left of T.
- ** Knowing the bitmask for all tables to the left of a left join is
- ** important. Ticket #3015.
- **
- ** Note that bitmasks are created for all pTabList->nSrc tables in
- ** pTabList, not just the first nTabList tables. nTabList is normally
- ** equal to pTabList->nSrc but might be shortened to 1 if the
- ** WHERE_OR_SUBCLAUSE flag is set.
- */
- for(ii=0; ii<pTabList->nSrc; ii++){
- createMask(pMaskSet, pTabList->a[ii].iCursor);
- sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
- }
-#ifdef SQLITE_DEBUG
- {
- Bitmask mx = 0;
- for(ii=0; ii<pTabList->nSrc; ii++){
- Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
- assert( m>=mx );
- mx = m;
+ }else{
+ /* Assign a bit from the bitmask to every term in the FROM clause.
+ **
+ ** The N-th term of the FROM clause is assigned a bitmask of 1<<N.
+ **
+ ** The rule of the previous sentence ensures thta if X is the bitmask for
+ ** a table T, then X-1 is the bitmask for all other tables to the left of T.
+ ** Knowing the bitmask for all tables to the left of a left join is
+ ** important. Ticket #3015.
+ **
+ ** Note that bitmasks are created for all pTabList->nSrc tables in
+ ** pTabList, not just the first nTabList tables. nTabList is normally
+ ** equal to pTabList->nSrc but might be shortened to 1 if the
+ ** WHERE_OR_SUBCLAUSE flag is set.
+ */
+ ii = 0;
+ do{
+ createMask(pMaskSet, pTabList->a[ii].iCursor);
+ sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC);
+ }while( (++ii)<pTabList->nSrc );
+ #ifdef SQLITE_DEBUG
+ {
+ Bitmask mx = 0;
+ for(ii=0; ii<pTabList->nSrc; ii++){
+ Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor);
+ assert( m>=mx );
+ mx = m;
+ }
}
+ #endif
}
-#endif
-
+
/* Analyze all of the subexpressions. */
sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
if( db->mallocFailed ) goto whereBeginError;
@@ -136119,35 +137626,80 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
}
}
#endif
- /* Attempt to omit tables from the join that do not effect the result */
+
+ /* Attempt to omit tables from the join that do not affect the result.
+ ** For a table to not affect the result, the following must be true:
+ **
+ ** 1) The query must not be an aggregate.
+ ** 2) The table must be the RHS of a LEFT JOIN.
+ ** 3) Either the query must be DISTINCT, or else the ON or USING clause
+ ** must contain a constraint that limits the scan of the table to
+ ** at most a single row.
+ ** 4) The table must not be referenced by any part of the query apart
+ ** from its own USING or ON clause.
+ **
+ ** For example, given:
+ **
+ ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
+ ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
+ ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
+ **
+ ** then table t2 can be omitted from the following:
+ **
+ ** SELECT v1, v3 FROM t1
+ ** LEFT JOIN t2 USING (t1.ipk=t2.ipk)
+ ** LEFT JOIN t3 USING (t1.ipk=t3.ipk)
+ **
+ ** or from:
+ **
+ ** SELECT DISTINCT v1, v3 FROM t1
+ ** LEFT JOIN t2
+ ** LEFT JOIN t3 USING (t1.ipk=t3.ipk)
+ */
+ notReady = ~(Bitmask)0;
if( pWInfo->nLevel>=2
- && pResultSet!=0
+ && pResultSet!=0 /* guarantees condition (1) above */
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
){
+ int i;
Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
if( sWLB.pOrderBy ){
tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
}
- while( pWInfo->nLevel>=2 ){
+ for(i=pWInfo->nLevel-1; i>=1; i--){
WhereTerm *pTerm, *pEnd;
- pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop;
- if( (pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 ) break;
+ struct SrcList_item *pItem;
+ pLoop = pWInfo->a[i].pWLoop;
+ pItem = &pWInfo->pTabList->a[pLoop->iTab];
+ if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
&& (pLoop->wsFlags & WHERE_ONEROW)==0
){
- break;
+ continue;
}
- if( (tabUsed & pLoop->maskSelf)!=0 ) break;
+ if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
- if( (pTerm->prereqAll & pLoop->maskSelf)!=0
- && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
- ){
- break;
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
+ if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
+ || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
+ ){
+ break;
+ }
}
}
- if( pTerm<pEnd ) break;
+ if( pTerm<pEnd ) continue;
WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
+ notReady &= ~pLoop->maskSelf;
+ for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
+ pTerm->wtFlags |= TERM_CODED;
+ }
+ }
+ if( i!=pWInfo->nLevel-1 ){
+ int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
+ memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
+ }
pWInfo->nLevel--;
nTabList--;
}
@@ -136157,15 +137709,32 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
/* If the caller is an UPDATE or DELETE statement that is requesting
** to use a one-pass algorithm, determine if this is appropriate.
+ **
+ ** A one-pass approach can be used if the caller has requested one
+ ** and either (a) the scan visits at most one row or (b) each
+ ** of the following are true:
+ **
+ ** * the caller has indicated that a one-pass approach can be used
+ ** with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and
+ ** * the table is not a virtual table, and
+ ** * either the scan does not use the OR optimization or the caller
+ ** is a DELETE operation (WHERE_DUPLICATES_OK is only specified
+ ** for DELETE).
+ **
+ ** The last qualification is because an UPDATE statement uses
+ ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can
+ ** use a one-pass approach, and this is not set accurately for scans
+ ** that use the OR optimization.
*/
assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
- if( bOnerow
- || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0
- && 0==(wsFlags & WHERE_VIRTUALTABLE))
- ){
+ if( bOnerow || (
+ 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
+ && 0==(wsFlags & WHERE_VIRTUALTABLE)
+ && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
+ )){
pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
@@ -136237,7 +137806,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
Index *pIx = pLoop->u.btree.pIndex;
int iIndexCur;
int op = OP_OpenRead;
- /* iAuxArg is always set if to a positive value if ONEPASS is possible */
+ /* iAuxArg is always set to a positive value if ONEPASS is possible */
assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
&& (wctrlFlags & WHERE_OR_SUBCLAUSE)!=0
@@ -136302,7 +137871,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** loop below generates code for a single nested loop of the VM
** program.
*/
- notReady = ~(Bitmask)0;
for(ii=0; ii<nTabList; ii++){
int addrExplain;
int wsFlags;
@@ -136366,6 +137934,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
Index *pIdx;
int n;
if( pWInfo->eDistinct==WHERE_DISTINCT_ORDERED
+ && i==pWInfo->nLevel-1 /* Ticket [ef9318757b152e3] 2017-10-21 */
&& (pLoop->wsFlags & WHERE_INDEXED)!=0
&& (pIdx = pLoop->u.btree.pIndex)->hasStat1
&& (n = pLoop->u.btree.nIdxCol)>0
@@ -136432,7 +138001,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 );
if( (ws & WHERE_IDX_ONLY)==0 ){
- sqlite3VdbeAddOp1(v, OP_NullRow, pTabList->a[i].iCursor);
+ assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
+ sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
}
if( (ws & WHERE_INDEXED)
|| ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx)
@@ -136501,7 +138071,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
pOp = sqlite3VdbeGetOp(v, k);
for(; k<last; k++, pOp++){
if( pOp->p1!=pLevel->iTabCur ) continue;
- if( pOp->opcode==OP_Column ){
+ if( pOp->opcode==OP_Column
+#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+ || pOp->opcode==OP_Offset
+#endif
+ ){
int x = pOp->p2;
assert( pIdx->pTable==pTab );
if( !HasRowid(pTab) ){
@@ -136601,15 +138175,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
#define YYMALLOCARGTYPE u64
/*
-** An instance of this structure holds information about the
-** LIMIT clause of a SELECT statement.
-*/
-struct LimitVal {
- Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */
- Expr *pOffset; /* The OFFSET expression. NULL if there is none */
-};
-
-/*
** 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
@@ -136652,20 +138217,12 @@ static void disableLookaside(Parse *pParse){
}
}
- /* This is a utility routine used to set the ExprSpan.zStart and
- ** ExprSpan.zEnd values of pOut so that the span covers the complete
- ** range of text beginning with pStart and going to the end of pEnd.
- */
- static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
- pOut->zStart = pStart->z;
- pOut->zEnd = &pEnd->z[pEnd->n];
- }
/* Construct a new Expr object from a single identifier. Use the
** new Expr to populate pOut. Set the span of pOut to be the identifier
** that created the expression.
*/
- static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
+ static Expr *tokenExpr(Parse *pParse, int op, Token t){
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
if( p ){
memset(p, 0, sizeof(Expr));
@@ -136683,45 +138240,9 @@ static void disableLookaside(Parse *pParse){
p->nHeight = 1;
#endif
}
- pOut->pExpr = p;
- pOut->zStart = t.z;
- pOut->zEnd = &t.z[t.n];
- }
-
- /* This routine constructs a binary expression node out of two ExprSpan
- ** objects and uses the result to populate a new ExprSpan object.
- */
- static void spanBinaryExpr(
- Parse *pParse, /* The parsing context. Errors accumulate here */
- int op, /* The binary operation */
- ExprSpan *pLeft, /* The left operand, and output */
- ExprSpan *pRight /* The right operand */
- ){
- pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr);
- pLeft->zEnd = pRight->zEnd;
- }
-
- /* If doNot is true, then add a TK_NOT Expr-node wrapper around the
- ** outside of *ppExpr.
- */
- static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
- if( doNot ){
- pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0);
- }
+ return p;
}
- /* Construct an expression node for a unary postfix operator
- */
- static void spanUnaryPostfix(
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand, and output */
- Token *pPostOp /* The operand token for setting the span */
- ){
- pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
- pOperand->zEnd = &pPostOp->z[pPostOp->n];
- }
-
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
** unary TK_ISNULL or TK_NOTNULL expression. */
static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
@@ -136733,20 +138254,6 @@ static void disableLookaside(Parse *pParse){
}
}
- /* Construct an expression node for a unary prefix operator
- */
- static void spanUnaryPrefix(
- ExprSpan *pOut, /* Write the new expression node here */
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
- Token *pPreOp /* The operand token for setting the span */
- ){
- pOut->zStart = pPreOp->z;
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
- pOut->zEnd = pOperand->zEnd;
- }
-
/* Add a single new term to an ExprList that is used to store a
** list of identifiers. Report an error if the ID list contains
** a COLLATE clause or an ASC or DESC keyword, except ignore the
@@ -136815,38 +138322,39 @@ static void disableLookaside(Parse *pParse){
** defined, then do no error processing.
** YYNSTATE the combined number of states.
** YYNRULE the number of rules in the grammar
+** YYNTOKEN Number of terminal symbols
** YY_MAX_SHIFT Maximum value for shift actions
** YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
** YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
-** YY_MIN_REDUCE Maximum value for reduce actions
** YY_ERROR_ACTION The yy_action[] code for syntax error
** YY_ACCEPT_ACTION The yy_action[] code for accept
** YY_NO_ACTION The yy_action[] code for no-op
+** YY_MIN_REDUCE Minimum value for reduce actions
+** YY_MAX_REDUCE Maximum value for reduce actions
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned char
-#define YYNOCODE 252
+#define YYNOCODE 253
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 69
+#define YYWILDCARD 83
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- Expr* yy72;
- TriggerStep* yy145;
- ExprList* yy148;
- SrcList* yy185;
- ExprSpan yy190;
- int yy194;
- Select* yy243;
- IdList* yy254;
- With* yy285;
- struct TrigEvent yy332;
- struct LimitVal yy354;
- struct {int value; int mask;} yy497;
+ int yy4;
+ struct TrigEvent yy90;
+ TriggerStep* yy203;
+ struct {int value; int mask;} yy215;
+ SrcList* yy259;
+ Expr* yy314;
+ ExprList* yy322;
+ const char* yy336;
+ IdList* yy384;
+ Select* yy387;
+ With* yy451;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -136856,16 +138364,17 @@ typedef union {
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
#define YYFALLBACK 1
-#define YYNSTATE 455
-#define YYNRULE 329
-#define YY_MAX_SHIFT 454
-#define YY_MIN_SHIFTREDUCE 664
-#define YY_MAX_SHIFTREDUCE 992
-#define YY_MIN_REDUCE 993
-#define YY_MAX_REDUCE 1321
-#define YY_ERROR_ACTION 1322
-#define YY_ACCEPT_ACTION 1323
-#define YY_NO_ACTION 1324
+#define YYNSTATE 466
+#define YYNRULE 330
+#define YYNTOKEN 143
+#define YY_MAX_SHIFT 465
+#define YY_MIN_SHIFTREDUCE 675
+#define YY_MAX_SHIFTREDUCE 1004
+#define YY_ERROR_ACTION 1005
+#define YY_ACCEPT_ACTION 1006
+#define YY_NO_ACTION 1007
+#define YY_MIN_REDUCE 1008
+#define YY_MAX_REDUCE 1337
/************* End control #defines *******************************************/
/* Define the yytestcase() macro to be a no-op if is not already defined
@@ -136895,9 +138404,6 @@ typedef union {
** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE.
**
-** 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.
@@ -136905,25 +138411,22 @@ typedef union {
** N == YY_NO_ACTION No such action. Denotes unused
** slots in the yy_action[] table.
**
+** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE
+** and YY_MAX_REDUCE
+**
** The action table is constructed as a single large table named yy_action[].
** Given state S and lookahead X, the action is computed as either:
**
** (A) N = yy_action[ yy_shift_ofst[S] + X ]
** (B) N = yy_default[S]
**
-** 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 (A) formula is preferred. The B formula is used instead if
+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X.
**
** 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
-** YY_SHIFT_USE_DFLT.
+** the yy_shift_ofst[] array.
**
** The following are the tables generated in this section:
**
@@ -136937,463 +138440,474 @@ typedef union {
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (1565)
+#define YY_ACTTAB_COUNT (1541)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 324, 410, 342, 747, 747, 203, 939, 353, 969, 98,
- /* 10 */ 98, 98, 98, 91, 96, 96, 96, 96, 95, 95,
- /* 20 */ 94, 94, 94, 93, 350, 1323, 155, 155, 2, 808,
- /* 30 */ 971, 971, 98, 98, 98, 98, 20, 96, 96, 96,
- /* 40 */ 96, 95, 95, 94, 94, 94, 93, 350, 92, 89,
- /* 50 */ 178, 99, 100, 90, 847, 850, 839, 839, 97, 97,
- /* 60 */ 98, 98, 98, 98, 350, 96, 96, 96, 96, 95,
- /* 70 */ 95, 94, 94, 94, 93, 350, 324, 339, 969, 262,
- /* 80 */ 364, 251, 212, 169, 287, 404, 282, 403, 199, 786,
- /* 90 */ 242, 411, 21, 950, 378, 280, 93, 350, 787, 95,
- /* 100 */ 95, 94, 94, 94, 93, 350, 971, 971, 96, 96,
- /* 110 */ 96, 96, 95, 95, 94, 94, 94, 93, 350, 808,
- /* 120 */ 328, 242, 411, 1235, 826, 1235, 132, 99, 100, 90,
- /* 130 */ 847, 850, 839, 839, 97, 97, 98, 98, 98, 98,
- /* 140 */ 449, 96, 96, 96, 96, 95, 95, 94, 94, 94,
- /* 150 */ 93, 350, 324, 819, 348, 347, 120, 818, 120, 75,
- /* 160 */ 52, 52, 950, 951, 952, 1084, 977, 146, 360, 262,
- /* 170 */ 369, 261, 950, 975, 954, 976, 92, 89, 178, 370,
- /* 180 */ 230, 370, 971, 971, 1141, 360, 359, 101, 818, 818,
- /* 190 */ 820, 383, 24, 1286, 380, 427, 412, 368, 978, 379,
- /* 200 */ 978, 1032, 324, 99, 100, 90, 847, 850, 839, 839,
- /* 210 */ 97, 97, 98, 98, 98, 98, 372, 96, 96, 96,
- /* 220 */ 96, 95, 95, 94, 94, 94, 93, 350, 950, 132,
- /* 230 */ 890, 449, 971, 971, 890, 60, 94, 94, 94, 93,
- /* 240 */ 350, 950, 951, 952, 954, 103, 360, 950, 384, 333,
- /* 250 */ 697, 52, 52, 99, 100, 90, 847, 850, 839, 839,
- /* 260 */ 97, 97, 98, 98, 98, 98, 1022, 96, 96, 96,
- /* 270 */ 96, 95, 95, 94, 94, 94, 93, 350, 324, 454,
- /* 280 */ 995, 449, 227, 61, 157, 243, 343, 114, 1025, 1211,
- /* 290 */ 147, 826, 950, 372, 1071, 950, 319, 950, 951, 952,
- /* 300 */ 194, 10, 10, 401, 398, 397, 1211, 1213, 971, 971,
- /* 310 */ 757, 171, 170, 157, 396, 336, 950, 951, 952, 697,
- /* 320 */ 819, 310, 153, 950, 818, 320, 82, 23, 80, 99,
- /* 330 */ 100, 90, 847, 850, 839, 839, 97, 97, 98, 98,
- /* 340 */ 98, 98, 888, 96, 96, 96, 96, 95, 95, 94,
- /* 350 */ 94, 94, 93, 350, 324, 818, 818, 820, 277, 231,
- /* 360 */ 300, 950, 951, 952, 950, 951, 952, 1211, 194, 25,
- /* 370 */ 449, 401, 398, 397, 950, 354, 300, 449, 950, 74,
- /* 380 */ 449, 1, 396, 132, 971, 971, 950, 224, 224, 808,
- /* 390 */ 10, 10, 950, 951, 952, 1290, 132, 52, 52, 414,
- /* 400 */ 52, 52, 1063, 1063, 338, 99, 100, 90, 847, 850,
- /* 410 */ 839, 839, 97, 97, 98, 98, 98, 98, 1114, 96,
- /* 420 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 350,
- /* 430 */ 324, 1113, 427, 417, 701, 427, 426, 1260, 1260, 262,
- /* 440 */ 369, 261, 950, 950, 951, 952, 752, 950, 951, 952,
- /* 450 */ 449, 751, 449, 1058, 1037, 950, 951, 952, 442, 706,
- /* 460 */ 971, 971, 1058, 393, 92, 89, 178, 446, 446, 446,
- /* 470 */ 51, 51, 52, 52, 438, 773, 1024, 92, 89, 178,
- /* 480 */ 172, 99, 100, 90, 847, 850, 839, 839, 97, 97,
- /* 490 */ 98, 98, 98, 98, 198, 96, 96, 96, 96, 95,
- /* 500 */ 95, 94, 94, 94, 93, 350, 324, 427, 407, 909,
- /* 510 */ 694, 950, 951, 952, 92, 89, 178, 224, 224, 157,
- /* 520 */ 241, 221, 418, 299, 771, 910, 415, 374, 449, 414,
- /* 530 */ 58, 323, 1061, 1061, 1242, 378, 971, 971, 378, 772,
- /* 540 */ 448, 911, 362, 735, 296, 681, 9, 9, 52, 52,
- /* 550 */ 234, 329, 234, 256, 416, 736, 280, 99, 100, 90,
- /* 560 */ 847, 850, 839, 839, 97, 97, 98, 98, 98, 98,
- /* 570 */ 449, 96, 96, 96, 96, 95, 95, 94, 94, 94,
- /* 580 */ 93, 350, 324, 422, 72, 449, 827, 120, 367, 449,
- /* 590 */ 10, 10, 5, 301, 203, 449, 177, 969, 253, 419,
- /* 600 */ 255, 771, 200, 175, 233, 10, 10, 836, 836, 36,
- /* 610 */ 36, 1289, 971, 971, 724, 37, 37, 348, 347, 424,
- /* 620 */ 203, 260, 771, 969, 232, 930, 1316, 870, 337, 1316,
- /* 630 */ 421, 848, 851, 99, 100, 90, 847, 850, 839, 839,
- /* 640 */ 97, 97, 98, 98, 98, 98, 268, 96, 96, 96,
- /* 650 */ 96, 95, 95, 94, 94, 94, 93, 350, 324, 840,
- /* 660 */ 449, 978, 813, 978, 1200, 449, 909, 969, 715, 349,
- /* 670 */ 349, 349, 928, 177, 449, 930, 1317, 254, 198, 1317,
- /* 680 */ 12, 12, 910, 402, 449, 27, 27, 250, 971, 971,
- /* 690 */ 118, 716, 162, 969, 38, 38, 268, 176, 911, 771,
- /* 700 */ 432, 1265, 939, 353, 39, 39, 316, 991, 324, 99,
- /* 710 */ 100, 90, 847, 850, 839, 839, 97, 97, 98, 98,
- /* 720 */ 98, 98, 928, 96, 96, 96, 96, 95, 95, 94,
- /* 730 */ 94, 94, 93, 350, 449, 329, 449, 357, 971, 971,
- /* 740 */ 1041, 316, 929, 340, 893, 893, 386, 669, 670, 671,
- /* 750 */ 275, 1318, 317, 992, 40, 40, 41, 41, 268, 99,
- /* 760 */ 100, 90, 847, 850, 839, 839, 97, 97, 98, 98,
- /* 770 */ 98, 98, 449, 96, 96, 96, 96, 95, 95, 94,
- /* 780 */ 94, 94, 93, 350, 324, 449, 355, 449, 992, 449,
- /* 790 */ 1016, 330, 42, 42, 786, 270, 449, 273, 449, 228,
- /* 800 */ 449, 298, 449, 787, 449, 28, 28, 29, 29, 31,
- /* 810 */ 31, 449, 1141, 449, 971, 971, 43, 43, 44, 44,
- /* 820 */ 45, 45, 11, 11, 46, 46, 887, 78, 887, 268,
- /* 830 */ 268, 105, 105, 47, 47, 99, 100, 90, 847, 850,
- /* 840 */ 839, 839, 97, 97, 98, 98, 98, 98, 449, 96,
- /* 850 */ 96, 96, 96, 95, 95, 94, 94, 94, 93, 350,
- /* 860 */ 324, 449, 117, 449, 1073, 158, 449, 691, 48, 48,
- /* 870 */ 229, 1241, 449, 1250, 449, 414, 449, 334, 449, 245,
- /* 880 */ 449, 33, 33, 49, 49, 449, 50, 50, 246, 1141,
- /* 890 */ 971, 971, 34, 34, 122, 122, 123, 123, 124, 124,
- /* 900 */ 56, 56, 268, 81, 249, 35, 35, 197, 196, 195,
- /* 910 */ 324, 99, 100, 90, 847, 850, 839, 839, 97, 97,
- /* 920 */ 98, 98, 98, 98, 449, 96, 96, 96, 96, 95,
- /* 930 */ 95, 94, 94, 94, 93, 350, 449, 691, 449, 1141,
- /* 940 */ 971, 971, 968, 1207, 106, 106, 268, 1209, 268, 1266,
- /* 950 */ 2, 886, 268, 886, 335, 1040, 53, 53, 107, 107,
- /* 960 */ 324, 99, 100, 90, 847, 850, 839, 839, 97, 97,
- /* 970 */ 98, 98, 98, 98, 449, 96, 96, 96, 96, 95,
- /* 980 */ 95, 94, 94, 94, 93, 350, 449, 1070, 449, 1066,
- /* 990 */ 971, 971, 1039, 267, 108, 108, 445, 330, 331, 133,
- /* 1000 */ 223, 175, 301, 225, 385, 1255, 104, 104, 121, 121,
- /* 1010 */ 324, 99, 88, 90, 847, 850, 839, 839, 97, 97,
- /* 1020 */ 98, 98, 98, 98, 1141, 96, 96, 96, 96, 95,
- /* 1030 */ 95, 94, 94, 94, 93, 350, 449, 346, 449, 167,
- /* 1040 */ 971, 971, 925, 810, 371, 318, 202, 202, 373, 263,
- /* 1050 */ 394, 202, 74, 208, 721, 722, 119, 119, 112, 112,
- /* 1060 */ 324, 406, 100, 90, 847, 850, 839, 839, 97, 97,
- /* 1070 */ 98, 98, 98, 98, 449, 96, 96, 96, 96, 95,
- /* 1080 */ 95, 94, 94, 94, 93, 350, 449, 752, 449, 344,
- /* 1090 */ 971, 971, 751, 278, 111, 111, 74, 714, 713, 704,
- /* 1100 */ 286, 877, 749, 1279, 257, 77, 109, 109, 110, 110,
- /* 1110 */ 1230, 285, 1134, 90, 847, 850, 839, 839, 97, 97,
- /* 1120 */ 98, 98, 98, 98, 1233, 96, 96, 96, 96, 95,
- /* 1130 */ 95, 94, 94, 94, 93, 350, 86, 444, 449, 3,
- /* 1140 */ 1193, 449, 1069, 132, 351, 120, 1013, 86, 444, 780,
- /* 1150 */ 3, 1091, 202, 376, 447, 351, 1229, 120, 55, 55,
- /* 1160 */ 449, 57, 57, 822, 873, 447, 449, 208, 449, 704,
- /* 1170 */ 449, 877, 237, 433, 435, 120, 439, 428, 361, 120,
- /* 1180 */ 54, 54, 132, 449, 433, 826, 52, 52, 26, 26,
- /* 1190 */ 30, 30, 381, 132, 408, 443, 826, 689, 264, 389,
- /* 1200 */ 116, 269, 272, 32, 32, 83, 84, 120, 274, 120,
- /* 1210 */ 120, 276, 85, 351, 451, 450, 83, 84, 818, 1054,
- /* 1220 */ 1038, 427, 429, 85, 351, 451, 450, 120, 120, 818,
- /* 1230 */ 377, 218, 281, 822, 1107, 1140, 86, 444, 409, 3,
- /* 1240 */ 1087, 1098, 430, 431, 351, 302, 303, 1146, 1021, 818,
- /* 1250 */ 818, 820, 821, 19, 447, 1015, 1004, 1003, 1005, 1273,
- /* 1260 */ 818, 818, 820, 821, 19, 289, 159, 291, 293, 7,
- /* 1270 */ 315, 173, 259, 433, 1129, 363, 252, 1232, 375, 1037,
- /* 1280 */ 295, 434, 168, 986, 399, 826, 284, 1204, 1203, 205,
- /* 1290 */ 1276, 308, 1249, 86, 444, 983, 3, 1247, 332, 144,
- /* 1300 */ 130, 351, 72, 135, 59, 83, 84, 756, 137, 365,
- /* 1310 */ 1126, 447, 85, 351, 451, 450, 139, 226, 818, 140,
- /* 1320 */ 156, 62, 314, 314, 313, 215, 311, 366, 392, 678,
- /* 1330 */ 433, 185, 141, 1234, 142, 160, 148, 1136, 1198, 382,
- /* 1340 */ 189, 67, 826, 180, 388, 248, 1218, 1099, 219, 818,
- /* 1350 */ 818, 820, 821, 19, 247, 190, 266, 154, 390, 271,
- /* 1360 */ 191, 192, 83, 84, 1006, 405, 1057, 182, 321, 85,
- /* 1370 */ 351, 451, 450, 1056, 183, 818, 341, 132, 181, 706,
- /* 1380 */ 1055, 420, 76, 444, 1029, 3, 322, 1028, 283, 1048,
- /* 1390 */ 351, 1095, 1027, 1288, 1047, 71, 204, 6, 288, 290,
- /* 1400 */ 447, 1096, 1094, 1093, 79, 292, 818, 818, 820, 821,
- /* 1410 */ 19, 294, 297, 437, 345, 441, 102, 1184, 1077, 433,
- /* 1420 */ 238, 425, 73, 305, 239, 304, 325, 240, 423, 306,
- /* 1430 */ 307, 826, 213, 1012, 22, 945, 452, 214, 216, 217,
- /* 1440 */ 453, 1001, 115, 996, 125, 126, 235, 127, 665, 352,
- /* 1450 */ 326, 83, 84, 358, 166, 244, 179, 327, 85, 351,
- /* 1460 */ 451, 450, 134, 356, 818, 113, 885, 806, 883, 136,
- /* 1470 */ 128, 138, 738, 258, 184, 899, 143, 145, 63, 64,
- /* 1480 */ 65, 66, 129, 902, 187, 186, 898, 8, 13, 188,
- /* 1490 */ 265, 891, 149, 202, 980, 818, 818, 820, 821, 19,
- /* 1500 */ 150, 387, 161, 680, 285, 391, 151, 395, 400, 193,
- /* 1510 */ 68, 14, 236, 279, 15, 69, 717, 825, 131, 824,
- /* 1520 */ 853, 70, 746, 16, 413, 750, 4, 174, 220, 222,
- /* 1530 */ 152, 779, 857, 774, 201, 77, 74, 868, 17, 854,
- /* 1540 */ 852, 908, 18, 907, 207, 206, 934, 163, 436, 210,
- /* 1550 */ 935, 164, 209, 165, 440, 856, 823, 690, 87, 211,
- /* 1560 */ 309, 312, 1281, 940, 1280,
+ /* 0 */ 1006, 156, 156, 2, 1302, 90, 87, 179, 90, 87,
+ /* 10 */ 179, 460, 1048, 460, 465, 1010, 460, 333, 1130, 335,
+ /* 20 */ 246, 330, 112, 303, 439, 1258, 304, 419, 1129, 1087,
+ /* 30 */ 72, 798, 50, 50, 50, 50, 331, 30, 30, 799,
+ /* 40 */ 951, 364, 371, 97, 98, 88, 983, 983, 859, 862,
+ /* 50 */ 851, 851, 95, 95, 96, 96, 96, 96, 120, 371,
+ /* 60 */ 370, 120, 348, 22, 90, 87, 179, 438, 423, 438,
+ /* 70 */ 440, 335, 420, 385, 90, 87, 179, 116, 73, 163,
+ /* 80 */ 848, 848, 860, 863, 94, 94, 94, 94, 93, 93,
+ /* 90 */ 92, 92, 92, 91, 361, 97, 98, 88, 983, 983,
+ /* 100 */ 859, 862, 851, 851, 95, 95, 96, 96, 96, 96,
+ /* 110 */ 718, 365, 339, 93, 93, 92, 92, 92, 91, 361,
+ /* 120 */ 99, 371, 453, 335, 94, 94, 94, 94, 93, 93,
+ /* 130 */ 92, 92, 92, 91, 361, 852, 94, 94, 94, 94,
+ /* 140 */ 93, 93, 92, 92, 92, 91, 361, 97, 98, 88,
+ /* 150 */ 983, 983, 859, 862, 851, 851, 95, 95, 96, 96,
+ /* 160 */ 96, 96, 92, 92, 92, 91, 361, 838, 132, 195,
+ /* 170 */ 58, 244, 412, 409, 408, 335, 457, 457, 457, 304,
+ /* 180 */ 59, 332, 831, 407, 394, 962, 830, 391, 94, 94,
+ /* 190 */ 94, 94, 93, 93, 92, 92, 92, 91, 361, 97,
+ /* 200 */ 98, 88, 983, 983, 859, 862, 851, 851, 95, 95,
+ /* 210 */ 96, 96, 96, 96, 426, 357, 460, 830, 830, 832,
+ /* 220 */ 91, 361, 962, 963, 964, 195, 459, 335, 412, 409,
+ /* 230 */ 408, 280, 361, 820, 132, 11, 11, 50, 50, 407,
+ /* 240 */ 94, 94, 94, 94, 93, 93, 92, 92, 92, 91,
+ /* 250 */ 361, 97, 98, 88, 983, 983, 859, 862, 851, 851,
+ /* 260 */ 95, 95, 96, 96, 96, 96, 460, 221, 460, 264,
+ /* 270 */ 375, 254, 438, 428, 1276, 1276, 383, 1074, 1053, 335,
+ /* 280 */ 245, 422, 299, 713, 271, 271, 1074, 50, 50, 50,
+ /* 290 */ 50, 962, 94, 94, 94, 94, 93, 93, 92, 92,
+ /* 300 */ 92, 91, 361, 97, 98, 88, 983, 983, 859, 862,
+ /* 310 */ 851, 851, 95, 95, 96, 96, 96, 96, 90, 87,
+ /* 320 */ 179, 1306, 438, 437, 438, 418, 368, 253, 962, 963,
+ /* 330 */ 964, 335, 360, 360, 360, 706, 359, 358, 324, 962,
+ /* 340 */ 1281, 951, 364, 230, 94, 94, 94, 94, 93, 93,
+ /* 350 */ 92, 92, 92, 91, 361, 97, 98, 88, 983, 983,
+ /* 360 */ 859, 862, 851, 851, 95, 95, 96, 96, 96, 96,
+ /* 370 */ 769, 460, 120, 226, 226, 366, 962, 963, 964, 1089,
+ /* 380 */ 990, 900, 990, 335, 1057, 425, 421, 839, 759, 759,
+ /* 390 */ 425, 427, 50, 50, 432, 381, 94, 94, 94, 94,
+ /* 400 */ 93, 93, 92, 92, 92, 91, 361, 97, 98, 88,
+ /* 410 */ 983, 983, 859, 862, 851, 851, 95, 95, 96, 96,
+ /* 420 */ 96, 96, 460, 259, 460, 120, 117, 354, 942, 1332,
+ /* 430 */ 942, 1333, 1332, 278, 1333, 335, 680, 681, 682, 825,
+ /* 440 */ 201, 176, 303, 50, 50, 49, 49, 404, 94, 94,
+ /* 450 */ 94, 94, 93, 93, 92, 92, 92, 91, 361, 97,
+ /* 460 */ 98, 88, 983, 983, 859, 862, 851, 851, 95, 95,
+ /* 470 */ 96, 96, 96, 96, 199, 460, 380, 265, 433, 380,
+ /* 480 */ 265, 383, 256, 158, 258, 319, 1003, 335, 155, 940,
+ /* 490 */ 177, 940, 273, 379, 276, 322, 34, 34, 302, 962,
+ /* 500 */ 94, 94, 94, 94, 93, 93, 92, 92, 92, 91,
+ /* 510 */ 361, 97, 98, 88, 983, 983, 859, 862, 851, 851,
+ /* 520 */ 95, 95, 96, 96, 96, 96, 905, 905, 397, 460,
+ /* 530 */ 301, 158, 101, 319, 941, 340, 962, 963, 964, 313,
+ /* 540 */ 283, 449, 335, 327, 146, 1266, 1004, 257, 234, 248,
+ /* 550 */ 35, 35, 94, 94, 94, 94, 93, 93, 92, 92,
+ /* 560 */ 92, 91, 361, 709, 785, 1227, 97, 98, 88, 983,
+ /* 570 */ 983, 859, 862, 851, 851, 95, 95, 96, 96, 96,
+ /* 580 */ 96, 962, 1227, 1229, 245, 422, 838, 198, 197, 196,
+ /* 590 */ 1079, 1079, 1077, 1077, 1004, 1334, 320, 335, 172, 171,
+ /* 600 */ 709, 831, 159, 271, 271, 830, 76, 94, 94, 94,
+ /* 610 */ 94, 93, 93, 92, 92, 92, 91, 361, 962, 963,
+ /* 620 */ 964, 97, 98, 88, 983, 983, 859, 862, 851, 851,
+ /* 630 */ 95, 95, 96, 96, 96, 96, 830, 830, 832, 1157,
+ /* 640 */ 1157, 199, 1157, 173, 1227, 231, 232, 1282, 2, 335,
+ /* 650 */ 271, 764, 271, 820, 271, 271, 763, 389, 389, 389,
+ /* 660 */ 132, 79, 94, 94, 94, 94, 93, 93, 92, 92,
+ /* 670 */ 92, 91, 361, 97, 98, 88, 983, 983, 859, 862,
+ /* 680 */ 851, 851, 95, 95, 96, 96, 96, 96, 460, 264,
+ /* 690 */ 223, 460, 1257, 783, 1223, 1157, 1086, 1082, 80, 271,
+ /* 700 */ 78, 335, 340, 1031, 341, 344, 345, 902, 346, 10,
+ /* 710 */ 10, 902, 25, 25, 94, 94, 94, 94, 93, 93,
+ /* 720 */ 92, 92, 92, 91, 361, 97, 86, 88, 983, 983,
+ /* 730 */ 859, 862, 851, 851, 95, 95, 96, 96, 96, 96,
+ /* 740 */ 1157, 270, 395, 117, 233, 263, 235, 70, 456, 341,
+ /* 750 */ 225, 176, 335, 1305, 342, 133, 736, 966, 980, 249,
+ /* 760 */ 1150, 396, 325, 1085, 1028, 178, 94, 94, 94, 94,
+ /* 770 */ 93, 93, 92, 92, 92, 91, 361, 98, 88, 983,
+ /* 780 */ 983, 859, 862, 851, 851, 95, 95, 96, 96, 96,
+ /* 790 */ 96, 783, 783, 132, 120, 966, 120, 120, 120, 798,
+ /* 800 */ 252, 937, 335, 353, 321, 429, 355, 799, 822, 692,
+ /* 810 */ 390, 203, 446, 450, 372, 716, 454, 94, 94, 94,
+ /* 820 */ 94, 93, 93, 92, 92, 92, 91, 361, 88, 983,
+ /* 830 */ 983, 859, 862, 851, 851, 95, 95, 96, 96, 96,
+ /* 840 */ 96, 84, 455, 1225, 3, 1209, 120, 120, 382, 387,
+ /* 850 */ 120, 203, 1271, 716, 384, 168, 266, 203, 458, 72,
+ /* 860 */ 260, 1246, 84, 455, 178, 3, 378, 94, 94, 94,
+ /* 870 */ 94, 93, 93, 92, 92, 92, 91, 361, 350, 458,
+ /* 880 */ 1245, 362, 430, 213, 228, 290, 415, 285, 414, 200,
+ /* 890 */ 783, 882, 444, 726, 725, 405, 283, 921, 209, 921,
+ /* 900 */ 281, 132, 362, 72, 838, 289, 147, 733, 734, 392,
+ /* 910 */ 81, 82, 922, 444, 922, 267, 288, 83, 362, 462,
+ /* 920 */ 461, 272, 132, 830, 23, 838, 388, 923, 1216, 923,
+ /* 930 */ 1056, 81, 82, 84, 455, 899, 3, 899, 83, 362,
+ /* 940 */ 462, 461, 761, 962, 830, 75, 1, 443, 275, 747,
+ /* 950 */ 458, 5, 962, 204, 830, 830, 832, 833, 18, 748,
+ /* 960 */ 229, 962, 277, 19, 153, 317, 317, 316, 216, 314,
+ /* 970 */ 279, 460, 689, 362, 1055, 830, 830, 832, 833, 18,
+ /* 980 */ 962, 963, 964, 962, 444, 181, 460, 251, 981, 962,
+ /* 990 */ 963, 964, 8, 8, 20, 250, 838, 1070, 962, 963,
+ /* 1000 */ 964, 417, 81, 82, 768, 204, 347, 36, 36, 83,
+ /* 1010 */ 362, 462, 461, 1054, 284, 830, 84, 455, 1123, 3,
+ /* 1020 */ 962, 963, 964, 460, 183, 962, 981, 764, 889, 1107,
+ /* 1030 */ 460, 184, 763, 458, 132, 182, 74, 455, 460, 3,
+ /* 1040 */ 981, 898, 834, 898, 8, 8, 830, 830, 832, 833,
+ /* 1050 */ 18, 8, 8, 458, 219, 1156, 362, 1103, 349, 8,
+ /* 1060 */ 8, 240, 962, 963, 964, 236, 889, 444, 792, 336,
+ /* 1070 */ 158, 203, 885, 435, 700, 209, 362, 114, 981, 838,
+ /* 1080 */ 834, 227, 334, 1114, 441, 81, 82, 444, 442, 305,
+ /* 1090 */ 784, 306, 83, 362, 462, 461, 369, 1162, 830, 838,
+ /* 1100 */ 460, 1037, 237, 1030, 237, 81, 82, 7, 96, 96,
+ /* 1110 */ 96, 96, 83, 362, 462, 461, 1019, 1018, 830, 1020,
+ /* 1120 */ 1289, 37, 37, 400, 96, 96, 96, 96, 89, 830,
+ /* 1130 */ 830, 832, 833, 18, 1100, 318, 962, 292, 94, 94,
+ /* 1140 */ 94, 94, 93, 93, 92, 92, 92, 91, 361, 830,
+ /* 1150 */ 830, 832, 833, 18, 94, 94, 94, 94, 93, 93,
+ /* 1160 */ 92, 92, 92, 91, 361, 359, 358, 226, 226, 727,
+ /* 1170 */ 294, 296, 460, 962, 963, 964, 460, 989, 160, 425,
+ /* 1180 */ 170, 1295, 262, 460, 987, 374, 988, 386, 1145, 255,
+ /* 1190 */ 326, 460, 373, 38, 38, 410, 174, 39, 39, 413,
+ /* 1200 */ 460, 287, 460, 1053, 40, 40, 298, 728, 1220, 990,
+ /* 1210 */ 445, 990, 26, 26, 1219, 460, 311, 460, 169, 1292,
+ /* 1220 */ 460, 27, 27, 29, 29, 998, 460, 206, 135, 995,
+ /* 1230 */ 1265, 1263, 460, 57, 60, 460, 41, 41, 42, 42,
+ /* 1240 */ 460, 43, 43, 460, 343, 351, 460, 9, 9, 460,
+ /* 1250 */ 144, 460, 130, 44, 44, 460, 103, 103, 460, 137,
+ /* 1260 */ 70, 45, 45, 460, 46, 46, 460, 31, 31, 1142,
+ /* 1270 */ 47, 47, 48, 48, 460, 376, 32, 32, 460, 122,
+ /* 1280 */ 122, 460, 157, 460, 123, 123, 139, 124, 124, 460,
+ /* 1290 */ 186, 460, 377, 460, 115, 54, 54, 460, 403, 33,
+ /* 1300 */ 33, 460, 104, 104, 51, 51, 460, 161, 460, 140,
+ /* 1310 */ 105, 105, 106, 106, 102, 102, 460, 141, 121, 121,
+ /* 1320 */ 460, 142, 119, 119, 190, 460, 1152, 110, 110, 109,
+ /* 1330 */ 109, 702, 460, 148, 393, 65, 460, 107, 107, 460,
+ /* 1340 */ 323, 108, 108, 399, 460, 1234, 53, 53, 1214, 269,
+ /* 1350 */ 154, 416, 1115, 55, 55, 220, 401, 52, 52, 191,
+ /* 1360 */ 24, 24, 274, 192, 193, 28, 28, 1021, 328, 702,
+ /* 1370 */ 1073, 352, 1072, 718, 1071, 431, 1111, 1064, 329, 1045,
+ /* 1380 */ 69, 205, 6, 291, 1044, 286, 1112, 1043, 1304, 1110,
+ /* 1390 */ 293, 300, 295, 297, 1063, 1200, 1109, 77, 241, 448,
+ /* 1400 */ 356, 452, 436, 100, 214, 71, 434, 1027, 1093, 21,
+ /* 1410 */ 463, 242, 243, 957, 215, 217, 218, 464, 309, 307,
+ /* 1420 */ 308, 310, 1016, 125, 1250, 1251, 1011, 1249, 126, 127,
+ /* 1430 */ 1248, 113, 676, 337, 238, 338, 134, 363, 167, 1041,
+ /* 1440 */ 1040, 56, 247, 367, 180, 897, 111, 895, 136, 1038,
+ /* 1450 */ 818, 128, 138, 750, 261, 911, 185, 143, 145, 61,
+ /* 1460 */ 62, 63, 64, 129, 914, 187, 188, 910, 118, 12,
+ /* 1470 */ 189, 903, 268, 992, 203, 162, 398, 150, 149, 691,
+ /* 1480 */ 402, 288, 194, 406, 151, 411, 66, 13, 729, 239,
+ /* 1490 */ 282, 14, 67, 131, 837, 836, 865, 758, 15, 4,
+ /* 1500 */ 68, 762, 175, 222, 224, 424, 152, 869, 791, 202,
+ /* 1510 */ 786, 75, 72, 880, 866, 864, 16, 17, 920, 207,
+ /* 1520 */ 919, 208, 447, 946, 164, 211, 947, 210, 165, 451,
+ /* 1530 */ 868, 166, 315, 835, 701, 85, 212, 1297, 312, 952,
+ /* 1540 */ 1296,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 115, 19, 117, 118, 24, 1, 2, 27, 79,
- /* 10 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
- /* 20 */ 90, 91, 92, 93, 94, 144, 145, 146, 147, 58,
- /* 30 */ 49, 50, 79, 80, 81, 82, 22, 84, 85, 86,
- /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 221, 222,
- /* 50 */ 223, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 79, 80, 81, 82, 94, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 93, 94, 19, 94, 97, 108,
- /* 80 */ 109, 110, 99, 100, 101, 102, 103, 104, 105, 32,
- /* 90 */ 119, 120, 78, 27, 152, 112, 93, 94, 41, 88,
- /* 100 */ 89, 90, 91, 92, 93, 94, 49, 50, 84, 85,
- /* 110 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 58,
- /* 120 */ 157, 119, 120, 163, 68, 163, 65, 70, 71, 72,
- /* 130 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- /* 140 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 150 */ 93, 94, 19, 97, 88, 89, 196, 101, 196, 26,
- /* 160 */ 172, 173, 96, 97, 98, 210, 100, 22, 152, 108,
- /* 170 */ 109, 110, 27, 107, 27, 109, 221, 222, 223, 219,
- /* 180 */ 238, 219, 49, 50, 152, 169, 170, 54, 132, 133,
- /* 190 */ 134, 228, 232, 171, 231, 207, 208, 237, 132, 237,
- /* 200 */ 134, 179, 19, 70, 71, 72, 73, 74, 75, 76,
- /* 210 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86,
- /* 220 */ 87, 88, 89, 90, 91, 92, 93, 94, 27, 65,
- /* 230 */ 30, 152, 49, 50, 34, 52, 90, 91, 92, 93,
- /* 240 */ 94, 96, 97, 98, 97, 22, 230, 27, 48, 217,
- /* 250 */ 27, 172, 173, 70, 71, 72, 73, 74, 75, 76,
- /* 260 */ 77, 78, 79, 80, 81, 82, 172, 84, 85, 86,
- /* 270 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 148,
- /* 280 */ 149, 152, 218, 24, 152, 154, 207, 156, 172, 152,
- /* 290 */ 22, 68, 27, 152, 163, 27, 164, 96, 97, 98,
- /* 300 */ 99, 172, 173, 102, 103, 104, 169, 170, 49, 50,
- /* 310 */ 90, 88, 89, 152, 113, 186, 96, 97, 98, 96,
- /* 320 */ 97, 160, 57, 27, 101, 164, 137, 196, 139, 70,
- /* 330 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 340 */ 81, 82, 11, 84, 85, 86, 87, 88, 89, 90,
- /* 350 */ 91, 92, 93, 94, 19, 132, 133, 134, 23, 218,
- /* 360 */ 152, 96, 97, 98, 96, 97, 98, 230, 99, 22,
- /* 370 */ 152, 102, 103, 104, 27, 244, 152, 152, 27, 26,
- /* 380 */ 152, 22, 113, 65, 49, 50, 27, 194, 195, 58,
- /* 390 */ 172, 173, 96, 97, 98, 185, 65, 172, 173, 206,
- /* 400 */ 172, 173, 190, 191, 186, 70, 71, 72, 73, 74,
- /* 410 */ 75, 76, 77, 78, 79, 80, 81, 82, 175, 84,
- /* 420 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 430 */ 19, 175, 207, 208, 23, 207, 208, 119, 120, 108,
- /* 440 */ 109, 110, 27, 96, 97, 98, 116, 96, 97, 98,
- /* 450 */ 152, 121, 152, 179, 180, 96, 97, 98, 250, 106,
- /* 460 */ 49, 50, 188, 19, 221, 222, 223, 168, 169, 170,
- /* 470 */ 172, 173, 172, 173, 250, 124, 172, 221, 222, 223,
- /* 480 */ 26, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 490 */ 79, 80, 81, 82, 50, 84, 85, 86, 87, 88,
- /* 500 */ 89, 90, 91, 92, 93, 94, 19, 207, 208, 12,
- /* 510 */ 23, 96, 97, 98, 221, 222, 223, 194, 195, 152,
- /* 520 */ 199, 23, 19, 225, 26, 28, 152, 152, 152, 206,
- /* 530 */ 209, 164, 190, 191, 241, 152, 49, 50, 152, 124,
- /* 540 */ 152, 44, 219, 46, 152, 21, 172, 173, 172, 173,
- /* 550 */ 183, 107, 185, 16, 163, 58, 112, 70, 71, 72,
- /* 560 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
- /* 570 */ 152, 84, 85, 86, 87, 88, 89, 90, 91, 92,
- /* 580 */ 93, 94, 19, 207, 130, 152, 23, 196, 64, 152,
- /* 590 */ 172, 173, 22, 152, 24, 152, 98, 27, 61, 96,
- /* 600 */ 63, 26, 211, 212, 186, 172, 173, 49, 50, 172,
- /* 610 */ 173, 23, 49, 50, 26, 172, 173, 88, 89, 186,
- /* 620 */ 24, 238, 124, 27, 238, 22, 23, 103, 187, 26,
- /* 630 */ 152, 73, 74, 70, 71, 72, 73, 74, 75, 76,
- /* 640 */ 77, 78, 79, 80, 81, 82, 152, 84, 85, 86,
- /* 650 */ 87, 88, 89, 90, 91, 92, 93, 94, 19, 101,
- /* 660 */ 152, 132, 23, 134, 140, 152, 12, 97, 36, 168,
- /* 670 */ 169, 170, 69, 98, 152, 22, 23, 140, 50, 26,
- /* 680 */ 172, 173, 28, 51, 152, 172, 173, 193, 49, 50,
- /* 690 */ 22, 59, 24, 97, 172, 173, 152, 152, 44, 124,
- /* 700 */ 46, 0, 1, 2, 172, 173, 22, 23, 19, 70,
- /* 710 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 720 */ 81, 82, 69, 84, 85, 86, 87, 88, 89, 90,
- /* 730 */ 91, 92, 93, 94, 152, 107, 152, 193, 49, 50,
- /* 740 */ 181, 22, 23, 111, 108, 109, 110, 7, 8, 9,
- /* 750 */ 16, 247, 248, 69, 172, 173, 172, 173, 152, 70,
- /* 760 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
- /* 770 */ 81, 82, 152, 84, 85, 86, 87, 88, 89, 90,
- /* 780 */ 91, 92, 93, 94, 19, 152, 242, 152, 69, 152,
- /* 790 */ 166, 167, 172, 173, 32, 61, 152, 63, 152, 193,
- /* 800 */ 152, 152, 152, 41, 152, 172, 173, 172, 173, 172,
- /* 810 */ 173, 152, 152, 152, 49, 50, 172, 173, 172, 173,
- /* 820 */ 172, 173, 172, 173, 172, 173, 132, 138, 134, 152,
- /* 830 */ 152, 172, 173, 172, 173, 70, 71, 72, 73, 74,
- /* 840 */ 75, 76, 77, 78, 79, 80, 81, 82, 152, 84,
- /* 850 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- /* 860 */ 19, 152, 22, 152, 195, 24, 152, 27, 172, 173,
- /* 870 */ 193, 193, 152, 152, 152, 206, 152, 217, 152, 152,
- /* 880 */ 152, 172, 173, 172, 173, 152, 172, 173, 152, 152,
- /* 890 */ 49, 50, 172, 173, 172, 173, 172, 173, 172, 173,
- /* 900 */ 172, 173, 152, 138, 152, 172, 173, 108, 109, 110,
- /* 910 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 920 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 930 */ 89, 90, 91, 92, 93, 94, 152, 97, 152, 152,
- /* 940 */ 49, 50, 26, 193, 172, 173, 152, 152, 152, 146,
- /* 950 */ 147, 132, 152, 134, 217, 181, 172, 173, 172, 173,
- /* 960 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 970 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 980 */ 89, 90, 91, 92, 93, 94, 152, 193, 152, 193,
- /* 990 */ 49, 50, 181, 193, 172, 173, 166, 167, 245, 246,
- /* 1000 */ 211, 212, 152, 22, 217, 152, 172, 173, 172, 173,
- /* 1010 */ 19, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1020 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 1030 */ 89, 90, 91, 92, 93, 94, 152, 187, 152, 123,
- /* 1040 */ 49, 50, 23, 23, 23, 26, 26, 26, 23, 23,
- /* 1050 */ 23, 26, 26, 26, 7, 8, 172, 173, 172, 173,
- /* 1060 */ 19, 90, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1070 */ 79, 80, 81, 82, 152, 84, 85, 86, 87, 88,
- /* 1080 */ 89, 90, 91, 92, 93, 94, 152, 116, 152, 217,
- /* 1090 */ 49, 50, 121, 23, 172, 173, 26, 100, 101, 27,
- /* 1100 */ 101, 27, 23, 122, 152, 26, 172, 173, 172, 173,
- /* 1110 */ 152, 112, 163, 72, 73, 74, 75, 76, 77, 78,
- /* 1120 */ 79, 80, 81, 82, 163, 84, 85, 86, 87, 88,
- /* 1130 */ 89, 90, 91, 92, 93, 94, 19, 20, 152, 22,
- /* 1140 */ 23, 152, 163, 65, 27, 196, 163, 19, 20, 23,
- /* 1150 */ 22, 213, 26, 19, 37, 27, 152, 196, 172, 173,
- /* 1160 */ 152, 172, 173, 27, 23, 37, 152, 26, 152, 97,
- /* 1170 */ 152, 97, 210, 56, 163, 196, 163, 163, 100, 196,
- /* 1180 */ 172, 173, 65, 152, 56, 68, 172, 173, 172, 173,
- /* 1190 */ 172, 173, 152, 65, 163, 163, 68, 23, 152, 234,
- /* 1200 */ 26, 152, 152, 172, 173, 88, 89, 196, 152, 196,
- /* 1210 */ 196, 152, 95, 96, 97, 98, 88, 89, 101, 152,
- /* 1220 */ 152, 207, 208, 95, 96, 97, 98, 196, 196, 101,
- /* 1230 */ 96, 233, 152, 97, 152, 152, 19, 20, 207, 22,
- /* 1240 */ 152, 152, 152, 191, 27, 152, 152, 152, 152, 132,
- /* 1250 */ 133, 134, 135, 136, 37, 152, 152, 152, 152, 152,
- /* 1260 */ 132, 133, 134, 135, 136, 210, 197, 210, 210, 198,
- /* 1270 */ 150, 184, 239, 56, 201, 214, 214, 201, 239, 180,
- /* 1280 */ 214, 227, 198, 38, 176, 68, 175, 175, 175, 122,
- /* 1290 */ 155, 200, 159, 19, 20, 40, 22, 159, 159, 22,
- /* 1300 */ 70, 27, 130, 243, 240, 88, 89, 90, 189, 18,
- /* 1310 */ 201, 37, 95, 96, 97, 98, 192, 5, 101, 192,
- /* 1320 */ 220, 240, 10, 11, 12, 13, 14, 159, 18, 17,
- /* 1330 */ 56, 158, 192, 201, 192, 220, 189, 189, 201, 159,
- /* 1340 */ 158, 137, 68, 31, 45, 33, 236, 159, 159, 132,
- /* 1350 */ 133, 134, 135, 136, 42, 158, 235, 22, 177, 159,
- /* 1360 */ 158, 158, 88, 89, 159, 107, 174, 55, 177, 95,
- /* 1370 */ 96, 97, 98, 174, 62, 101, 47, 65, 66, 106,
- /* 1380 */ 174, 125, 19, 20, 174, 22, 177, 176, 174, 182,
- /* 1390 */ 27, 216, 174, 174, 182, 107, 159, 22, 215, 215,
- /* 1400 */ 37, 216, 216, 216, 137, 215, 132, 133, 134, 135,
- /* 1410 */ 136, 215, 159, 177, 94, 177, 129, 224, 205, 56,
- /* 1420 */ 226, 126, 128, 203, 229, 204, 114, 229, 127, 202,
- /* 1430 */ 201, 68, 25, 162, 26, 13, 161, 153, 153, 6,
- /* 1440 */ 151, 151, 178, 151, 165, 165, 178, 165, 4, 3,
- /* 1450 */ 249, 88, 89, 141, 22, 142, 15, 249, 95, 96,
- /* 1460 */ 97, 98, 246, 67, 101, 16, 23, 120, 23, 131,
- /* 1470 */ 111, 123, 20, 16, 125, 1, 123, 131, 78, 78,
- /* 1480 */ 78, 78, 111, 96, 122, 35, 1, 5, 22, 107,
- /* 1490 */ 140, 53, 53, 26, 60, 132, 133, 134, 135, 136,
- /* 1500 */ 107, 43, 24, 20, 112, 19, 22, 52, 52, 105,
- /* 1510 */ 22, 22, 52, 23, 22, 22, 29, 23, 39, 23,
- /* 1520 */ 23, 26, 116, 22, 26, 23, 22, 122, 23, 23,
- /* 1530 */ 22, 96, 11, 124, 35, 26, 26, 23, 35, 23,
- /* 1540 */ 23, 23, 35, 23, 22, 26, 23, 22, 24, 122,
- /* 1550 */ 23, 22, 26, 22, 24, 23, 23, 23, 22, 122,
- /* 1560 */ 23, 15, 122, 1, 122,
+ /* 0 */ 144, 145, 146, 147, 172, 222, 223, 224, 222, 223,
+ /* 10 */ 224, 152, 180, 152, 148, 149, 152, 173, 176, 19,
+ /* 20 */ 154, 173, 156, 152, 163, 242, 152, 163, 176, 163,
+ /* 30 */ 26, 31, 173, 174, 173, 174, 173, 173, 174, 39,
+ /* 40 */ 1, 2, 152, 43, 44, 45, 46, 47, 48, 49,
+ /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 197, 169,
+ /* 60 */ 170, 197, 188, 197, 222, 223, 224, 208, 209, 208,
+ /* 70 */ 209, 19, 208, 152, 222, 223, 224, 22, 26, 24,
+ /* 80 */ 46, 47, 48, 49, 84, 85, 86, 87, 88, 89,
+ /* 90 */ 90, 91, 92, 93, 94, 43, 44, 45, 46, 47,
+ /* 100 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ /* 110 */ 106, 245, 157, 88, 89, 90, 91, 92, 93, 94,
+ /* 120 */ 68, 231, 251, 19, 84, 85, 86, 87, 88, 89,
+ /* 130 */ 90, 91, 92, 93, 94, 101, 84, 85, 86, 87,
+ /* 140 */ 88, 89, 90, 91, 92, 93, 94, 43, 44, 45,
+ /* 150 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 160 */ 56, 57, 90, 91, 92, 93, 94, 82, 79, 99,
+ /* 170 */ 66, 200, 102, 103, 104, 19, 168, 169, 170, 152,
+ /* 180 */ 24, 210, 97, 113, 229, 59, 101, 232, 84, 85,
+ /* 190 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 43,
+ /* 200 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 210 */ 54, 55, 56, 57, 152, 188, 152, 132, 133, 134,
+ /* 220 */ 93, 94, 96, 97, 98, 99, 152, 19, 102, 103,
+ /* 230 */ 104, 23, 94, 72, 79, 173, 174, 173, 174, 113,
+ /* 240 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 250 */ 94, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 260 */ 52, 53, 54, 55, 56, 57, 152, 171, 152, 108,
+ /* 270 */ 109, 110, 208, 209, 119, 120, 152, 180, 181, 19,
+ /* 280 */ 119, 120, 152, 23, 152, 152, 189, 173, 174, 173,
+ /* 290 */ 174, 59, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 300 */ 92, 93, 94, 43, 44, 45, 46, 47, 48, 49,
+ /* 310 */ 50, 51, 52, 53, 54, 55, 56, 57, 222, 223,
+ /* 320 */ 224, 186, 208, 209, 208, 209, 194, 194, 96, 97,
+ /* 330 */ 98, 19, 168, 169, 170, 23, 88, 89, 163, 59,
+ /* 340 */ 0, 1, 2, 219, 84, 85, 86, 87, 88, 89,
+ /* 350 */ 90, 91, 92, 93, 94, 43, 44, 45, 46, 47,
+ /* 360 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ /* 370 */ 90, 152, 197, 195, 196, 243, 96, 97, 98, 196,
+ /* 380 */ 132, 11, 134, 19, 182, 207, 115, 23, 117, 118,
+ /* 390 */ 207, 163, 173, 174, 152, 220, 84, 85, 86, 87,
+ /* 400 */ 88, 89, 90, 91, 92, 93, 94, 43, 44, 45,
+ /* 410 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ /* 420 */ 56, 57, 152, 16, 152, 197, 171, 208, 22, 23,
+ /* 430 */ 22, 23, 26, 16, 26, 19, 7, 8, 9, 23,
+ /* 440 */ 212, 213, 152, 173, 174, 173, 174, 19, 84, 85,
+ /* 450 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 43,
+ /* 460 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ /* 470 */ 54, 55, 56, 57, 46, 152, 109, 110, 208, 109,
+ /* 480 */ 110, 152, 75, 152, 77, 22, 23, 19, 233, 83,
+ /* 490 */ 152, 83, 75, 238, 77, 164, 173, 174, 226, 59,
+ /* 500 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 510 */ 94, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 520 */ 52, 53, 54, 55, 56, 57, 108, 109, 110, 152,
+ /* 530 */ 152, 152, 22, 22, 23, 107, 96, 97, 98, 160,
+ /* 540 */ 112, 251, 19, 164, 22, 152, 83, 140, 219, 152,
+ /* 550 */ 173, 174, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 560 */ 92, 93, 94, 59, 124, 152, 43, 44, 45, 46,
+ /* 570 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 580 */ 57, 59, 169, 170, 119, 120, 82, 108, 109, 110,
+ /* 590 */ 191, 192, 191, 192, 83, 248, 249, 19, 88, 89,
+ /* 600 */ 96, 97, 24, 152, 152, 101, 138, 84, 85, 86,
+ /* 610 */ 87, 88, 89, 90, 91, 92, 93, 94, 96, 97,
+ /* 620 */ 98, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ /* 630 */ 52, 53, 54, 55, 56, 57, 132, 133, 134, 152,
+ /* 640 */ 152, 46, 152, 26, 231, 194, 194, 146, 147, 19,
+ /* 650 */ 152, 116, 152, 72, 152, 152, 121, 152, 152, 152,
+ /* 660 */ 79, 138, 84, 85, 86, 87, 88, 89, 90, 91,
+ /* 670 */ 92, 93, 94, 43, 44, 45, 46, 47, 48, 49,
+ /* 680 */ 50, 51, 52, 53, 54, 55, 56, 57, 152, 108,
+ /* 690 */ 23, 152, 194, 26, 194, 152, 194, 194, 137, 152,
+ /* 700 */ 139, 19, 107, 166, 167, 218, 218, 29, 218, 173,
+ /* 710 */ 174, 33, 173, 174, 84, 85, 86, 87, 88, 89,
+ /* 720 */ 90, 91, 92, 93, 94, 43, 44, 45, 46, 47,
+ /* 730 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ /* 740 */ 152, 194, 64, 171, 239, 239, 239, 130, 166, 167,
+ /* 750 */ 212, 213, 19, 23, 246, 247, 26, 59, 26, 152,
+ /* 760 */ 163, 218, 163, 163, 163, 98, 84, 85, 86, 87,
+ /* 770 */ 88, 89, 90, 91, 92, 93, 94, 44, 45, 46,
+ /* 780 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 790 */ 57, 124, 26, 79, 197, 97, 197, 197, 197, 31,
+ /* 800 */ 152, 23, 19, 19, 26, 19, 218, 39, 23, 21,
+ /* 810 */ 238, 26, 163, 163, 100, 59, 163, 84, 85, 86,
+ /* 820 */ 87, 88, 89, 90, 91, 92, 93, 94, 45, 46,
+ /* 830 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+ /* 840 */ 57, 19, 20, 152, 22, 23, 197, 197, 23, 19,
+ /* 850 */ 197, 26, 152, 97, 23, 123, 23, 26, 36, 26,
+ /* 860 */ 152, 152, 19, 20, 98, 22, 78, 84, 85, 86,
+ /* 870 */ 87, 88, 89, 90, 91, 92, 93, 94, 94, 36,
+ /* 880 */ 152, 59, 96, 99, 100, 101, 102, 103, 104, 105,
+ /* 890 */ 124, 103, 70, 100, 101, 23, 112, 12, 26, 12,
+ /* 900 */ 23, 79, 59, 26, 82, 101, 22, 7, 8, 152,
+ /* 910 */ 88, 89, 27, 70, 27, 152, 112, 95, 96, 97,
+ /* 920 */ 98, 152, 79, 101, 22, 82, 96, 42, 140, 42,
+ /* 930 */ 182, 88, 89, 19, 20, 132, 22, 134, 95, 96,
+ /* 940 */ 97, 98, 23, 59, 101, 26, 22, 62, 152, 62,
+ /* 950 */ 36, 22, 59, 24, 132, 133, 134, 135, 136, 72,
+ /* 960 */ 5, 59, 152, 22, 71, 10, 11, 12, 13, 14,
+ /* 970 */ 152, 152, 17, 59, 182, 132, 133, 134, 135, 136,
+ /* 980 */ 96, 97, 98, 59, 70, 30, 152, 32, 59, 96,
+ /* 990 */ 97, 98, 173, 174, 53, 40, 82, 152, 96, 97,
+ /* 1000 */ 98, 90, 88, 89, 90, 24, 187, 173, 174, 95,
+ /* 1010 */ 96, 97, 98, 152, 152, 101, 19, 20, 152, 22,
+ /* 1020 */ 96, 97, 98, 152, 69, 59, 97, 116, 59, 214,
+ /* 1030 */ 152, 76, 121, 36, 79, 80, 19, 20, 152, 22,
+ /* 1040 */ 59, 132, 59, 134, 173, 174, 132, 133, 134, 135,
+ /* 1050 */ 136, 173, 174, 36, 234, 152, 59, 152, 187, 173,
+ /* 1060 */ 174, 211, 96, 97, 98, 187, 97, 70, 23, 114,
+ /* 1070 */ 152, 26, 23, 187, 23, 26, 59, 26, 97, 82,
+ /* 1080 */ 97, 22, 164, 152, 152, 88, 89, 70, 192, 152,
+ /* 1090 */ 124, 152, 95, 96, 97, 98, 141, 152, 101, 82,
+ /* 1100 */ 152, 152, 184, 152, 186, 88, 89, 199, 54, 55,
+ /* 1110 */ 56, 57, 95, 96, 97, 98, 152, 152, 101, 152,
+ /* 1120 */ 152, 173, 174, 235, 54, 55, 56, 57, 58, 132,
+ /* 1130 */ 133, 134, 135, 136, 211, 150, 59, 211, 84, 85,
+ /* 1140 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 132,
+ /* 1150 */ 133, 134, 135, 136, 84, 85, 86, 87, 88, 89,
+ /* 1160 */ 90, 91, 92, 93, 94, 88, 89, 195, 196, 35,
+ /* 1170 */ 211, 211, 152, 96, 97, 98, 152, 100, 198, 207,
+ /* 1180 */ 171, 122, 240, 152, 107, 215, 109, 240, 202, 215,
+ /* 1190 */ 202, 152, 220, 173, 174, 177, 185, 173, 174, 65,
+ /* 1200 */ 152, 176, 152, 181, 173, 174, 215, 73, 176, 132,
+ /* 1210 */ 228, 134, 173, 174, 176, 152, 201, 152, 199, 155,
+ /* 1220 */ 152, 173, 174, 173, 174, 60, 152, 122, 244, 38,
+ /* 1230 */ 159, 159, 152, 241, 241, 152, 173, 174, 173, 174,
+ /* 1240 */ 152, 173, 174, 152, 159, 111, 152, 173, 174, 152,
+ /* 1250 */ 22, 152, 43, 173, 174, 152, 173, 174, 152, 190,
+ /* 1260 */ 130, 173, 174, 152, 173, 174, 152, 173, 174, 202,
+ /* 1270 */ 173, 174, 173, 174, 152, 18, 173, 174, 152, 173,
+ /* 1280 */ 174, 152, 221, 152, 173, 174, 193, 173, 174, 152,
+ /* 1290 */ 158, 152, 159, 152, 22, 173, 174, 152, 18, 173,
+ /* 1300 */ 174, 152, 173, 174, 173, 174, 152, 221, 152, 193,
+ /* 1310 */ 173, 174, 173, 174, 173, 174, 152, 193, 173, 174,
+ /* 1320 */ 152, 193, 173, 174, 158, 152, 190, 173, 174, 173,
+ /* 1330 */ 174, 59, 152, 190, 159, 137, 152, 173, 174, 152,
+ /* 1340 */ 202, 173, 174, 61, 152, 237, 173, 174, 202, 236,
+ /* 1350 */ 22, 107, 159, 173, 174, 159, 178, 173, 174, 158,
+ /* 1360 */ 173, 174, 159, 158, 158, 173, 174, 159, 178, 97,
+ /* 1370 */ 175, 63, 175, 106, 175, 125, 217, 183, 178, 175,
+ /* 1380 */ 107, 159, 22, 216, 177, 175, 217, 175, 175, 217,
+ /* 1390 */ 216, 159, 216, 216, 183, 225, 217, 137, 227, 178,
+ /* 1400 */ 94, 178, 126, 129, 25, 128, 127, 162, 206, 26,
+ /* 1410 */ 161, 230, 230, 13, 153, 153, 6, 151, 203, 205,
+ /* 1420 */ 204, 202, 151, 165, 171, 171, 151, 171, 165, 165,
+ /* 1430 */ 171, 179, 4, 250, 179, 250, 247, 3, 22, 171,
+ /* 1440 */ 171, 171, 142, 81, 15, 23, 16, 23, 131, 171,
+ /* 1450 */ 120, 111, 123, 20, 16, 1, 125, 123, 131, 53,
+ /* 1460 */ 53, 53, 53, 111, 96, 34, 122, 1, 5, 22,
+ /* 1470 */ 107, 67, 140, 74, 26, 24, 41, 107, 67, 20,
+ /* 1480 */ 19, 112, 105, 66, 22, 66, 22, 22, 28, 66,
+ /* 1490 */ 23, 22, 22, 37, 23, 23, 23, 116, 22, 22,
+ /* 1500 */ 26, 23, 122, 23, 23, 26, 22, 11, 96, 34,
+ /* 1510 */ 124, 26, 26, 23, 23, 23, 34, 34, 23, 26,
+ /* 1520 */ 23, 22, 24, 23, 22, 122, 23, 26, 22, 24,
+ /* 1530 */ 23, 22, 15, 23, 23, 22, 122, 122, 23, 1,
+ /* 1540 */ 122, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1550 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1560 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1570 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1580 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1590 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1600 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1610 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1620 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1630 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1640 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1650 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1660 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1670 */ 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
+ /* 1680 */ 252, 252, 252, 252,
};
-#define YY_SHIFT_USE_DFLT (1565)
-#define YY_SHIFT_COUNT (454)
-#define YY_SHIFT_MIN (-114)
-#define YY_SHIFT_MAX (1562)
-static const short yy_shift_ofst[] = {
- /* 0 */ 5, 1117, 1312, 1128, 1274, 1274, 1274, 1274, 61, -19,
- /* 10 */ 57, 57, 183, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 20 */ 66, 66, 201, -29, 331, 318, 133, 259, 335, 411,
- /* 30 */ 487, 563, 639, 689, 765, 841, 891, 891, 891, 891,
- /* 40 */ 891, 891, 891, 891, 891, 891, 891, 891, 891, 891,
- /* 50 */ 891, 891, 891, 941, 891, 991, 1041, 1041, 1217, 1274,
- /* 60 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 70 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 80 */ 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 90 */ 1363, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274, 1274,
- /* 100 */ 1274, 1274, 1274, 1274, -70, -47, -47, -47, -47, -47,
- /* 110 */ 24, 11, 146, 296, 524, 444, 529, 529, 296, 3,
- /* 120 */ 2, -30, 1565, 1565, 1565, -17, -17, -17, 145, 145,
- /* 130 */ 497, 497, 265, 603, 653, 296, 296, 296, 296, 296,
- /* 140 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- /* 150 */ 296, 296, 296, 296, 296, 701, 1078, 147, 147, 2,
- /* 160 */ 164, 164, 164, 164, 164, 164, 1565, 1565, 1565, 223,
- /* 170 */ 56, 56, 268, 269, 220, 347, 351, 415, 359, 296,
- /* 180 */ 296, 296, 296, 296, 296, 296, 296, 296, 296, 296,
- /* 190 */ 296, 296, 296, 296, 296, 632, 632, 632, 296, 296,
- /* 200 */ 498, 296, 296, 296, 570, 296, 296, 654, 296, 296,
- /* 210 */ 296, 296, 296, 296, 296, 296, 296, 296, 636, 200,
- /* 220 */ 596, 596, 596, 575, -114, 971, 740, 454, 503, 503,
- /* 230 */ 1134, 454, 1134, 353, 588, 628, 762, 503, 189, 762,
- /* 240 */ 762, 916, 330, 668, 1245, 1167, 1167, 1255, 1255, 1167,
- /* 250 */ 1277, 1230, 1172, 1291, 1291, 1291, 1291, 1167, 1310, 1172,
- /* 260 */ 1277, 1230, 1230, 1172, 1167, 1310, 1204, 1299, 1167, 1167,
- /* 270 */ 1310, 1335, 1167, 1310, 1167, 1310, 1335, 1258, 1258, 1258,
- /* 280 */ 1329, 1335, 1258, 1273, 1258, 1329, 1258, 1258, 1256, 1288,
- /* 290 */ 1256, 1288, 1256, 1288, 1256, 1288, 1167, 1375, 1167, 1267,
- /* 300 */ 1335, 1320, 1320, 1335, 1287, 1295, 1294, 1301, 1172, 1407,
- /* 310 */ 1408, 1422, 1422, 1433, 1433, 1433, 1565, 1565, 1565, 1565,
- /* 320 */ 1565, 1565, 1565, 1565, 558, 537, 684, 719, 734, 799,
- /* 330 */ 840, 1019, 14, 1020, 1021, 1025, 1026, 1027, 1070, 1072,
- /* 340 */ 997, 1047, 999, 1079, 1126, 1074, 1141, 694, 819, 1174,
- /* 350 */ 1136, 981, 1444, 1446, 1432, 1313, 1441, 1396, 1449, 1443,
- /* 360 */ 1445, 1347, 1338, 1359, 1348, 1452, 1349, 1457, 1474, 1353,
- /* 370 */ 1346, 1400, 1401, 1402, 1403, 1371, 1387, 1450, 1362, 1485,
- /* 380 */ 1482, 1466, 1382, 1350, 1438, 1467, 1439, 1434, 1458, 1393,
- /* 390 */ 1478, 1483, 1486, 1392, 1404, 1484, 1455, 1488, 1489, 1490,
- /* 400 */ 1492, 1456, 1487, 1493, 1460, 1479, 1494, 1496, 1497, 1495,
- /* 410 */ 1406, 1501, 1502, 1504, 1498, 1405, 1505, 1506, 1435, 1499,
- /* 420 */ 1508, 1409, 1509, 1503, 1510, 1507, 1514, 1509, 1516, 1517,
- /* 430 */ 1518, 1519, 1520, 1522, 1521, 1523, 1525, 1524, 1526, 1527,
- /* 440 */ 1529, 1530, 1526, 1532, 1531, 1533, 1534, 1536, 1427, 1437,
- /* 450 */ 1440, 1442, 1537, 1546, 1562,
+#define YY_SHIFT_COUNT (465)
+#define YY_SHIFT_MIN (0)
+#define YY_SHIFT_MAX (1538)
+static const unsigned short int yy_shift_ofst[] = {
+ /* 0 */ 39, 822, 955, 843, 997, 997, 997, 997, 0, 0,
+ /* 10 */ 104, 630, 997, 997, 997, 997, 997, 997, 997, 1077,
+ /* 20 */ 1077, 126, 161, 155, 52, 156, 208, 260, 312, 364,
+ /* 30 */ 416, 468, 523, 578, 630, 630, 630, 630, 630, 630,
+ /* 40 */ 630, 630, 630, 630, 630, 630, 630, 630, 630, 630,
+ /* 50 */ 630, 682, 630, 733, 783, 783, 914, 997, 997, 997,
+ /* 60 */ 997, 997, 997, 997, 997, 997, 997, 997, 997, 997,
+ /* 70 */ 997, 997, 997, 997, 997, 997, 997, 997, 997, 997,
+ /* 80 */ 997, 997, 997, 997, 997, 997, 997, 997, 1017, 997,
+ /* 90 */ 997, 997, 997, 997, 997, 997, 997, 997, 997, 997,
+ /* 100 */ 997, 997, 1070, 1054, 1054, 1054, 1054, 1054, 40, 25,
+ /* 110 */ 72, 232, 788, 428, 248, 248, 232, 581, 367, 127,
+ /* 120 */ 465, 138, 1541, 1541, 1541, 784, 784, 784, 522, 522,
+ /* 130 */ 887, 887, 893, 406, 408, 232, 232, 232, 232, 232,
+ /* 140 */ 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
+ /* 150 */ 232, 232, 232, 232, 232, 370, 340, 714, 698, 698,
+ /* 160 */ 465, 89, 89, 89, 89, 89, 89, 1541, 1541, 1541,
+ /* 170 */ 504, 85, 85, 884, 70, 280, 902, 440, 966, 924,
+ /* 180 */ 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
+ /* 190 */ 232, 232, 232, 232, 232, 232, 1134, 1134, 1134, 232,
+ /* 200 */ 232, 667, 232, 232, 232, 929, 232, 232, 885, 232,
+ /* 210 */ 232, 232, 232, 232, 232, 232, 232, 232, 232, 418,
+ /* 220 */ 678, 981, 981, 981, 981, 766, 271, 911, 510, 429,
+ /* 230 */ 617, 786, 786, 830, 617, 830, 4, 730, 595, 768,
+ /* 240 */ 786, 561, 768, 768, 732, 535, 55, 1165, 1105, 1105,
+ /* 250 */ 1191, 1191, 1105, 1228, 1209, 1130, 1257, 1257, 1257, 1257,
+ /* 260 */ 1105, 1280, 1130, 1228, 1209, 1209, 1130, 1105, 1280, 1198,
+ /* 270 */ 1282, 1105, 1105, 1280, 1328, 1105, 1280, 1105, 1280, 1328,
+ /* 280 */ 1244, 1244, 1244, 1308, 1328, 1244, 1267, 1244, 1308, 1244,
+ /* 290 */ 1244, 1250, 1273, 1250, 1273, 1250, 1273, 1250, 1273, 1105,
+ /* 300 */ 1360, 1105, 1260, 1328, 1306, 1306, 1328, 1274, 1276, 1277,
+ /* 310 */ 1279, 1130, 1379, 1383, 1400, 1400, 1410, 1410, 1410, 1541,
+ /* 320 */ 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541,
+ /* 330 */ 1541, 1541, 1541, 1541, 1541, 34, 407, 463, 511, 417,
+ /* 340 */ 479, 1272, 778, 941, 785, 825, 831, 833, 872, 877,
+ /* 350 */ 756, 793, 900, 804, 919, 1045, 969, 1049, 803, 909,
+ /* 360 */ 1051, 983, 1059, 1428, 1434, 1416, 1300, 1429, 1362, 1430,
+ /* 370 */ 1422, 1424, 1330, 1317, 1340, 1329, 1433, 1331, 1438, 1454,
+ /* 380 */ 1334, 1327, 1406, 1407, 1408, 1409, 1352, 1368, 1431, 1344,
+ /* 390 */ 1466, 1463, 1447, 1363, 1332, 1404, 1448, 1411, 1399, 1435,
+ /* 400 */ 1370, 1451, 1459, 1461, 1369, 1377, 1462, 1417, 1464, 1465,
+ /* 410 */ 1467, 1469, 1419, 1460, 1470, 1423, 1456, 1471, 1472, 1473,
+ /* 420 */ 1474, 1381, 1476, 1478, 1477, 1479, 1380, 1480, 1481, 1412,
+ /* 430 */ 1475, 1484, 1386, 1485, 1482, 1486, 1483, 1490, 1485, 1491,
+ /* 440 */ 1492, 1495, 1493, 1497, 1499, 1496, 1500, 1502, 1498, 1501,
+ /* 450 */ 1503, 1506, 1505, 1501, 1507, 1509, 1510, 1511, 1513, 1403,
+ /* 460 */ 1414, 1415, 1418, 1515, 1517, 1538,
};
-#define YY_REDUCE_USE_DFLT (-174)
-#define YY_REDUCE_COUNT (323)
-#define YY_REDUCE_MIN (-173)
-#define YY_REDUCE_MAX (1292)
+#define YY_REDUCE_COUNT (334)
+#define YY_REDUCE_MIN (-217)
+#define YY_REDUCE_MAX (1278)
static const short yy_reduce_ofst[] = {
- /* 0 */ -119, 1014, 131, 1031, -12, 225, 228, 300, -40, -45,
- /* 10 */ 243, 256, 293, 129, 218, 418, 79, 376, 433, 298,
- /* 20 */ 16, 137, 367, 323, -38, 391, -173, -173, -173, -173,
- /* 30 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
- /* 40 */ -173, -173, -173, -173, -173, -173, -173, -173, -173, -173,
- /* 50 */ -173, -173, -173, -173, -173, -173, -173, -173, 374, 437,
- /* 60 */ 443, 508, 513, 522, 532, 582, 584, 620, 633, 635,
- /* 70 */ 637, 644, 646, 648, 650, 652, 659, 661, 696, 709,
- /* 80 */ 711, 714, 720, 722, 724, 726, 728, 733, 772, 784,
- /* 90 */ 786, 822, 834, 836, 884, 886, 922, 934, 936, 986,
- /* 100 */ 989, 1008, 1016, 1018, -173, -173, -173, -173, -173, -173,
- /* 110 */ -173, -173, -173, 544, -37, 274, 299, 501, 161, -173,
- /* 120 */ 193, -173, -173, -173, -173, 22, 22, 22, 64, 141,
- /* 130 */ 212, 342, 208, 504, 504, 132, 494, 606, 677, 678,
- /* 140 */ 750, 794, 796, -58, 32, 383, 660, 737, 386, 787,
- /* 150 */ 800, 441, 872, 224, 850, 803, 949, 624, 830, 669,
- /* 160 */ 961, 979, 983, 1011, 1013, 1032, 753, 789, 321, 94,
- /* 170 */ 116, 304, 375, 210, 388, 392, 478, 545, 649, 721,
- /* 180 */ 727, 736, 752, 795, 853, 952, 958, 1004, 1040, 1046,
- /* 190 */ 1049, 1050, 1056, 1059, 1067, 559, 774, 811, 1068, 1080,
- /* 200 */ 938, 1082, 1083, 1088, 962, 1089, 1090, 1052, 1093, 1094,
- /* 210 */ 1095, 388, 1096, 1103, 1104, 1105, 1106, 1107, 965, 998,
- /* 220 */ 1055, 1057, 1058, 938, 1069, 1071, 1120, 1073, 1061, 1062,
- /* 230 */ 1033, 1076, 1039, 1108, 1087, 1099, 1111, 1066, 1054, 1112,
- /* 240 */ 1113, 1091, 1084, 1135, 1060, 1133, 1138, 1064, 1081, 1139,
- /* 250 */ 1100, 1119, 1109, 1124, 1127, 1140, 1142, 1168, 1173, 1132,
- /* 260 */ 1115, 1147, 1148, 1137, 1180, 1182, 1110, 1121, 1188, 1189,
- /* 270 */ 1197, 1181, 1200, 1202, 1205, 1203, 1191, 1192, 1199, 1206,
- /* 280 */ 1207, 1209, 1210, 1211, 1214, 1212, 1218, 1219, 1175, 1183,
- /* 290 */ 1185, 1184, 1186, 1190, 1187, 1196, 1237, 1193, 1253, 1194,
- /* 300 */ 1236, 1195, 1198, 1238, 1213, 1221, 1220, 1227, 1229, 1271,
- /* 310 */ 1275, 1284, 1285, 1289, 1290, 1292, 1201, 1208, 1216, 1279,
- /* 320 */ 1280, 1264, 1268, 1282,
+ /* 0 */ -144, -139, -134, -136, -141, 64, 114, 116, -158, -148,
+ /* 10 */ -217, 96, 819, 871, 878, 219, 270, 886, 272, -110,
+ /* 20 */ 413, 918, 972, 228, -214, -214, -214, -214, -214, -214,
+ /* 30 */ -214, -214, -214, -214, -214, -214, -214, -214, -214, -214,
+ /* 40 */ -214, -214, -214, -214, -214, -214, -214, -214, -214, -214,
+ /* 50 */ -214, -214, -214, -214, -214, -214, 62, 323, 377, 536,
+ /* 60 */ 539, 834, 948, 1020, 1024, 1031, 1039, 1048, 1050, 1063,
+ /* 70 */ 1065, 1068, 1074, 1080, 1083, 1088, 1091, 1094, 1097, 1099,
+ /* 80 */ 1103, 1106, 1111, 1114, 1122, 1126, 1129, 1131, 1137, 1139,
+ /* 90 */ 1141, 1145, 1149, 1154, 1156, 1164, 1168, 1173, 1180, 1184,
+ /* 100 */ 1187, 1192, -214, -214, -214, -214, -214, -214, -214, -214,
+ /* 110 */ -214, 132, -45, 97, 8, 164, 379, 175, 255, -214,
+ /* 120 */ 178, -214, -214, -214, -214, -168, -168, -168, 124, 329,
+ /* 130 */ 399, 401, -129, 347, 347, 331, 133, 451, 452, 498,
+ /* 140 */ 500, 502, 503, 505, 487, 506, 488, 490, 507, 543,
+ /* 150 */ 547, -126, 588, 290, 27, 572, 501, 597, 537, 582,
+ /* 160 */ 183, 599, 600, 601, 649, 650, 653, 508, 538, -29,
+ /* 170 */ -156, -152, -137, -79, 135, 74, 130, 242, 338, 378,
+ /* 180 */ 393, 397, 607, 648, 691, 700, 708, 709, 728, 757,
+ /* 190 */ 763, 769, 796, 810, 818, 845, 202, 748, 792, 861,
+ /* 200 */ 862, 815, 866, 903, 905, 850, 931, 932, 896, 937,
+ /* 210 */ 939, 945, 74, 949, 951, 964, 965, 967, 968, 888,
+ /* 220 */ 820, 923, 926, 959, 960, 815, 980, 908, 1009, 985,
+ /* 230 */ 986, 970, 974, 942, 988, 947, 1018, 1011, 1022, 1025,
+ /* 240 */ 991, 982, 1032, 1038, 1015, 1019, 1064, 984, 1071, 1072,
+ /* 250 */ 992, 993, 1085, 1061, 1069, 1067, 1093, 1116, 1124, 1128,
+ /* 260 */ 1133, 1132, 1138, 1086, 1136, 1143, 1146, 1175, 1166, 1108,
+ /* 270 */ 1113, 1193, 1196, 1201, 1178, 1203, 1205, 1208, 1206, 1190,
+ /* 280 */ 1195, 1197, 1199, 1194, 1200, 1204, 1207, 1210, 1211, 1212,
+ /* 290 */ 1213, 1159, 1167, 1169, 1174, 1172, 1176, 1179, 1177, 1222,
+ /* 300 */ 1170, 1232, 1171, 1221, 1181, 1182, 1223, 1202, 1214, 1216,
+ /* 310 */ 1215, 1219, 1245, 1249, 1261, 1262, 1266, 1271, 1275, 1183,
+ /* 320 */ 1185, 1189, 1258, 1253, 1254, 1256, 1259, 1263, 1252, 1255,
+ /* 330 */ 1268, 1269, 1270, 1278, 1264,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 1270, 1260, 1260, 1260, 1193, 1193, 1193, 1193, 1260, 1088,
- /* 10 */ 1117, 1117, 1244, 1322, 1322, 1322, 1322, 1322, 1322, 1192,
- /* 20 */ 1322, 1322, 1322, 1322, 1260, 1092, 1123, 1322, 1322, 1322,
- /* 30 */ 1322, 1194, 1195, 1322, 1322, 1322, 1243, 1245, 1133, 1132,
- /* 40 */ 1131, 1130, 1226, 1104, 1128, 1121, 1125, 1194, 1188, 1189,
- /* 50 */ 1187, 1191, 1195, 1322, 1124, 1158, 1172, 1157, 1322, 1322,
- /* 60 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 70 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 80 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 90 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 100 */ 1322, 1322, 1322, 1322, 1166, 1171, 1178, 1170, 1167, 1160,
- /* 110 */ 1159, 1161, 1162, 1322, 1011, 1059, 1322, 1322, 1322, 1163,
- /* 120 */ 1322, 1164, 1175, 1174, 1173, 1251, 1278, 1277, 1322, 1322,
- /* 130 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 140 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 150 */ 1322, 1322, 1322, 1322, 1322, 1270, 1260, 1017, 1017, 1322,
- /* 160 */ 1260, 1260, 1260, 1260, 1260, 1260, 1256, 1092, 1083, 1322,
- /* 170 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 180 */ 1248, 1246, 1322, 1208, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 190 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 200 */ 1322, 1322, 1322, 1322, 1088, 1322, 1322, 1322, 1322, 1322,
- /* 210 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1272, 1322, 1221,
- /* 220 */ 1088, 1088, 1088, 1090, 1072, 1082, 997, 1127, 1106, 1106,
- /* 230 */ 1311, 1127, 1311, 1034, 1292, 1031, 1117, 1106, 1190, 1117,
- /* 240 */ 1117, 1089, 1082, 1322, 1314, 1097, 1097, 1313, 1313, 1097,
- /* 250 */ 1138, 1062, 1127, 1068, 1068, 1068, 1068, 1097, 1008, 1127,
- /* 260 */ 1138, 1062, 1062, 1127, 1097, 1008, 1225, 1308, 1097, 1097,
- /* 270 */ 1008, 1201, 1097, 1008, 1097, 1008, 1201, 1060, 1060, 1060,
- /* 280 */ 1049, 1201, 1060, 1034, 1060, 1049, 1060, 1060, 1110, 1105,
- /* 290 */ 1110, 1105, 1110, 1105, 1110, 1105, 1097, 1196, 1097, 1322,
- /* 300 */ 1201, 1205, 1205, 1201, 1122, 1111, 1120, 1118, 1127, 1014,
- /* 310 */ 1052, 1275, 1275, 1271, 1271, 1271, 1319, 1319, 1256, 1287,
- /* 320 */ 1287, 1036, 1036, 1287, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 330 */ 1282, 1322, 1210, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 340 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 350 */ 1322, 1143, 1322, 993, 1253, 1322, 1322, 1252, 1322, 1322,
- /* 360 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 370 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1310, 1322,
- /* 380 */ 1322, 1322, 1322, 1322, 1322, 1224, 1223, 1322, 1322, 1322,
- /* 390 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 400 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322,
- /* 410 */ 1074, 1322, 1322, 1322, 1296, 1322, 1322, 1322, 1322, 1322,
- /* 420 */ 1322, 1322, 1119, 1322, 1112, 1322, 1322, 1301, 1322, 1322,
- /* 430 */ 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1322, 1262, 1322,
- /* 440 */ 1322, 1322, 1261, 1322, 1322, 1322, 1322, 1322, 1145, 1322,
- /* 450 */ 1144, 1148, 1322, 1002, 1322,
+ /* 0 */ 1286, 1276, 1276, 1276, 1209, 1209, 1209, 1209, 1133, 1133,
+ /* 10 */ 1260, 1036, 1005, 1005, 1005, 1005, 1005, 1005, 1208, 1005,
+ /* 20 */ 1005, 1005, 1005, 1108, 1139, 1005, 1005, 1005, 1005, 1210,
+ /* 30 */ 1211, 1005, 1005, 1005, 1259, 1261, 1149, 1148, 1147, 1146,
+ /* 40 */ 1242, 1120, 1144, 1137, 1141, 1210, 1204, 1205, 1203, 1207,
+ /* 50 */ 1211, 1005, 1140, 1174, 1188, 1173, 1005, 1005, 1005, 1005,
+ /* 60 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 70 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 80 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 90 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 100 */ 1005, 1005, 1182, 1187, 1194, 1186, 1183, 1176, 1175, 1177,
+ /* 110 */ 1178, 1005, 1026, 1075, 1005, 1005, 1005, 1276, 1036, 1179,
+ /* 120 */ 1005, 1180, 1191, 1190, 1189, 1267, 1294, 1293, 1005, 1005,
+ /* 130 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 140 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 150 */ 1005, 1005, 1005, 1005, 1005, 1036, 1286, 1276, 1032, 1032,
+ /* 160 */ 1005, 1276, 1276, 1276, 1276, 1276, 1276, 1272, 1108, 1099,
+ /* 170 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 180 */ 1005, 1264, 1262, 1005, 1224, 1005, 1005, 1005, 1005, 1005,
+ /* 190 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 200 */ 1005, 1005, 1005, 1005, 1005, 1104, 1005, 1005, 1005, 1005,
+ /* 210 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1288, 1005,
+ /* 220 */ 1237, 1104, 1104, 1104, 1104, 1106, 1088, 1098, 1036, 1012,
+ /* 230 */ 1143, 1122, 1122, 1327, 1143, 1327, 1050, 1308, 1047, 1133,
+ /* 240 */ 1122, 1206, 1133, 1133, 1105, 1098, 1005, 1330, 1113, 1113,
+ /* 250 */ 1329, 1329, 1113, 1154, 1078, 1143, 1084, 1084, 1084, 1084,
+ /* 260 */ 1113, 1023, 1143, 1154, 1078, 1078, 1143, 1113, 1023, 1241,
+ /* 270 */ 1324, 1113, 1113, 1023, 1217, 1113, 1023, 1113, 1023, 1217,
+ /* 280 */ 1076, 1076, 1076, 1065, 1217, 1076, 1050, 1076, 1065, 1076,
+ /* 290 */ 1076, 1126, 1121, 1126, 1121, 1126, 1121, 1126, 1121, 1113,
+ /* 300 */ 1212, 1113, 1005, 1217, 1221, 1221, 1217, 1138, 1127, 1136,
+ /* 310 */ 1134, 1143, 1029, 1068, 1291, 1291, 1287, 1287, 1287, 1335,
+ /* 320 */ 1335, 1272, 1303, 1036, 1036, 1036, 1036, 1303, 1052, 1052,
+ /* 330 */ 1036, 1036, 1036, 1036, 1303, 1005, 1005, 1005, 1005, 1005,
+ /* 340 */ 1005, 1298, 1005, 1226, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 350 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 360 */ 1005, 1005, 1159, 1005, 1008, 1269, 1005, 1005, 1268, 1005,
+ /* 370 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 380 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1326,
+ /* 390 */ 1005, 1005, 1005, 1005, 1005, 1005, 1240, 1239, 1005, 1005,
+ /* 400 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 410 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005,
+ /* 420 */ 1005, 1090, 1005, 1005, 1005, 1312, 1005, 1005, 1005, 1005,
+ /* 430 */ 1005, 1005, 1005, 1135, 1005, 1128, 1005, 1005, 1317, 1005,
+ /* 440 */ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1278,
+ /* 450 */ 1005, 1005, 1005, 1277, 1005, 1005, 1005, 1005, 1005, 1161,
+ /* 460 */ 1005, 1160, 1164, 1005, 1017, 1005,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -137415,73 +138929,87 @@ static const YYACTIONTYPE yy_default[] = {
static const YYCODETYPE yyFallback[] = {
0, /* $ => nothing */
0, /* SEMI => nothing */
- 27, /* EXPLAIN => ID */
- 27, /* QUERY => ID */
- 27, /* PLAN => ID */
- 27, /* BEGIN => ID */
+ 59, /* EXPLAIN => ID */
+ 59, /* QUERY => ID */
+ 59, /* PLAN => ID */
+ 59, /* BEGIN => ID */
0, /* TRANSACTION => nothing */
- 27, /* DEFERRED => ID */
- 27, /* IMMEDIATE => ID */
- 27, /* EXCLUSIVE => ID */
+ 59, /* DEFERRED => ID */
+ 59, /* IMMEDIATE => ID */
+ 59, /* EXCLUSIVE => ID */
0, /* COMMIT => nothing */
- 27, /* END => ID */
- 27, /* ROLLBACK => ID */
- 27, /* SAVEPOINT => ID */
- 27, /* RELEASE => ID */
+ 59, /* END => ID */
+ 59, /* ROLLBACK => ID */
+ 59, /* SAVEPOINT => ID */
+ 59, /* RELEASE => ID */
0, /* TO => nothing */
0, /* TABLE => nothing */
0, /* CREATE => nothing */
- 27, /* IF => ID */
+ 59, /* IF => ID */
0, /* NOT => nothing */
0, /* EXISTS => nothing */
- 27, /* TEMP => ID */
+ 59, /* TEMP => ID */
0, /* LP => nothing */
0, /* RP => nothing */
0, /* AS => nothing */
- 27, /* WITHOUT => ID */
+ 59, /* WITHOUT => ID */
0, /* COMMA => nothing */
+ 59, /* ABORT => ID */
+ 59, /* ACTION => ID */
+ 59, /* AFTER => ID */
+ 59, /* ANALYZE => ID */
+ 59, /* ASC => ID */
+ 59, /* ATTACH => ID */
+ 59, /* BEFORE => ID */
+ 59, /* BY => ID */
+ 59, /* CASCADE => ID */
+ 59, /* CAST => ID */
+ 59, /* CONFLICT => ID */
+ 59, /* DATABASE => ID */
+ 59, /* DESC => ID */
+ 59, /* DETACH => ID */
+ 59, /* EACH => ID */
+ 59, /* FAIL => ID */
+ 0, /* OR => nothing */
+ 0, /* AND => nothing */
+ 0, /* IS => nothing */
+ 59, /* MATCH => ID */
+ 59, /* LIKE_KW => ID */
+ 0, /* BETWEEN => nothing */
+ 0, /* IN => nothing */
+ 0, /* ISNULL => nothing */
+ 0, /* NOTNULL => nothing */
+ 0, /* NE => nothing */
+ 0, /* EQ => nothing */
+ 0, /* GT => nothing */
+ 0, /* LE => nothing */
+ 0, /* LT => nothing */
+ 0, /* GE => nothing */
+ 0, /* ESCAPE => nothing */
0, /* ID => nothing */
- 27, /* ABORT => ID */
- 27, /* ACTION => ID */
- 27, /* AFTER => ID */
- 27, /* ANALYZE => ID */
- 27, /* ASC => ID */
- 27, /* ATTACH => ID */
- 27, /* BEFORE => ID */
- 27, /* BY => ID */
- 27, /* CASCADE => ID */
- 27, /* CAST => ID */
- 27, /* COLUMNKW => ID */
- 27, /* CONFLICT => ID */
- 27, /* DATABASE => ID */
- 27, /* DESC => ID */
- 27, /* DETACH => ID */
- 27, /* EACH => ID */
- 27, /* FAIL => ID */
- 27, /* FOR => ID */
- 27, /* IGNORE => ID */
- 27, /* INITIALLY => ID */
- 27, /* INSTEAD => ID */
- 27, /* LIKE_KW => ID */
- 27, /* MATCH => ID */
- 27, /* NO => ID */
- 27, /* KEY => ID */
- 27, /* OF => ID */
- 27, /* OFFSET => ID */
- 27, /* PRAGMA => ID */
- 27, /* RAISE => ID */
- 27, /* RECURSIVE => ID */
- 27, /* REPLACE => ID */
- 27, /* RESTRICT => ID */
- 27, /* ROW => ID */
- 27, /* TRIGGER => ID */
- 27, /* VACUUM => ID */
- 27, /* VIEW => ID */
- 27, /* VIRTUAL => ID */
- 27, /* WITH => ID */
- 27, /* REINDEX => ID */
- 27, /* RENAME => ID */
- 27, /* CTIME_KW => ID */
+ 59, /* COLUMNKW => ID */
+ 59, /* FOR => ID */
+ 59, /* IGNORE => ID */
+ 59, /* INITIALLY => ID */
+ 59, /* INSTEAD => ID */
+ 59, /* NO => ID */
+ 59, /* KEY => ID */
+ 59, /* OF => ID */
+ 59, /* OFFSET => ID */
+ 59, /* PRAGMA => ID */
+ 59, /* RAISE => ID */
+ 59, /* RECURSIVE => ID */
+ 59, /* REPLACE => ID */
+ 59, /* RESTRICT => ID */
+ 59, /* ROW => ID */
+ 59, /* TRIGGER => ID */
+ 59, /* VACUUM => ID */
+ 59, /* VIEW => ID */
+ 59, /* VIRTUAL => ID */
+ 59, /* WITH => ID */
+ 59, /* REINDEX => ID */
+ 59, /* RENAME => ID */
+ 59, /* CTIME_KW => ID */
};
#endif /* YYFALLBACK */
@@ -137564,75 +139092,264 @@ SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){
}
#endif /* NDEBUG */
-#ifndef NDEBUG
+#if defined(YYCOVERAGE) || !defined(NDEBUG)
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const yyTokenName[] = {
- "$", "SEMI", "EXPLAIN", "QUERY",
- "PLAN", "BEGIN", "TRANSACTION", "DEFERRED",
- "IMMEDIATE", "EXCLUSIVE", "COMMIT", "END",
- "ROLLBACK", "SAVEPOINT", "RELEASE", "TO",
- "TABLE", "CREATE", "IF", "NOT",
- "EXISTS", "TEMP", "LP", "RP",
- "AS", "WITHOUT", "COMMA", "ID",
- "ABORT", "ACTION", "AFTER", "ANALYZE",
- "ASC", "ATTACH", "BEFORE", "BY",
- "CASCADE", "CAST", "COLUMNKW", "CONFLICT",
- "DATABASE", "DESC", "DETACH", "EACH",
- "FAIL", "FOR", "IGNORE", "INITIALLY",
- "INSTEAD", "LIKE_KW", "MATCH", "NO",
- "KEY", "OF", "OFFSET", "PRAGMA",
- "RAISE", "RECURSIVE", "REPLACE", "RESTRICT",
- "ROW", "TRIGGER", "VACUUM", "VIEW",
- "VIRTUAL", "WITH", "REINDEX", "RENAME",
- "CTIME_KW", "ANY", "OR", "AND",
- "IS", "BETWEEN", "IN", "ISNULL",
- "NOTNULL", "NE", "EQ", "GT",
- "LE", "LT", "GE", "ESCAPE",
- "BITAND", "BITOR", "LSHIFT", "RSHIFT",
- "PLUS", "MINUS", "STAR", "SLASH",
- "REM", "CONCAT", "COLLATE", "BITNOT",
- "INDEXED", "STRING", "JOIN_KW", "CONSTRAINT",
- "DEFAULT", "NULL", "PRIMARY", "UNIQUE",
- "CHECK", "REFERENCES", "AUTOINCR", "ON",
- "INSERT", "DELETE", "UPDATE", "SET",
- "DEFERRABLE", "FOREIGN", "DROP", "UNION",
- "ALL", "EXCEPT", "INTERSECT", "SELECT",
- "VALUES", "DISTINCT", "DOT", "FROM",
- "JOIN", "USING", "ORDER", "GROUP",
- "HAVING", "LIMIT", "WHERE", "INTO",
- "FLOAT", "BLOB", "INTEGER", "VARIABLE",
- "CASE", "WHEN", "THEN", "ELSE",
- "INDEX", "ALTER", "ADD", "error",
- "input", "cmdlist", "ecmd", "explain",
- "cmdx", "cmd", "transtype", "trans_opt",
- "nm", "savepoint_opt", "create_table", "create_table_args",
- "createkw", "temp", "ifnotexists", "dbnm",
- "columnlist", "conslist_opt", "table_options", "select",
- "columnname", "carglist", "typetoken", "typename",
- "signed", "plus_num", "minus_num", "ccons",
- "term", "expr", "onconf", "sortorder",
- "autoinc", "eidlist_opt", "refargs", "defer_subclause",
- "refarg", "refact", "init_deferred_pred_opt", "conslist",
- "tconscomma", "tcons", "sortlist", "eidlist",
- "defer_subclause_opt", "orconf", "resolvetype", "raisetype",
- "ifexists", "fullname", "selectnowith", "oneselect",
- "with", "multiselect_op", "distinct", "selcollist",
- "from", "where_opt", "groupby_opt", "having_opt",
- "orderby_opt", "limit_opt", "values", "nexprlist",
- "exprlist", "sclp", "as", "seltablist",
- "stl_prefix", "joinop", "indexed_opt", "on_opt",
- "using_opt", "idlist", "setlist", "insert_cmd",
- "idlist_opt", "likeop", "between_op", "in_op",
- "paren_exprlist", "case_operand", "case_exprlist", "case_else",
- "uniqueflag", "collate", "nmnum", "trigger_decl",
- "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause",
- "when_clause", "trigger_cmd", "trnm", "tridxby",
- "database_kw_opt", "key_opt", "add_column_fullname", "kwcolumn_opt",
- "create_vtab", "vtabarglist", "vtabarg", "vtabargtoken",
- "lp", "anylist", "wqlist",
+ /* 0 */ "$",
+ /* 1 */ "SEMI",
+ /* 2 */ "EXPLAIN",
+ /* 3 */ "QUERY",
+ /* 4 */ "PLAN",
+ /* 5 */ "BEGIN",
+ /* 6 */ "TRANSACTION",
+ /* 7 */ "DEFERRED",
+ /* 8 */ "IMMEDIATE",
+ /* 9 */ "EXCLUSIVE",
+ /* 10 */ "COMMIT",
+ /* 11 */ "END",
+ /* 12 */ "ROLLBACK",
+ /* 13 */ "SAVEPOINT",
+ /* 14 */ "RELEASE",
+ /* 15 */ "TO",
+ /* 16 */ "TABLE",
+ /* 17 */ "CREATE",
+ /* 18 */ "IF",
+ /* 19 */ "NOT",
+ /* 20 */ "EXISTS",
+ /* 21 */ "TEMP",
+ /* 22 */ "LP",
+ /* 23 */ "RP",
+ /* 24 */ "AS",
+ /* 25 */ "WITHOUT",
+ /* 26 */ "COMMA",
+ /* 27 */ "ABORT",
+ /* 28 */ "ACTION",
+ /* 29 */ "AFTER",
+ /* 30 */ "ANALYZE",
+ /* 31 */ "ASC",
+ /* 32 */ "ATTACH",
+ /* 33 */ "BEFORE",
+ /* 34 */ "BY",
+ /* 35 */ "CASCADE",
+ /* 36 */ "CAST",
+ /* 37 */ "CONFLICT",
+ /* 38 */ "DATABASE",
+ /* 39 */ "DESC",
+ /* 40 */ "DETACH",
+ /* 41 */ "EACH",
+ /* 42 */ "FAIL",
+ /* 43 */ "OR",
+ /* 44 */ "AND",
+ /* 45 */ "IS",
+ /* 46 */ "MATCH",
+ /* 47 */ "LIKE_KW",
+ /* 48 */ "BETWEEN",
+ /* 49 */ "IN",
+ /* 50 */ "ISNULL",
+ /* 51 */ "NOTNULL",
+ /* 52 */ "NE",
+ /* 53 */ "EQ",
+ /* 54 */ "GT",
+ /* 55 */ "LE",
+ /* 56 */ "LT",
+ /* 57 */ "GE",
+ /* 58 */ "ESCAPE",
+ /* 59 */ "ID",
+ /* 60 */ "COLUMNKW",
+ /* 61 */ "FOR",
+ /* 62 */ "IGNORE",
+ /* 63 */ "INITIALLY",
+ /* 64 */ "INSTEAD",
+ /* 65 */ "NO",
+ /* 66 */ "KEY",
+ /* 67 */ "OF",
+ /* 68 */ "OFFSET",
+ /* 69 */ "PRAGMA",
+ /* 70 */ "RAISE",
+ /* 71 */ "RECURSIVE",
+ /* 72 */ "REPLACE",
+ /* 73 */ "RESTRICT",
+ /* 74 */ "ROW",
+ /* 75 */ "TRIGGER",
+ /* 76 */ "VACUUM",
+ /* 77 */ "VIEW",
+ /* 78 */ "VIRTUAL",
+ /* 79 */ "WITH",
+ /* 80 */ "REINDEX",
+ /* 81 */ "RENAME",
+ /* 82 */ "CTIME_KW",
+ /* 83 */ "ANY",
+ /* 84 */ "BITAND",
+ /* 85 */ "BITOR",
+ /* 86 */ "LSHIFT",
+ /* 87 */ "RSHIFT",
+ /* 88 */ "PLUS",
+ /* 89 */ "MINUS",
+ /* 90 */ "STAR",
+ /* 91 */ "SLASH",
+ /* 92 */ "REM",
+ /* 93 */ "CONCAT",
+ /* 94 */ "COLLATE",
+ /* 95 */ "BITNOT",
+ /* 96 */ "INDEXED",
+ /* 97 */ "STRING",
+ /* 98 */ "JOIN_KW",
+ /* 99 */ "CONSTRAINT",
+ /* 100 */ "DEFAULT",
+ /* 101 */ "NULL",
+ /* 102 */ "PRIMARY",
+ /* 103 */ "UNIQUE",
+ /* 104 */ "CHECK",
+ /* 105 */ "REFERENCES",
+ /* 106 */ "AUTOINCR",
+ /* 107 */ "ON",
+ /* 108 */ "INSERT",
+ /* 109 */ "DELETE",
+ /* 110 */ "UPDATE",
+ /* 111 */ "SET",
+ /* 112 */ "DEFERRABLE",
+ /* 113 */ "FOREIGN",
+ /* 114 */ "DROP",
+ /* 115 */ "UNION",
+ /* 116 */ "ALL",
+ /* 117 */ "EXCEPT",
+ /* 118 */ "INTERSECT",
+ /* 119 */ "SELECT",
+ /* 120 */ "VALUES",
+ /* 121 */ "DISTINCT",
+ /* 122 */ "DOT",
+ /* 123 */ "FROM",
+ /* 124 */ "JOIN",
+ /* 125 */ "USING",
+ /* 126 */ "ORDER",
+ /* 127 */ "GROUP",
+ /* 128 */ "HAVING",
+ /* 129 */ "LIMIT",
+ /* 130 */ "WHERE",
+ /* 131 */ "INTO",
+ /* 132 */ "FLOAT",
+ /* 133 */ "BLOB",
+ /* 134 */ "INTEGER",
+ /* 135 */ "VARIABLE",
+ /* 136 */ "CASE",
+ /* 137 */ "WHEN",
+ /* 138 */ "THEN",
+ /* 139 */ "ELSE",
+ /* 140 */ "INDEX",
+ /* 141 */ "ALTER",
+ /* 142 */ "ADD",
+ /* 143 */ "error",
+ /* 144 */ "input",
+ /* 145 */ "cmdlist",
+ /* 146 */ "ecmd",
+ /* 147 */ "explain",
+ /* 148 */ "cmdx",
+ /* 149 */ "cmd",
+ /* 150 */ "transtype",
+ /* 151 */ "trans_opt",
+ /* 152 */ "nm",
+ /* 153 */ "savepoint_opt",
+ /* 154 */ "create_table",
+ /* 155 */ "create_table_args",
+ /* 156 */ "createkw",
+ /* 157 */ "temp",
+ /* 158 */ "ifnotexists",
+ /* 159 */ "dbnm",
+ /* 160 */ "columnlist",
+ /* 161 */ "conslist_opt",
+ /* 162 */ "table_options",
+ /* 163 */ "select",
+ /* 164 */ "columnname",
+ /* 165 */ "carglist",
+ /* 166 */ "typetoken",
+ /* 167 */ "typename",
+ /* 168 */ "signed",
+ /* 169 */ "plus_num",
+ /* 170 */ "minus_num",
+ /* 171 */ "scanpt",
+ /* 172 */ "ccons",
+ /* 173 */ "term",
+ /* 174 */ "expr",
+ /* 175 */ "onconf",
+ /* 176 */ "sortorder",
+ /* 177 */ "autoinc",
+ /* 178 */ "eidlist_opt",
+ /* 179 */ "refargs",
+ /* 180 */ "defer_subclause",
+ /* 181 */ "refarg",
+ /* 182 */ "refact",
+ /* 183 */ "init_deferred_pred_opt",
+ /* 184 */ "conslist",
+ /* 185 */ "tconscomma",
+ /* 186 */ "tcons",
+ /* 187 */ "sortlist",
+ /* 188 */ "eidlist",
+ /* 189 */ "defer_subclause_opt",
+ /* 190 */ "orconf",
+ /* 191 */ "resolvetype",
+ /* 192 */ "raisetype",
+ /* 193 */ "ifexists",
+ /* 194 */ "fullname",
+ /* 195 */ "selectnowith",
+ /* 196 */ "oneselect",
+ /* 197 */ "with",
+ /* 198 */ "multiselect_op",
+ /* 199 */ "distinct",
+ /* 200 */ "selcollist",
+ /* 201 */ "from",
+ /* 202 */ "where_opt",
+ /* 203 */ "groupby_opt",
+ /* 204 */ "having_opt",
+ /* 205 */ "orderby_opt",
+ /* 206 */ "limit_opt",
+ /* 207 */ "values",
+ /* 208 */ "nexprlist",
+ /* 209 */ "exprlist",
+ /* 210 */ "sclp",
+ /* 211 */ "as",
+ /* 212 */ "seltablist",
+ /* 213 */ "stl_prefix",
+ /* 214 */ "joinop",
+ /* 215 */ "indexed_opt",
+ /* 216 */ "on_opt",
+ /* 217 */ "using_opt",
+ /* 218 */ "idlist",
+ /* 219 */ "setlist",
+ /* 220 */ "insert_cmd",
+ /* 221 */ "idlist_opt",
+ /* 222 */ "likeop",
+ /* 223 */ "between_op",
+ /* 224 */ "in_op",
+ /* 225 */ "paren_exprlist",
+ /* 226 */ "case_operand",
+ /* 227 */ "case_exprlist",
+ /* 228 */ "case_else",
+ /* 229 */ "uniqueflag",
+ /* 230 */ "collate",
+ /* 231 */ "nmnum",
+ /* 232 */ "trigger_decl",
+ /* 233 */ "trigger_cmd_list",
+ /* 234 */ "trigger_time",
+ /* 235 */ "trigger_event",
+ /* 236 */ "foreach_clause",
+ /* 237 */ "when_clause",
+ /* 238 */ "trigger_cmd",
+ /* 239 */ "trnm",
+ /* 240 */ "tridxby",
+ /* 241 */ "database_kw_opt",
+ /* 242 */ "key_opt",
+ /* 243 */ "add_column_fullname",
+ /* 244 */ "kwcolumn_opt",
+ /* 245 */ "create_vtab",
+ /* 246 */ "vtabarglist",
+ /* 247 */ "vtabarg",
+ /* 248 */ "vtabargtoken",
+ /* 249 */ "lp",
+ /* 250 */ "anylist",
+ /* 251 */ "wqlist",
};
-#endif /* NDEBUG */
+#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
@@ -137666,307 +139383,308 @@ static const char *const yyRuleName[] = {
/* 25 */ "typetoken ::= typename LP signed RP",
/* 26 */ "typetoken ::= typename LP signed COMMA signed RP",
/* 27 */ "typename ::= typename ID|STRING",
- /* 28 */ "ccons ::= CONSTRAINT nm",
- /* 29 */ "ccons ::= DEFAULT term",
- /* 30 */ "ccons ::= DEFAULT LP expr RP",
- /* 31 */ "ccons ::= DEFAULT PLUS term",
- /* 32 */ "ccons ::= DEFAULT MINUS term",
- /* 33 */ "ccons ::= DEFAULT ID|INDEXED",
- /* 34 */ "ccons ::= NOT NULL onconf",
- /* 35 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 36 */ "ccons ::= UNIQUE onconf",
- /* 37 */ "ccons ::= CHECK LP expr RP",
- /* 38 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
- /* 39 */ "ccons ::= defer_subclause",
- /* 40 */ "ccons ::= COLLATE ID|STRING",
- /* 41 */ "autoinc ::=",
- /* 42 */ "autoinc ::= AUTOINCR",
- /* 43 */ "refargs ::=",
- /* 44 */ "refargs ::= refargs refarg",
- /* 45 */ "refarg ::= MATCH nm",
- /* 46 */ "refarg ::= ON INSERT refact",
- /* 47 */ "refarg ::= ON DELETE refact",
- /* 48 */ "refarg ::= ON UPDATE refact",
- /* 49 */ "refact ::= SET NULL",
- /* 50 */ "refact ::= SET DEFAULT",
- /* 51 */ "refact ::= CASCADE",
- /* 52 */ "refact ::= RESTRICT",
- /* 53 */ "refact ::= NO ACTION",
- /* 54 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 55 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 56 */ "init_deferred_pred_opt ::=",
- /* 57 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 58 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 59 */ "conslist_opt ::=",
- /* 60 */ "tconscomma ::= COMMA",
- /* 61 */ "tcons ::= CONSTRAINT nm",
- /* 62 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
- /* 63 */ "tcons ::= UNIQUE LP sortlist RP onconf",
- /* 64 */ "tcons ::= CHECK LP expr RP onconf",
- /* 65 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
- /* 66 */ "defer_subclause_opt ::=",
- /* 67 */ "onconf ::=",
- /* 68 */ "onconf ::= ON CONFLICT resolvetype",
- /* 69 */ "orconf ::=",
- /* 70 */ "orconf ::= OR resolvetype",
- /* 71 */ "resolvetype ::= IGNORE",
- /* 72 */ "resolvetype ::= REPLACE",
- /* 73 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 74 */ "ifexists ::= IF EXISTS",
- /* 75 */ "ifexists ::=",
- /* 76 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
- /* 77 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 78 */ "cmd ::= select",
- /* 79 */ "select ::= with selectnowith",
- /* 80 */ "selectnowith ::= selectnowith multiselect_op oneselect",
- /* 81 */ "multiselect_op ::= UNION",
- /* 82 */ "multiselect_op ::= UNION ALL",
- /* 83 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 84 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 85 */ "values ::= VALUES LP nexprlist RP",
- /* 86 */ "values ::= values COMMA LP exprlist RP",
- /* 87 */ "distinct ::= DISTINCT",
- /* 88 */ "distinct ::= ALL",
- /* 89 */ "distinct ::=",
- /* 90 */ "sclp ::=",
- /* 91 */ "selcollist ::= sclp expr as",
- /* 92 */ "selcollist ::= sclp STAR",
- /* 93 */ "selcollist ::= sclp nm DOT STAR",
- /* 94 */ "as ::= AS nm",
- /* 95 */ "as ::=",
- /* 96 */ "from ::=",
- /* 97 */ "from ::= FROM seltablist",
- /* 98 */ "stl_prefix ::= seltablist joinop",
- /* 99 */ "stl_prefix ::=",
- /* 100 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 101 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
- /* 102 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 103 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 104 */ "dbnm ::=",
- /* 105 */ "dbnm ::= DOT nm",
- /* 106 */ "fullname ::= nm dbnm",
- /* 107 */ "joinop ::= COMMA|JOIN",
- /* 108 */ "joinop ::= JOIN_KW JOIN",
- /* 109 */ "joinop ::= JOIN_KW nm JOIN",
- /* 110 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 111 */ "on_opt ::= ON expr",
- /* 112 */ "on_opt ::=",
- /* 113 */ "indexed_opt ::=",
- /* 114 */ "indexed_opt ::= INDEXED BY nm",
- /* 115 */ "indexed_opt ::= NOT INDEXED",
- /* 116 */ "using_opt ::= USING LP idlist RP",
- /* 117 */ "using_opt ::=",
- /* 118 */ "orderby_opt ::=",
- /* 119 */ "orderby_opt ::= ORDER BY sortlist",
- /* 120 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 121 */ "sortlist ::= expr sortorder",
- /* 122 */ "sortorder ::= ASC",
- /* 123 */ "sortorder ::= DESC",
- /* 124 */ "sortorder ::=",
- /* 125 */ "groupby_opt ::=",
- /* 126 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 127 */ "having_opt ::=",
- /* 128 */ "having_opt ::= HAVING expr",
- /* 129 */ "limit_opt ::=",
- /* 130 */ "limit_opt ::= LIMIT expr",
- /* 131 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 132 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 133 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
- /* 134 */ "where_opt ::=",
- /* 135 */ "where_opt ::= WHERE expr",
- /* 136 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 137 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 138 */ "setlist ::= setlist COMMA LP idlist RP EQ expr",
- /* 139 */ "setlist ::= nm EQ expr",
- /* 140 */ "setlist ::= LP idlist RP EQ expr",
- /* 141 */ "cmd ::= with insert_cmd INTO fullname idlist_opt select",
- /* 142 */ "cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES",
- /* 143 */ "insert_cmd ::= INSERT orconf",
- /* 144 */ "insert_cmd ::= REPLACE",
- /* 145 */ "idlist_opt ::=",
- /* 146 */ "idlist_opt ::= LP idlist RP",
- /* 147 */ "idlist ::= idlist COMMA nm",
- /* 148 */ "idlist ::= nm",
- /* 149 */ "expr ::= LP expr RP",
- /* 150 */ "expr ::= ID|INDEXED",
- /* 151 */ "expr ::= JOIN_KW",
- /* 152 */ "expr ::= nm DOT nm",
- /* 153 */ "expr ::= nm DOT nm DOT nm",
- /* 154 */ "term ::= NULL|FLOAT|BLOB",
- /* 155 */ "term ::= STRING",
- /* 156 */ "term ::= INTEGER",
- /* 157 */ "expr ::= VARIABLE",
- /* 158 */ "expr ::= expr COLLATE ID|STRING",
- /* 159 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 160 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
- /* 161 */ "expr ::= ID|INDEXED LP STAR RP",
- /* 162 */ "term ::= CTIME_KW",
- /* 163 */ "expr ::= LP nexprlist COMMA expr RP",
- /* 164 */ "expr ::= expr AND expr",
- /* 165 */ "expr ::= expr OR expr",
- /* 166 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 167 */ "expr ::= expr EQ|NE expr",
- /* 168 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 169 */ "expr ::= expr PLUS|MINUS expr",
- /* 170 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 171 */ "expr ::= expr CONCAT expr",
- /* 172 */ "likeop ::= NOT LIKE_KW|MATCH",
- /* 173 */ "expr ::= expr likeop expr",
- /* 174 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 175 */ "expr ::= expr ISNULL|NOTNULL",
- /* 176 */ "expr ::= expr NOT NULL",
- /* 177 */ "expr ::= expr IS expr",
- /* 178 */ "expr ::= expr IS NOT expr",
- /* 179 */ "expr ::= NOT expr",
- /* 180 */ "expr ::= BITNOT expr",
- /* 181 */ "expr ::= MINUS expr",
- /* 182 */ "expr ::= PLUS expr",
- /* 183 */ "between_op ::= BETWEEN",
- /* 184 */ "between_op ::= NOT BETWEEN",
- /* 185 */ "expr ::= expr between_op expr AND expr",
- /* 186 */ "in_op ::= IN",
- /* 187 */ "in_op ::= NOT IN",
- /* 188 */ "expr ::= expr in_op LP exprlist RP",
- /* 189 */ "expr ::= LP select RP",
- /* 190 */ "expr ::= expr in_op LP select RP",
- /* 191 */ "expr ::= expr in_op nm dbnm paren_exprlist",
- /* 192 */ "expr ::= EXISTS LP select RP",
- /* 193 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 194 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 195 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 196 */ "case_else ::= ELSE expr",
- /* 197 */ "case_else ::=",
- /* 198 */ "case_operand ::= expr",
- /* 199 */ "case_operand ::=",
- /* 200 */ "exprlist ::=",
- /* 201 */ "nexprlist ::= nexprlist COMMA expr",
- /* 202 */ "nexprlist ::= expr",
- /* 203 */ "paren_exprlist ::=",
- /* 204 */ "paren_exprlist ::= LP exprlist RP",
- /* 205 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
- /* 206 */ "uniqueflag ::= UNIQUE",
- /* 207 */ "uniqueflag ::=",
- /* 208 */ "eidlist_opt ::=",
- /* 209 */ "eidlist_opt ::= LP eidlist RP",
- /* 210 */ "eidlist ::= eidlist COMMA nm collate sortorder",
- /* 211 */ "eidlist ::= nm collate sortorder",
- /* 212 */ "collate ::=",
- /* 213 */ "collate ::= COLLATE ID|STRING",
- /* 214 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 215 */ "cmd ::= VACUUM",
- /* 216 */ "cmd ::= VACUUM nm",
- /* 217 */ "cmd ::= PRAGMA nm dbnm",
- /* 218 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 219 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 220 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 221 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 222 */ "plus_num ::= PLUS INTEGER|FLOAT",
- /* 223 */ "minus_num ::= MINUS INTEGER|FLOAT",
- /* 224 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 225 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 226 */ "trigger_time ::= BEFORE|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 */ "likeop ::= LIKE_KW|MATCH",
- /* 308 */ "exprlist ::= nexprlist",
- /* 309 */ "nmnum ::= plus_num",
- /* 310 */ "nmnum ::= nm",
- /* 311 */ "nmnum ::= ON",
- /* 312 */ "nmnum ::= DELETE",
- /* 313 */ "nmnum ::= DEFAULT",
- /* 314 */ "plus_num ::= INTEGER|FLOAT",
- /* 315 */ "foreach_clause ::=",
- /* 316 */ "foreach_clause ::= FOR EACH ROW",
- /* 317 */ "trnm ::= nm",
- /* 318 */ "tridxby ::=",
- /* 319 */ "database_kw_opt ::= DATABASE",
- /* 320 */ "database_kw_opt ::=",
- /* 321 */ "kwcolumn_opt ::=",
- /* 322 */ "kwcolumn_opt ::= COLUMNKW",
- /* 323 */ "vtabarglist ::= vtabarg",
- /* 324 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 325 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 326 */ "anylist ::=",
- /* 327 */ "anylist ::= anylist LP anylist RP",
- /* 328 */ "anylist ::= anylist ANY",
+ /* 28 */ "scanpt ::=",
+ /* 29 */ "ccons ::= CONSTRAINT nm",
+ /* 30 */ "ccons ::= DEFAULT scanpt term scanpt",
+ /* 31 */ "ccons ::= DEFAULT LP expr RP",
+ /* 32 */ "ccons ::= DEFAULT PLUS term scanpt",
+ /* 33 */ "ccons ::= DEFAULT MINUS term scanpt",
+ /* 34 */ "ccons ::= DEFAULT scanpt ID|INDEXED",
+ /* 35 */ "ccons ::= NOT NULL onconf",
+ /* 36 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 37 */ "ccons ::= UNIQUE onconf",
+ /* 38 */ "ccons ::= CHECK LP expr RP",
+ /* 39 */ "ccons ::= REFERENCES nm eidlist_opt refargs",
+ /* 40 */ "ccons ::= defer_subclause",
+ /* 41 */ "ccons ::= COLLATE ID|STRING",
+ /* 42 */ "autoinc ::=",
+ /* 43 */ "autoinc ::= AUTOINCR",
+ /* 44 */ "refargs ::=",
+ /* 45 */ "refargs ::= refargs refarg",
+ /* 46 */ "refarg ::= MATCH nm",
+ /* 47 */ "refarg ::= ON INSERT refact",
+ /* 48 */ "refarg ::= ON DELETE refact",
+ /* 49 */ "refarg ::= ON UPDATE refact",
+ /* 50 */ "refact ::= SET NULL",
+ /* 51 */ "refact ::= SET DEFAULT",
+ /* 52 */ "refact ::= CASCADE",
+ /* 53 */ "refact ::= RESTRICT",
+ /* 54 */ "refact ::= NO ACTION",
+ /* 55 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 56 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 57 */ "init_deferred_pred_opt ::=",
+ /* 58 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 59 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 60 */ "conslist_opt ::=",
+ /* 61 */ "tconscomma ::= COMMA",
+ /* 62 */ "tcons ::= CONSTRAINT nm",
+ /* 63 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf",
+ /* 64 */ "tcons ::= UNIQUE LP sortlist RP onconf",
+ /* 65 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 66 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt",
+ /* 67 */ "defer_subclause_opt ::=",
+ /* 68 */ "onconf ::=",
+ /* 69 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 70 */ "orconf ::=",
+ /* 71 */ "orconf ::= OR resolvetype",
+ /* 72 */ "resolvetype ::= IGNORE",
+ /* 73 */ "resolvetype ::= REPLACE",
+ /* 74 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 75 */ "ifexists ::= IF EXISTS",
+ /* 76 */ "ifexists ::=",
+ /* 77 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select",
+ /* 78 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 79 */ "cmd ::= select",
+ /* 80 */ "select ::= with selectnowith",
+ /* 81 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+ /* 82 */ "multiselect_op ::= UNION",
+ /* 83 */ "multiselect_op ::= UNION ALL",
+ /* 84 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 85 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 86 */ "values ::= VALUES LP nexprlist RP",
+ /* 87 */ "values ::= values COMMA LP exprlist RP",
+ /* 88 */ "distinct ::= DISTINCT",
+ /* 89 */ "distinct ::= ALL",
+ /* 90 */ "distinct ::=",
+ /* 91 */ "sclp ::=",
+ /* 92 */ "selcollist ::= sclp scanpt expr scanpt as",
+ /* 93 */ "selcollist ::= sclp scanpt STAR",
+ /* 94 */ "selcollist ::= sclp scanpt nm DOT STAR",
+ /* 95 */ "as ::= AS nm",
+ /* 96 */ "as ::=",
+ /* 97 */ "from ::=",
+ /* 98 */ "from ::= FROM seltablist",
+ /* 99 */ "stl_prefix ::= seltablist joinop",
+ /* 100 */ "stl_prefix ::=",
+ /* 101 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 102 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
+ /* 103 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 104 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 105 */ "dbnm ::=",
+ /* 106 */ "dbnm ::= DOT nm",
+ /* 107 */ "fullname ::= nm dbnm",
+ /* 108 */ "joinop ::= COMMA|JOIN",
+ /* 109 */ "joinop ::= JOIN_KW JOIN",
+ /* 110 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 111 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 112 */ "on_opt ::= ON expr",
+ /* 113 */ "on_opt ::=",
+ /* 114 */ "indexed_opt ::=",
+ /* 115 */ "indexed_opt ::= INDEXED BY nm",
+ /* 116 */ "indexed_opt ::= NOT INDEXED",
+ /* 117 */ "using_opt ::= USING LP idlist RP",
+ /* 118 */ "using_opt ::=",
+ /* 119 */ "orderby_opt ::=",
+ /* 120 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 121 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 122 */ "sortlist ::= expr sortorder",
+ /* 123 */ "sortorder ::= ASC",
+ /* 124 */ "sortorder ::= DESC",
+ /* 125 */ "sortorder ::=",
+ /* 126 */ "groupby_opt ::=",
+ /* 127 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 128 */ "having_opt ::=",
+ /* 129 */ "having_opt ::= HAVING expr",
+ /* 130 */ "limit_opt ::=",
+ /* 131 */ "limit_opt ::= LIMIT expr",
+ /* 132 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 133 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 134 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
+ /* 135 */ "where_opt ::=",
+ /* 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 ::= 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 */ "expr ::= ID|INDEXED",
+ /* 152 */ "expr ::= JOIN_KW",
+ /* 153 */ "expr ::= nm DOT nm",
+ /* 154 */ "expr ::= nm DOT nm DOT nm",
+ /* 155 */ "term ::= NULL|FLOAT|BLOB",
+ /* 156 */ "term ::= STRING",
+ /* 157 */ "term ::= INTEGER",
+ /* 158 */ "expr ::= VARIABLE",
+ /* 159 */ "expr ::= expr COLLATE ID|STRING",
+ /* 160 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 161 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 162 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 163 */ "term ::= CTIME_KW",
+ /* 164 */ "expr ::= LP nexprlist COMMA expr RP",
+ /* 165 */ "expr ::= expr AND expr",
+ /* 166 */ "expr ::= expr OR expr",
+ /* 167 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 168 */ "expr ::= expr EQ|NE expr",
+ /* 169 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 170 */ "expr ::= expr PLUS|MINUS expr",
+ /* 171 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 172 */ "expr ::= expr CONCAT expr",
+ /* 173 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 174 */ "expr ::= expr likeop expr",
+ /* 175 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 176 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 177 */ "expr ::= expr NOT NULL",
+ /* 178 */ "expr ::= expr IS expr",
+ /* 179 */ "expr ::= expr IS NOT expr",
+ /* 180 */ "expr ::= NOT expr",
+ /* 181 */ "expr ::= BITNOT expr",
+ /* 182 */ "expr ::= MINUS expr",
+ /* 183 */ "expr ::= PLUS expr",
+ /* 184 */ "between_op ::= BETWEEN",
+ /* 185 */ "between_op ::= NOT BETWEEN",
+ /* 186 */ "expr ::= expr between_op expr AND expr",
+ /* 187 */ "in_op ::= IN",
+ /* 188 */ "in_op ::= NOT IN",
+ /* 189 */ "expr ::= expr in_op LP exprlist RP",
+ /* 190 */ "expr ::= LP select RP",
+ /* 191 */ "expr ::= expr in_op LP select RP",
+ /* 192 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+ /* 193 */ "expr ::= EXISTS LP select RP",
+ /* 194 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 195 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 196 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 197 */ "case_else ::= ELSE expr",
+ /* 198 */ "case_else ::=",
+ /* 199 */ "case_operand ::= expr",
+ /* 200 */ "case_operand ::=",
+ /* 201 */ "exprlist ::=",
+ /* 202 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 203 */ "nexprlist ::= expr",
+ /* 204 */ "paren_exprlist ::=",
+ /* 205 */ "paren_exprlist ::= LP exprlist RP",
+ /* 206 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+ /* 207 */ "uniqueflag ::= UNIQUE",
+ /* 208 */ "uniqueflag ::=",
+ /* 209 */ "eidlist_opt ::=",
+ /* 210 */ "eidlist_opt ::= LP eidlist RP",
+ /* 211 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+ /* 212 */ "eidlist ::= nm collate sortorder",
+ /* 213 */ "collate ::=",
+ /* 214 */ "collate ::= COLLATE ID|STRING",
+ /* 215 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 216 */ "cmd ::= VACUUM",
+ /* 217 */ "cmd ::= VACUUM nm",
+ /* 218 */ "cmd ::= PRAGMA nm dbnm",
+ /* 219 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 220 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 221 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 222 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 223 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 224 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 225 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 226 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 227 */ "trigger_time ::= BEFORE|AFTER",
+ /* 228 */ "trigger_time ::= INSTEAD OF",
+ /* 229 */ "trigger_time ::=",
+ /* 230 */ "trigger_event ::= DELETE|INSERT",
+ /* 231 */ "trigger_event ::= UPDATE",
+ /* 232 */ "trigger_event ::= UPDATE OF idlist",
+ /* 233 */ "when_clause ::=",
+ /* 234 */ "when_clause ::= WHEN expr",
+ /* 235 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 236 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 237 */ "trnm ::= nm DOT nm",
+ /* 238 */ "tridxby ::= INDEXED BY nm",
+ /* 239 */ "tridxby ::= NOT INDEXED",
+ /* 240 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt",
+ /* 241 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select scanpt",
+ /* 242 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+ /* 243 */ "trigger_cmd ::= scanpt select scanpt",
+ /* 244 */ "expr ::= RAISE LP IGNORE RP",
+ /* 245 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 246 */ "raisetype ::= ROLLBACK",
+ /* 247 */ "raisetype ::= ABORT",
+ /* 248 */ "raisetype ::= FAIL",
+ /* 249 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 250 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 251 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 252 */ "key_opt ::=",
+ /* 253 */ "key_opt ::= KEY expr",
+ /* 254 */ "cmd ::= REINDEX",
+ /* 255 */ "cmd ::= REINDEX nm dbnm",
+ /* 256 */ "cmd ::= ANALYZE",
+ /* 257 */ "cmd ::= ANALYZE nm dbnm",
+ /* 258 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 259 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+ /* 260 */ "add_column_fullname ::= fullname",
+ /* 261 */ "cmd ::= create_vtab",
+ /* 262 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 263 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 264 */ "vtabarg ::=",
+ /* 265 */ "vtabargtoken ::= ANY",
+ /* 266 */ "vtabargtoken ::= lp anylist RP",
+ /* 267 */ "lp ::= LP",
+ /* 268 */ "with ::=",
+ /* 269 */ "with ::= WITH wqlist",
+ /* 270 */ "with ::= WITH RECURSIVE wqlist",
+ /* 271 */ "wqlist ::= nm eidlist_opt AS LP select RP",
+ /* 272 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP",
+ /* 273 */ "input ::= cmdlist",
+ /* 274 */ "cmdlist ::= cmdlist ecmd",
+ /* 275 */ "cmdlist ::= ecmd",
+ /* 276 */ "ecmd ::= SEMI",
+ /* 277 */ "ecmd ::= explain cmdx SEMI",
+ /* 278 */ "explain ::=",
+ /* 279 */ "trans_opt ::=",
+ /* 280 */ "trans_opt ::= TRANSACTION",
+ /* 281 */ "trans_opt ::= TRANSACTION nm",
+ /* 282 */ "savepoint_opt ::= SAVEPOINT",
+ /* 283 */ "savepoint_opt ::=",
+ /* 284 */ "cmd ::= create_table create_table_args",
+ /* 285 */ "columnlist ::= columnlist COMMA columnname carglist",
+ /* 286 */ "columnlist ::= columnname carglist",
+ /* 287 */ "nm ::= ID|INDEXED",
+ /* 288 */ "nm ::= STRING",
+ /* 289 */ "nm ::= JOIN_KW",
+ /* 290 */ "typetoken ::= typename",
+ /* 291 */ "typename ::= ID|STRING",
+ /* 292 */ "signed ::= plus_num",
+ /* 293 */ "signed ::= minus_num",
+ /* 294 */ "carglist ::= carglist ccons",
+ /* 295 */ "carglist ::=",
+ /* 296 */ "ccons ::= NULL onconf",
+ /* 297 */ "conslist_opt ::= COMMA conslist",
+ /* 298 */ "conslist ::= conslist tconscomma tcons",
+ /* 299 */ "conslist ::= tcons",
+ /* 300 */ "tconscomma ::=",
+ /* 301 */ "defer_subclause_opt ::= defer_subclause",
+ /* 302 */ "resolvetype ::= raisetype",
+ /* 303 */ "selectnowith ::= oneselect",
+ /* 304 */ "oneselect ::= values",
+ /* 305 */ "sclp ::= selcollist COMMA",
+ /* 306 */ "as ::= ID|STRING",
+ /* 307 */ "expr ::= term",
+ /* 308 */ "likeop ::= LIKE_KW|MATCH",
+ /* 309 */ "exprlist ::= nexprlist",
+ /* 310 */ "nmnum ::= plus_num",
+ /* 311 */ "nmnum ::= nm",
+ /* 312 */ "nmnum ::= ON",
+ /* 313 */ "nmnum ::= DELETE",
+ /* 314 */ "nmnum ::= DEFAULT",
+ /* 315 */ "plus_num ::= INTEGER|FLOAT",
+ /* 316 */ "foreach_clause ::=",
+ /* 317 */ "foreach_clause ::= FOR EACH ROW",
+ /* 318 */ "trnm ::= nm",
+ /* 319 */ "tridxby ::=",
+ /* 320 */ "database_kw_opt ::= DATABASE",
+ /* 321 */ "database_kw_opt ::=",
+ /* 322 */ "kwcolumn_opt ::=",
+ /* 323 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 324 */ "vtabarglist ::= vtabarg",
+ /* 325 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 326 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 327 */ "anylist ::=",
+ /* 328 */ "anylist ::= anylist LP anylist RP",
+ /* 329 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
@@ -138088,76 +139806,72 @@ static void yy_destructor(
*/
/********* Begin destructor definitions ***************************************/
case 163: /* select */
- case 194: /* selectnowith */
- case 195: /* oneselect */
- case 206: /* values */
+ case 195: /* selectnowith */
+ case 196: /* oneselect */
+ case 207: /* values */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy243));
+sqlite3SelectDelete(pParse->db, (yypminor->yy387));
}
break;
- case 172: /* term */
- case 173: /* expr */
+ case 173: /* term */
+ case 174: /* expr */
+ case 202: /* where_opt */
+ case 204: /* having_opt */
+ case 216: /* on_opt */
+ case 226: /* case_operand */
+ case 228: /* case_else */
+ case 237: /* when_clause */
+ case 242: /* key_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy314));
}
break;
- case 177: /* eidlist_opt */
- case 186: /* sortlist */
- case 187: /* eidlist */
- case 199: /* selcollist */
- case 202: /* groupby_opt */
- case 204: /* orderby_opt */
- case 207: /* nexprlist */
- case 208: /* exprlist */
- case 209: /* sclp */
- case 218: /* setlist */
- case 224: /* paren_exprlist */
- case 226: /* case_exprlist */
+ case 178: /* eidlist_opt */
+ case 187: /* sortlist */
+ case 188: /* eidlist */
+ case 200: /* selcollist */
+ case 203: /* groupby_opt */
+ case 205: /* orderby_opt */
+ case 208: /* nexprlist */
+ case 209: /* exprlist */
+ case 210: /* sclp */
+ case 219: /* setlist */
+ case 225: /* paren_exprlist */
+ case 227: /* case_exprlist */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy148));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
}
break;
- case 193: /* fullname */
- case 200: /* from */
- case 211: /* seltablist */
- case 212: /* stl_prefix */
+ case 194: /* fullname */
+ case 201: /* from */
+ case 212: /* seltablist */
+ case 213: /* stl_prefix */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy185));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy259));
}
break;
- case 196: /* with */
- case 250: /* wqlist */
+ case 197: /* with */
+ case 251: /* wqlist */
{
-sqlite3WithDelete(pParse->db, (yypminor->yy285));
+sqlite3WithDelete(pParse->db, (yypminor->yy451));
}
break;
- case 201: /* where_opt */
- case 203: /* having_opt */
- case 215: /* on_opt */
- case 225: /* case_operand */
- case 227: /* case_else */
- case 236: /* when_clause */
- case 241: /* key_opt */
+ case 217: /* using_opt */
+ case 218: /* idlist */
+ case 221: /* idlist_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy72));
+sqlite3IdListDelete(pParse->db, (yypminor->yy384));
}
break;
- case 216: /* using_opt */
- case 217: /* idlist */
- case 220: /* idlist_opt */
+ case 233: /* trigger_cmd_list */
+ case 238: /* trigger_cmd */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy254));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203));
}
break;
- case 232: /* trigger_cmd_list */
- case 237: /* trigger_cmd */
+ case 235: /* trigger_event */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145));
-}
- break;
- case 234: /* trigger_event */
-{
-sqlite3IdListDelete(pParse->db, (yypminor->yy332).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
}
break;
/********* End destructor definitions *****************************************/
@@ -138228,6 +139942,43 @@ SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){
}
#endif
+/* This array of booleans keeps track of the parser statement
+** coverage. The element yycoverage[X][Y] is set when the parser
+** is in state X and has a lookahead token Y. In a well-tested
+** systems, every element of this matrix should end up being set.
+*/
+#if defined(YYCOVERAGE)
+static unsigned char yycoverage[YYNSTATE][YYNTOKEN];
+#endif
+
+/*
+** Write into out a description of every state/lookahead combination that
+**
+** (1) has not been used by the parser, and
+** (2) is not a syntax error.
+**
+** Return the number of missed state/lookahead combinations.
+*/
+#if defined(YYCOVERAGE)
+SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){
+ int stateno, iLookAhead, i;
+ int nMissed = 0;
+ for(stateno=0; stateno<YYNSTATE; stateno++){
+ i = yy_shift_ofst[stateno];
+ for(iLookAhead=0; iLookAhead<YYNTOKEN; iLookAhead++){
+ if( yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
+ if( yycoverage[stateno][iLookAhead]==0 ) nMissed++;
+ if( out ){
+ fprintf(out,"State %d lookahead %s %s\n", stateno,
+ yyTokenName[iLookAhead],
+ yycoverage[stateno][iLookAhead] ? "ok" : "missed");
+ }
+ }
+ }
+ return nMissed;
+}
+#endif
+
/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
@@ -138239,13 +139990,18 @@ static unsigned int yy_find_shift_action(
int i;
int stateno = pParser->yytos->stateno;
- if( stateno>=YY_MIN_REDUCE ) return stateno;
+ if( stateno>YY_MAX_SHIFT ) return stateno;
assert( stateno <= YY_SHIFT_COUNT );
+#if defined(YYCOVERAGE)
+ yycoverage[stateno][iLookAhead] = 1;
+#endif
do{
i = yy_shift_ofst[stateno];
+ assert( i>=0 && i+YYNTOKEN<=sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) );
assert( iLookAhead!=YYNOCODE );
+ assert( iLookAhead < YYNTOKEN );
i += iLookAhead;
- if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+ if( yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
@@ -138308,7 +140064,6 @@ static int yy_find_reduce_action(
assert( stateno<=YY_REDUCE_COUNT );
#endif
i = yy_reduce_ofst[stateno];
- assert( i!=YY_REDUCE_USE_DFLT );
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
#ifdef YYERRORSYMBOL
@@ -138346,20 +140101,21 @@ static void yyStackOverflow(yyParser *yypParser){
** Print tracing information for a SHIFT action
*/
#ifndef NDEBUG
-static void yyTraceShift(yyParser *yypParser, int yyNewState){
+static void yyTraceShift(yyParser *yypParser, int yyNewState, const char *zTag){
if( yyTraceFILE ){
if( yyNewState<YYNSTATE ){
- fprintf(yyTraceFILE,"%sShift '%s', go to state %d\n",
- yyTracePrompt,yyTokenName[yypParser->yytos->major],
+ fprintf(yyTraceFILE,"%s%s '%s', go to state %d\n",
+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
yyNewState);
}else{
- fprintf(yyTraceFILE,"%sShift '%s'\n",
- yyTracePrompt,yyTokenName[yypParser->yytos->major]);
+ fprintf(yyTraceFILE,"%s%s '%s', pending reduce %d\n",
+ yyTracePrompt, zTag, yyTokenName[yypParser->yytos->major],
+ yyNewState - YY_MIN_REDUCE);
}
}
}
#else
-# define yyTraceShift(X,Y)
+# define yyTraceShift(X,Y,Z)
#endif
/*
@@ -138401,7 +140157,7 @@ static void yy_shift(
yytos->stateno = (YYACTIONTYPE)yyNewState;
yytos->major = (YYCODETYPE)yyMajor;
yytos->minor.yy0 = yyMinor;
- yyTraceShift(yypParser, yyNewState);
+ yyTraceShift(yypParser, yyNewState, "Shift");
}
/* The following table contains information about every rule that
@@ -138411,335 +140167,336 @@ static const struct {
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
signed char nrhs; /* Negative of the number of RHS symbols in the rule */
} yyRuleInfo[] = {
- { 147, -1 },
- { 147, -3 },
- { 148, -1 },
- { 149, -3 },
- { 150, 0 },
- { 150, -1 },
- { 150, -1 },
- { 150, -1 },
- { 149, -2 },
- { 149, -2 },
- { 149, -2 },
- { 149, -3 },
- { 149, -5 },
- { 154, -6 },
- { 156, -1 },
- { 158, 0 },
- { 158, -3 },
- { 157, -1 },
- { 157, 0 },
- { 155, -5 },
- { 155, -2 },
- { 162, 0 },
- { 162, -2 },
- { 164, -2 },
- { 166, 0 },
- { 166, -4 },
- { 166, -6 },
- { 167, -2 },
- { 171, -2 },
- { 171, -2 },
- { 171, -4 },
- { 171, -3 },
- { 171, -3 },
- { 171, -2 },
- { 171, -3 },
- { 171, -5 },
- { 171, -2 },
- { 171, -4 },
- { 171, -4 },
- { 171, -1 },
- { 171, -2 },
- { 176, 0 },
- { 176, -1 },
- { 178, 0 },
- { 178, -2 },
- { 180, -2 },
- { 180, -3 },
- { 180, -3 },
- { 180, -3 },
- { 181, -2 },
- { 181, -2 },
- { 181, -1 },
- { 181, -1 },
- { 181, -2 },
- { 179, -3 },
- { 179, -2 },
- { 182, 0 },
- { 182, -2 },
- { 182, -2 },
- { 161, 0 },
- { 184, -1 },
- { 185, -2 },
- { 185, -7 },
- { 185, -5 },
- { 185, -5 },
- { 185, -10 },
- { 188, 0 },
- { 174, 0 },
- { 174, -3 },
- { 189, 0 },
- { 189, -2 },
- { 190, -1 },
- { 190, -1 },
- { 149, -4 },
- { 192, -2 },
- { 192, 0 },
- { 149, -9 },
- { 149, -4 },
- { 149, -1 },
- { 163, -2 },
- { 194, -3 },
- { 197, -1 },
- { 197, -2 },
- { 197, -1 },
- { 195, -9 },
- { 206, -4 },
- { 206, -5 },
- { 198, -1 },
- { 198, -1 },
- { 198, 0 },
- { 209, 0 },
- { 199, -3 },
- { 199, -2 },
- { 199, -4 },
- { 210, -2 },
- { 210, 0 },
- { 200, 0 },
- { 200, -2 },
- { 212, -2 },
- { 212, 0 },
- { 211, -7 },
- { 211, -9 },
- { 211, -7 },
- { 211, -7 },
- { 159, 0 },
- { 159, -2 },
- { 193, -2 },
- { 213, -1 },
- { 213, -2 },
- { 213, -3 },
- { 213, -4 },
- { 215, -2 },
- { 215, 0 },
- { 214, 0 },
- { 214, -3 },
- { 214, -2 },
- { 216, -4 },
- { 216, 0 },
- { 204, 0 },
- { 204, -3 },
- { 186, -4 },
- { 186, -2 },
- { 175, -1 },
- { 175, -1 },
- { 175, 0 },
- { 202, 0 },
- { 202, -3 },
- { 203, 0 },
- { 203, -2 },
- { 205, 0 },
- { 205, -2 },
- { 205, -4 },
- { 205, -4 },
- { 149, -6 },
- { 201, 0 },
- { 201, -2 },
- { 149, -8 },
- { 218, -5 },
- { 218, -7 },
- { 218, -3 },
- { 218, -5 },
- { 149, -6 },
- { 149, -7 },
- { 219, -2 },
- { 219, -1 },
- { 220, 0 },
- { 220, -3 },
- { 217, -3 },
- { 217, -1 },
- { 173, -3 },
- { 173, -1 },
- { 173, -1 },
- { 173, -3 },
- { 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 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 173, -3 },
- { 221, -2 },
- { 173, -3 },
- { 173, -5 },
- { 173, -2 },
- { 173, -3 },
- { 173, -3 },
- { 173, -4 },
- { 173, -2 },
- { 173, -2 },
- { 173, -2 },
- { 173, -2 },
- { 222, -1 },
- { 222, -2 },
- { 173, -5 },
- { 223, -1 },
- { 223, -2 },
- { 173, -5 },
- { 173, -3 },
- { 173, -5 },
- { 173, -5 },
- { 173, -4 },
- { 173, -5 },
- { 226, -5 },
- { 226, -4 },
- { 227, -2 },
- { 227, 0 },
- { 225, -1 },
- { 225, 0 },
- { 208, 0 },
- { 207, -3 },
- { 207, -1 },
- { 224, 0 },
- { 224, -3 },
- { 149, -12 },
- { 228, -1 },
- { 228, 0 },
- { 177, 0 },
- { 177, -3 },
- { 187, -5 },
- { 187, -3 },
- { 229, 0 },
- { 229, -2 },
- { 149, -4 },
- { 149, -1 },
- { 149, -2 },
- { 149, -3 },
- { 149, -5 },
- { 149, -6 },
- { 149, -5 },
- { 149, -6 },
- { 169, -2 },
- { 170, -2 },
- { 149, -5 },
- { 231, -11 },
- { 233, -1 },
- { 233, -2 },
- { 233, 0 },
- { 234, -1 },
- { 234, -1 },
- { 234, -3 },
- { 236, 0 },
- { 236, -2 },
- { 232, -3 },
- { 232, -2 },
- { 238, -3 },
- { 239, -3 },
- { 239, -2 },
- { 237, -7 },
- { 237, -5 },
- { 237, -5 },
- { 237, -1 },
- { 173, -4 },
- { 173, -6 },
- { 191, -1 },
- { 191, -1 },
- { 191, -1 },
- { 149, -4 },
- { 149, -6 },
- { 149, -3 },
- { 241, 0 },
- { 241, -2 },
- { 149, -1 },
- { 149, -3 },
- { 149, -1 },
- { 149, -3 },
- { 149, -6 },
- { 149, -7 },
- { 242, -1 },
- { 149, -1 },
- { 149, -4 },
- { 244, -8 },
- { 246, 0 },
- { 247, -1 },
- { 247, -3 },
- { 248, -1 },
- { 196, 0 },
- { 196, -2 },
- { 196, -3 },
- { 250, -6 },
- { 250, -8 },
- { 144, -1 },
- { 145, -2 },
- { 145, -1 },
- { 146, -1 },
- { 146, -3 },
- { 147, 0 },
- { 151, 0 },
- { 151, -1 },
- { 151, -2 },
- { 153, -1 },
- { 153, 0 },
- { 149, -2 },
- { 160, -4 },
- { 160, -2 },
- { 152, -1 },
- { 152, -1 },
- { 152, -1 },
- { 166, -1 },
- { 167, -1 },
- { 168, -1 },
- { 168, -1 },
- { 165, -2 },
- { 165, 0 },
- { 171, -2 },
- { 161, -2 },
- { 183, -3 },
- { 183, -1 },
- { 184, 0 },
- { 188, -1 },
- { 190, -1 },
- { 194, -1 },
- { 195, -1 },
- { 209, -2 },
- { 210, -1 },
- { 173, -1 },
- { 221, -1 },
- { 208, -1 },
- { 230, -1 },
- { 230, -1 },
- { 230, -1 },
- { 230, -1 },
- { 230, -1 },
- { 169, -1 },
- { 235, 0 },
- { 235, -3 },
- { 238, -1 },
- { 239, 0 },
- { 240, -1 },
- { 240, 0 },
- { 243, 0 },
- { 243, -1 },
- { 245, -1 },
- { 245, -3 },
- { 246, -2 },
- { 249, 0 },
- { 249, -4 },
- { 249, -2 },
+ { 147, -1 }, /* (0) explain ::= EXPLAIN */
+ { 147, -3 }, /* (1) explain ::= EXPLAIN QUERY PLAN */
+ { 148, -1 }, /* (2) cmdx ::= cmd */
+ { 149, -3 }, /* (3) cmd ::= BEGIN transtype trans_opt */
+ { 150, 0 }, /* (4) transtype ::= */
+ { 150, -1 }, /* (5) transtype ::= DEFERRED */
+ { 150, -1 }, /* (6) transtype ::= IMMEDIATE */
+ { 150, -1 }, /* (7) transtype ::= EXCLUSIVE */
+ { 149, -2 }, /* (8) cmd ::= COMMIT|END trans_opt */
+ { 149, -2 }, /* (9) cmd ::= ROLLBACK trans_opt */
+ { 149, -2 }, /* (10) cmd ::= SAVEPOINT nm */
+ { 149, -3 }, /* (11) cmd ::= RELEASE savepoint_opt nm */
+ { 149, -5 }, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
+ { 154, -6 }, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
+ { 156, -1 }, /* (14) createkw ::= CREATE */
+ { 158, 0 }, /* (15) ifnotexists ::= */
+ { 158, -3 }, /* (16) ifnotexists ::= IF NOT EXISTS */
+ { 157, -1 }, /* (17) temp ::= TEMP */
+ { 157, 0 }, /* (18) temp ::= */
+ { 155, -5 }, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */
+ { 155, -2 }, /* (20) create_table_args ::= AS select */
+ { 162, 0 }, /* (21) table_options ::= */
+ { 162, -2 }, /* (22) table_options ::= WITHOUT nm */
+ { 164, -2 }, /* (23) columnname ::= nm typetoken */
+ { 166, 0 }, /* (24) typetoken ::= */
+ { 166, -4 }, /* (25) typetoken ::= typename LP signed RP */
+ { 166, -6 }, /* (26) typetoken ::= typename LP signed COMMA signed RP */
+ { 167, -2 }, /* (27) typename ::= typename ID|STRING */
+ { 171, 0 }, /* (28) scanpt ::= */
+ { 172, -2 }, /* (29) ccons ::= CONSTRAINT nm */
+ { 172, -4 }, /* (30) ccons ::= DEFAULT scanpt term scanpt */
+ { 172, -4 }, /* (31) ccons ::= DEFAULT LP expr RP */
+ { 172, -4 }, /* (32) ccons ::= DEFAULT PLUS term scanpt */
+ { 172, -4 }, /* (33) ccons ::= DEFAULT MINUS term scanpt */
+ { 172, -3 }, /* (34) ccons ::= DEFAULT scanpt ID|INDEXED */
+ { 172, -3 }, /* (35) ccons ::= NOT NULL onconf */
+ { 172, -5 }, /* (36) ccons ::= PRIMARY KEY sortorder onconf autoinc */
+ { 172, -2 }, /* (37) ccons ::= UNIQUE onconf */
+ { 172, -4 }, /* (38) ccons ::= CHECK LP expr RP */
+ { 172, -4 }, /* (39) ccons ::= REFERENCES nm eidlist_opt refargs */
+ { 172, -1 }, /* (40) ccons ::= defer_subclause */
+ { 172, -2 }, /* (41) ccons ::= COLLATE ID|STRING */
+ { 177, 0 }, /* (42) autoinc ::= */
+ { 177, -1 }, /* (43) autoinc ::= AUTOINCR */
+ { 179, 0 }, /* (44) refargs ::= */
+ { 179, -2 }, /* (45) refargs ::= refargs refarg */
+ { 181, -2 }, /* (46) refarg ::= MATCH nm */
+ { 181, -3 }, /* (47) refarg ::= ON INSERT refact */
+ { 181, -3 }, /* (48) refarg ::= ON DELETE refact */
+ { 181, -3 }, /* (49) refarg ::= ON UPDATE refact */
+ { 182, -2 }, /* (50) refact ::= SET NULL */
+ { 182, -2 }, /* (51) refact ::= SET DEFAULT */
+ { 182, -1 }, /* (52) refact ::= CASCADE */
+ { 182, -1 }, /* (53) refact ::= RESTRICT */
+ { 182, -2 }, /* (54) refact ::= NO ACTION */
+ { 180, -3 }, /* (55) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+ { 180, -2 }, /* (56) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ { 183, 0 }, /* (57) init_deferred_pred_opt ::= */
+ { 183, -2 }, /* (58) init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ { 183, -2 }, /* (59) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+ { 161, 0 }, /* (60) conslist_opt ::= */
+ { 185, -1 }, /* (61) tconscomma ::= COMMA */
+ { 186, -2 }, /* (62) tcons ::= CONSTRAINT nm */
+ { 186, -7 }, /* (63) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+ { 186, -5 }, /* (64) tcons ::= UNIQUE LP sortlist RP onconf */
+ { 186, -5 }, /* (65) tcons ::= CHECK LP expr RP onconf */
+ { 186, -10 }, /* (66) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ { 189, 0 }, /* (67) defer_subclause_opt ::= */
+ { 175, 0 }, /* (68) onconf ::= */
+ { 175, -3 }, /* (69) onconf ::= ON CONFLICT resolvetype */
+ { 190, 0 }, /* (70) orconf ::= */
+ { 190, -2 }, /* (71) orconf ::= OR resolvetype */
+ { 191, -1 }, /* (72) resolvetype ::= IGNORE */
+ { 191, -1 }, /* (73) resolvetype ::= REPLACE */
+ { 149, -4 }, /* (74) cmd ::= DROP TABLE ifexists fullname */
+ { 193, -2 }, /* (75) ifexists ::= IF EXISTS */
+ { 193, 0 }, /* (76) ifexists ::= */
+ { 149, -9 }, /* (77) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ { 149, -4 }, /* (78) cmd ::= DROP VIEW ifexists fullname */
+ { 149, -1 }, /* (79) cmd ::= select */
+ { 163, -2 }, /* (80) select ::= with selectnowith */
+ { 195, -3 }, /* (81) selectnowith ::= selectnowith multiselect_op oneselect */
+ { 198, -1 }, /* (82) multiselect_op ::= UNION */
+ { 198, -2 }, /* (83) multiselect_op ::= UNION ALL */
+ { 198, -1 }, /* (84) multiselect_op ::= EXCEPT|INTERSECT */
+ { 196, -9 }, /* (85) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ { 207, -4 }, /* (86) values ::= VALUES LP nexprlist RP */
+ { 207, -5 }, /* (87) values ::= values COMMA LP exprlist RP */
+ { 199, -1 }, /* (88) distinct ::= DISTINCT */
+ { 199, -1 }, /* (89) distinct ::= ALL */
+ { 199, 0 }, /* (90) distinct ::= */
+ { 210, 0 }, /* (91) sclp ::= */
+ { 200, -5 }, /* (92) selcollist ::= sclp scanpt expr scanpt as */
+ { 200, -3 }, /* (93) selcollist ::= sclp scanpt STAR */
+ { 200, -5 }, /* (94) selcollist ::= sclp scanpt nm DOT STAR */
+ { 211, -2 }, /* (95) as ::= AS nm */
+ { 211, 0 }, /* (96) as ::= */
+ { 201, 0 }, /* (97) from ::= */
+ { 201, -2 }, /* (98) from ::= FROM seltablist */
+ { 213, -2 }, /* (99) stl_prefix ::= seltablist joinop */
+ { 213, 0 }, /* (100) stl_prefix ::= */
+ { 212, -7 }, /* (101) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ { 212, -9 }, /* (102) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ { 212, -7 }, /* (103) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ { 212, -7 }, /* (104) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ { 159, 0 }, /* (105) dbnm ::= */
+ { 159, -2 }, /* (106) dbnm ::= DOT nm */
+ { 194, -2 }, /* (107) fullname ::= nm dbnm */
+ { 214, -1 }, /* (108) joinop ::= COMMA|JOIN */
+ { 214, -2 }, /* (109) joinop ::= JOIN_KW JOIN */
+ { 214, -3 }, /* (110) joinop ::= JOIN_KW nm JOIN */
+ { 214, -4 }, /* (111) joinop ::= JOIN_KW nm nm JOIN */
+ { 216, -2 }, /* (112) on_opt ::= ON expr */
+ { 216, 0 }, /* (113) on_opt ::= */
+ { 215, 0 }, /* (114) indexed_opt ::= */
+ { 215, -3 }, /* (115) indexed_opt ::= INDEXED BY nm */
+ { 215, -2 }, /* (116) indexed_opt ::= NOT INDEXED */
+ { 217, -4 }, /* (117) using_opt ::= USING LP idlist RP */
+ { 217, 0 }, /* (118) using_opt ::= */
+ { 205, 0 }, /* (119) orderby_opt ::= */
+ { 205, -3 }, /* (120) orderby_opt ::= ORDER BY sortlist */
+ { 187, -4 }, /* (121) sortlist ::= sortlist COMMA expr sortorder */
+ { 187, -2 }, /* (122) sortlist ::= expr sortorder */
+ { 176, -1 }, /* (123) sortorder ::= ASC */
+ { 176, -1 }, /* (124) sortorder ::= DESC */
+ { 176, 0 }, /* (125) sortorder ::= */
+ { 203, 0 }, /* (126) groupby_opt ::= */
+ { 203, -3 }, /* (127) groupby_opt ::= GROUP BY nexprlist */
+ { 204, 0 }, /* (128) having_opt ::= */
+ { 204, -2 }, /* (129) having_opt ::= HAVING expr */
+ { 206, 0 }, /* (130) limit_opt ::= */
+ { 206, -2 }, /* (131) limit_opt ::= LIMIT expr */
+ { 206, -4 }, /* (132) limit_opt ::= LIMIT expr OFFSET expr */
+ { 206, -4 }, /* (133) limit_opt ::= LIMIT expr COMMA expr */
+ { 149, -6 }, /* (134) cmd ::= with DELETE FROM fullname indexed_opt where_opt */
+ { 202, 0 }, /* (135) where_opt ::= */
+ { 202, -2 }, /* (136) where_opt ::= WHERE expr */
+ { 149, -8 }, /* (137) cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
+ { 219, -5 }, /* (138) setlist ::= setlist COMMA nm EQ expr */
+ { 219, -7 }, /* (139) setlist ::= setlist COMMA LP idlist RP EQ expr */
+ { 219, -3 }, /* (140) setlist ::= nm EQ expr */
+ { 219, -5 }, /* (141) setlist ::= LP idlist RP EQ expr */
+ { 149, -6 }, /* (142) cmd ::= with insert_cmd INTO fullname idlist_opt select */
+ { 149, -7 }, /* (143) cmd ::= with insert_cmd INTO fullname idlist_opt DEFAULT VALUES */
+ { 220, -2 }, /* (144) insert_cmd ::= INSERT orconf */
+ { 220, -1 }, /* (145) insert_cmd ::= REPLACE */
+ { 221, 0 }, /* (146) idlist_opt ::= */
+ { 221, -3 }, /* (147) idlist_opt ::= LP idlist RP */
+ { 218, -3 }, /* (148) idlist ::= idlist COMMA nm */
+ { 218, -1 }, /* (149) idlist ::= nm */
+ { 174, -3 }, /* (150) expr ::= LP expr RP */
+ { 174, -1 }, /* (151) expr ::= ID|INDEXED */
+ { 174, -1 }, /* (152) expr ::= JOIN_KW */
+ { 174, -3 }, /* (153) expr ::= nm DOT nm */
+ { 174, -5 }, /* (154) expr ::= nm DOT nm DOT nm */
+ { 173, -1 }, /* (155) term ::= NULL|FLOAT|BLOB */
+ { 173, -1 }, /* (156) term ::= STRING */
+ { 173, -1 }, /* (157) term ::= INTEGER */
+ { 174, -1 }, /* (158) expr ::= VARIABLE */
+ { 174, -3 }, /* (159) expr ::= expr COLLATE ID|STRING */
+ { 174, -6 }, /* (160) expr ::= CAST LP expr AS typetoken RP */
+ { 174, -5 }, /* (161) expr ::= ID|INDEXED LP distinct exprlist RP */
+ { 174, -4 }, /* (162) expr ::= ID|INDEXED LP STAR RP */
+ { 173, -1 }, /* (163) term ::= CTIME_KW */
+ { 174, -5 }, /* (164) expr ::= LP nexprlist COMMA expr RP */
+ { 174, -3 }, /* (165) expr ::= expr AND expr */
+ { 174, -3 }, /* (166) expr ::= expr OR expr */
+ { 174, -3 }, /* (167) expr ::= expr LT|GT|GE|LE expr */
+ { 174, -3 }, /* (168) expr ::= expr EQ|NE expr */
+ { 174, -3 }, /* (169) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+ { 174, -3 }, /* (170) expr ::= expr PLUS|MINUS expr */
+ { 174, -3 }, /* (171) expr ::= expr STAR|SLASH|REM expr */
+ { 174, -3 }, /* (172) expr ::= expr CONCAT expr */
+ { 222, -2 }, /* (173) likeop ::= NOT LIKE_KW|MATCH */
+ { 174, -3 }, /* (174) expr ::= expr likeop expr */
+ { 174, -5 }, /* (175) expr ::= expr likeop expr ESCAPE expr */
+ { 174, -2 }, /* (176) expr ::= expr ISNULL|NOTNULL */
+ { 174, -3 }, /* (177) expr ::= expr NOT NULL */
+ { 174, -3 }, /* (178) expr ::= expr IS expr */
+ { 174, -4 }, /* (179) expr ::= expr IS NOT expr */
+ { 174, -2 }, /* (180) expr ::= NOT expr */
+ { 174, -2 }, /* (181) expr ::= BITNOT expr */
+ { 174, -2 }, /* (182) expr ::= MINUS expr */
+ { 174, -2 }, /* (183) expr ::= PLUS expr */
+ { 223, -1 }, /* (184) between_op ::= BETWEEN */
+ { 223, -2 }, /* (185) between_op ::= NOT BETWEEN */
+ { 174, -5 }, /* (186) expr ::= expr between_op expr AND expr */
+ { 224, -1 }, /* (187) in_op ::= IN */
+ { 224, -2 }, /* (188) in_op ::= NOT IN */
+ { 174, -5 }, /* (189) expr ::= expr in_op LP exprlist RP */
+ { 174, -3 }, /* (190) expr ::= LP select RP */
+ { 174, -5 }, /* (191) expr ::= expr in_op LP select RP */
+ { 174, -5 }, /* (192) expr ::= expr in_op nm dbnm paren_exprlist */
+ { 174, -4 }, /* (193) expr ::= EXISTS LP select RP */
+ { 174, -5 }, /* (194) expr ::= CASE case_operand case_exprlist case_else END */
+ { 227, -5 }, /* (195) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ { 227, -4 }, /* (196) case_exprlist ::= WHEN expr THEN expr */
+ { 228, -2 }, /* (197) case_else ::= ELSE expr */
+ { 228, 0 }, /* (198) case_else ::= */
+ { 226, -1 }, /* (199) case_operand ::= expr */
+ { 226, 0 }, /* (200) case_operand ::= */
+ { 209, 0 }, /* (201) exprlist ::= */
+ { 208, -3 }, /* (202) nexprlist ::= nexprlist COMMA expr */
+ { 208, -1 }, /* (203) nexprlist ::= expr */
+ { 225, 0 }, /* (204) paren_exprlist ::= */
+ { 225, -3 }, /* (205) paren_exprlist ::= LP exprlist RP */
+ { 149, -12 }, /* (206) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ { 229, -1 }, /* (207) uniqueflag ::= UNIQUE */
+ { 229, 0 }, /* (208) uniqueflag ::= */
+ { 178, 0 }, /* (209) eidlist_opt ::= */
+ { 178, -3 }, /* (210) eidlist_opt ::= LP eidlist RP */
+ { 188, -5 }, /* (211) eidlist ::= eidlist COMMA nm collate sortorder */
+ { 188, -3 }, /* (212) eidlist ::= nm collate sortorder */
+ { 230, 0 }, /* (213) collate ::= */
+ { 230, -2 }, /* (214) collate ::= COLLATE ID|STRING */
+ { 149, -4 }, /* (215) cmd ::= DROP INDEX ifexists fullname */
+ { 149, -1 }, /* (216) cmd ::= VACUUM */
+ { 149, -2 }, /* (217) cmd ::= VACUUM nm */
+ { 149, -3 }, /* (218) cmd ::= PRAGMA nm dbnm */
+ { 149, -5 }, /* (219) cmd ::= PRAGMA nm dbnm EQ nmnum */
+ { 149, -6 }, /* (220) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ { 149, -5 }, /* (221) cmd ::= PRAGMA nm dbnm EQ minus_num */
+ { 149, -6 }, /* (222) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ { 169, -2 }, /* (223) plus_num ::= PLUS INTEGER|FLOAT */
+ { 170, -2 }, /* (224) minus_num ::= MINUS INTEGER|FLOAT */
+ { 149, -5 }, /* (225) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ { 232, -11 }, /* (226) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ { 234, -1 }, /* (227) trigger_time ::= BEFORE|AFTER */
+ { 234, -2 }, /* (228) trigger_time ::= INSTEAD OF */
+ { 234, 0 }, /* (229) trigger_time ::= */
+ { 235, -1 }, /* (230) trigger_event ::= DELETE|INSERT */
+ { 235, -1 }, /* (231) trigger_event ::= UPDATE */
+ { 235, -3 }, /* (232) trigger_event ::= UPDATE OF idlist */
+ { 237, 0 }, /* (233) when_clause ::= */
+ { 237, -2 }, /* (234) when_clause ::= WHEN expr */
+ { 233, -3 }, /* (235) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ { 233, -2 }, /* (236) trigger_cmd_list ::= trigger_cmd SEMI */
+ { 239, -3 }, /* (237) trnm ::= nm DOT nm */
+ { 240, -3 }, /* (238) tridxby ::= INDEXED BY nm */
+ { 240, -2 }, /* (239) tridxby ::= NOT INDEXED */
+ { 238, -8 }, /* (240) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+ { 238, -7 }, /* (241) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select scanpt */
+ { 238, -6 }, /* (242) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+ { 238, -3 }, /* (243) trigger_cmd ::= scanpt select scanpt */
+ { 174, -4 }, /* (244) expr ::= RAISE LP IGNORE RP */
+ { 174, -6 }, /* (245) expr ::= RAISE LP raisetype COMMA nm RP */
+ { 192, -1 }, /* (246) raisetype ::= ROLLBACK */
+ { 192, -1 }, /* (247) raisetype ::= ABORT */
+ { 192, -1 }, /* (248) raisetype ::= FAIL */
+ { 149, -4 }, /* (249) cmd ::= DROP TRIGGER ifexists fullname */
+ { 149, -6 }, /* (250) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ { 149, -3 }, /* (251) cmd ::= DETACH database_kw_opt expr */
+ { 242, 0 }, /* (252) key_opt ::= */
+ { 242, -2 }, /* (253) key_opt ::= KEY expr */
+ { 149, -1 }, /* (254) cmd ::= REINDEX */
+ { 149, -3 }, /* (255) cmd ::= REINDEX nm dbnm */
+ { 149, -1 }, /* (256) cmd ::= ANALYZE */
+ { 149, -3 }, /* (257) cmd ::= ANALYZE nm dbnm */
+ { 149, -6 }, /* (258) cmd ::= ALTER TABLE fullname RENAME TO nm */
+ { 149, -7 }, /* (259) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ { 243, -1 }, /* (260) add_column_fullname ::= fullname */
+ { 149, -1 }, /* (261) cmd ::= create_vtab */
+ { 149, -4 }, /* (262) cmd ::= create_vtab LP vtabarglist RP */
+ { 245, -8 }, /* (263) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ { 247, 0 }, /* (264) vtabarg ::= */
+ { 248, -1 }, /* (265) vtabargtoken ::= ANY */
+ { 248, -3 }, /* (266) vtabargtoken ::= lp anylist RP */
+ { 249, -1 }, /* (267) lp ::= LP */
+ { 197, 0 }, /* (268) with ::= */
+ { 197, -2 }, /* (269) with ::= WITH wqlist */
+ { 197, -3 }, /* (270) with ::= WITH RECURSIVE wqlist */
+ { 251, -6 }, /* (271) wqlist ::= nm eidlist_opt AS LP select RP */
+ { 251, -8 }, /* (272) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ { 144, -1 }, /* (273) input ::= cmdlist */
+ { 145, -2 }, /* (274) cmdlist ::= cmdlist ecmd */
+ { 145, -1 }, /* (275) cmdlist ::= ecmd */
+ { 146, -1 }, /* (276) ecmd ::= SEMI */
+ { 146, -3 }, /* (277) ecmd ::= explain cmdx SEMI */
+ { 147, 0 }, /* (278) explain ::= */
+ { 151, 0 }, /* (279) trans_opt ::= */
+ { 151, -1 }, /* (280) trans_opt ::= TRANSACTION */
+ { 151, -2 }, /* (281) trans_opt ::= TRANSACTION nm */
+ { 153, -1 }, /* (282) savepoint_opt ::= SAVEPOINT */
+ { 153, 0 }, /* (283) savepoint_opt ::= */
+ { 149, -2 }, /* (284) cmd ::= create_table create_table_args */
+ { 160, -4 }, /* (285) columnlist ::= columnlist COMMA columnname carglist */
+ { 160, -2 }, /* (286) columnlist ::= columnname carglist */
+ { 152, -1 }, /* (287) nm ::= ID|INDEXED */
+ { 152, -1 }, /* (288) nm ::= STRING */
+ { 152, -1 }, /* (289) nm ::= JOIN_KW */
+ { 166, -1 }, /* (290) typetoken ::= typename */
+ { 167, -1 }, /* (291) typename ::= ID|STRING */
+ { 168, -1 }, /* (292) signed ::= plus_num */
+ { 168, -1 }, /* (293) signed ::= minus_num */
+ { 165, -2 }, /* (294) carglist ::= carglist ccons */
+ { 165, 0 }, /* (295) carglist ::= */
+ { 172, -2 }, /* (296) ccons ::= NULL onconf */
+ { 161, -2 }, /* (297) conslist_opt ::= COMMA conslist */
+ { 184, -3 }, /* (298) conslist ::= conslist tconscomma tcons */
+ { 184, -1 }, /* (299) conslist ::= tcons */
+ { 185, 0 }, /* (300) tconscomma ::= */
+ { 189, -1 }, /* (301) defer_subclause_opt ::= defer_subclause */
+ { 191, -1 }, /* (302) resolvetype ::= raisetype */
+ { 195, -1 }, /* (303) selectnowith ::= oneselect */
+ { 196, -1 }, /* (304) oneselect ::= values */
+ { 210, -2 }, /* (305) sclp ::= selcollist COMMA */
+ { 211, -1 }, /* (306) as ::= ID|STRING */
+ { 174, -1 }, /* (307) expr ::= term */
+ { 222, -1 }, /* (308) likeop ::= LIKE_KW|MATCH */
+ { 209, -1 }, /* (309) exprlist ::= nexprlist */
+ { 231, -1 }, /* (310) nmnum ::= plus_num */
+ { 231, -1 }, /* (311) nmnum ::= nm */
+ { 231, -1 }, /* (312) nmnum ::= ON */
+ { 231, -1 }, /* (313) nmnum ::= DELETE */
+ { 231, -1 }, /* (314) nmnum ::= DEFAULT */
+ { 169, -1 }, /* (315) plus_num ::= INTEGER|FLOAT */
+ { 236, 0 }, /* (316) foreach_clause ::= */
+ { 236, -3 }, /* (317) foreach_clause ::= FOR EACH ROW */
+ { 239, -1 }, /* (318) trnm ::= nm */
+ { 240, 0 }, /* (319) tridxby ::= */
+ { 241, -1 }, /* (320) database_kw_opt ::= DATABASE */
+ { 241, 0 }, /* (321) database_kw_opt ::= */
+ { 244, 0 }, /* (322) kwcolumn_opt ::= */
+ { 244, -1 }, /* (323) kwcolumn_opt ::= COLUMNKW */
+ { 246, -1 }, /* (324) vtabarglist ::= vtabarg */
+ { 246, -3 }, /* (325) vtabarglist ::= vtabarglist COMMA vtabarg */
+ { 247, -2 }, /* (326) vtabarg ::= vtabarg vtabargtoken */
+ { 250, 0 }, /* (327) anylist ::= */
+ { 250, -4 }, /* (328) anylist ::= anylist LP anylist RP */
+ { 250, -2 }, /* (329) anylist ::= anylist ANY */
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -138747,22 +140504,38 @@ static void yy_accept(yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
+**
+** The yyLookahead and yyLookaheadToken parameters provide reduce actions
+** access to the lookahead token (if any). The yyLookahead will be YYNOCODE
+** if the lookahead token has already been consumed. As this procedure is
+** only called from one place, optimizing compilers will in-line it, which
+** means that the extra parameters have no performance impact.
*/
static void yy_reduce(
yyParser *yypParser, /* The parser */
- unsigned int yyruleno /* Number of the rule by which to reduce */
+ unsigned int yyruleno, /* Number of the rule by which to reduce */
+ int yyLookahead, /* Lookahead token, or YYNOCODE if none */
+ sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */
){
int yygoto; /* The next state */
int yyact; /* The next action */
yyStackEntry *yymsp; /* The top of the parser's stack */
int yysize; /* Amount to pop the stack */
sqlite3ParserARG_FETCH;
+ (void)yyLookahead;
+ (void)yyLookaheadToken;
yymsp = yypParser->yytos;
#ifndef NDEBUG
if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
yysize = yyRuleInfo[yyruleno].nrhs;
- fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt,
- yyRuleName[yyruleno], yymsp[yysize].stateno);
+ if( yysize ){
+ fprintf(yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
+ yyTracePrompt,
+ yyruleno, yyRuleName[yyruleno], yymsp[yysize].stateno);
+ }else{
+ fprintf(yyTraceFILE, "%sReduce %d [%s].\n",
+ yyTracePrompt, yyruleno, yyRuleName[yyruleno]);
+ }
}
#endif /* NDEBUG */
@@ -138813,15 +140586,15 @@ static void yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);}
break;
case 4: /* transtype ::= */
-{yymsp[1].minor.yy194 = TK_DEFERRED;}
+{yymsp[1].minor.yy4 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
-{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/}
+{yymsp[0].minor.yy4 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
@@ -138844,7 +140617,7 @@ static void yy_reduce(
break;
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4);
}
break;
case 14: /* createkw ::= CREATE */
@@ -138853,38 +140626,38 @@ static void yy_reduce(
case 15: /* ifnotexists ::= */
case 18: /* temp ::= */ yytestcase(yyruleno==18);
case 21: /* table_options ::= */ yytestcase(yyruleno==21);
- case 41: /* autoinc ::= */ yytestcase(yyruleno==41);
- case 56: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==56);
- case 66: /* defer_subclause_opt ::= */ yytestcase(yyruleno==66);
- case 75: /* ifexists ::= */ yytestcase(yyruleno==75);
- case 89: /* distinct ::= */ yytestcase(yyruleno==89);
- case 212: /* collate ::= */ yytestcase(yyruleno==212);
-{yymsp[1].minor.yy194 = 0;}
+ case 42: /* autoinc ::= */ yytestcase(yyruleno==42);
+ case 57: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==57);
+ case 67: /* defer_subclause_opt ::= */ yytestcase(yyruleno==67);
+ case 76: /* ifexists ::= */ yytestcase(yyruleno==76);
+ case 90: /* distinct ::= */ yytestcase(yyruleno==90);
+ case 213: /* collate ::= */ yytestcase(yyruleno==213);
+{yymsp[1].minor.yy4 = 0;}
break;
case 16: /* ifnotexists ::= IF NOT EXISTS */
-{yymsp[-2].minor.yy194 = 1;}
+{yymsp[-2].minor.yy4 = 1;}
break;
case 17: /* temp ::= TEMP */
- case 42: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==42);
-{yymsp[0].minor.yy194 = 1;}
+ case 43: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==43);
+{yymsp[0].minor.yy4 = 1;}
break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy194,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy4,0);
}
break;
case 20: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy243);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
}
break;
case 22: /* table_options ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yymsp[-1].minor.yy194 = TF_WithoutRowid | TF_NoVisibleRowid;
+ yymsp[-1].minor.yy4 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
- yymsp[-1].minor.yy194 = 0;
+ yymsp[-1].minor.yy4 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -138893,8 +140666,8 @@ static void yy_reduce(
{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 24: /* typetoken ::= */
- case 59: /* conslist_opt ::= */ yytestcase(yyruleno==59);
- case 95: /* as ::= */ yytestcase(yyruleno==95);
+ case 60: /* conslist_opt ::= */ yytestcase(yyruleno==60);
+ case 96: /* as ::= */ yytestcase(yyruleno==96);
{yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;}
break;
case 25: /* typetoken ::= typename LP signed RP */
@@ -138910,210 +140683,214 @@ static void yy_reduce(
case 27: /* typename ::= typename ID|STRING */
{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
- case 28: /* ccons ::= CONSTRAINT nm */
- case 61: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==61);
+ case 28: /* scanpt ::= */
+{
+ assert( yyLookahead!=YYNOCODE );
+ yymsp[1].minor.yy336 = yyLookaheadToken.z;
+}
+ break;
+ case 29: /* ccons ::= CONSTRAINT nm */
+ case 62: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==62);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
- case 29: /* ccons ::= DEFAULT term */
- case 31: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==31);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);}
+ case 30: /* ccons ::= DEFAULT scanpt term scanpt */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy314,yymsp[-2].minor.yy336,yymsp[0].minor.yy336);}
+ break;
+ case 31: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy314,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
- case 30: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);}
+ case 32: /* ccons ::= DEFAULT PLUS term scanpt */
+{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy314,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy336);}
break;
- case 32: /* ccons ::= DEFAULT MINUS term */
+ case 33: /* ccons ::= DEFAULT MINUS term scanpt */
{
- ExprSpan v;
- 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);
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[-1].minor.yy314, 0);
+ sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy336);
}
break;
- case 33: /* ccons ::= DEFAULT ID|INDEXED */
+ case 34: /* ccons ::= DEFAULT scanpt ID|INDEXED */
{
- ExprSpan v;
- spanExpr(&v, pParse, TK_STRING, yymsp[0].minor.yy0);
- sqlite3AddDefaultValue(pParse,&v);
+ Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
+ sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
}
break;
- case 34: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);}
+ case 35: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);}
break;
- case 35: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);}
+ case 36: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);}
break;
- case 36: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0,
+ case 37: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 37: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);}
+ case 38: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy314);}
break;
- case 38: /* ccons ::= REFERENCES nm eidlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);}
+ case 39: /* ccons ::= REFERENCES nm eidlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);}
break;
- case 39: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);}
+ case 40: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);}
break;
- case 40: /* ccons ::= COLLATE ID|STRING */
+ case 41: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 43: /* refargs ::= */
-{ yymsp[1].minor.yy194 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ case 44: /* refargs ::= */
+{ yymsp[1].minor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
- case 44: /* refargs ::= refargs refarg */
-{ yymsp[-1].minor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | yymsp[0].minor.yy497.value; }
+ case 45: /* refargs ::= refargs refarg */
+{ yymsp[-1].minor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; }
break;
- case 45: /* refarg ::= MATCH nm */
-{ yymsp[-1].minor.yy497.value = 0; yymsp[-1].minor.yy497.mask = 0x000000; }
+ case 46: /* refarg ::= MATCH nm */
+{ yymsp[-1].minor.yy215.value = 0; yymsp[-1].minor.yy215.mask = 0x000000; }
break;
- case 46: /* refarg ::= ON INSERT refact */
-{ yymsp[-2].minor.yy497.value = 0; yymsp[-2].minor.yy497.mask = 0x000000; }
+ case 47: /* refarg ::= ON INSERT refact */
+{ yymsp[-2].minor.yy215.value = 0; yymsp[-2].minor.yy215.mask = 0x000000; }
break;
- case 47: /* refarg ::= ON DELETE refact */
-{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194; yymsp[-2].minor.yy497.mask = 0x0000ff; }
+ case 48: /* refarg ::= ON DELETE refact */
+{ yymsp[-2].minor.yy215.value = yymsp[0].minor.yy4; yymsp[-2].minor.yy215.mask = 0x0000ff; }
break;
- case 48: /* refarg ::= ON UPDATE refact */
-{ yymsp[-2].minor.yy497.value = yymsp[0].minor.yy194<<8; yymsp[-2].minor.yy497.mask = 0x00ff00; }
+ case 49: /* refarg ::= ON UPDATE refact */
+{ yymsp[-2].minor.yy215.value = yymsp[0].minor.yy4<<8; yymsp[-2].minor.yy215.mask = 0x00ff00; }
break;
- case 49: /* refact ::= SET NULL */
-{ yymsp[-1].minor.yy194 = OE_SetNull; /* EV: R-33326-45252 */}
+ case 50: /* refact ::= SET NULL */
+{ yymsp[-1].minor.yy4 = OE_SetNull; /* EV: R-33326-45252 */}
break;
- case 50: /* refact ::= SET DEFAULT */
-{ yymsp[-1].minor.yy194 = OE_SetDflt; /* EV: R-33326-45252 */}
+ case 51: /* refact ::= SET DEFAULT */
+{ yymsp[-1].minor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
- case 51: /* refact ::= CASCADE */
-{ yymsp[0].minor.yy194 = OE_Cascade; /* EV: R-33326-45252 */}
+ case 52: /* refact ::= CASCADE */
+{ yymsp[0].minor.yy4 = OE_Cascade; /* EV: R-33326-45252 */}
break;
- case 52: /* refact ::= RESTRICT */
-{ yymsp[0].minor.yy194 = OE_Restrict; /* EV: R-33326-45252 */}
+ case 53: /* refact ::= RESTRICT */
+{ yymsp[0].minor.yy4 = OE_Restrict; /* EV: R-33326-45252 */}
break;
- case 53: /* refact ::= NO ACTION */
-{ yymsp[-1].minor.yy194 = OE_None; /* EV: R-33326-45252 */}
+ case 54: /* refact ::= NO ACTION */
+{ yymsp[-1].minor.yy4 = OE_None; /* EV: R-33326-45252 */}
break;
- case 54: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
-{yymsp[-2].minor.yy194 = 0;}
+ case 55: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
+{yymsp[-2].minor.yy4 = 0;}
break;
- case 55: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 70: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==70);
- case 143: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==143);
-{yymsp[-1].minor.yy194 = yymsp[0].minor.yy194;}
+ case 56: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 71: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==71);
+ case 144: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==144);
+{yymsp[-1].minor.yy4 = yymsp[0].minor.yy4;}
break;
- case 57: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
- case 74: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==74);
- case 184: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==184);
- case 187: /* in_op ::= NOT IN */ yytestcase(yyruleno==187);
- case 213: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==213);
-{yymsp[-1].minor.yy194 = 1;}
+ case 58: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
+ case 75: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==75);
+ case 185: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==185);
+ case 188: /* in_op ::= NOT IN */ yytestcase(yyruleno==188);
+ case 214: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==214);
+{yymsp[-1].minor.yy4 = 1;}
break;
- case 58: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
-{yymsp[-1].minor.yy194 = 0;}
+ case 59: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
+{yymsp[-1].minor.yy4 = 0;}
break;
- case 60: /* tconscomma ::= COMMA */
+ case 61: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 62: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);}
+ case 63: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);}
break;
- case 63: /* tcons ::= UNIQUE LP sortlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0,
+ case 64: /* tcons ::= UNIQUE LP sortlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
- case 64: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);}
+ case 65: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy314);}
break;
- case 65: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
+ case 66: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4);
}
break;
- case 67: /* onconf ::= */
- case 69: /* orconf ::= */ yytestcase(yyruleno==69);
-{yymsp[1].minor.yy194 = OE_Default;}
+ case 68: /* onconf ::= */
+ case 70: /* orconf ::= */ yytestcase(yyruleno==70);
+{yymsp[1].minor.yy4 = OE_Default;}
break;
- case 68: /* onconf ::= ON CONFLICT resolvetype */
-{yymsp[-2].minor.yy194 = yymsp[0].minor.yy194;}
+ case 69: /* onconf ::= ON CONFLICT resolvetype */
+{yymsp[-2].minor.yy4 = yymsp[0].minor.yy4;}
break;
- case 71: /* resolvetype ::= IGNORE */
-{yymsp[0].minor.yy194 = OE_Ignore;}
+ case 72: /* resolvetype ::= IGNORE */
+{yymsp[0].minor.yy4 = OE_Ignore;}
break;
- case 72: /* resolvetype ::= REPLACE */
- case 144: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==144);
-{yymsp[0].minor.yy194 = OE_Replace;}
+ case 73: /* resolvetype ::= REPLACE */
+ case 145: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==145);
+{yymsp[0].minor.yy4 = OE_Replace;}
break;
- case 73: /* cmd ::= DROP TABLE ifexists fullname */
+ case 74: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4);
}
break;
- case 76: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
+ case 77: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
{
- sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[0].minor.yy243, yymsp[-7].minor.yy194, yymsp[-5].minor.yy194);
+ sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy387, yymsp[-7].minor.yy4, yymsp[-5].minor.yy4);
}
break;
- case 77: /* cmd ::= DROP VIEW ifexists fullname */
+ case 78: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4);
}
break;
- case 78: /* cmd ::= select */
+ case 79: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy243, &dest);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243);
+ sqlite3Select(pParse, yymsp[0].minor.yy387, &dest);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
}
break;
- case 79: /* select ::= with selectnowith */
+ case 80: /* select ::= with selectnowith */
{
- Select *p = yymsp[0].minor.yy243;
+ Select *p = yymsp[0].minor.yy387;
if( p ){
- p->pWith = yymsp[-1].minor.yy285;
+ p->pWith = yymsp[-1].minor.yy451;
parserDoubleLinkSelect(pParse, p);
}else{
- sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy285);
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy451);
}
- yymsp[-1].minor.yy243 = p; /*A-overwrites-W*/
+ yymsp[-1].minor.yy387 = p; /*A-overwrites-W*/
}
break;
- case 80: /* selectnowith ::= selectnowith multiselect_op oneselect */
+ case 81: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- Select *pRhs = yymsp[0].minor.yy243;
- Select *pLhs = yymsp[-2].minor.yy243;
+ Select *pRhs = yymsp[0].minor.yy387;
+ Select *pLhs = yymsp[-2].minor.yy387;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
x.n = 0;
parserDoubleLinkSelect(pParse, pRhs);
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
- pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
+ pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
- pRhs->op = (u8)yymsp[-1].minor.yy194;
+ pRhs->op = (u8)yymsp[-1].minor.yy4;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
- if( yymsp[-1].minor.yy194!=TK_ALL ) pParse->hasCompound = 1;
+ if( yymsp[-1].minor.yy4!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
- yymsp[-2].minor.yy243 = pRhs;
+ yymsp[-2].minor.yy387 = pRhs;
}
break;
- case 81: /* multiselect_op ::= UNION */
- case 83: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==83);
-{yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-OP*/}
+ case 82: /* multiselect_op ::= UNION */
+ case 84: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==84);
+{yymsp[0].minor.yy4 = yymsp[0].major; /*A-overwrites-OP*/}
break;
- case 82: /* multiselect_op ::= UNION ALL */
-{yymsp[-1].minor.yy194 = TK_ALL;}
+ case 83: /* multiselect_op ::= UNION ALL */
+{yymsp[-1].minor.yy4 = TK_ALL;}
break;
- case 84: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ case 85: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
#if SELECTTRACE_ENABLED
Token s = yymsp[-8].minor.yy0; /*A-overwrites-S*/
#endif
- yymsp[-8].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset);
+ yymsp[-8].minor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy4,yymsp[0].minor.yy314);
#if SELECTTRACE_ENABLED
/* Populate the Select.zSelName[] string that is used to help with
** query planner debugging, to differentiate between multiple Select
@@ -139124,483 +140901,468 @@ static void yy_reduce(
** comment to be the zSelName value. Otherwise, the label is #N where
** is an integer that is incremented with each SELECT statement seen.
*/
- if( yymsp[-8].minor.yy243!=0 ){
+ if( yymsp[-8].minor.yy387!=0 ){
const char *z = s.z+6;
int i;
- sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "#%d",
+ sqlite3_snprintf(sizeof(yymsp[-8].minor.yy387->zSelName), yymsp[-8].minor.yy387->zSelName, "#%d",
++pParse->nSelect);
while( z[0]==' ' ) z++;
if( z[0]=='/' && z[1]=='*' ){
z += 2;
while( z[0]==' ' ) z++;
for(i=0; sqlite3Isalnum(z[i]); i++){}
- sqlite3_snprintf(sizeof(yymsp[-8].minor.yy243->zSelName), yymsp[-8].minor.yy243->zSelName, "%.*s", i, z);
+ sqlite3_snprintf(sizeof(yymsp[-8].minor.yy387->zSelName), yymsp[-8].minor.yy387->zSelName, "%.*s", i, z);
}
}
#endif /* SELECTRACE_ENABLED */
}
break;
- case 85: /* values ::= VALUES LP nexprlist RP */
+ case 86: /* values ::= VALUES LP nexprlist RP */
{
- yymsp[-3].minor.yy243 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values,0,0);
+ yymsp[-3].minor.yy387 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0);
}
break;
- case 86: /* values ::= values COMMA LP exprlist RP */
+ case 87: /* values ::= values COMMA LP exprlist RP */
{
- Select *pRight, *pLeft = yymsp[-4].minor.yy243;
- pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy148,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
+ Select *pRight, *pLeft = yymsp[-4].minor.yy387;
+ pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
pRight->pPrior = pLeft;
- yymsp[-4].minor.yy243 = pRight;
+ yymsp[-4].minor.yy387 = pRight;
}else{
- yymsp[-4].minor.yy243 = pLeft;
+ yymsp[-4].minor.yy387 = pLeft;
}
}
break;
- case 87: /* distinct ::= DISTINCT */
-{yymsp[0].minor.yy194 = SF_Distinct;}
+ case 88: /* distinct ::= DISTINCT */
+{yymsp[0].minor.yy4 = SF_Distinct;}
break;
- case 88: /* distinct ::= ALL */
-{yymsp[0].minor.yy194 = SF_All;}
+ case 89: /* distinct ::= ALL */
+{yymsp[0].minor.yy4 = SF_All;}
break;
- case 90: /* sclp ::= */
- case 118: /* orderby_opt ::= */ yytestcase(yyruleno==118);
- case 125: /* groupby_opt ::= */ yytestcase(yyruleno==125);
- case 200: /* exprlist ::= */ yytestcase(yyruleno==200);
- case 203: /* paren_exprlist ::= */ yytestcase(yyruleno==203);
- case 208: /* eidlist_opt ::= */ yytestcase(yyruleno==208);
-{yymsp[1].minor.yy148 = 0;}
+ case 91: /* sclp ::= */
+ case 119: /* orderby_opt ::= */ yytestcase(yyruleno==119);
+ case 126: /* groupby_opt ::= */ yytestcase(yyruleno==126);
+ case 201: /* exprlist ::= */ yytestcase(yyruleno==201);
+ case 204: /* paren_exprlist ::= */ yytestcase(yyruleno==204);
+ case 209: /* eidlist_opt ::= */ yytestcase(yyruleno==209);
+{yymsp[1].minor.yy322 = 0;}
break;
- case 91: /* selcollist ::= sclp expr as */
+ case 92: /* selcollist ::= sclp scanpt expr scanpt as */
{
- yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-2].minor.yy148, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yymsp[-2].minor.yy148,&yymsp[-1].minor.yy190);
+ yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy314);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy336,yymsp[-1].minor.yy336);
}
break;
- case 92: /* selcollist ::= sclp STAR */
+ case 93: /* selcollist ::= sclp scanpt STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
- yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
+ yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p);
}
break;
- case 93: /* selcollist ::= sclp nm DOT STAR */
+ case 94: /* selcollist ::= sclp scanpt nm DOT STAR */
{
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);
+ yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot);
}
break;
- case 94: /* as ::= AS nm */
- case 105: /* dbnm ::= DOT nm */ yytestcase(yyruleno==105);
- case 222: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==222);
- case 223: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==223);
+ case 95: /* as ::= AS nm */
+ case 106: /* dbnm ::= DOT nm */ yytestcase(yyruleno==106);
+ case 223: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==223);
+ case 224: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==224);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 96: /* from ::= */
-{yymsp[1].minor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy185));}
+ case 97: /* from ::= */
+{yymsp[1].minor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy259));}
break;
- case 97: /* from ::= FROM seltablist */
+ case 98: /* from ::= FROM seltablist */
{
- yymsp[-1].minor.yy185 = yymsp[0].minor.yy185;
- sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy185);
+ yymsp[-1].minor.yy259 = yymsp[0].minor.yy259;
+ sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy259);
}
break;
- case 98: /* stl_prefix ::= seltablist joinop */
+ case 99: /* stl_prefix ::= seltablist joinop */
{
- if( ALWAYS(yymsp[-1].minor.yy185 && yymsp[-1].minor.yy185->nSrc>0) ) yymsp[-1].minor.yy185->a[yymsp[-1].minor.yy185->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy194;
+ if( ALWAYS(yymsp[-1].minor.yy259 && yymsp[-1].minor.yy259->nSrc>0) ) yymsp[-1].minor.yy259->a[yymsp[-1].minor.yy259->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy4;
}
break;
- case 99: /* stl_prefix ::= */
-{yymsp[1].minor.yy185 = 0;}
+ case 100: /* stl_prefix ::= */
+{yymsp[1].minor.yy259 = 0;}
break;
- case 100: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ case 101: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
- sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy185, &yymsp[-2].minor.yy0);
+ yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy259, &yymsp[-2].minor.yy0);
}
break;
- case 101: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+ case 102: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
{
- yymsp[-8].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy185,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
- sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy185, yymsp[-4].minor.yy148);
+ yymsp[-8].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy259,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy259, yymsp[-4].minor.yy322);
}
break;
- case 102: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 103: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+ yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
}
break;
- case 103: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 104: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
- if( yymsp[-6].minor.yy185==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy72==0 && yymsp[0].minor.yy254==0 ){
- yymsp[-6].minor.yy185 = yymsp[-4].minor.yy185;
- }else if( yymsp[-4].minor.yy185->nSrc==1 ){
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
- if( yymsp[-6].minor.yy185 ){
- struct SrcList_item *pNew = &yymsp[-6].minor.yy185->a[yymsp[-6].minor.yy185->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy185->a;
+ if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){
+ yymsp[-6].minor.yy259 = yymsp[-4].minor.yy259;
+ }else if( yymsp[-4].minor.yy259->nSrc==1 ){
+ yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ if( yymsp[-6].minor.yy259 ){
+ struct SrcList_item *pNew = &yymsp[-6].minor.yy259->a[yymsp[-6].minor.yy259->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy259->a;
pNew->zName = pOld->zName;
pNew->zDatabase = pOld->zDatabase;
pNew->pSelect = pOld->pSelect;
pOld->zName = pOld->zDatabase = 0;
pOld->pSelect = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy185);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy259);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,SF_NestedFrom,0,0);
- yymsp[-6].minor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,SF_NestedFrom,0);
+ yymsp[-6].minor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
}
}
break;
- case 104: /* dbnm ::= */
- case 113: /* indexed_opt ::= */ yytestcase(yyruleno==113);
+ case 105: /* dbnm ::= */
+ case 114: /* indexed_opt ::= */ yytestcase(yyruleno==114);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
- case 106: /* fullname ::= nm dbnm */
-{yymsp[-1].minor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 107: /* fullname ::= nm dbnm */
+{yymsp[-1].minor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 107: /* joinop ::= COMMA|JOIN */
-{ yymsp[0].minor.yy194 = JT_INNER; }
+ case 108: /* joinop ::= COMMA|JOIN */
+{ yymsp[0].minor.yy4 = JT_INNER; }
break;
- case 108: /* joinop ::= JOIN_KW JOIN */
-{yymsp[-1].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
+ case 109: /* joinop ::= JOIN_KW JOIN */
+{yymsp[-1].minor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
- case 109: /* joinop ::= JOIN_KW nm JOIN */
-{yymsp[-2].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
+ case 110: /* joinop ::= JOIN_KW nm JOIN */
+{yymsp[-2].minor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
- case 110: /* joinop ::= JOIN_KW nm nm JOIN */
-{yymsp[-3].minor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
+ case 111: /* joinop ::= JOIN_KW nm nm JOIN */
+{yymsp[-3].minor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
break;
- case 111: /* on_opt ::= ON expr */
- case 128: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==128);
- case 135: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==135);
- case 196: /* case_else ::= ELSE expr */ yytestcase(yyruleno==196);
-{yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr;}
+ 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 197: /* case_else ::= ELSE expr */ yytestcase(yyruleno==197);
+{yymsp[-1].minor.yy314 = yymsp[0].minor.yy314;}
break;
- case 112: /* on_opt ::= */
- case 127: /* having_opt ::= */ yytestcase(yyruleno==127);
- case 134: /* where_opt ::= */ yytestcase(yyruleno==134);
- case 197: /* case_else ::= */ yytestcase(yyruleno==197);
- case 199: /* case_operand ::= */ yytestcase(yyruleno==199);
-{yymsp[1].minor.yy72 = 0;}
+ case 113: /* on_opt ::= */
+ case 128: /* having_opt ::= */ yytestcase(yyruleno==128);
+ case 130: /* limit_opt ::= */ yytestcase(yyruleno==130);
+ case 135: /* where_opt ::= */ yytestcase(yyruleno==135);
+ case 198: /* case_else ::= */ yytestcase(yyruleno==198);
+ case 200: /* case_operand ::= */ yytestcase(yyruleno==200);
+{yymsp[1].minor.yy314 = 0;}
break;
- case 114: /* indexed_opt ::= INDEXED BY nm */
+ case 115: /* indexed_opt ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
- case 115: /* indexed_opt ::= NOT INDEXED */
+ case 116: /* indexed_opt ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
- case 116: /* using_opt ::= USING LP idlist RP */
-{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
+ case 117: /* using_opt ::= USING LP idlist RP */
+{yymsp[-3].minor.yy384 = yymsp[-1].minor.yy384;}
break;
- case 117: /* using_opt ::= */
- case 145: /* idlist_opt ::= */ yytestcase(yyruleno==145);
-{yymsp[1].minor.yy254 = 0;}
+ case 118: /* using_opt ::= */
+ case 146: /* idlist_opt ::= */ yytestcase(yyruleno==146);
+{yymsp[1].minor.yy384 = 0;}
break;
- case 119: /* orderby_opt ::= ORDER BY sortlist */
- case 126: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==126);
-{yymsp[-2].minor.yy148 = yymsp[0].minor.yy148;}
+ case 120: /* orderby_opt ::= ORDER BY sortlist */
+ case 127: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==127);
+{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;}
break;
- case 120: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 121: /* sortlist ::= sortlist COMMA expr sortorder */
{
- yymsp[-3].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy190.pExpr);
- sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy148,yymsp[0].minor.yy194);
+ yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy314);
+ sqlite3ExprListSetSortOrder(yymsp[-3].minor.yy322,yymsp[0].minor.yy4);
}
break;
- case 121: /* sortlist ::= expr sortorder */
+ case 122: /* sortlist ::= expr sortorder */
{
- yymsp[-1].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy190.pExpr); /*A-overwrites-Y*/
- sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy148,yymsp[0].minor.yy194);
+ yymsp[-1].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy314); /*A-overwrites-Y*/
+ sqlite3ExprListSetSortOrder(yymsp[-1].minor.yy322,yymsp[0].minor.yy4);
}
break;
- case 122: /* sortorder ::= ASC */
-{yymsp[0].minor.yy194 = SQLITE_SO_ASC;}
+ case 123: /* sortorder ::= ASC */
+{yymsp[0].minor.yy4 = SQLITE_SO_ASC;}
break;
- case 123: /* sortorder ::= DESC */
-{yymsp[0].minor.yy194 = SQLITE_SO_DESC;}
+ case 124: /* sortorder ::= DESC */
+{yymsp[0].minor.yy4 = SQLITE_SO_DESC;}
break;
- case 124: /* sortorder ::= */
-{yymsp[1].minor.yy194 = SQLITE_SO_UNDEFINED;}
+ case 125: /* sortorder ::= */
+{yymsp[1].minor.yy4 = SQLITE_SO_UNDEFINED;}
break;
- case 129: /* limit_opt ::= */
-{yymsp[1].minor.yy354.pLimit = 0; yymsp[1].minor.yy354.pOffset = 0;}
+ case 131: /* limit_opt ::= LIMIT expr */
+{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy314,0);}
break;
- case 130: /* limit_opt ::= LIMIT expr */
-{yymsp[-1].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yymsp[-1].minor.yy354.pOffset = 0;}
+ case 132: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yymsp[-3].minor.yy314 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy314,yymsp[0].minor.yy314);}
break;
- case 131: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yymsp[-3].minor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;}
+ case 133: /* limit_opt ::= LIMIT expr COMMA expr */
+{yymsp[-3].minor.yy314 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy314,yymsp[-2].minor.yy314);}
break;
- case 132: /* limit_opt ::= LIMIT expr COMMA expr */
-{yymsp[-3].minor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yymsp[-3].minor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;}
- break;
- case 133: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
+ case 134: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
{
- sqlite3WithPush(pParse, yymsp[-5].minor.yy285, 1);
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72);
+ sqlite3WithPush(pParse, yymsp[-5].minor.yy451, 1);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314,0,0);
}
break;
- case 136: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
+ case 137: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
{
- sqlite3WithPush(pParse, yymsp[-7].minor.yy285, 1);
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194);
+ sqlite3WithPush(pParse, yymsp[-7].minor.yy451, 1);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy4,0,0);
}
break;
- case 137: /* setlist ::= setlist COMMA nm EQ expr */
+ case 138: /* setlist ::= setlist COMMA nm EQ expr */
{
- yymsp[-4].minor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
- sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy148, &yymsp[-2].minor.yy0, 1);
+ yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy314);
+ sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1);
}
break;
- case 138: /* setlist ::= setlist COMMA LP idlist RP 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);
+ yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy384, yymsp[0].minor.yy314);
}
break;
- case 139: /* setlist ::= nm EQ expr */
+ 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);
+ yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy314);
+ sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1);
}
- yymsp[-2].minor.yy148 = yylhsminor.yy148;
+ yymsp[-2].minor.yy322 = yylhsminor.yy322;
break;
- case 140: /* setlist ::= LP idlist RP EQ expr */
+ case 141: /* setlist ::= LP idlist RP EQ expr */
{
- yymsp[-4].minor.yy148 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy190.pExpr);
+ yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy384, yymsp[0].minor.yy314);
}
break;
- case 141: /* cmd ::= with insert_cmd INTO fullname idlist_opt select */
+ 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);
+ sqlite3WithPush(pParse, yymsp[-5].minor.yy451, 1);
+ sqlite3Insert(pParse, yymsp[-2].minor.yy259, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy4);
}
break;
- case 142: /* 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);
+ sqlite3WithPush(pParse, yymsp[-6].minor.yy451, 1);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy4);
}
break;
- case 146: /* idlist_opt ::= LP idlist RP */
-{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
+ case 147: /* idlist_opt ::= LP idlist RP */
+{yymsp[-2].minor.yy384 = yymsp[-1].minor.yy384;}
break;
- case 147: /* idlist ::= idlist COMMA nm */
-{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
+ case 148: /* idlist ::= idlist COMMA nm */
+{yymsp[-2].minor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);}
break;
- case 148: /* idlist ::= nm */
-{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
+ case 149: /* idlist ::= nm */
+{yymsp[0].minor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
- case 149: /* 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;}
+ case 150: /* expr ::= LP expr RP */
+{yymsp[-2].minor.yy314 = yymsp[-1].minor.yy314;}
break;
- case 150: /* expr ::= ID|INDEXED */
- case 151: /* expr ::= JOIN_KW */ yytestcase(yyruleno==151);
-{spanExpr(&yymsp[0].minor.yy190,pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 151: /* expr ::= ID|INDEXED */
+ case 152: /* expr ::= JOIN_KW */ yytestcase(yyruleno==152);
+{yymsp[0].minor.yy314=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 152: /* expr ::= nm DOT nm */
+ case 153: /* expr ::= nm DOT nm */
{
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);
+ yylhsminor.yy314 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
+ yymsp[-2].minor.yy314 = yylhsminor.yy314;
break;
- case 153: /* expr ::= nm DOT nm DOT nm */
+ case 154: /* expr ::= nm DOT nm DOT nm */
{
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);
+ yylhsminor.yy314 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
+ yymsp[-4].minor.yy314 = yylhsminor.yy314;
break;
- case 154: /* term ::= NULL|FLOAT|BLOB */
- case 155: /* term ::= STRING */ yytestcase(yyruleno==155);
-{spanExpr(&yymsp[0].minor.yy190,pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
+ case 155: /* term ::= NULL|FLOAT|BLOB */
+ case 156: /* term ::= STRING */ yytestcase(yyruleno==156);
+{yymsp[0].minor.yy314=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
- case 156: /* term ::= INTEGER */
+ case 157: /* 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;
+ yylhsminor.yy314 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
}
- yymsp[0].minor.yy190 = yylhsminor.yy190;
+ yymsp[0].minor.yy314 = yylhsminor.yy314;
break;
- case 157: /* expr ::= VARIABLE */
+ case 158: /* 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, n);
+ yymsp[0].minor.yy314 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy314, 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
** in the virtual machine. #N is the N-th register. */
Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
assert( t.n>=2 );
- spanSet(&yymsp[0].minor.yy190, &t, &t);
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- yymsp[0].minor.yy190.pExpr = 0;
+ yymsp[0].minor.yy314 = 0;
}else{
- 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);
+ yymsp[0].minor.yy314 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( yymsp[0].minor.yy314 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy314->iTable);
}
}
}
break;
- case 158: /* expr ::= expr COLLATE ID|STRING */
+ case 159: /* 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];
+ yymsp[-2].minor.yy314 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy314, &yymsp[0].minor.yy0, 1);
}
break;
- case 159: /* expr ::= CAST LP expr AS typetoken RP */
+ case 160: /* 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 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
- sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy190.pExpr, yymsp[-3].minor.yy190.pExpr, 0);
+ yymsp[-5].minor.yy314 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy314, yymsp[-3].minor.yy314, 0);
}
break;
- case 160: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+ case 161: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
- if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+ if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
- spanSet(&yylhsminor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy194==SF_Distinct && yylhsminor.yy190.pExpr ){
- yylhsminor.yy190.pExpr->flags |= EP_Distinct;
+ yylhsminor.yy314 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
+ if( yymsp[-2].minor.yy4==SF_Distinct && yylhsminor.yy314 ){
+ yylhsminor.yy314->flags |= EP_Distinct;
}
}
- yymsp[-4].minor.yy190 = yylhsminor.yy190;
+ yymsp[-4].minor.yy314 = yylhsminor.yy314;
break;
- case 161: /* expr ::= ID|INDEXED LP STAR RP */
+ case 162: /* 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);
+ yylhsminor.yy314 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
}
- yymsp[-3].minor.yy190 = yylhsminor.yy190;
+ yymsp[-3].minor.yy314 = yylhsminor.yy314;
break;
- case 162: /* term ::= CTIME_KW */
+ case 163: /* term ::= CTIME_KW */
{
- yylhsminor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
- spanSet(&yylhsminor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ yylhsminor.yy314 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
}
- yymsp[0].minor.yy190 = yylhsminor.yy190;
+ yymsp[0].minor.yy314 = yylhsminor.yy314;
break;
- case 163: /* expr ::= LP nexprlist COMMA expr RP */
+ case 164: /* 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);
+ ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy314);
+ yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( yymsp[-4].minor.yy314 ){
+ yymsp[-4].minor.yy314->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
- yymsp[-4].minor.yy190 = yylhsminor.yy190;
break;
- case 164: /* expr ::= expr AND expr */
- case 165: /* expr ::= expr OR expr */ yytestcase(yyruleno==165);
- case 166: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==166);
- case 167: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==167);
- case 168: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==168);
- case 169: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==169);
- case 170: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==170);
- case 171: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==171);
-{spanBinaryExpr(pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
+ case 165: /* expr ::= expr AND expr */
+ case 166: /* expr ::= expr OR expr */ yytestcase(yyruleno==166);
+ case 167: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==167);
+ case 168: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==168);
+ case 169: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==169);
+ case 170: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==170);
+ case 171: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==171);
+ case 172: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==172);
+{yymsp[-2].minor.yy314=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy314,yymsp[0].minor.yy314);}
break;
- case 172: /* likeop ::= NOT LIKE_KW|MATCH */
+ case 173: /* 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 173: /* expr ::= expr likeop expr */
+ case 174: /* 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.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;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy314);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy314);
+ yymsp[-2].minor.yy314 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0);
+ if( bNot ) yymsp[-2].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy314, 0);
+ if( yymsp[-2].minor.yy314 ) yymsp[-2].minor.yy314->flags |= EP_InfixFunc;
}
break;
- case 174: /* expr ::= expr likeop expr ESCAPE expr */
+ case 175: /* 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.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;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy314);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy314);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy314);
+ yymsp[-4].minor.yy314 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0);
+ if( bNot ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
+ if( yymsp[-4].minor.yy314 ) yymsp[-4].minor.yy314->flags |= EP_InfixFunc;
}
break;
- case 175: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
+ case 176: /* expr ::= expr ISNULL|NOTNULL */
+{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy314,0);}
break;
- case 176: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
+ case 177: /* expr ::= expr NOT NULL */
+{yymsp[-2].minor.yy314 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy314,0);}
break;
- case 177: /* expr ::= expr IS expr */
+ case 178: /* 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);
+ yymsp[-2].minor.yy314 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy314,yymsp[0].minor.yy314);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy314, yymsp[-2].minor.yy314, TK_ISNULL);
}
break;
- case 178: /* expr ::= expr IS NOT expr */
+ case 179: /* 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);
+ yymsp[-3].minor.yy314 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy314,yymsp[0].minor.yy314);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy314, yymsp[-3].minor.yy314, TK_NOTNULL);
}
break;
- case 179: /* expr ::= NOT expr */
- case 180: /* expr ::= BITNOT expr */ yytestcase(yyruleno==180);
-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+ case 180: /* expr ::= NOT expr */
+ case 181: /* expr ::= BITNOT expr */ yytestcase(yyruleno==181);
+{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy314, 0);/*A-overwrites-B*/}
break;
- case 181: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+ case 182: /* expr ::= MINUS expr */
+{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy314, 0);}
break;
- case 182: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yymsp[-1].minor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);/*A-overwrites-B*/}
+ case 183: /* expr ::= PLUS expr */
+{yymsp[-1].minor.yy314 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy314, 0);}
break;
- case 183: /* between_op ::= BETWEEN */
- case 186: /* in_op ::= IN */ yytestcase(yyruleno==186);
-{yymsp[0].minor.yy194 = 0;}
+ case 184: /* between_op ::= BETWEEN */
+ case 187: /* in_op ::= IN */ yytestcase(yyruleno==187);
+{yymsp[0].minor.yy4 = 0;}
break;
- case 185: /* expr ::= expr between_op expr AND expr */
+ case 186: /* 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);
- if( yymsp[-4].minor.yy190.pExpr ){
- yymsp[-4].minor.yy190.pExpr->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy314);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy314);
+ yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy314, 0);
+ if( yymsp[-4].minor.yy314 ){
+ yymsp[-4].minor.yy314->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
- yymsp[-4].minor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
+ if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
}
break;
- case 188: /* expr ::= expr in_op LP exprlist RP */
+ case 189: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy148==0 ){
+ if( yymsp[-1].minor.yy322==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -139609,9 +141371,9 @@ static void yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy190.pExpr);
- yymsp[-4].minor.yy190.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy194],1);
- }else if( yymsp[-1].minor.yy148->nExpr==1 ){
+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy314);
+ yymsp[-4].minor.yy314 = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[yymsp[-3].minor.yy4],1);
+ }else if( yymsp[-1].minor.yy322->nExpr==1 ){
/* Expressions of the form:
**
** expr1 IN (?1)
@@ -139628,201 +141390,195 @@ static void yy_reduce(
** affinity or the collating sequence to use for comparison. Otherwise,
** the semantics would be subtly different from IN or NOT IN.
*/
- Expr *pRHS = yymsp[-1].minor.yy148->a[0].pExpr;
- yymsp[-1].minor.yy148->a[0].pExpr = 0;
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
+ Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
+ yymsp[-1].minor.yy322->a[0].pExpr = 0;
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
/* pRHS cannot be NULL because a malloc error would have been detected
** before now and control would have never reached this point */
if( ALWAYS(pRHS) ){
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);
+ yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, yymsp[-3].minor.yy4 ? TK_NE : TK_EQ, yymsp[-4].minor.yy314, pRHS);
}else{
- 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);
+ yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy314, 0);
+ if( yymsp[-4].minor.yy314 ){
+ yymsp[-4].minor.yy314->x.pList = yymsp[-1].minor.yy322;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy314);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
}
- exprNot(pParse, yymsp[-3].minor.yy194, &yymsp[-4].minor.yy190);
+ if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
}
- yymsp[-4].minor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 189: /* expr ::= LP select RP */
+ case 190: /* 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);
- sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy190.pExpr, yymsp[-1].minor.yy243);
+ yymsp[-2].minor.yy314 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy314, yymsp[-1].minor.yy387);
}
break;
- case 190: /* expr ::= expr in_op LP select RP */
+ case 191: /* expr ::= expr in_op LP select RP */
{
- 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];
+ yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy314, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy314, yymsp[-1].minor.yy387);
+ if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
}
break;
- case 191: /* expr ::= expr in_op nm dbnm paren_exprlist */
+ case 192: /* 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);
- 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];
+ Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
+ if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322);
+ yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy314, 0);
+ sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy314, pSelect);
+ if( yymsp[-3].minor.yy4 ) yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy314, 0);
}
break;
- case 192: /* expr ::= EXISTS LP select RP */
+ case 193: /* 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);
- sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy243);
+ p = yymsp[-3].minor.yy314 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy387);
}
break;
- case 193: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 194: /* 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);
- 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);
+ yymsp[-4].minor.yy314 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, 0);
+ if( yymsp[-4].minor.yy314 ){
+ yymsp[-4].minor.yy314->x.pList = yymsp[-1].minor.yy314 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy314) : yymsp[-2].minor.yy322;
+ sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy314);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy314);
}
}
break;
- case 194: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 195: /* 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);
+ yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy314);
+ yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy314);
}
break;
- case 195: /* case_exprlist ::= WHEN expr THEN expr */
+ case 196: /* 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);
+ yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy314);
+ yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy314);
}
break;
- case 198: /* case_operand ::= expr */
-{yymsp[0].minor.yy72 = yymsp[0].minor.yy190.pExpr; /*A-overwrites-X*/}
+ case 199: /* case_operand ::= expr */
+{yymsp[0].minor.yy314 = yymsp[0].minor.yy314; /*A-overwrites-X*/}
break;
- case 201: /* nexprlist ::= nexprlist COMMA expr */
-{yymsp[-2].minor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
+ case 202: /* nexprlist ::= nexprlist COMMA expr */
+{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy314);}
break;
- case 202: /* nexprlist ::= expr */
-{yymsp[0].minor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr); /*A-overwrites-Y*/}
+ case 203: /* nexprlist ::= expr */
+{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy314); /*A-overwrites-Y*/}
break;
- case 204: /* paren_exprlist ::= LP exprlist RP */
- case 209: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==209);
-{yymsp[-2].minor.yy148 = yymsp[-1].minor.yy148;}
+ case 205: /* paren_exprlist ::= LP exprlist RP */
+ case 210: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==210);
+{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
break;
- case 205: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+ case 206: /* 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);
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy4,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy314, SQLITE_SO_ASC, yymsp[-8].minor.yy4, SQLITE_IDXTYPE_APPDEF);
}
break;
- case 206: /* uniqueflag ::= UNIQUE */
- case 246: /* raisetype ::= ABORT */ yytestcase(yyruleno==246);
-{yymsp[0].minor.yy194 = OE_Abort;}
+ case 207: /* uniqueflag ::= UNIQUE */
+ case 247: /* raisetype ::= ABORT */ yytestcase(yyruleno==247);
+{yymsp[0].minor.yy4 = OE_Abort;}
break;
- case 207: /* uniqueflag ::= */
-{yymsp[1].minor.yy194 = OE_None;}
+ case 208: /* uniqueflag ::= */
+{yymsp[1].minor.yy4 = OE_None;}
break;
- case 210: /* eidlist ::= eidlist COMMA nm collate sortorder */
+ case 211: /* 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);
+ yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4);
}
break;
- case 211: /* eidlist ::= nm collate sortorder */
+ case 212: /* 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*/
+ yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy4, yymsp[0].minor.yy4); /*A-overwrites-Y*/
}
break;
- case 214: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
+ case 215: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);}
break;
- case 215: /* cmd ::= VACUUM */
+ case 216: /* cmd ::= VACUUM */
{sqlite3Vacuum(pParse,0);}
break;
- case 216: /* cmd ::= VACUUM nm */
+ case 217: /* cmd ::= VACUUM nm */
{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
break;
- case 217: /* cmd ::= PRAGMA nm dbnm */
+ case 218: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 218: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 219: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 219: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 220: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 220: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 221: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 221: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 222: /* 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 224: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 225: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all);
}
break;
- case 225: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 226: /* 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);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
break;
- case 226: /* trigger_time ::= BEFORE|AFTER */
-{ yymsp[0].minor.yy194 = yymsp[0].major; /*A-overwrites-X*/ }
+ case 227: /* trigger_time ::= BEFORE|AFTER */
+{ yymsp[0].minor.yy4 = yymsp[0].major; /*A-overwrites-X*/ }
break;
- case 227: /* trigger_time ::= INSTEAD OF */
-{ yymsp[-1].minor.yy194 = TK_INSTEAD;}
+ case 228: /* trigger_time ::= INSTEAD OF */
+{ yymsp[-1].minor.yy4 = TK_INSTEAD;}
break;
- case 228: /* trigger_time ::= */
-{ yymsp[1].minor.yy194 = TK_BEFORE; }
+ case 229: /* trigger_time ::= */
+{ yymsp[1].minor.yy4 = TK_BEFORE; }
break;
- case 229: /* trigger_event ::= DELETE|INSERT */
- case 230: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==230);
-{yymsp[0].minor.yy332.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy332.b = 0;}
+ case 230: /* trigger_event ::= DELETE|INSERT */
+ case 231: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==231);
+{yymsp[0].minor.yy90.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy90.b = 0;}
break;
- case 231: /* trigger_event ::= UPDATE OF idlist */
-{yymsp[-2].minor.yy332.a = TK_UPDATE; yymsp[-2].minor.yy332.b = yymsp[0].minor.yy254;}
+ case 232: /* trigger_event ::= UPDATE OF idlist */
+{yymsp[-2].minor.yy90.a = TK_UPDATE; yymsp[-2].minor.yy90.b = yymsp[0].minor.yy384;}
break;
- case 232: /* when_clause ::= */
- case 251: /* key_opt ::= */ yytestcase(yyruleno==251);
-{ yymsp[1].minor.yy72 = 0; }
+ case 233: /* when_clause ::= */
+ case 252: /* key_opt ::= */ yytestcase(yyruleno==252);
+{ yymsp[1].minor.yy314 = 0; }
break;
- case 233: /* when_clause ::= WHEN expr */
- case 252: /* key_opt ::= KEY expr */ yytestcase(yyruleno==252);
-{ yymsp[-1].minor.yy72 = yymsp[0].minor.yy190.pExpr; }
+ case 234: /* when_clause ::= WHEN expr */
+ case 253: /* key_opt ::= KEY expr */ yytestcase(yyruleno==253);
+{ yymsp[-1].minor.yy314 = yymsp[0].minor.yy314; }
break;
- case 234: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 235: /* 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;
+ assert( yymsp[-2].minor.yy203!=0 );
+ yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203;
+ yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203;
}
break;
- case 235: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 236: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy145!=0 );
- yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
+ assert( yymsp[-1].minor.yy203!=0 );
+ yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203;
}
break;
- case 236: /* trnm ::= nm DOT nm */
+ case 237: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -139830,196 +141586,198 @@ static void yy_reduce(
"statements within triggers");
}
break;
- case 237: /* tridxby ::= INDEXED BY nm */
+ case 238: /* 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 239: /* 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 */
-{yymsp[-6].minor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-5].minor.yy194);}
+ case 240: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */
+{yylhsminor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy314, yymsp[-6].minor.yy4, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy336);}
+ yymsp[-7].minor.yy203 = yylhsminor.yy203;
break;
- case 240: /* 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*/}
+ case 241: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select scanpt */
+{yylhsminor.yy203 = sqlite3TriggerInsertStep(pParse->db,&yymsp[-3].minor.yy0,yymsp[-2].minor.yy384,yymsp[-1].minor.yy387,yymsp[-5].minor.yy4,yymsp[-6].minor.yy336,yymsp[0].minor.yy336);/*yylhsminor.yy203-overwrites-yymsp[-5].minor.yy4*/}
+ yymsp[-6].minor.yy203 = yylhsminor.yy203;
break;
- case 241: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yymsp[-4].minor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy72);}
+ case 242: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+{yylhsminor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy314, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy336);}
+ yymsp[-5].minor.yy203 = yylhsminor.yy203;
break;
- case 242: /* trigger_cmd ::= select */
-{yymsp[0].minor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); /*A-overwrites-X*/}
+ case 243: /* trigger_cmd ::= scanpt select scanpt */
+{yylhsminor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy387, yymsp[-2].minor.yy336, yymsp[0].minor.yy336); /*yylhsminor.yy203-overwrites-yymsp[-1].minor.yy387*/}
+ yymsp[-2].minor.yy203 = yylhsminor.yy203;
break;
- case 243: /* expr ::= RAISE LP IGNORE RP */
+ case 244: /* 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);
- if( yymsp[-3].minor.yy190.pExpr ){
- yymsp[-3].minor.yy190.pExpr->affinity = OE_Ignore;
+ yymsp[-3].minor.yy314 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( yymsp[-3].minor.yy314 ){
+ yymsp[-3].minor.yy314->affinity = OE_Ignore;
}
}
break;
- case 244: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 245: /* 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 = 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;
+ yymsp[-5].minor.yy314 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
+ if( yymsp[-5].minor.yy314 ) {
+ yymsp[-5].minor.yy314->affinity = (char)yymsp[-3].minor.yy4;
}
}
break;
- case 245: /* raisetype ::= ROLLBACK */
-{yymsp[0].minor.yy194 = OE_Rollback;}
+ case 246: /* raisetype ::= ROLLBACK */
+{yymsp[0].minor.yy4 = OE_Rollback;}
break;
- case 247: /* raisetype ::= FAIL */
-{yymsp[0].minor.yy194 = OE_Fail;}
+ case 248: /* raisetype ::= FAIL */
+{yymsp[0].minor.yy4 = OE_Fail;}
break;
- case 248: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 249: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4);
}
break;
- case 249: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 250: /* 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);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy314, yymsp[-1].minor.yy314, yymsp[0].minor.yy314);
}
break;
- case 250: /* cmd ::= DETACH database_kw_opt expr */
+ case 251: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
+ sqlite3Detach(pParse, yymsp[0].minor.yy314);
}
break;
- case 253: /* cmd ::= REINDEX */
+ case 254: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 254: /* cmd ::= REINDEX nm dbnm */
+ case 255: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 255: /* cmd ::= ANALYZE */
+ case 256: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 256: /* cmd ::= ANALYZE nm dbnm */
+ case 257: /* 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 258: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0);
}
break;
- case 258: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+ case 259: /* 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 260: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259);
}
break;
- case 260: /* cmd ::= create_vtab */
+ case 261: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 261: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 262: /* 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 263: /* 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);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy4);
}
break;
- case 263: /* vtabarg ::= */
+ case 264: /* 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 265: /* vtabargtoken ::= ANY */
+ case 266: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==266);
+ case 267: /* lp ::= LP */ yytestcase(yyruleno==267);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
- case 267: /* with ::= */
-{yymsp[1].minor.yy285 = 0;}
+ case 268: /* with ::= */
+{yymsp[1].minor.yy451 = 0;}
break;
- case 268: /* with ::= WITH wqlist */
-{ yymsp[-1].minor.yy285 = yymsp[0].minor.yy285; }
+ case 269: /* with ::= WITH wqlist */
+{ yymsp[-1].minor.yy451 = yymsp[0].minor.yy451; }
break;
- case 269: /* with ::= WITH RECURSIVE wqlist */
-{ yymsp[-2].minor.yy285 = yymsp[0].minor.yy285; }
+ case 270: /* with ::= WITH RECURSIVE wqlist */
+{ yymsp[-2].minor.yy451 = yymsp[0].minor.yy451; }
break;
- case 270: /* wqlist ::= nm eidlist_opt AS LP select RP */
+ case 271: /* 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*/
+ yymsp[-5].minor.yy451 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387); /*A-overwrites-X*/
}
break;
- case 271: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */
+ case 272: /* 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);
+ yymsp[-7].minor.yy451 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy451, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy387);
}
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) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==307);
- /* (308) exprlist ::= nexprlist */ yytestcase(yyruleno==308);
- /* (309) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=309);
- /* (310) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=310);
- /* (311) nmnum ::= ON */ yytestcase(yyruleno==311);
- /* (312) nmnum ::= DELETE */ yytestcase(yyruleno==312);
- /* (313) nmnum ::= DEFAULT */ yytestcase(yyruleno==313);
- /* (314) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==314);
- /* (315) foreach_clause ::= */ yytestcase(yyruleno==315);
- /* (316) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==316);
- /* (317) trnm ::= nm */ yytestcase(yyruleno==317);
- /* (318) tridxby ::= */ yytestcase(yyruleno==318);
- /* (319) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==319);
- /* (320) database_kw_opt ::= */ yytestcase(yyruleno==320);
- /* (321) kwcolumn_opt ::= */ yytestcase(yyruleno==321);
- /* (322) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==322);
- /* (323) vtabarglist ::= vtabarg */ yytestcase(yyruleno==323);
- /* (324) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==324);
- /* (325) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==325);
- /* (326) anylist ::= */ yytestcase(yyruleno==326);
- /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
- /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
+ /* (273) input ::= cmdlist */ yytestcase(yyruleno==273);
+ /* (274) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==274);
+ /* (275) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=275);
+ /* (276) ecmd ::= SEMI */ yytestcase(yyruleno==276);
+ /* (277) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==277);
+ /* (278) explain ::= */ yytestcase(yyruleno==278);
+ /* (279) trans_opt ::= */ yytestcase(yyruleno==279);
+ /* (280) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==280);
+ /* (281) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==281);
+ /* (282) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==282);
+ /* (283) savepoint_opt ::= */ yytestcase(yyruleno==283);
+ /* (284) cmd ::= create_table create_table_args */ yytestcase(yyruleno==284);
+ /* (285) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==285);
+ /* (286) columnlist ::= columnname carglist */ yytestcase(yyruleno==286);
+ /* (287) nm ::= ID|INDEXED */ yytestcase(yyruleno==287);
+ /* (288) nm ::= STRING */ yytestcase(yyruleno==288);
+ /* (289) nm ::= JOIN_KW */ yytestcase(yyruleno==289);
+ /* (290) typetoken ::= typename */ yytestcase(yyruleno==290);
+ /* (291) typename ::= ID|STRING */ yytestcase(yyruleno==291);
+ /* (292) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=292);
+ /* (293) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=293);
+ /* (294) carglist ::= carglist ccons */ yytestcase(yyruleno==294);
+ /* (295) carglist ::= */ yytestcase(yyruleno==295);
+ /* (296) ccons ::= NULL onconf */ yytestcase(yyruleno==296);
+ /* (297) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==297);
+ /* (298) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==298);
+ /* (299) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=299);
+ /* (300) tconscomma ::= */ yytestcase(yyruleno==300);
+ /* (301) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=301);
+ /* (302) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=302);
+ /* (303) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=303);
+ /* (304) oneselect ::= values */ yytestcase(yyruleno==304);
+ /* (305) sclp ::= selcollist COMMA */ yytestcase(yyruleno==305);
+ /* (306) as ::= ID|STRING */ yytestcase(yyruleno==306);
+ /* (307) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=307);
+ /* (308) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==308);
+ /* (309) exprlist ::= nexprlist */ yytestcase(yyruleno==309);
+ /* (310) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=310);
+ /* (311) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=311);
+ /* (312) nmnum ::= ON */ yytestcase(yyruleno==312);
+ /* (313) nmnum ::= DELETE */ yytestcase(yyruleno==313);
+ /* (314) nmnum ::= DEFAULT */ yytestcase(yyruleno==314);
+ /* (315) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==315);
+ /* (316) foreach_clause ::= */ yytestcase(yyruleno==316);
+ /* (317) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==317);
+ /* (318) trnm ::= nm */ yytestcase(yyruleno==318);
+ /* (319) tridxby ::= */ yytestcase(yyruleno==319);
+ /* (320) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==320);
+ /* (321) database_kw_opt ::= */ yytestcase(yyruleno==321);
+ /* (322) kwcolumn_opt ::= */ yytestcase(yyruleno==322);
+ /* (323) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==323);
+ /* (324) vtabarglist ::= vtabarg */ yytestcase(yyruleno==324);
+ /* (325) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==325);
+ /* (326) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==326);
+ /* (327) anylist ::= */ yytestcase(yyruleno==327);
+ /* (328) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==328);
+ /* (329) anylist ::= anylist ANY */ yytestcase(yyruleno==329);
break;
/********** End reduce actions ************************************************/
};
@@ -140035,16 +141793,11 @@ static void yy_reduce(
/* It is not possible for a REDUCE to be followed by an error */
assert( yyact!=YY_ERROR_ACTION );
- if( yyact==YY_ACCEPT_ACTION ){
- yypParser->yytos += yysize;
- yy_accept(yypParser);
- }else{
- yymsp += yysize+1;
- yypParser->yytos = yymsp;
- yymsp->stateno = (YYACTIONTYPE)yyact;
- yymsp->major = (YYCODETYPE)yygoto;
- yyTraceShift(yypParser, yyact);
- }
+ yymsp += yysize+1;
+ yypParser->yytos = yymsp;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
+ yyTraceShift(yypParser, yyact, "... then shift");
}
/*
@@ -140082,8 +141835,11 @@ static void yy_syntax_error(
/************ Begin %syntax_error code ****************************************/
UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */
- assert( TOKEN.z[0] ); /* The tokenizer always gives us a token */
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
+ if( TOKEN.z[0] ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
+ }else{
+ sqlite3ErrorMsg(pParse, "incomplete input");
+ }
/************ End %syntax_error code ******************************************/
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
@@ -140155,20 +141911,31 @@ SQLITE_PRIVATE void sqlite3Parser(
#ifndef NDEBUG
if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]);
+ int stateno = yypParser->yytos->stateno;
+ if( stateno < YY_MIN_REDUCE ){
+ fprintf(yyTraceFILE,"%sInput '%s' in state %d\n",
+ yyTracePrompt,yyTokenName[yymajor],stateno);
+ }else{
+ fprintf(yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+ yyTracePrompt,yyTokenName[yymajor],stateno-YY_MIN_REDUCE);
+ }
}
#endif
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
- if( yyact <= YY_MAX_SHIFTREDUCE ){
+ if( yyact >= YY_MIN_REDUCE ){
+ yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,yyminor);
+ }else if( yyact <= YY_MAX_SHIFTREDUCE ){
yy_shift(yypParser,yyact,yymajor,yyminor);
#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt--;
#endif
yymajor = YYNOCODE;
- }else if( yyact <= YY_MAX_REDUCE ){
- yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
+ }else if( yyact==YY_ACCEPT_ACTION ){
+ yypParser->yytos--;
+ yy_accept(yypParser);
+ return;
}else{
assert( yyact == YY_ERROR_ACTION );
yyminorunion.yy0 = yyminor;
@@ -141117,7 +142884,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
}else{
tokenType = TK_SEMI;
}
- zSql -= n;
+ n = 0;
}
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
@@ -141572,6 +143339,10 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db);
*/
/* #include "sqlite3.h" */
+#ifdef SQLITE_OMIT_VIRTUALTABLE
+# undef SQLITE_ENABLE_RTREE
+#endif
+
#if 0
extern "C" {
#endif /* __cplusplus */
@@ -141585,7 +143356,7 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
/************** End of rtree.h ***********************************************/
/************** Continuing where we left off in main.c ***********************/
#endif
-#ifdef SQLITE_ENABLE_ICU
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
/************** Include sqliteicu.h in the middle of main.c ******************/
/************** Begin file sqliteicu.h ***************************************/
/*
@@ -141641,11 +143412,13 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
*/
SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
-/* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
+/* IMPLEMENTATION-OF: R-25063-23286 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_SOURCE_ID C preprocessor macro. Except if SQLite is built using
+** an edited copy of the amalgamation, then the last four characters of
+** the hash might be different from SQLITE_SOURCE_ID.
*/
-SQLITE_API const char *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.
@@ -142030,14 +143803,8 @@ SQLITE_API int sqlite3_config(int op, ...){
sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
break;
}
- case SQLITE_CONFIG_SCRATCH: {
- /* EVIDENCE-OF: R-08404-60887 There are three arguments to
- ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from
- ** which the scratch allocations will be drawn, the size of each scratch
- ** allocation (sz), and the maximum number of scratch allocations (N). */
- sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
- sqlite3GlobalConfig.szScratch = va_arg(ap, int);
- sqlite3GlobalConfig.nScratch = va_arg(ap, int);
+ case SQLITE_CONFIG_SMALL_MALLOC: {
+ sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int);
break;
}
case SQLITE_CONFIG_PAGECACHE: {
@@ -142258,7 +144025,8 @@ SQLITE_API int sqlite3_config(int op, ...){
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
#ifndef SQLITE_OMIT_LOOKASIDE
void *pStart;
- if( db->lookaside.nOut ){
+
+ if( sqlite3LookasideUsed(db,0)>0 ){
return SQLITE_BUSY;
}
/* Free any existing lookaside buffer for this handle before
@@ -142286,16 +144054,18 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
pStart = pBuf;
}
db->lookaside.pStart = pStart;
+ db->lookaside.pInit = 0;
db->lookaside.pFree = 0;
db->lookaside.sz = (u16)sz;
if( pStart ){
int i;
LookasideSlot *p;
assert( sz > (int)sizeof(LookasideSlot*) );
+ db->lookaside.nSlot = cnt;
p = (LookasideSlot*)pStart;
for(i=cnt-1; i>=0; i--){
- p->pNext = db->lookaside.pFree;
- db->lookaside.pFree = p;
+ p->pNext = db->lookaside.pInit;
+ db->lookaside.pInit = p;
p = (LookasideSlot*)&((u8*)p)[sz];
}
db->lookaside.pEnd = p;
@@ -142306,6 +144076,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
db->lookaside.pEnd = db;
db->lookaside.bDisable = 1;
db->lookaside.bMalloced = 0;
+ db->lookaside.nSlot = 0;
}
#endif /* SQLITE_OMIT_LOOKASIDE */
return SQLITE_OK;
@@ -142411,6 +144182,7 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
+ { SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -142418,7 +144190,7 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
if( aFlagOp[i].op==op ){
int onoff = va_arg(ap, int);
int *pRes = va_arg(ap, int*);
- int oldFlags = db->flags;
+ u32 oldFlags = db->flags;
if( onoff>0 ){
db->flags |= aFlagOp[i].mask;
}else if( onoff==0 ){
@@ -142825,7 +144597,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
sqlite3_mutex_leave(db->mutex);
db->magic = SQLITE_MAGIC_CLOSED;
sqlite3_mutex_free(db->mutex);
- assert( db->lookaside.nOut==0 ); /* Fails on a lookaside memory leak */
+ assert( sqlite3LookasideUsed(db,0)==0 );
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
@@ -142853,7 +144625,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** the database rollback and schema reset, which can cause false
** corruption reports in some cases. */
sqlite3BtreeEnterAll(db);
- schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0;
+ schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0;
for(i=0; i<db->nDb; i++){
Btree *p = db->aDb[i].pBt;
@@ -142867,7 +144639,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
- if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
+ if( (db->mDbFlags&DBFLAG_SchemaChange)!=0 && db->init.busy==0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
}
@@ -142908,9 +144680,10 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break;
case SQLITE_READONLY: zName = "SQLITE_READONLY"; break;
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
- case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
+ case SQLITE_READONLY_CANTINIT: zName = "SQLITE_READONLY_CANTINIT"; break;
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break;
+ case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
@@ -143769,7 +145542,8 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
** checkpointed. If an error is encountered it is returned immediately -
** no attempt is made to checkpoint any remaining databases.
**
-** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
+** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART
+** or TRUNCATE.
*/
SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){
int rc = SQLITE_OK; /* Return code */
@@ -144415,6 +146189,7 @@ static int openDatabase(
}else{
isThreadsafe = sqlite3GlobalConfig.bFullMutex;
}
+
if( flags & SQLITE_OPEN_PRIVATECACHE ){
flags &= ~SQLITE_OPEN_SHAREDCACHE;
}else if( sqlite3GlobalConfig.sharedCacheEnabled ){
@@ -144447,13 +146222,20 @@ static int openDatabase(
/* Allocate the sqlite data structure */
db = sqlite3MallocZero( sizeof(sqlite3) );
if( db==0 ) goto opendb_out;
- if( isThreadsafe ){
+ if( isThreadsafe
+#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
+ || sqlite3GlobalConfig.bCoreMutex
+#endif
+ ){
db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
if( db->mutex==0 ){
sqlite3_free(db);
db = 0;
goto opendb_out;
}
+ if( isThreadsafe==0 ){
+ sqlite3MutexWarnOnContention(db->mutex);
+ }
}
sqlite3_mutex_enter(db->mutex);
db->errMask = 0xff;
@@ -144635,7 +146417,7 @@ static int openDatabase(
}
#endif
-#ifdef SQLITE_ENABLE_ICU
+#if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
if( !db->mallocFailed && rc==SQLITE_OK ){
rc = sqlite3IcuInit(db);
}
@@ -144647,6 +146429,12 @@ static int openDatabase(
}
#endif
+#ifdef SQLITE_ENABLE_DBPAGE_VTAB
+ if( !db->mallocFailed && rc==SQLITE_OK){
+ rc = sqlite3DbpageRegister(db);
+ }
+#endif
+
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
if( !db->mallocFailed && rc==SQLITE_OK){
rc = sqlite3DbstatRegister(db);
@@ -144931,37 +146719,37 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
** 2. Invoke sqlite3_log() to provide the source code location where
** a low-level error is first detected.
*/
-static int reportError(int iErr, int lineno, const char *zType){
+SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){
sqlite3_log(iErr, "%s at line %d of [%.10s]",
zType, lineno, 20+sqlite3_sourceid());
return iErr;
}
SQLITE_PRIVATE int sqlite3CorruptError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_CORRUPT, lineno, "database corruption");
+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption");
}
SQLITE_PRIVATE int sqlite3MisuseError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_MISUSE, lineno, "misuse");
+ return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse");
}
SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
+ return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file");
}
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){
char zMsg[100];
sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno);
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_CORRUPT, lineno, zMsg);
+ return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
}
SQLITE_PRIVATE int sqlite3NomemError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_NOMEM, lineno, "OOM");
+ return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM");
}
SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
+ return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
}
#endif
@@ -145306,7 +147094,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
** This action provides a run-time test to see how the ALWAYS and
** NEVER macros were defined at compile-time.
**
- ** The return value is ALWAYS(X).
+ ** The return value is ALWAYS(X) if X is true, or 0 if X is false.
**
** The recommended test is X==2. If the return value is 2, that means
** ALWAYS() and NEVER() are both no-op pass-through macros, which is the
@@ -145329,7 +147117,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
*/
case SQLITE_TESTCTRL_ALWAYS: {
int x = va_arg(ap,int);
- rc = ALWAYS(x);
+ rc = x ? ALWAYS(x) : 0;
break;
}
@@ -145396,22 +147184,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){
}
#endif
- /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree);
- **
- ** Pass pFree into sqlite3ScratchFree().
- ** If sz>0 then allocate a scratch buffer into pNew.
- */
- case SQLITE_TESTCTRL_SCRATCHMALLOC: {
- void *pFree, **ppNew;
- int sz;
- sz = va_arg(ap, int);
- ppNew = va_arg(ap, void**);
- pFree = va_arg(ap, void*);
- if( sz ) *ppNew = sqlite3ScratchMalloc(sz);
- sqlite3ScratchFree(pFree);
- break;
- }
-
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
**
** If parameter onoff is non-zero, configure the wrappers so that all
@@ -145505,6 +147277,22 @@ SQLITE_API int sqlite3_test_control(int op, ...){
sqlite3_mutex_leave(db->mutex);
break;
}
+
+#if defined(YYCOVERAGE)
+ /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out)
+ **
+ ** This test control (only available when SQLite is compiled with
+ ** -DYYCOVERAGE) writes a report onto "out" that shows all
+ ** state/lookahead combinations in the parser state machine
+ ** which are never exercised. If any state is missed, make the
+ ** return code SQLITE_ERROR.
+ */
+ case SQLITE_TESTCTRL_PARSER_COVERAGE: {
+ FILE *out = va_arg(ap, FILE*);
+ if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR;
+ break;
+ }
+#endif /* defined(YYCOVERAGE) */
}
va_end(ap);
#endif /* SQLITE_UNTESTABLE */
@@ -145553,7 +147341,7 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(
){
const char *z = sqlite3_uri_parameter(zFilename, zParam);
sqlite3_int64 v;
- if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){
+ if( z && sqlite3DecOrHexToI64(z, &v)==0 ){
bDflt = v;
}
return bDflt;
@@ -165309,7 +167097,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
** child page.
*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
+#if !defined(SQLITE_CORE) \
+ || (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE))
#ifndef SQLITE_CORE
/* #include "sqlite3ext.h" */
@@ -165466,7 +167255,7 @@ struct RtreeSearchPoint {
** The smallest possible node-size is (512-64)==448 bytes. And the largest
** supported cell size is 48 bytes (8 byte rowid + ten 4 byte coordinates).
** Therefore all non-root nodes must contain at least 3 entries. Since
-** 2^40 is greater than 2^64, an r-tree structure always has a depth of
+** 3^40 is greater than 2^64, an r-tree structure always has a depth of
** 40 or less.
*/
#define RTREE_MAX_DEPTH 40
@@ -167278,7 +169067,7 @@ static int ChooseLeaf(
){
int rc;
int ii;
- RtreeNode *pNode;
+ RtreeNode *pNode = 0;
rc = nodeAcquire(pRtree, 1, 0, &pNode);
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
@@ -168110,7 +169899,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
int rc; /* Return code */
RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */
int iCell; /* Index of iDelete cell in pLeaf */
- RtreeNode *pRoot; /* Root node of rtree structure */
+ RtreeNode *pRoot = 0; /* Root node of rtree structure */
/* Obtain a reference to the root node to initialize Rtree.iDepth */
@@ -168153,7 +169942,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
*/
if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
int rc2;
- RtreeNode *pChild;
+ RtreeNode *pChild = 0;
i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
if( rc==SQLITE_OK ){
@@ -168671,7 +170460,7 @@ static int getNodeSize(
if( rc!=SQLITE_OK ){
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
}else if( pRtree->iNodeSize<(512-64) ){
- rc = SQLITE_CORRUPT;
+ rc = SQLITE_CORRUPT_VTAB;
*pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
pRtree->zName);
}
@@ -168866,6 +170655,463 @@ static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
}
/*
+** Context object passed between the various routines that make up the
+** implementation of integrity-check function rtreecheck().
+*/
+typedef struct RtreeCheck RtreeCheck;
+struct RtreeCheck {
+ sqlite3 *db; /* Database handle */
+ const char *zDb; /* Database containing rtree table */
+ const char *zTab; /* Name of rtree table */
+ int bInt; /* True for rtree_i32 table */
+ int nDim; /* Number of dimensions for this rtree tbl */
+ sqlite3_stmt *pGetNode; /* Statement used to retrieve nodes */
+ sqlite3_stmt *aCheckMapping[2]; /* Statements to query %_parent/%_rowid */
+ int nLeaf; /* Number of leaf cells in table */
+ int nNonLeaf; /* Number of non-leaf cells in table */
+ int rc; /* Return code */
+ char *zReport; /* Message to report */
+ int nErr; /* Number of lines in zReport */
+};
+
+#define RTREE_CHECK_MAX_ERROR 100
+
+/*
+** Reset SQL statement pStmt. If the sqlite3_reset() call returns an error,
+** and RtreeCheck.rc==SQLITE_OK, set RtreeCheck.rc to the error code.
+*/
+static void rtreeCheckReset(RtreeCheck *pCheck, sqlite3_stmt *pStmt){
+ int rc = sqlite3_reset(pStmt);
+ if( pCheck->rc==SQLITE_OK ) pCheck->rc = rc;
+}
+
+/*
+** The second and subsequent arguments to this function are a format string
+** and printf style arguments. This function formats the string and attempts
+** to compile it as an SQL statement.
+**
+** If successful, a pointer to the new SQL statement is returned. Otherwise,
+** NULL is returned and an error code left in RtreeCheck.rc.
+*/
+static sqlite3_stmt *rtreeCheckPrepare(
+ RtreeCheck *pCheck, /* RtreeCheck object */
+ const char *zFmt, ... /* Format string and trailing args */
+){
+ va_list ap;
+ char *z;
+ sqlite3_stmt *pRet = 0;
+
+ va_start(ap, zFmt);
+ z = sqlite3_vmprintf(zFmt, ap);
+
+ if( pCheck->rc==SQLITE_OK ){
+ if( z==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0);
+ }
+ }
+
+ sqlite3_free(z);
+ va_end(ap);
+ return pRet;
+}
+
+/*
+** The second and subsequent arguments to this function are a printf()
+** style format string and arguments. This function formats the string and
+** appends it to the report being accumuated in pCheck.
+*/
+static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){
+ va_list ap;
+ va_start(ap, zFmt);
+ if( pCheck->rc==SQLITE_OK && pCheck->nErr<RTREE_CHECK_MAX_ERROR ){
+ char *z = sqlite3_vmprintf(zFmt, ap);
+ if( z==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ pCheck->zReport = sqlite3_mprintf("%z%s%z",
+ pCheck->zReport, (pCheck->zReport ? "\n" : ""), z
+ );
+ if( pCheck->zReport==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }
+ }
+ pCheck->nErr++;
+ }
+ va_end(ap);
+}
+
+/*
+** This function is a no-op if there is already an error code stored
+** in the RtreeCheck object indicated by the first argument. NULL is
+** returned in this case.
+**
+** Otherwise, the contents of rtree table node iNode are loaded from
+** the database and copied into a buffer obtained from sqlite3_malloc().
+** If no error occurs, a pointer to the buffer is returned and (*pnNode)
+** is set to the size of the buffer in bytes.
+**
+** Or, if an error does occur, NULL is returned and an error code left
+** in the RtreeCheck object. The final value of *pnNode is undefined in
+** this case.
+*/
+static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
+ u8 *pRet = 0; /* Return value */
+
+ assert( pCheck->rc==SQLITE_OK );
+ if( pCheck->pGetNode==0 ){
+ pCheck->pGetNode = rtreeCheckPrepare(pCheck,
+ "SELECT data FROM %Q.'%q_node' WHERE nodeno=?",
+ pCheck->zDb, pCheck->zTab
+ );
+ }
+
+ if( pCheck->rc==SQLITE_OK ){
+ sqlite3_bind_int64(pCheck->pGetNode, 1, iNode);
+ if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){
+ int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0);
+ const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0);
+ pRet = sqlite3_malloc(nNode);
+ if( pRet==0 ){
+ pCheck->rc = SQLITE_NOMEM;
+ }else{
+ memcpy(pRet, pNode, nNode);
+ *pnNode = nNode;
+ }
+ }
+ rtreeCheckReset(pCheck, pCheck->pGetNode);
+ if( pCheck->rc==SQLITE_OK && pRet==0 ){
+ rtreeCheckAppendMsg(pCheck, "Node %lld missing from database", iNode);
+ }
+ }
+
+ return pRet;
+}
+
+/*
+** This function is used to check that the %_parent (if bLeaf==0) or %_rowid
+** (if bLeaf==1) table contains a specified entry. The schemas of the
+** two tables are:
+**
+** CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
+** CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
+**
+** In both cases, this function checks that there exists an entry with
+** IPK value iKey and the second column set to iVal.
+**
+*/
+static void rtreeCheckMapping(
+ RtreeCheck *pCheck, /* RtreeCheck object */
+ int bLeaf, /* True for a leaf cell, false for interior */
+ i64 iKey, /* Key for mapping */
+ i64 iVal /* Expected value for mapping */
+){
+ int rc;
+ sqlite3_stmt *pStmt;
+ const char *azSql[2] = {
+ "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?",
+ "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?"
+ };
+
+ assert( bLeaf==0 || bLeaf==1 );
+ if( pCheck->aCheckMapping[bLeaf]==0 ){
+ pCheck->aCheckMapping[bLeaf] = rtreeCheckPrepare(pCheck,
+ azSql[bLeaf], pCheck->zDb, pCheck->zTab
+ );
+ }
+ if( pCheck->rc!=SQLITE_OK ) return;
+
+ pStmt = pCheck->aCheckMapping[bLeaf];
+ sqlite3_bind_int64(pStmt, 1, iKey);
+ rc = sqlite3_step(pStmt);
+ if( rc==SQLITE_DONE ){
+ rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table",
+ iKey, iVal, (bLeaf ? "%_rowid" : "%_parent")
+ );
+ }else if( rc==SQLITE_ROW ){
+ i64 ii = sqlite3_column_int64(pStmt, 0);
+ if( ii!=iVal ){
+ rtreeCheckAppendMsg(pCheck,
+ "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)",
+ iKey, ii, (bLeaf ? "%_rowid" : "%_parent"), iKey, iVal
+ );
+ }
+ }
+ rtreeCheckReset(pCheck, pStmt);
+}
+
+/*
+** Argument pCell points to an array of coordinates stored on an rtree page.
+** This function checks that the coordinates are internally consistent (no
+** x1>x2 conditions) and adds an error message to the RtreeCheck object
+** if they are not.
+**
+** Additionally, if pParent is not NULL, then it is assumed to point to
+** the array of coordinates on the parent page that bound the page
+** containing pCell. In this case it is also verified that the two
+** sets of coordinates are mutually consistent and an error message added
+** to the RtreeCheck object if they are not.
+*/
+static void rtreeCheckCellCoord(
+ RtreeCheck *pCheck,
+ i64 iNode, /* Node id to use in error messages */
+ int iCell, /* Cell number to use in error messages */
+ u8 *pCell, /* Pointer to cell coordinates */
+ u8 *pParent /* Pointer to parent coordinates */
+){
+ RtreeCoord c1, c2;
+ RtreeCoord p1, p2;
+ int i;
+
+ for(i=0; i<pCheck->nDim; i++){
+ readCoord(&pCell[4*2*i], &c1);
+ readCoord(&pCell[4*(2*i + 1)], &c2);
+
+ /* printf("%e, %e\n", c1.u.f, c2.u.f); */
+ if( pCheck->bInt ? c1.i>c2.i : c1.f>c2.f ){
+ rtreeCheckAppendMsg(pCheck,
+ "Dimension %d of cell %d on node %lld is corrupt", i, iCell, iNode
+ );
+ }
+
+ if( pParent ){
+ readCoord(&pParent[4*2*i], &p1);
+ readCoord(&pParent[4*(2*i + 1)], &p2);
+
+ if( (pCheck->bInt ? c1.i<p1.i : c1.f<p1.f)
+ || (pCheck->bInt ? c2.i>p2.i : c2.f>p2.f)
+ ){
+ rtreeCheckAppendMsg(pCheck,
+ "Dimension %d of cell %d on node %lld is corrupt relative to parent"
+ , i, iCell, iNode
+ );
+ }
+ }
+ }
+}
+
+/*
+** Run rtreecheck() checks on node iNode, which is at depth iDepth within
+** the r-tree structure. Argument aParent points to the array of coordinates
+** that bound node iNode on the parent node.
+**
+** If any problems are discovered, an error message is appended to the
+** report accumulated in the RtreeCheck object.
+*/
+static void rtreeCheckNode(
+ RtreeCheck *pCheck,
+ int iDepth, /* Depth of iNode (0==leaf) */
+ u8 *aParent, /* Buffer containing parent coords */
+ i64 iNode /* Node to check */
+){
+ u8 *aNode = 0;
+ int nNode = 0;
+
+ assert( iNode==1 || aParent!=0 );
+ assert( pCheck->nDim>0 );
+
+ aNode = rtreeCheckGetNode(pCheck, iNode, &nNode);
+ if( aNode ){
+ if( nNode<4 ){
+ rtreeCheckAppendMsg(pCheck,
+ "Node %lld is too small (%d bytes)", iNode, nNode
+ );
+ }else{
+ int nCell; /* Number of cells on page */
+ int i; /* Used to iterate through cells */
+ if( aParent==0 ){
+ iDepth = readInt16(aNode);
+ if( iDepth>RTREE_MAX_DEPTH ){
+ rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth);
+ sqlite3_free(aNode);
+ return;
+ }
+ }
+ nCell = readInt16(&aNode[2]);
+ if( (4 + nCell*(8 + pCheck->nDim*2*4))>nNode ){
+ rtreeCheckAppendMsg(pCheck,
+ "Node %lld is too small for cell count of %d (%d bytes)",
+ iNode, nCell, nNode
+ );
+ }else{
+ for(i=0; i<nCell; i++){
+ u8 *pCell = &aNode[4 + i*(8 + pCheck->nDim*2*4)];
+ i64 iVal = readInt64(pCell);
+ rtreeCheckCellCoord(pCheck, iNode, i, &pCell[8], aParent);
+
+ if( iDepth>0 ){
+ rtreeCheckMapping(pCheck, 0, iVal, iNode);
+ rtreeCheckNode(pCheck, iDepth-1, &pCell[8], iVal);
+ pCheck->nNonLeaf++;
+ }else{
+ rtreeCheckMapping(pCheck, 1, iVal, iNode);
+ pCheck->nLeaf++;
+ }
+ }
+ }
+ }
+ sqlite3_free(aNode);
+ }
+}
+
+/*
+** The second argument to this function must be either "_rowid" or
+** "_parent". This function checks that the number of entries in the
+** %_rowid or %_parent table is exactly nExpect. If not, it adds
+** an error message to the report in the RtreeCheck object indicated
+** by the first argument.
+*/
+static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){
+ if( pCheck->rc==SQLITE_OK ){
+ sqlite3_stmt *pCount;
+ pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'",
+ pCheck->zDb, pCheck->zTab, zTbl
+ );
+ if( pCount ){
+ if( sqlite3_step(pCount)==SQLITE_ROW ){
+ i64 nActual = sqlite3_column_int64(pCount, 0);
+ if( nActual!=nExpect ){
+ rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table"
+ " - expected %lld, actual %lld" , zTbl, nExpect, nActual
+ );
+ }
+ }
+ pCheck->rc = sqlite3_finalize(pCount);
+ }
+ }
+}
+
+/*
+** This function does the bulk of the work for the rtree integrity-check.
+** It is called by rtreecheck(), which is the SQL function implementation.
+*/
+static int rtreeCheckTable(
+ sqlite3 *db, /* Database handle to access db through */
+ const char *zDb, /* Name of db ("main", "temp" etc.) */
+ const char *zTab, /* Name of rtree table to check */
+ char **pzReport /* OUT: sqlite3_malloc'd report text */
+){
+ RtreeCheck check; /* Common context for various routines */
+ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */
+ int bEnd = 0; /* True if transaction should be closed */
+
+ /* Initialize the context object */
+ memset(&check, 0, sizeof(check));
+ check.db = db;
+ check.zDb = zDb;
+ check.zTab = zTab;
+
+ /* If there is not already an open transaction, open one now. This is
+ ** to ensure that the queries run as part of this integrity-check operate
+ ** on a consistent snapshot. */
+ if( sqlite3_get_autocommit(db) ){
+ check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0);
+ bEnd = 1;
+ }
+
+ /* Find number of dimensions in the rtree table. */
+ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
+ if( pStmt ){
+ int rc;
+ check.nDim = (sqlite3_column_count(pStmt) - 1) / 2;
+ if( check.nDim<1 ){
+ rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree");
+ }else if( SQLITE_ROW==sqlite3_step(pStmt) ){
+ check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER);
+ }
+ rc = sqlite3_finalize(pStmt);
+ if( rc!=SQLITE_CORRUPT ) check.rc = rc;
+ }
+
+ /* Do the actual integrity-check */
+ if( check.nDim>=1 ){
+ if( check.rc==SQLITE_OK ){
+ rtreeCheckNode(&check, 0, 0, 1);
+ }
+ rtreeCheckCount(&check, "_rowid", check.nLeaf);
+ rtreeCheckCount(&check, "_parent", check.nNonLeaf);
+ }
+
+ /* Finalize SQL statements used by the integrity-check */
+ sqlite3_finalize(check.pGetNode);
+ sqlite3_finalize(check.aCheckMapping[0]);
+ sqlite3_finalize(check.aCheckMapping[1]);
+
+ /* If one was opened, close the transaction */
+ if( bEnd ){
+ int rc = sqlite3_exec(db, "END", 0, 0, 0);
+ if( check.rc==SQLITE_OK ) check.rc = rc;
+ }
+ *pzReport = check.zReport;
+ return check.rc;
+}
+
+/*
+** Usage:
+**
+** rtreecheck(<rtree-table>);
+** rtreecheck(<database>, <rtree-table>);
+**
+** Invoking this SQL function runs an integrity-check on the named rtree
+** table. The integrity-check verifies the following:
+**
+** 1. For each cell in the r-tree structure (%_node table), that:
+**
+** a) for each dimension, (coord1 <= coord2).
+**
+** b) unless the cell is on the root node, that the cell is bounded
+** by the parent cell on the parent node.
+**
+** c) for leaf nodes, that there is an entry in the %_rowid
+** table corresponding to the cell's rowid value that
+** points to the correct node.
+**
+** d) for cells on non-leaf nodes, that there is an entry in the
+** %_parent table mapping from the cell's child node to the
+** node that it resides on.
+**
+** 2. That there are the same number of entries in the %_rowid table
+** as there are leaf cells in the r-tree structure, and that there
+** is a leaf cell that corresponds to each entry in the %_rowid table.
+**
+** 3. That there are the same number of entries in the %_parent table
+** as there are non-leaf cells in the r-tree structure, and that
+** there is a non-leaf cell that corresponds to each entry in the
+** %_parent table.
+*/
+static void rtreecheck(
+ sqlite3_context *ctx,
+ int nArg,
+ sqlite3_value **apArg
+){
+ if( nArg!=1 && nArg!=2 ){
+ sqlite3_result_error(ctx,
+ "wrong number of arguments to function rtreecheck()", -1
+ );
+ }else{
+ int rc;
+ char *zReport = 0;
+ const char *zDb = (const char*)sqlite3_value_text(apArg[0]);
+ const char *zTab;
+ if( nArg==1 ){
+ zTab = zDb;
+ zDb = "main";
+ }else{
+ zTab = (const char*)sqlite3_value_text(apArg[1]);
+ }
+ rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT);
+ }else{
+ sqlite3_result_error_code(ctx, rc);
+ }
+ sqlite3_free(zReport);
+ }
+}
+
+
+/*
** Register the r-tree module with database handle db. This creates the
** virtual table module "rtree" and the debugging/analysis scalar
** function "rtreenode".
@@ -168879,6 +171125,9 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
}
if( rc==SQLITE_OK ){
+ rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0);
+ }
+ if( rc==SQLITE_OK ){
#ifdef SQLITE_RTREE_INT_ONLY
void *c = (void *)RTREE_COORD_INT32;
#else
@@ -169064,7 +171313,9 @@ SQLITE_API int sqlite3_rtree_init(
** provide case-independent matching.
*/
-#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+#if !defined(SQLITE_CORE) \
+ || defined(SQLITE_ENABLE_ICU) \
+ || defined(SQLITE_ENABLE_ICU_COLLATIONS)
/* Include ICU headers */
#include <unicode/utypes.h>
@@ -169082,6 +171333,26 @@ SQLITE_API int sqlite3_rtree_init(
#endif
/*
+** This function is called when an ICU function called from within
+** the implementation of an SQL scalar function returns an error.
+**
+** The scalar function context passed as the first argument is
+** loaded with an error message based on the following two args.
+*/
+static void icuFunctionError(
+ sqlite3_context *pCtx, /* SQLite scalar function context */
+ const char *zName, /* Name of ICU function that failed */
+ UErrorCode e /* Error code returned by ICU function */
+){
+ char zBuf[128];
+ sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
+ zBuf[127] = '\0';
+ sqlite3_result_error(pCtx, zBuf, -1);
+}
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
+
+/*
** Maximum length (in bytes) of the pattern in a LIKE or GLOB
** operator.
*/
@@ -169138,15 +171409,15 @@ static int icuLikeCompare(
const uint8_t *zString, /* The UTF-8 string to compare against */
const UChar32 uEsc /* The escape character */
){
- static const int MATCH_ONE = (UChar32)'_';
- static const int MATCH_ALL = (UChar32)'%';
+ static const uint32_t MATCH_ONE = (uint32_t)'_';
+ static const uint32_t MATCH_ALL = (uint32_t)'%';
int prevEscape = 0; /* True if the previous character was uEsc */
while( 1 ){
/* Read (and consume) the next character from the input pattern. */
- UChar32 uPattern;
+ uint32_t uPattern;
SQLITE_ICU_READ_UTF8(zPattern, uPattern);
if( uPattern==0 ) break;
@@ -169188,16 +171459,16 @@ static int icuLikeCompare(
if( *zString==0 ) return 0;
SQLITE_ICU_SKIP_UTF8(zString);
- }else if( !prevEscape && uPattern==uEsc){
+ }else if( !prevEscape && uPattern==(uint32_t)uEsc){
/* Case 3. */
prevEscape = 1;
}else{
/* Case 4. */
- UChar32 uString;
+ uint32_t uString;
SQLITE_ICU_READ_UTF8(zString, uString);
- uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
- uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
+ uString = (uint32_t)u_foldCase((UChar32)uString, U_FOLD_CASE_DEFAULT);
+ uPattern = (uint32_t)u_foldCase((UChar32)uPattern, U_FOLD_CASE_DEFAULT);
if( uString!=uPattern ){
return 0;
}
@@ -169261,24 +171532,6 @@ static void icuLikeFunc(
}
/*
-** This function is called when an ICU function called from within
-** the implementation of an SQL scalar function returns an error.
-**
-** The scalar function context passed as the first argument is
-** loaded with an error message based on the following two args.
-*/
-static void icuFunctionError(
- sqlite3_context *pCtx, /* SQLite scalar function context */
- const char *zName, /* Name of ICU function that failed */
- UErrorCode e /* Error code returned by ICU function */
-){
- char zBuf[128];
- sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
- zBuf[127] = '\0';
- sqlite3_result_error(pCtx, zBuf, -1);
-}
-
-/*
** Function to delete compiled regexp objects. Registered as
** a destructor function with sqlite3_set_auxdata().
*/
@@ -169443,6 +171696,8 @@ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
assert( 0 ); /* Unreachable */
}
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
+
/*
** Collation sequence destructor function. The pCtx argument points to
** a UCollator structure previously allocated using ucol_open().
@@ -169537,6 +171792,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
} scalars[] = {
{"icu_load_collation", 2, SQLITE_UTF8, 1, icuLoadCollation},
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
{"regexp", 2, SQLITE_ANY|SQLITE_DETERMINISTIC, 0, icuRegexpFunc},
{"lower", 1, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
{"lower", 2, SQLITE_UTF16|SQLITE_DETERMINISTIC, 0, icuCaseFunc16},
@@ -169548,10 +171804,10 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
{"upper", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 1, icuCaseFunc16},
{"like", 2, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
{"like", 3, SQLITE_UTF8|SQLITE_DETERMINISTIC, 0, icuLikeFunc},
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) */
};
int rc = SQLITE_OK;
int i;
-
for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){
const struct IcuScalar *p = &scalars[i];
@@ -170294,6 +172550,28 @@ SQLITE_API sqlite3rbu *sqlite3rbu_vacuum(
);
/*
+** Configure a limit for the amount of temp space that may be used by
+** the RBU handle passed as the first argument. The new limit is specified
+** in bytes by the second parameter. If it is positive, the limit is updated.
+** If the second parameter to this function is passed zero, then the limit
+** is removed entirely. If the second parameter is negative, the limit is
+** not modified (this is useful for querying the current limit).
+**
+** In all cases the returned value is the current limit in bytes (zero
+** indicates unlimited).
+**
+** If the temp space limit is exceeded during operation, an SQLITE_FULL
+** error is returned.
+*/
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64);
+
+/*
+** Return the current amount of temp file space, in bytes, currently used by
+** the RBU handle passed as the only argument.
+*/
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*);
+
+/*
** Internally, each RBU connection uses a separate SQLite database
** connection to access the target and rbu update databases. This
** API allows the application direct access to these database handles.
@@ -170419,7 +172697,7 @@ SQLITE_API sqlite3_int64 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 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.
@@ -170529,6 +172807,13 @@ SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName);
/* Maximum number of prepared UPDATE statements held by this module */
#define SQLITE_RBU_UPDATE_CACHESIZE 16
+/* Delta checksums disabled by default. Compile with -DRBU_ENABLE_DELTA_CKSUM
+** to enable checksum verification.
+*/
+#ifndef RBU_ENABLE_DELTA_CKSUM
+# define RBU_ENABLE_DELTA_CKSUM 0
+#endif
+
/*
** Swap two objects of type TYPE.
*/
@@ -170804,6 +173089,8 @@ struct sqlite3rbu {
int pgsz;
u8 *aBuf;
i64 iWalCksum;
+ i64 szTemp; /* Current size of all temp files in use */
+ i64 szTempLimit; /* Total size limit for temp files */
/* Used in RBU vacuum mode only */
int nRbu; /* Number of RBU VFS in the stack */
@@ -170812,23 +173099,33 @@ struct sqlite3rbu {
/*
** An rbu VFS is implemented using an instance of this structure.
+**
+** Variable pRbu is only non-NULL for automatically created RBU VFS objects.
+** It is NULL for RBU VFS objects created explicitly using
+** sqlite3rbu_create_vfs(). It is used to track the total amount of temp
+** space used by the RBU handle.
*/
struct rbu_vfs {
sqlite3_vfs base; /* rbu VFS shim methods */
sqlite3_vfs *pRealVfs; /* Underlying VFS */
sqlite3_mutex *mutex; /* Mutex to protect pMain */
+ sqlite3rbu *pRbu; /* Owner RBU object */
rbu_file *pMain; /* Linked list of main db files */
};
/*
** Each file opened by an rbu VFS is represented by an instance of
** the following structure.
+**
+** If this is a temporary file (pRbu!=0 && flags&DELETE_ON_CLOSE), variable
+** "sz" is set to the current size of the database file.
*/
struct rbu_file {
sqlite3_file base; /* sqlite3_file methods */
sqlite3_file *pReal; /* Underlying file handle */
rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */
sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */
+ i64 sz; /* Size of file in bytes (temp only) */
int openFlags; /* Flags this file was opened with */
u32 iCookie; /* Cookie value for main db files */
@@ -170891,6 +173188,7 @@ static unsigned int rbuDeltaGetInt(const char **pz, int *pLen){
return v;
}
+#if RBU_ENABLE_DELTA_CKSUM
/*
** Compute a 32-bit checksum on the N-byte buffer. Return the result.
*/
@@ -170925,6 +173223,7 @@ static unsigned int rbuDeltaChecksum(const char *zIn, size_t N){
}
return sum3;
}
+#endif
/*
** Apply a delta.
@@ -170955,7 +173254,7 @@ static int rbuDeltaApply(
){
unsigned int limit;
unsigned int total = 0;
-#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
+#if RBU_ENABLE_DELTA_CKSUM
char *zOrigOut = zOut;
#endif
@@ -171010,7 +173309,7 @@ static int rbuDeltaApply(
case ';': {
zDelta++; lenDelta--;
zOut[0] = 0;
-#ifndef FOSSIL_OMIT_DELTA_CKSUM_TEST
+#if RBU_ENABLE_DELTA_CKSUM
if( cnt!=rbuDeltaChecksum(zOrigOut, total) ){
/* ERROR: bad checksum */
return -1;
@@ -173842,6 +176141,7 @@ static void rbuCreateVfs(sqlite3rbu *p){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
assert( pVfs );
p->zVfsName = pVfs->zName;
+ ((rbu_vfs*)pVfs)->pRbu = p;
}
}
@@ -174214,6 +176514,7 @@ SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){
/* Close the open database handle and VFS object. */
sqlite3_close(p->dbRbu);
sqlite3_close(p->dbMain);
+ assert( p->szTemp==0 );
rbuDeleteVfs(p);
sqlite3_free(p->aBuf);
sqlite3_free(p->aFrame);
@@ -174401,6 +176702,7 @@ SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){
*/
static void rbuUnlockShm(rbu_file *p){
+ assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
if( p->pRbu ){
int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
int i;
@@ -174414,6 +176716,18 @@ static void rbuUnlockShm(rbu_file *p){
}
/*
+*/
+static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){
+ sqlite3rbu *pRbu = pFd->pRbu;
+ i64 nDiff = nNew - pFd->sz;
+ pRbu->szTemp += nDiff;
+ pFd->sz = nNew;
+ assert( pRbu->szTemp>=0 );
+ if( pRbu->szTempLimit && pRbu->szTemp>pRbu->szTempLimit ) return SQLITE_FULL;
+ return SQLITE_OK;
+}
+
+/*
** Close an rbu file.
*/
static int rbuVfsClose(sqlite3_file *pFile){
@@ -174438,6 +176752,9 @@ static int rbuVfsClose(sqlite3_file *pFile){
rbuUnlockShm(p);
p->pReal->pMethods->xShmUnmap(p->pReal, 0);
}
+ else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
+ rbuUpdateTempSize(p, 0);
+ }
/* Close the underlying file handle */
rc = p->pReal->pMethods->xClose(p->pReal);
@@ -174555,11 +176872,19 @@ static int rbuVfsWrite(
assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
rc = rbuCaptureDbWrite(p->pRbu, iOfst);
}else{
- if( pRbu && pRbu->eStage==RBU_STAGE_OAL
- && (p->openFlags & SQLITE_OPEN_WAL)
- && iOfst>=pRbu->iOalSz
- ){
- pRbu->iOalSz = iAmt + iOfst;
+ if( pRbu ){
+ if( pRbu->eStage==RBU_STAGE_OAL
+ && (p->openFlags & SQLITE_OPEN_WAL)
+ && iOfst>=pRbu->iOalSz
+ ){
+ pRbu->iOalSz = iAmt + iOfst;
+ }else if( p->openFlags & SQLITE_OPEN_DELETEONCLOSE ){
+ i64 szNew = iAmt+iOfst;
+ if( szNew>p->sz ){
+ rc = rbuUpdateTempSize(p, szNew);
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ }
}
rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
@@ -174578,6 +176903,10 @@ static int rbuVfsWrite(
*/
static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
rbu_file *p = (rbu_file*)pFile;
+ if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
+ int rc = rbuUpdateTempSize(p, size);
+ if( rc!=SQLITE_OK ) return rc;
+ }
return p->pReal->pMethods->xTruncate(p->pReal, size);
}
@@ -174967,6 +177296,8 @@ static int rbuVfsOpen(
pDb->pWalFd = pFd;
}
}
+ }else{
+ pFd->pRbu = pRbuVfs->pRbu;
}
if( oflags & SQLITE_OPEN_MAIN_DB
@@ -175043,7 +177374,9 @@ static int rbuVfsAccess(
if( *pResOut ){
rc = SQLITE_CANTOPEN;
}else{
- *pResOut = 1;
+ sqlite3_int64 sz = 0;
+ rc = rbuVfsFileSize(&pDb->base, &sz);
+ *pResOut = (sz>0);
}
}
}
@@ -175232,6 +177565,20 @@ SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){
return rc;
}
+/*
+** Configure the aggregate temp file size limit for this RBU handle.
+*/
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu *pRbu, sqlite3_int64 n){
+ if( n>=0 ){
+ pRbu->szTempLimit = n;
+ }
+ return pRbu->szTempLimit;
+}
+
+SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){
+ return pRbu->szTemp;
+}
+
/**************************************************************************/
@@ -175946,6 +178293,420 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
/************** End of dbstat.c **********************************************/
+/************** Begin file dbpage.c ******************************************/
+/*
+** 2017-10-11
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains an implementation of the "sqlite_dbpage" virtual table.
+**
+** The sqlite_dbpage virtual table is used to read or write whole raw
+** pages of the database file. The pager interface is used so that
+** uncommitted changes and changes recorded in the WAL file are correctly
+** retrieved.
+**
+** Usage example:
+**
+** SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123;
+**
+** This is an eponymous virtual table so it does not need to be created before
+** use. The optional argument to the sqlite_dbpage() table name is the
+** schema for the database file that is to be read. The default schema is
+** "main".
+**
+** The data field of sqlite_dbpage table can be updated. The new
+** value must be a BLOB which is the correct page size, otherwise the
+** update fails. Rows may not be deleted or inserted.
+*/
+
+/* #include "sqliteInt.h" ** Requires access to internal data structures ** */
+#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
+ && !defined(SQLITE_OMIT_VIRTUALTABLE)
+
+typedef struct DbpageTable DbpageTable;
+typedef struct DbpageCursor DbpageCursor;
+
+struct DbpageCursor {
+ sqlite3_vtab_cursor base; /* Base class. Must be first */
+ int pgno; /* Current page number */
+ int mxPgno; /* Last page to visit on this scan */
+ Pager *pPager; /* Pager being read/written */
+ DbPage *pPage1; /* Page 1 of the database */
+ int iDb; /* Index of database to analyze */
+ int szPage; /* Size of each page in bytes */
+};
+
+struct DbpageTable {
+ sqlite3_vtab base; /* Base class. Must be first */
+ sqlite3 *db; /* The database */
+};
+
+/* Columns */
+#define DBPAGE_COLUMN_PGNO 0
+#define DBPAGE_COLUMN_DATA 1
+#define DBPAGE_COLUMN_SCHEMA 2
+
+
+
+/*
+** Connect to or create a dbpagevfs virtual table.
+*/
+static int dbpageConnect(
+ sqlite3 *db,
+ void *pAux,
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVtab,
+ char **pzErr
+){
+ DbpageTable *pTab = 0;
+ int rc = SQLITE_OK;
+
+ rc = sqlite3_declare_vtab(db,
+ "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
+ if( rc==SQLITE_OK ){
+ pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
+ if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
+ }
+
+ assert( rc==SQLITE_OK || pTab==0 );
+ if( rc==SQLITE_OK ){
+ memset(pTab, 0, sizeof(DbpageTable));
+ pTab->db = db;
+ }
+
+ *ppVtab = (sqlite3_vtab*)pTab;
+ return rc;
+}
+
+/*
+** Disconnect from or destroy a dbpagevfs virtual table.
+*/
+static int dbpageDisconnect(sqlite3_vtab *pVtab){
+ sqlite3_free(pVtab);
+ return SQLITE_OK;
+}
+
+/*
+** idxNum:
+**
+** 0 schema=main, full table scan
+** 1 schema=main, pgno=?1
+** 2 schema=?1, full table scan
+** 3 schema=?1, pgno=?2
+*/
+static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+ int i;
+ int iPlan = 0;
+
+ /* If there is a schema= constraint, it must be honored. Report a
+ ** ridiculously large estimated cost if the schema= constraint is
+ ** unavailable
+ */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
+ if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue;
+ if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+ if( !p->usable ){
+ /* No solution. Use the default SQLITE_BIG_DBL cost */
+ pIdxInfo->estimatedRows = 0x7fffffff;
+ return SQLITE_OK;
+ }
+ iPlan = 2;
+ pIdxInfo->aConstraintUsage[i].argvIndex = 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ break;
+ }
+
+ /* If we reach this point, it means that either there is no schema=
+ ** constraint (in which case we use the "main" schema) or else the
+ ** schema constraint was accepted. Lower the estimated cost accordingly
+ */
+ pIdxInfo->estimatedCost = 1.0e6;
+
+ /* Check for constraints against pgno */
+ for(i=0; i<pIdxInfo->nConstraint; i++){
+ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
+ if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+ pIdxInfo->estimatedRows = 1;
+ pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
+ pIdxInfo->estimatedCost = 1.0;
+ pIdxInfo->aConstraintUsage[i].argvIndex = iPlan ? 2 : 1;
+ pIdxInfo->aConstraintUsage[i].omit = 1;
+ iPlan |= 1;
+ break;
+ }
+ }
+ pIdxInfo->idxNum = iPlan;
+
+ if( pIdxInfo->nOrderBy>=1
+ && pIdxInfo->aOrderBy[0].iColumn<=0
+ && pIdxInfo->aOrderBy[0].desc==0
+ ){
+ pIdxInfo->orderByConsumed = 1;
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Open a new dbpagevfs cursor.
+*/
+static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+ DbpageCursor *pCsr;
+
+ pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor));
+ if( pCsr==0 ){
+ return SQLITE_NOMEM_BKPT;
+ }else{
+ memset(pCsr, 0, sizeof(DbpageCursor));
+ pCsr->base.pVtab = pVTab;
+ pCsr->pgno = -1;
+ }
+
+ *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+ return SQLITE_OK;
+}
+
+/*
+** Close a dbpagevfs cursor.
+*/
+static int dbpageClose(sqlite3_vtab_cursor *pCursor){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
+ sqlite3_free(pCsr);
+ return SQLITE_OK;
+}
+
+/*
+** Move a dbpagevfs cursor to the next entry in the file.
+*/
+static int dbpageNext(sqlite3_vtab_cursor *pCursor){
+ int rc = SQLITE_OK;
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ pCsr->pgno++;
+ return rc;
+}
+
+static int dbpageEof(sqlite3_vtab_cursor *pCursor){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ return pCsr->pgno > pCsr->mxPgno;
+}
+
+/*
+** idxNum:
+**
+** 0 schema=main, full table scan
+** 1 schema=main, pgno=?1
+** 2 schema=?1, full table scan
+** 3 schema=?1, pgno=?2
+**
+** idxStr is not used
+*/
+static int dbpageFilter(
+ sqlite3_vtab_cursor *pCursor,
+ int idxNum, const char *idxStr,
+ int argc, sqlite3_value **argv
+){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
+ int rc;
+ sqlite3 *db = pTab->db;
+ Btree *pBt;
+
+ /* Default setting is no rows of result */
+ pCsr->pgno = 1;
+ pCsr->mxPgno = 0;
+
+ if( idxNum & 2 ){
+ const char *zSchema;
+ assert( argc>=1 );
+ zSchema = (const char*)sqlite3_value_text(argv[0]);
+ pCsr->iDb = sqlite3FindDbName(db, zSchema);
+ if( pCsr->iDb<0 ) return SQLITE_OK;
+ }else{
+ pCsr->iDb = 0;
+ }
+ pBt = db->aDb[pCsr->iDb].pBt;
+ if( pBt==0 ) return SQLITE_OK;
+ pCsr->pPager = sqlite3BtreePager(pBt);
+ pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
+ pCsr->mxPgno = sqlite3BtreeLastPage(pBt);
+ if( idxNum & 1 ){
+ assert( argc>(idxNum>>1) );
+ pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]);
+ if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){
+ pCsr->pgno = 1;
+ pCsr->mxPgno = 0;
+ }else{
+ pCsr->mxPgno = pCsr->pgno;
+ }
+ }else{
+ assert( pCsr->pgno==1 );
+ }
+ if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1);
+ rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0);
+ return rc;
+}
+
+static int dbpageColumn(
+ sqlite3_vtab_cursor *pCursor,
+ sqlite3_context *ctx,
+ int i
+){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ int rc = SQLITE_OK;
+ switch( i ){
+ case 0: { /* pgno */
+ sqlite3_result_int(ctx, pCsr->pgno);
+ break;
+ }
+ case 1: { /* data */
+ DbPage *pDbPage = 0;
+ rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
+ if( rc==SQLITE_OK ){
+ sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage,
+ SQLITE_TRANSIENT);
+ }
+ sqlite3PagerUnref(pDbPage);
+ break;
+ }
+ default: { /* schema */
+ sqlite3 *db = sqlite3_context_db_handle(ctx);
+ sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC);
+ break;
+ }
+ }
+ return SQLITE_OK;
+}
+
+static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
+ DbpageCursor *pCsr = (DbpageCursor *)pCursor;
+ *pRowid = pCsr->pgno;
+ return SQLITE_OK;
+}
+
+static int dbpageUpdate(
+ sqlite3_vtab *pVtab,
+ int argc,
+ sqlite3_value **argv,
+ sqlite_int64 *pRowid
+){
+ DbpageTable *pTab = (DbpageTable *)pVtab;
+ Pgno pgno;
+ DbPage *pDbPage = 0;
+ int rc = SQLITE_OK;
+ char *zErr = 0;
+ const char *zSchema;
+ int iDb;
+ Btree *pBt;
+ Pager *pPager;
+ int szPage;
+
+ if( argc==1 ){
+ zErr = "cannot delete";
+ goto update_fail;
+ }
+ pgno = sqlite3_value_int(argv[0]);
+ if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
+ zErr = "cannot insert";
+ goto update_fail;
+ }
+ zSchema = (const char*)sqlite3_value_text(argv[4]);
+ iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1;
+ if( iDb<0 ){
+ zErr = "no such schema";
+ goto update_fail;
+ }
+ pBt = pTab->db->aDb[iDb].pBt;
+ if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
+ zErr = "bad page number";
+ goto update_fail;
+ }
+ szPage = sqlite3BtreeGetPageSize(pBt);
+ if( sqlite3_value_type(argv[3])!=SQLITE_BLOB
+ || sqlite3_value_bytes(argv[3])!=szPage
+ ){
+ zErr = "bad page value";
+ goto update_fail;
+ }
+ pPager = sqlite3BtreePager(pBt);
+ rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3PagerWrite(pDbPage);
+ if( rc==SQLITE_OK ){
+ memcpy(sqlite3PagerGetData(pDbPage),
+ sqlite3_value_blob(argv[3]),
+ szPage);
+ }
+ }
+ sqlite3PagerUnref(pDbPage);
+ return rc;
+
+update_fail:
+ sqlite3_free(pVtab->zErrMsg);
+ pVtab->zErrMsg = sqlite3_mprintf("%s", zErr);
+ return SQLITE_ERROR;
+}
+
+/* Since we do not know in advance which database files will be
+** written by the sqlite_dbpage virtual table, start a write transaction
+** on them all.
+*/
+static int dbpageBegin(sqlite3_vtab *pVtab){
+ DbpageTable *pTab = (DbpageTable *)pVtab;
+ sqlite3 *db = pTab->db;
+ int i;
+ for(i=0; i<db->nDb; i++){
+ Btree *pBt = db->aDb[i].pBt;
+ if( pBt ) sqlite3BtreeBeginTrans(pBt, 1);
+ }
+ return SQLITE_OK;
+}
+
+
+/*
+** Invoke this routine to register the "dbpage" virtual table module
+*/
+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
+ static sqlite3_module dbpage_module = {
+ 0, /* iVersion */
+ dbpageConnect, /* xCreate */
+ dbpageConnect, /* xConnect */
+ dbpageBestIndex, /* xBestIndex */
+ dbpageDisconnect, /* xDisconnect */
+ dbpageDisconnect, /* xDestroy */
+ dbpageOpen, /* xOpen - open a cursor */
+ dbpageClose, /* xClose - close a cursor */
+ dbpageFilter, /* xFilter - configure scan constraints */
+ dbpageNext, /* xNext - advance a cursor */
+ dbpageEof, /* xEof - check for end of scan */
+ dbpageColumn, /* xColumn - read data */
+ dbpageRowid, /* xRowid - read data */
+ dbpageUpdate, /* xUpdate */
+ dbpageBegin, /* xBegin */
+ 0, /* xSync */
+ 0, /* xCommit */
+ 0, /* xRollback */
+ 0, /* xFindMethod */
+ 0, /* xRename */
+ 0, /* xSavepoint */
+ 0, /* xRelease */
+ 0, /* xRollbackTo */
+ };
+ return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
+}
+#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
+SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
+#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
+
+/************** End of dbpage.c **********************************************/
/************** Begin file sqlite3session.c **********************************/
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
@@ -175995,6 +178756,7 @@ struct sqlite3_session {
int rc; /* Non-zero if an error has occurred */
void *pFilterCtx; /* First argument to pass to xTableFilter */
int (*xTableFilter)(void *pCtx, const char *zTab);
+ sqlite3_value *pZeroBlob; /* Value containing X'' */
sqlite3_session *pNext; /* Next session object on same db. */
SessionTable *pTable; /* List of attached tables */
SessionHook hook; /* APIs to grab new and old data with */
@@ -176062,6 +178824,7 @@ struct SessionTable {
SessionTable *pNext;
char *zName; /* Local name of table */
int nCol; /* Number of columns in table zName */
+ int bStat1; /* True if this is sqlite_stat1 */
const char **azCol; /* Column names */
u8 *abPK; /* Array of primary key flags */
int nEntry; /* Total number of entries in hash table */
@@ -176445,6 +179208,7 @@ static int sessionPreupdateHash(
h = sessionHashAppendBlob(h, n, z);
}else{
assert( eType==SQLITE_NULL );
+ assert( pTab->bStat1==0 || i!=1 );
*pbNullPK = 1;
}
}
@@ -176787,7 +179551,6 @@ static int sessionPreupdateEqual(
}
if( memcmp(a, z, n) ) return 0;
a += n;
- break;
}
}
}
@@ -176843,9 +179606,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
/*
** This function queries the database for the names of the columns of table
-** zThis, in schema zDb. It is expected that the table has nCol columns. If
-** not, SQLITE_SCHEMA is returned and none of the output variables are
-** populated.
+** zThis, in schema zDb.
**
** Otherwise, if they are not NULL, variable *pnCol is set to the number
** of columns in the database table and variable *pzTab is set to point to a
@@ -176866,9 +179627,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){
** *pabPK = {1, 0, 0, 1}
**
** All returned buffers are part of the same single allocation, which must
-** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then
-** pointer *pazCol should be freed to release all memory. Otherwise, pointer
-** *pabPK. It is illegal for both pazCol and pabPK to be NULL.
+** be freed using sqlite3_free() by the caller
*/
static int sessionTableInfo(
sqlite3 *db, /* Database connection */
@@ -176893,7 +179652,23 @@ static int sessionTableInfo(
assert( pazCol && pabPK );
nThis = sqlite3Strlen30(zThis);
- zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
+ if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
+ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
+ if( rc==SQLITE_OK ){
+ /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
+ zPragma = sqlite3_mprintf(
+ "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL "
+ "SELECT 1, 'idx', '', 0, '', 2 UNION ALL "
+ "SELECT 2, 'stat', '', 0, '', 0"
+ );
+ }else if( rc==SQLITE_ERROR ){
+ zPragma = sqlite3_mprintf("");
+ }else{
+ return rc;
+ }
+ }else{
+ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
+ }
if( !zPragma ) return SQLITE_NOMEM;
rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
@@ -176985,12 +179760,56 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
break;
}
}
+ if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
+ pTab->bStat1 = 1;
+ }
}
}
return (pSession->rc || pTab->abPK==0);
}
/*
+** Versions of the four methods in object SessionHook for use with the
+** sqlite_stat1 table. The purpose of this is to substitute a zero-length
+** blob each time a NULL value is read from the "idx" column of the
+** sqlite_stat1 table.
+*/
+typedef struct SessionStat1Ctx SessionStat1Ctx;
+struct SessionStat1Ctx {
+ SessionHook hook;
+ sqlite3_session *pSession;
+};
+static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ sqlite3_value *pVal = 0;
+ int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
+ pVal = p->pSession->pZeroBlob;
+ }
+ *ppVal = pVal;
+ return rc;
+}
+static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ sqlite3_value *pVal = 0;
+ int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
+ if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
+ pVal = p->pSession->pZeroBlob;
+ }
+ *ppVal = pVal;
+ return rc;
+}
+static int sessionStat1Count(void *pCtx){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ return p->hook.xCount(p->hook.pCtx);
+}
+static int sessionStat1Depth(void *pCtx){
+ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
+ return p->hook.xDepth(p->hook.pCtx);
+}
+
+
+/*
** This function is only called from with a pre-update-hook reporting a
** change on table pTab (attached to session pSession). The type of change
** (UPDATE, INSERT, DELETE) is specified by the first argument.
@@ -177006,6 +179825,7 @@ static void sessionPreupdateOneChange(
int iHash;
int bNull = 0;
int rc = SQLITE_OK;
+ SessionStat1Ctx stat1;
if( pSession->rc ) return;
@@ -177025,6 +179845,25 @@ static void sessionPreupdateOneChange(
return;
}
+ if( pTab->bStat1 ){
+ stat1.hook = pSession->hook;
+ stat1.pSession = pSession;
+ pSession->hook.pCtx = (void*)&stat1;
+ pSession->hook.xNew = sessionStat1New;
+ pSession->hook.xOld = sessionStat1Old;
+ pSession->hook.xCount = sessionStat1Count;
+ pSession->hook.xDepth = sessionStat1Depth;
+ if( pSession->pZeroBlob==0 ){
+ sqlite3_value *p = sqlite3ValueNew(0);
+ if( p==0 ){
+ rc = SQLITE_NOMEM;
+ goto error_out;
+ }
+ sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
+ pSession->pZeroBlob = p;
+ }
+ }
+
/* Calculate the hash-key for this change. If the primary key of the row
** includes a NULL value, exit early. Such changes are ignored by the
** session module. */
@@ -177114,6 +179953,9 @@ static void sessionPreupdateOneChange(
/* If an error has occurred, mark the session object as failed. */
error_out:
+ if( pTab->bStat1 ){
+ pSession->hook = stat1.hook;
+ }
if( rc!=SQLITE_OK ){
pSession->rc = rc;
}
@@ -177450,7 +180292,6 @@ SQLITE_API int sqlite3session_diff(
if( abPK[i] ) bHasPk = 1;
}
}
-
}
sqlite3_free((char*)azCol);
if( bMismatch ){
@@ -177576,6 +180417,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){
}
}
sqlite3_mutex_leave(sqlite3_db_mutex(db));
+ sqlite3ValueFree(pSession->pZeroBlob);
/* Delete all attached table objects. And the contents of their
** associated hash-tables. */
@@ -178043,28 +180885,41 @@ static int sessionSelectStmt(
sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){
int rc = SQLITE_OK;
- int i;
- const char *zSep = "";
- SessionBuffer buf = {0, 0, 0};
+ char *zSql = 0;
+ int nSql = -1;
- sessionAppendStr(&buf, "SELECT * FROM ", &rc);
- sessionAppendIdent(&buf, zDb, &rc);
- sessionAppendStr(&buf, ".", &rc);
- sessionAppendIdent(&buf, zTab, &rc);
- sessionAppendStr(&buf, " WHERE ", &rc);
- for(i=0; i<nCol; i++){
- if( abPK[i] ){
- sessionAppendStr(&buf, zSep, &rc);
- sessionAppendIdent(&buf, azCol[i], &rc);
- sessionAppendStr(&buf, " = ?", &rc);
- sessionAppendInteger(&buf, i+1, &rc);
- zSep = " AND ";
+ if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
+ zSql = sqlite3_mprintf(
+ "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
+ "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
+ );
+ }else{
+ int i;
+ const char *zSep = "";
+ SessionBuffer buf = {0, 0, 0};
+
+ sessionAppendStr(&buf, "SELECT * FROM ", &rc);
+ sessionAppendIdent(&buf, zDb, &rc);
+ sessionAppendStr(&buf, ".", &rc);
+ sessionAppendIdent(&buf, zTab, &rc);
+ sessionAppendStr(&buf, " WHERE ", &rc);
+ for(i=0; i<nCol; i++){
+ if( abPK[i] ){
+ sessionAppendStr(&buf, zSep, &rc);
+ sessionAppendIdent(&buf, azCol[i], &rc);
+ sessionAppendStr(&buf, " IS ?", &rc);
+ sessionAppendInteger(&buf, i+1, &rc);
+ zSep = " AND ";
+ }
}
+ zSql = (char*)buf.aBuf;
+ nSql = buf.nBuf;
}
+
if( rc==SQLITE_OK ){
- rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0);
+ rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
}
- sqlite3_free(buf.aBuf);
+ sqlite3_free(zSql);
return rc;
}
@@ -179233,7 +182088,7 @@ struct SessionApplyCtx {
int nCol; /* Size of azCol[] and abPK[] arrays */
const char **azCol; /* Array of column names */
u8 *abPK; /* Boolean array - true if column is in PK */
-
+ int bStat1; /* True if table is sqlite_stat1 */
int bDeferConstraints; /* True to defer constraints */
SessionBuffer constraints; /* Deferred constraints are stored here */
};
@@ -179403,6 +182258,7 @@ static int sessionUpdateRow(
return rc;
}
+
/*
** Formulate and prepare an SQL statement to query table zTab by primary
** key. Assuming the following table structure:
@@ -179464,6 +182320,47 @@ static int sessionInsertRow(
return rc;
}
+static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
+ return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
+}
+
+/*
+** Prepare statements for applying changes to the sqlite_stat1 table.
+** These are similar to those created by sessionSelectRow(),
+** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for
+** other tables.
+*/
+static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
+ int rc = sessionSelectRow(db, "sqlite_stat1", p);
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pInsert,
+ "INSERT INTO main.sqlite_stat1 VALUES(?1, "
+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
+ "?3)"
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pUpdate,
+ "UPDATE main.sqlite_stat1 SET "
+ "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, "
+ "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, "
+ "stat = CASE WHEN ?8 THEN ?9 ELSE stat END "
+ "WHERE tbl=?1 AND idx IS "
+ "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END "
+ "AND (?10 OR ?8=0 OR stat IS ?7)"
+ );
+ }
+ if( rc==SQLITE_OK ){
+ rc = sessionPrepare(db, &p->pDelete,
+ "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
+ "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
+ "AND (?4 OR stat IS ?3)"
+ );
+ }
+ assert( rc==SQLITE_OK );
+ return rc;
+}
+
/*
** A wrapper around sqlite3_bind_value() that detects an extra problem.
** See comments in the body of this function for details.
@@ -179794,11 +182691,25 @@ static int sessionApplyOneOp(
}else{
assert( op==SQLITE_INSERT );
- rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
- if( rc!=SQLITE_OK ) return rc;
+ if( p->bStat1 ){
+ /* Check if there is a conflicting row. For sqlite_stat1, this needs
+ ** to be done using a SELECT, as there is no PRIMARY KEY in the
+ ** database schema to throw an exception if a duplicate is inserted. */
+ rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+ if( rc==SQLITE_ROW ){
+ rc = SQLITE_CONSTRAINT;
+ sqlite3_reset(p->pSelect);
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
+ if( rc!=SQLITE_OK ) return rc;
+
+ sqlite3_step(p->pInsert);
+ rc = sqlite3_reset(p->pInsert);
+ }
- sqlite3_step(p->pInsert);
- rc = sqlite3_reset(p->pInsert);
if( (rc&0xff)==SQLITE_CONSTRAINT ){
rc = sessionConflictHandler(
SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
@@ -180031,12 +182942,20 @@ static int sessionChangesetApply(
}
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;
+ if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
+ if( (rc = sessionStat1Sql(db, &sApply) ) ){
+ break;
+ }
+ sApply.bStat1 = 1;
+ }else{
+ if((rc = sessionSelectRow(db, zTab, &sApply))
+ || (rc = sessionUpdateRow(db, zTab, &sApply))
+ || (rc = sessionDeleteRow(db, zTab, &sApply))
+ || (rc = sessionInsertRow(db, zTab, &sApply))
+ ){
+ break;
+ }
+ sApply.bStat1 = 0;
}
}
nTab = sqlite3Strlen30(zTab);
@@ -184350,6 +187269,8 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm(
int bPrefix
);
+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*);
+
static Fts5ExprNearset *sqlite3Fts5ParseNearset(
Fts5Parse*,
Fts5ExprNearset*,
@@ -184430,9 +187351,10 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
#define FTS5_STRING 9
#define FTS5_LP 10
#define FTS5_RP 11
-#define FTS5_COMMA 12
-#define FTS5_PLUS 13
-#define FTS5_STAR 14
+#define FTS5_CARET 12
+#define FTS5_COMMA 13
+#define FTS5_PLUS 14
+#define FTS5_STAR 15
/*
** 2000-05-29
@@ -184533,30 +187455,32 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
** defined, then do no error processing.
** fts5YYNSTATE the combined number of states.
** fts5YYNRULE the number of rules in the grammar
+** fts5YYNFTS5TOKEN Number of terminal symbols
** fts5YY_MAX_SHIFT Maximum value for shift actions
** fts5YY_MIN_SHIFTREDUCE Minimum value for shift-reduce actions
** fts5YY_MAX_SHIFTREDUCE Maximum value for shift-reduce actions
-** fts5YY_MIN_REDUCE Maximum value for reduce actions
** fts5YY_ERROR_ACTION The fts5yy_action[] code for syntax error
** fts5YY_ACCEPT_ACTION The fts5yy_action[] code for accept
** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
+** fts5YY_MIN_REDUCE Minimum value for reduce actions
+** fts5YY_MAX_REDUCE Maximum value for reduce actions
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
#define fts5YYCODETYPE unsigned char
-#define fts5YYNOCODE 28
+#define fts5YYNOCODE 29
#define fts5YYACTIONTYPE unsigned char
#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
typedef union {
int fts5yyinit;
sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
int fts5yy4;
- Fts5Colset* fts5yy11;
- Fts5ExprNode* fts5yy24;
- Fts5ExprNearset* fts5yy46;
- Fts5ExprPhrase* fts5yy53;
+ Fts5ExprPhrase* fts5yy11;
+ Fts5ExprNearset* fts5yy14;
+ Fts5Colset* fts5yy43;
+ Fts5ExprNode* fts5yy54;
} fts5YYMINORTYPE;
#ifndef fts5YYSTACKDEPTH
#define fts5YYSTACKDEPTH 100
@@ -184565,16 +187489,17 @@ typedef union {
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
-#define fts5YYNSTATE 33
-#define fts5YYNRULE 27
-#define fts5YY_MAX_SHIFT 32
-#define fts5YY_MIN_SHIFTREDUCE 50
-#define fts5YY_MAX_SHIFTREDUCE 76
-#define fts5YY_MIN_REDUCE 77
-#define fts5YY_MAX_REDUCE 103
-#define fts5YY_ERROR_ACTION 104
-#define fts5YY_ACCEPT_ACTION 105
-#define fts5YY_NO_ACTION 106
+#define fts5YYNSTATE 35
+#define fts5YYNRULE 28
+#define fts5YYNFTS5TOKEN 16
+#define fts5YY_MAX_SHIFT 34
+#define fts5YY_MIN_SHIFTREDUCE 52
+#define fts5YY_MAX_SHIFTREDUCE 79
+#define fts5YY_ERROR_ACTION 80
+#define fts5YY_ACCEPT_ACTION 81
+#define fts5YY_NO_ACTION 82
+#define fts5YY_MIN_REDUCE 83
+#define fts5YY_MAX_REDUCE 110
/************* End control #defines *******************************************/
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
@@ -184604,9 +187529,6 @@ typedef union {
** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
**
-** 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.
@@ -184614,25 +187536,22 @@ typedef union {
** N == fts5YY_NO_ACTION No such action. Denotes unused
** slots in the fts5yy_action[] table.
**
+** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
+** and fts5YY_MAX_REDUCE
+**
** The action table is constructed as a single large table named fts5yy_action[].
** Given state S and lookahead X, the action is computed as either:
**
** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
** (B) N = fts5yy_default[S]
**
-** 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 (A) formula is preferred. The B formula is used instead if
+** fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X.
**
** 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
-** fts5YY_SHIFT_USE_DFLT.
+** the fts5yy_shift_ofst[] array.
**
** The following are the tables generated in this section:
**
@@ -184646,54 +187565,56 @@ typedef union {
** fts5yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
-#define fts5YY_ACTTAB_COUNT (98)
+#define fts5YY_ACTTAB_COUNT (105)
static const fts5YYACTIONTYPE fts5yy_action[] = {
- /* 0 */ 105, 19, 90, 6, 26, 93, 92, 24, 24, 17,
- /* 10 */ 90, 6, 26, 16, 92, 54, 24, 18, 90, 6,
- /* 20 */ 26, 10, 92, 12, 24, 75, 86, 90, 6, 26,
- /* 30 */ 13, 92, 75, 24, 20, 90, 6, 26, 101, 92,
- /* 40 */ 56, 24, 27, 90, 6, 26, 100, 92, 21, 24,
- /* 50 */ 23, 15, 30, 11, 1, 91, 22, 25, 9, 92,
- /* 60 */ 7, 24, 3, 4, 5, 3, 4, 5, 3, 77,
- /* 70 */ 4, 5, 3, 61, 23, 15, 60, 11, 80, 12,
- /* 80 */ 2, 13, 68, 10, 29, 52, 55, 75, 31, 32,
- /* 90 */ 8, 28, 5, 3, 51, 55, 72, 14,
+ /* 0 */ 81, 20, 96, 6, 28, 99, 98, 26, 26, 18,
+ /* 10 */ 96, 6, 28, 17, 98, 56, 26, 19, 96, 6,
+ /* 20 */ 28, 14, 98, 108, 26, 92, 96, 6, 28, 25,
+ /* 30 */ 98, 78, 26, 21, 96, 6, 28, 107, 98, 58,
+ /* 40 */ 26, 29, 96, 6, 28, 32, 98, 22, 26, 24,
+ /* 50 */ 16, 23, 11, 1, 14, 13, 24, 16, 31, 11,
+ /* 60 */ 3, 97, 13, 27, 8, 98, 82, 26, 7, 4,
+ /* 70 */ 5, 3, 4, 5, 3, 83, 4, 5, 3, 63,
+ /* 80 */ 33, 34, 62, 12, 2, 86, 13, 10, 12, 71,
+ /* 90 */ 10, 13, 78, 5, 3, 78, 9, 30, 75, 82,
+ /* 100 */ 54, 57, 53, 57, 15,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
- /* 0 */ 16, 17, 18, 19, 20, 22, 22, 24, 24, 17,
- /* 10 */ 18, 19, 20, 7, 22, 9, 24, 17, 18, 19,
- /* 20 */ 20, 10, 22, 9, 24, 14, 17, 18, 19, 20,
- /* 30 */ 9, 22, 14, 24, 17, 18, 19, 20, 26, 22,
- /* 40 */ 9, 24, 17, 18, 19, 20, 26, 22, 21, 24,
- /* 50 */ 6, 7, 13, 9, 10, 18, 21, 20, 5, 22,
- /* 60 */ 5, 24, 3, 1, 2, 3, 1, 2, 3, 0,
- /* 70 */ 1, 2, 3, 11, 6, 7, 11, 9, 5, 9,
- /* 80 */ 10, 9, 11, 10, 12, 8, 9, 14, 24, 25,
- /* 90 */ 23, 24, 2, 3, 8, 9, 9, 9,
+ /* 0 */ 17, 18, 19, 20, 21, 23, 23, 25, 25, 18,
+ /* 10 */ 19, 20, 21, 7, 23, 9, 25, 18, 19, 20,
+ /* 20 */ 21, 9, 23, 27, 25, 18, 19, 20, 21, 25,
+ /* 30 */ 23, 15, 25, 18, 19, 20, 21, 27, 23, 9,
+ /* 40 */ 25, 18, 19, 20, 21, 14, 23, 22, 25, 6,
+ /* 50 */ 7, 22, 9, 10, 9, 12, 6, 7, 13, 9,
+ /* 60 */ 3, 19, 12, 21, 5, 23, 28, 25, 5, 1,
+ /* 70 */ 2, 3, 1, 2, 3, 0, 1, 2, 3, 11,
+ /* 80 */ 25, 26, 11, 9, 10, 5, 12, 10, 9, 11,
+ /* 90 */ 10, 12, 15, 2, 3, 15, 24, 25, 9, 28,
+ /* 100 */ 8, 9, 8, 9, 9, 28, 28, 28, 28, 28,
+ /* 110 */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ /* 120 */ 28,
};
-#define fts5YY_SHIFT_USE_DFLT (98)
-#define fts5YY_SHIFT_COUNT (32)
+#define fts5YY_SHIFT_COUNT (34)
#define fts5YY_SHIFT_MIN (0)
-#define fts5YY_SHIFT_MAX (90)
+#define fts5YY_SHIFT_MAX (95)
static const unsigned char fts5yy_shift_ofst[] = {
- /* 0 */ 44, 44, 44, 44, 44, 44, 68, 70, 72, 14,
- /* 10 */ 21, 73, 11, 18, 18, 31, 31, 62, 65, 69,
- /* 20 */ 90, 77, 86, 6, 39, 53, 55, 59, 39, 87,
- /* 30 */ 88, 39, 71,
+ /* 0 */ 43, 43, 43, 43, 43, 43, 50, 74, 79, 45,
+ /* 10 */ 12, 80, 77, 12, 16, 16, 30, 30, 68, 71,
+ /* 20 */ 75, 91, 92, 94, 6, 31, 31, 59, 63, 57,
+ /* 30 */ 31, 89, 95, 31, 78,
};
-#define fts5YY_REDUCE_USE_DFLT (-18)
-#define fts5YY_REDUCE_COUNT (16)
-#define fts5YY_REDUCE_MIN (-17)
-#define fts5YY_REDUCE_MAX (67)
+#define fts5YY_REDUCE_COUNT (17)
+#define fts5YY_REDUCE_MIN (-18)
+#define fts5YY_REDUCE_MAX (72)
static const signed char fts5yy_reduce_ofst[] = {
- /* 0 */ -16, -8, 0, 9, 17, 25, 37, -17, 64, -17,
- /* 10 */ 67, 12, 12, 12, 20, 27, 35,
+ /* 0 */ -17, -9, -1, 7, 15, 23, 42, -18, -18, 55,
+ /* 10 */ 72, -4, -4, 4, -4, 10, 25, 29,
};
static const fts5YYACTIONTYPE fts5yy_default[] = {
- /* 0 */ 104, 104, 104, 104, 104, 104, 89, 104, 98, 104,
- /* 10 */ 104, 103, 103, 103, 103, 104, 104, 104, 104, 104,
- /* 20 */ 85, 104, 104, 104, 94, 104, 104, 84, 96, 104,
- /* 30 */ 104, 97, 104,
+ /* 0 */ 80, 80, 80, 80, 80, 80, 95, 80, 80, 105,
+ /* 10 */ 80, 110, 110, 80, 110, 110, 80, 80, 80, 80,
+ /* 20 */ 80, 91, 80, 80, 80, 101, 100, 80, 80, 90,
+ /* 30 */ 103, 80, 80, 104, 80,
};
/********** End of lemon-generated parsing tables *****************************/
@@ -184795,19 +187716,40 @@ static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){
}
#endif /* NDEBUG */
-#ifndef NDEBUG
+#if defined(fts5YYCOVERAGE) || !defined(NDEBUG)
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const fts5yyTokenName[] = {
- "$", "OR", "AND", "NOT",
- "TERM", "COLON", "MINUS", "LCP",
- "RCP", "STRING", "LP", "RP",
- "COMMA", "PLUS", "STAR", "error",
- "input", "expr", "cnearset", "exprlist",
- "colset", "colsetlist", "nearset", "nearphrases",
- "phrase", "neardist_opt", "star_opt",
+ /* 0 */ "$",
+ /* 1 */ "OR",
+ /* 2 */ "AND",
+ /* 3 */ "NOT",
+ /* 4 */ "TERM",
+ /* 5 */ "COLON",
+ /* 6 */ "MINUS",
+ /* 7 */ "LCP",
+ /* 8 */ "RCP",
+ /* 9 */ "STRING",
+ /* 10 */ "LP",
+ /* 11 */ "RP",
+ /* 12 */ "CARET",
+ /* 13 */ "COMMA",
+ /* 14 */ "PLUS",
+ /* 15 */ "STAR",
+ /* 16 */ "error",
+ /* 17 */ "input",
+ /* 18 */ "expr",
+ /* 19 */ "cnearset",
+ /* 20 */ "exprlist",
+ /* 21 */ "colset",
+ /* 22 */ "colsetlist",
+ /* 23 */ "nearset",
+ /* 24 */ "nearphrases",
+ /* 25 */ "phrase",
+ /* 26 */ "neardist_opt",
+ /* 27 */ "star_opt",
};
-#endif /* NDEBUG */
+#endif /* defined(fts5YYCOVERAGE) || !defined(NDEBUG) */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
@@ -184831,15 +187773,16 @@ static const char *const fts5yyRuleName[] = {
/* 15 */ "cnearset ::= nearset",
/* 16 */ "cnearset ::= colset COLON nearset",
/* 17 */ "nearset ::= phrase",
- /* 18 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
- /* 19 */ "nearphrases ::= phrase",
- /* 20 */ "nearphrases ::= nearphrases phrase",
- /* 21 */ "neardist_opt ::=",
- /* 22 */ "neardist_opt ::= COMMA STRING",
- /* 23 */ "phrase ::= phrase PLUS STRING star_opt",
- /* 24 */ "phrase ::= STRING star_opt",
- /* 25 */ "star_opt ::= STAR",
- /* 26 */ "star_opt ::=",
+ /* 18 */ "nearset ::= CARET phrase",
+ /* 19 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
+ /* 20 */ "nearphrases ::= phrase",
+ /* 21 */ "nearphrases ::= nearphrases phrase",
+ /* 22 */ "neardist_opt ::=",
+ /* 23 */ "neardist_opt ::= COMMA STRING",
+ /* 24 */ "phrase ::= phrase PLUS STRING star_opt",
+ /* 25 */ "phrase ::= STRING star_opt",
+ /* 26 */ "star_opt ::= STAR",
+ /* 27 */ "star_opt ::=",
};
#endif /* NDEBUG */
@@ -184960,33 +187903,33 @@ static void fts5yy_destructor(
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
- case 16: /* input */
+ case 17: /* input */
{
(void)pParse;
}
break;
- case 17: /* expr */
- case 18: /* cnearset */
- case 19: /* exprlist */
+ case 18: /* expr */
+ case 19: /* cnearset */
+ case 20: /* exprlist */
{
- sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
+ sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy54));
}
break;
- case 20: /* colset */
- case 21: /* colsetlist */
+ case 21: /* colset */
+ case 22: /* colsetlist */
{
- sqlite3_free((fts5yypminor->fts5yy11));
+ sqlite3_free((fts5yypminor->fts5yy43));
}
break;
- case 22: /* nearset */
- case 23: /* nearphrases */
+ case 23: /* nearset */
+ case 24: /* nearphrases */
{
- sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
+ sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy14));
}
break;
- case 24: /* phrase */
+ case 25: /* phrase */
{
- sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
+ sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy11));
}
break;
/********* End destructor definitions *****************************************/
@@ -185057,6 +188000,43 @@ static int sqlite3Fts5ParserStackPeak(void *p){
}
#endif
+/* This array of booleans keeps track of the parser statement
+** coverage. The element fts5yycoverage[X][Y] is set when the parser
+** is in state X and has a lookahead token Y. In a well-tested
+** systems, every element of this matrix should end up being set.
+*/
+#if defined(fts5YYCOVERAGE)
+static unsigned char fts5yycoverage[fts5YYNSTATE][fts5YYNFTS5TOKEN];
+#endif
+
+/*
+** Write into out a description of every state/lookahead combination that
+**
+** (1) has not been used by the parser, and
+** (2) is not a syntax error.
+**
+** Return the number of missed state/lookahead combinations.
+*/
+#if defined(fts5YYCOVERAGE)
+static int sqlite3Fts5ParserCoverage(FILE *out){
+ int stateno, iLookAhead, i;
+ int nMissed = 0;
+ for(stateno=0; stateno<fts5YYNSTATE; stateno++){
+ i = fts5yy_shift_ofst[stateno];
+ for(iLookAhead=0; iLookAhead<fts5YYNFTS5TOKEN; iLookAhead++){
+ if( fts5yy_lookahead[i+iLookAhead]!=iLookAhead ) continue;
+ if( fts5yycoverage[stateno][iLookAhead]==0 ) nMissed++;
+ if( out ){
+ fprintf(out,"State %d lookahead %s %s\n", stateno,
+ fts5yyTokenName[iLookAhead],
+ fts5yycoverage[stateno][iLookAhead] ? "ok" : "missed");
+ }
+ }
+ }
+ return nMissed;
+}
+#endif
+
/*
** Find the appropriate action for a parser given the terminal
** look-ahead token iLookAhead.
@@ -185068,13 +188048,18 @@ static unsigned int fts5yy_find_shift_action(
int i;
int stateno = pParser->fts5yytos->stateno;
- if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
+ if( stateno>fts5YY_MAX_SHIFT ) return stateno;
assert( stateno <= fts5YY_SHIFT_COUNT );
+#if defined(fts5YYCOVERAGE)
+ fts5yycoverage[stateno][iLookAhead] = 1;
+#endif
do{
i = fts5yy_shift_ofst[stateno];
+ assert( i>=0 && i+fts5YYNFTS5TOKEN<=sizeof(fts5yy_lookahead)/sizeof(fts5yy_lookahead[0]) );
assert( iLookAhead!=fts5YYNOCODE );
+ assert( iLookAhead < fts5YYNFTS5TOKEN );
i += iLookAhead;
- if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
+ if( fts5yy_lookahead[i]!=iLookAhead ){
#ifdef fts5YYFALLBACK
fts5YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
@@ -185137,7 +188122,6 @@ static int fts5yy_find_reduce_action(
assert( stateno<=fts5YY_REDUCE_COUNT );
#endif
i = fts5yy_reduce_ofst[stateno];
- assert( i!=fts5YY_REDUCE_USE_DFLT );
assert( iLookAhead!=fts5YYNOCODE );
i += iLookAhead;
#ifdef fts5YYERRORSYMBOL
@@ -185175,20 +188159,21 @@ static void fts5yyStackOverflow(fts5yyParser *fts5yypParser){
** Print tracing information for a SHIFT action
*/
#ifndef NDEBUG
-static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState){
+static void fts5yyTraceShift(fts5yyParser *fts5yypParser, int fts5yyNewState, const char *zTag){
if( fts5yyTraceFILE ){
if( fts5yyNewState<fts5YYNSTATE ){
- fprintf(fts5yyTraceFILE,"%sShift '%s', go to state %d\n",
- fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major],
+ fprintf(fts5yyTraceFILE,"%s%s '%s', go to state %d\n",
+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
fts5yyNewState);
}else{
- fprintf(fts5yyTraceFILE,"%sShift '%s'\n",
- fts5yyTracePrompt,fts5yyTokenName[fts5yypParser->fts5yytos->major]);
+ fprintf(fts5yyTraceFILE,"%s%s '%s', pending reduce %d\n",
+ fts5yyTracePrompt, zTag, fts5yyTokenName[fts5yypParser->fts5yytos->major],
+ fts5yyNewState - fts5YY_MIN_REDUCE);
}
}
}
#else
-# define fts5yyTraceShift(X,Y)
+# define fts5yyTraceShift(X,Y,Z)
#endif
/*
@@ -185230,7 +188215,7 @@ static void fts5yy_shift(
fts5yytos->stateno = (fts5YYACTIONTYPE)fts5yyNewState;
fts5yytos->major = (fts5YYCODETYPE)fts5yyMajor;
fts5yytos->minor.fts5yy0 = fts5yyMinor;
- fts5yyTraceShift(fts5yypParser, fts5yyNewState);
+ fts5yyTraceShift(fts5yypParser, fts5yyNewState, "Shift");
}
/* The following table contains information about every rule that
@@ -185240,33 +188225,34 @@ static const struct {
fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
signed char nrhs; /* Negative of the number of RHS symbols in the rule */
} fts5yyRuleInfo[] = {
- { 16, -1 },
- { 20, -4 },
- { 20, -3 },
- { 20, -1 },
- { 20, -2 },
- { 21, -2 },
- { 21, -1 },
- { 17, -3 },
- { 17, -3 },
- { 17, -3 },
- { 17, -5 },
- { 17, -3 },
- { 17, -1 },
- { 19, -1 },
- { 19, -2 },
- { 18, -1 },
- { 18, -3 },
- { 22, -1 },
- { 22, -5 },
- { 23, -1 },
- { 23, -2 },
- { 25, 0 },
- { 25, -2 },
- { 24, -4 },
- { 24, -2 },
- { 26, -1 },
- { 26, 0 },
+ { 17, -1 }, /* (0) input ::= expr */
+ { 21, -4 }, /* (1) colset ::= MINUS LCP colsetlist RCP */
+ { 21, -3 }, /* (2) colset ::= LCP colsetlist RCP */
+ { 21, -1 }, /* (3) colset ::= STRING */
+ { 21, -2 }, /* (4) colset ::= MINUS STRING */
+ { 22, -2 }, /* (5) colsetlist ::= colsetlist STRING */
+ { 22, -1 }, /* (6) colsetlist ::= STRING */
+ { 18, -3 }, /* (7) expr ::= expr AND expr */
+ { 18, -3 }, /* (8) expr ::= expr OR expr */
+ { 18, -3 }, /* (9) expr ::= expr NOT expr */
+ { 18, -5 }, /* (10) expr ::= colset COLON LP expr RP */
+ { 18, -3 }, /* (11) expr ::= LP expr RP */
+ { 18, -1 }, /* (12) expr ::= exprlist */
+ { 20, -1 }, /* (13) exprlist ::= cnearset */
+ { 20, -2 }, /* (14) exprlist ::= exprlist cnearset */
+ { 19, -1 }, /* (15) cnearset ::= nearset */
+ { 19, -3 }, /* (16) cnearset ::= colset COLON nearset */
+ { 23, -1 }, /* (17) nearset ::= phrase */
+ { 23, -2 }, /* (18) nearset ::= CARET phrase */
+ { 23, -5 }, /* (19) nearset ::= STRING LP nearphrases neardist_opt RP */
+ { 24, -1 }, /* (20) nearphrases ::= phrase */
+ { 24, -2 }, /* (21) nearphrases ::= nearphrases phrase */
+ { 26, 0 }, /* (22) neardist_opt ::= */
+ { 26, -2 }, /* (23) neardist_opt ::= COMMA STRING */
+ { 25, -4 }, /* (24) phrase ::= phrase PLUS STRING star_opt */
+ { 25, -2 }, /* (25) phrase ::= STRING star_opt */
+ { 27, -1 }, /* (26) star_opt ::= STAR */
+ { 27, 0 }, /* (27) star_opt ::= */
};
static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
@@ -185274,22 +188260,38 @@ static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
+**
+** The fts5yyLookahead and fts5yyLookaheadToken parameters provide reduce actions
+** access to the lookahead token (if any). The fts5yyLookahead will be fts5YYNOCODE
+** if the lookahead token has already been consumed. As this procedure is
+** only called from one place, optimizing compilers will in-line it, which
+** means that the extra parameters have no performance impact.
*/
static void fts5yy_reduce(
fts5yyParser *fts5yypParser, /* The parser */
- unsigned int fts5yyruleno /* Number of the rule by which to reduce */
+ unsigned int fts5yyruleno, /* Number of the rule by which to reduce */
+ int fts5yyLookahead, /* Lookahead token, or fts5YYNOCODE if none */
+ sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken /* Value of the lookahead token */
){
int fts5yygoto; /* The next state */
int fts5yyact; /* The next action */
fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */
int fts5yysize; /* Amount to pop the stack */
sqlite3Fts5ParserARG_FETCH;
+ (void)fts5yyLookahead;
+ (void)fts5yyLookaheadToken;
fts5yymsp = fts5yypParser->fts5yytos;
#ifndef NDEBUG
if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){
fts5yysize = fts5yyRuleInfo[fts5yyruleno].nrhs;
- fprintf(fts5yyTraceFILE, "%sReduce [%s], go to state %d.\n", fts5yyTracePrompt,
- fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno);
+ if( fts5yysize ){
+ fprintf(fts5yyTraceFILE, "%sReduce %d [%s], go to state %d.\n",
+ fts5yyTracePrompt,
+ fts5yyruleno, fts5yyRuleName[fts5yyruleno], fts5yymsp[fts5yysize].stateno);
+ }else{
+ fprintf(fts5yyTraceFILE, "%sReduce %d [%s].\n",
+ fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno]);
+ }
}
#endif /* NDEBUG */
@@ -185331,137 +188333,143 @@ static void fts5yy_reduce(
/********** Begin reduce actions **********************************************/
fts5YYMINORTYPE fts5yylhsminor;
case 0: /* input ::= expr */
-{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
+{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy54); }
break;
case 1: /* colset ::= MINUS LCP colsetlist RCP */
{
- fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+ fts5yymsp[-3].minor.fts5yy43 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy43);
}
break;
case 2: /* colset ::= LCP colsetlist RCP */
-{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
+{ fts5yymsp[-2].minor.fts5yy43 = fts5yymsp[-1].minor.fts5yy43; }
break;
case 3: /* colset ::= STRING */
{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yylhsminor.fts5yy43 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
}
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ fts5yymsp[0].minor.fts5yy43 = fts5yylhsminor.fts5yy43;
break;
case 4: /* colset ::= MINUS STRING */
{
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
- fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
+ fts5yymsp[-1].minor.fts5yy43 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yymsp[-1].minor.fts5yy43 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy43);
}
break;
case 5: /* colsetlist ::= colsetlist STRING */
{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
- fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ fts5yylhsminor.fts5yy43 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy43, &fts5yymsp[0].minor.fts5yy0); }
+ fts5yymsp[-1].minor.fts5yy43 = fts5yylhsminor.fts5yy43;
break;
case 6: /* colsetlist ::= STRING */
{
- fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
+ fts5yylhsminor.fts5yy43 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
}
- fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
+ fts5yymsp[0].minor.fts5yy43 = fts5yylhsminor.fts5yy43;
break;
case 7: /* expr ::= expr AND expr */
{
- fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
+ fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54, 0);
}
- fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 8: /* expr ::= expr OR expr */
{
- fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
+ fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54, 0);
}
- fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 9: /* expr ::= expr NOT expr */
{
- fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
+ fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54, 0);
}
- fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 10: /* expr ::= colset COLON LP expr RP */
{
- sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11);
- fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;
+ sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy54, fts5yymsp[-4].minor.fts5yy43);
+ fts5yylhsminor.fts5yy54 = fts5yymsp[-1].minor.fts5yy54;
}
- fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ fts5yymsp[-4].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 11: /* expr ::= LP expr RP */
-{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
+{fts5yymsp[-2].minor.fts5yy54 = fts5yymsp[-1].minor.fts5yy54;}
break;
case 12: /* expr ::= exprlist */
case 13: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==13);
-{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
- fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+{fts5yylhsminor.fts5yy54 = fts5yymsp[0].minor.fts5yy54;}
+ fts5yymsp[0].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 14: /* exprlist ::= exprlist cnearset */
{
- fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
+ fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy54, fts5yymsp[0].minor.fts5yy54);
}
- fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ fts5yymsp[-1].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 15: /* cnearset ::= nearset */
{
- fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
+ fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy14);
}
- fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ fts5yymsp[0].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 16: /* cnearset ::= colset COLON nearset */
{
- fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
- sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11);
+ fts5yylhsminor.fts5yy54 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy14);
+ sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy54, fts5yymsp[-2].minor.fts5yy43);
}
- fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
+ fts5yymsp[-2].minor.fts5yy54 = fts5yylhsminor.fts5yy54;
break;
case 17: /* nearset ::= phrase */
-{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
- fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+{ fts5yylhsminor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11); }
+ fts5yymsp[0].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
+ break;
+ case 18: /* nearset ::= CARET phrase */
+{
+ sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy11);
+ fts5yymsp[-1].minor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11);
+}
break;
- case 18: /* nearset ::= STRING LP nearphrases neardist_opt RP */
+ case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */
{
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
- sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
- fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
+ sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy14, &fts5yymsp[-1].minor.fts5yy0);
+ fts5yylhsminor.fts5yy14 = fts5yymsp[-2].minor.fts5yy14;
}
- fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+ fts5yymsp[-4].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
break;
- case 19: /* nearphrases ::= phrase */
+ case 20: /* nearphrases ::= phrase */
{
- fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
+ fts5yylhsminor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy11);
}
- fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+ fts5yymsp[0].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
break;
- case 20: /* nearphrases ::= nearphrases phrase */
+ case 21: /* nearphrases ::= nearphrases phrase */
{
- fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
+ fts5yylhsminor.fts5yy14 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy14, fts5yymsp[0].minor.fts5yy11);
}
- fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
+ fts5yymsp[-1].minor.fts5yy14 = fts5yylhsminor.fts5yy14;
break;
- case 21: /* neardist_opt ::= */
+ case 22: /* neardist_opt ::= */
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
break;
- case 22: /* neardist_opt ::= COMMA STRING */
+ case 23: /* neardist_opt ::= COMMA STRING */
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
break;
- case 23: /* phrase ::= phrase PLUS STRING star_opt */
+ case 24: /* phrase ::= phrase PLUS STRING star_opt */
{
- fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy11, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
- fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
+ fts5yymsp[-3].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
- case 24: /* phrase ::= STRING star_opt */
+ case 25: /* phrase ::= STRING star_opt */
{
- fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
+ fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
- fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
+ fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
- case 25: /* star_opt ::= STAR */
+ case 26: /* star_opt ::= STAR */
{ fts5yymsp[0].minor.fts5yy4 = 1; }
break;
- case 26: /* star_opt ::= */
+ case 27: /* star_opt ::= */
{ fts5yymsp[1].minor.fts5yy4 = 0; }
break;
default:
@@ -185480,16 +188488,11 @@ static void fts5yy_reduce(
/* It is not possible for a REDUCE to be followed by an error */
assert( fts5yyact!=fts5YY_ERROR_ACTION );
- if( fts5yyact==fts5YY_ACCEPT_ACTION ){
- fts5yypParser->fts5yytos += fts5yysize;
- fts5yy_accept(fts5yypParser);
- }else{
- fts5yymsp += fts5yysize+1;
- fts5yypParser->fts5yytos = fts5yymsp;
- fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
- fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
- fts5yyTraceShift(fts5yypParser, fts5yyact);
- }
+ fts5yymsp += fts5yysize+1;
+ fts5yypParser->fts5yytos = fts5yymsp;
+ fts5yymsp->stateno = (fts5YYACTIONTYPE)fts5yyact;
+ fts5yymsp->major = (fts5YYCODETYPE)fts5yygoto;
+ fts5yyTraceShift(fts5yypParser, fts5yyact, "... then shift");
}
/*
@@ -185601,20 +188604,31 @@ static void sqlite3Fts5Parser(
#ifndef NDEBUG
if( fts5yyTraceFILE ){
- fprintf(fts5yyTraceFILE,"%sInput '%s'\n",fts5yyTracePrompt,fts5yyTokenName[fts5yymajor]);
+ int stateno = fts5yypParser->fts5yytos->stateno;
+ if( stateno < fts5YY_MIN_REDUCE ){
+ fprintf(fts5yyTraceFILE,"%sInput '%s' in state %d\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],stateno);
+ }else{
+ fprintf(fts5yyTraceFILE,"%sInput '%s' with pending reduce %d\n",
+ fts5yyTracePrompt,fts5yyTokenName[fts5yymajor],stateno-fts5YY_MIN_REDUCE);
+ }
}
#endif
do{
fts5yyact = fts5yy_find_shift_action(fts5yypParser,(fts5YYCODETYPE)fts5yymajor);
- if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
+ if( fts5yyact >= fts5YY_MIN_REDUCE ){
+ fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor,fts5yyminor);
+ }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){
fts5yy_shift(fts5yypParser,fts5yyact,fts5yymajor,fts5yyminor);
#ifndef fts5YYNOERRORRECOVERY
fts5yypParser->fts5yyerrcnt--;
#endif
fts5yymajor = fts5YYNOCODE;
- }else if( fts5yyact <= fts5YY_MAX_REDUCE ){
- fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE);
+ }else if( fts5yyact==fts5YY_ACCEPT_ACTION ){
+ fts5yypParser->fts5yytos--;
+ fts5yy_accept(fts5yypParser);
+ return;
}else{
assert( fts5yyact == fts5YY_ERROR_ACTION );
fts5yyminorunion.fts5yy0 = fts5yyminor;
@@ -186094,6 +189108,16 @@ static int fts5SnippetScore(
}
/*
+** Return the value in pVal interpreted as utf-8 text. Except, if pVal
+** contains a NULL value, return a pointer to a static string zero
+** bytes in length instead of a NULL pointer.
+*/
+static const char *fts5ValueToText(sqlite3_value *pVal){
+ const char *zRet = (const char*)sqlite3_value_text(pVal);
+ return zRet ? zRet : "";
+}
+
+/*
** Implementation of snippet() function.
*/
static void fts5SnippetFunction(
@@ -186128,9 +189152,9 @@ static void fts5SnippetFunction(
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]);
+ ctx.zOpen = fts5ValueToText(apVal[1]);
+ ctx.zClose = fts5ValueToText(apVal[2]);
+ zEllips = fts5ValueToText(apVal[3]);
nToken = sqlite3_value_int(apVal[4]);
iBestCol = (iCol>=0 ? iCol : 0);
@@ -187884,7 +190908,8 @@ struct Fts5ExprNode {
** or term prefix.
*/
struct Fts5ExprTerm {
- int bPrefix; /* True for a prefix term */
+ u8 bPrefix; /* True for a prefix term */
+ u8 bFirst; /* True if token must be first in column */
char *zTerm; /* nul-terminated term */
Fts5IndexIter *pIter; /* Iterator for this term */
Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */
@@ -187965,6 +190990,7 @@ static int fts5ExprGetToken(
case '+': tok = FTS5_PLUS; break;
case '*': tok = FTS5_STAR; break;
case '-': tok = FTS5_MINUS; break;
+ case '^': tok = FTS5_CARET; break;
case '\0': tok = FTS5_EOF; break;
case '"': {
@@ -188224,6 +191250,7 @@ static int fts5ExprPhraseIsMatch(
Fts5PoslistReader *aIter = aStatic;
int i;
int rc = SQLITE_OK;
+ int bFirst = pPhrase->aTerm[0].bFirst;
fts5BufferZero(&pPhrase->poslist);
@@ -188278,8 +191305,10 @@ static int fts5ExprPhraseIsMatch(
}while( bMatch==0 );
/* Append position iPos to the output */
- rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
- if( rc!=SQLITE_OK ) goto ismatch_out;
+ if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){
+ rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
+ if( rc!=SQLITE_OK ) goto ismatch_out;
+ }
for(i=0; i<pPhrase->nTerm; i++){
if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
@@ -188533,7 +191562,9 @@ static int fts5ExprNearTest(
** phrase is not a match, break out of the loop early. */
for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
- if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
+ if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym
+ || pNear->pColset || pPhrase->aTerm[0].bFirst
+ ){
int bMatch = 0;
rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
if( bMatch==0 ) break;
@@ -188714,6 +191745,7 @@ static int fts5ExprNodeTest_STRING(
assert( pNear->nPhrase>1
|| pNear->apPhrase[0]->nTerm>1
|| pNear->apPhrase[0]->aTerm[0].pSynonym
+ || pNear->apPhrase[0]->aTerm[0].bFirst
);
/* Initialize iLast, the "lastest" rowid any iterator points to. If the
@@ -189239,6 +192271,16 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){
}
/*
+** Set the "bFirst" flag on the first token of the phrase passed as the
+** only argument.
+*/
+static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){
+ if( pPhrase && pPhrase->nTerm ){
+ pPhrase->aTerm[0].bFirst = 1;
+ }
+}
+
+/*
** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
** appended to it and the results returned.
@@ -189516,6 +192558,7 @@ static int sqlite3Fts5ExprClonePhrase(
}
if( rc==SQLITE_OK ){
sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
+ sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
}
}
}else{
@@ -189534,7 +192577,10 @@ static int sqlite3Fts5ExprClonePhrase(
pNew->pRoot->pNear->nPhrase = 1;
sCtx.pPhrase->pNode = pNew->pRoot;
- if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
+ if( pOrig->nTerm==1
+ && pOrig->aTerm[0].pSynonym==0
+ && pOrig->aTerm[0].bFirst==0
+ ){
pNew->pRoot->eType = FTS5_TERM;
pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
}else{
@@ -189808,6 +192854,7 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
Fts5ExprNearset *pNear = pNode->pNear;
if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1
&& pNear->apPhrase[0]->aTerm[0].pSynonym==0
+ && pNear->apPhrase[0]->aTerm[0].bFirst==0
){
pNode->eType = FTS5_TERM;
pNode->xNext = fts5ExprNodeNext_TERM;
@@ -189894,20 +192941,23 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
}
}
- if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL
- && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1)
- ){
- assert( pParse->rc==SQLITE_OK );
- pParse->rc = SQLITE_ERROR;
- assert( pParse->zErr==0 );
- pParse->zErr = sqlite3_mprintf(
- "fts5: %s queries are not supported (detail!=full)",
- pNear->nPhrase==1 ? "phrase": "NEAR"
- );
- sqlite3_free(pRet);
- pRet = 0;
+ if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
+ Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
+ if( pNear->nPhrase!=1
+ || pPhrase->nTerm>1
+ || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
+ ){
+ assert( pParse->rc==SQLITE_OK );
+ pParse->rc = SQLITE_ERROR;
+ assert( pParse->zErr==0 );
+ pParse->zErr = sqlite3_mprintf(
+ "fts5: %s queries are not supported (detail!=full)",
+ pNear->nPhrase==1 ? "phrase": "NEAR"
+ );
+ sqlite3_free(pRet);
+ pRet = 0;
+ }
}
-
}else{
fts5ExprAddChildren(pRet, pLeft);
fts5ExprAddChildren(pRet, pRight);
@@ -196061,7 +199111,13 @@ static void fts5MergePrefixLists(
Fts5Buffer out = {0, 0, 0};
Fts5Buffer tmp = {0, 0, 0};
- if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return;
+ /* The maximum size of the output is equal to the sum of the two
+ ** input sizes + 1 varint (9 bytes). The extra varint is because if the
+ ** first rowid in one input is a large negative number, and the first in
+ ** the other a non-negative number, the delta for the non-negative
+ ** number will be larger on disk than the literal integer value
+ ** was. */
+ if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
fts5DoclistIterInit(p1, &i1);
fts5DoclistIterInit(p2, &i2);
@@ -196155,6 +199211,7 @@ static void fts5MergePrefixLists(
fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
}
+ assert( out.n<=(p1->n+p2->n+9) );
fts5BufferSet(&p->rc, p1, out.n, out.p);
fts5BufferFree(&tmp);
@@ -200276,7 +203333,7 @@ static void fts5SourceIdFunc(
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
- sqlite3_result_text(pCtx, "fts5: 2017-08-24 16:21:36 8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34", -1, SQLITE_TRANSIENT);
+ sqlite3_result_text(pCtx, "fts5: 2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d", -1, SQLITE_TRANSIENT);
}
static int fts5Init(sqlite3 *db){
@@ -203504,6 +206561,11 @@ static int sqlite3Fts5GetVarintLen(u32 iVal){
** the number of fts5 rows that contain at least one instance of term
** $term. Field $cnt is set to the total number of instances of term
** $term in the database.
+**
+** instance:
+** CREATE TABLE vocab(term, doc, col, offset, PRIMARY KEY(<all-fields>));
+**
+** One row for each term instance in the database.
*/
@@ -203519,7 +206581,7 @@ struct Fts5VocabTable {
char *zFts5Db; /* Db containing fts5 table */
sqlite3 *db; /* Database handle */
Fts5Global *pGlobal; /* FTS5 global object for this database */
- int eType; /* FTS5_VOCAB_COL or ROW */
+ int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */
};
struct Fts5VocabCursor {
@@ -203539,16 +206601,22 @@ struct Fts5VocabCursor {
i64 *aCnt;
i64 *aDoc;
- /* Output values used by 'row' and 'col' tables */
+ /* Output values used by all tables. */
i64 rowid; /* This table's current rowid value */
Fts5Buffer term; /* Current value of 'term' column */
+
+ /* Output values Used by 'instance' tables only */
+ i64 iInstPos;
+ int iInstOff;
};
-#define FTS5_VOCAB_COL 0
-#define FTS5_VOCAB_ROW 1
+#define FTS5_VOCAB_COL 0
+#define FTS5_VOCAB_ROW 1
+#define FTS5_VOCAB_INSTANCE 2
#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt"
#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt"
+#define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset"
/*
** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
@@ -203576,6 +206644,9 @@ static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){
if( sqlite3_stricmp(zCopy, "row")==0 ){
*peType = FTS5_VOCAB_ROW;
}else
+ if( sqlite3_stricmp(zCopy, "instance")==0 ){
+ *peType = FTS5_VOCAB_INSTANCE;
+ }else
{
*pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy);
rc = SQLITE_ERROR;
@@ -203636,7 +206707,8 @@ static int fts5VocabInitVtab(
){
const char *azSchema[] = {
"CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA ")",
- "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")"
+ "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")",
+ "CREATE TABlE vocab(" FTS5_VOCAB_INST_SCHEMA ")"
};
Fts5VocabTable *pRet = 0;
@@ -203710,6 +206782,15 @@ static int fts5VocabCreateMethod(
/*
** Implementation of the xBestIndex method.
+**
+** Only constraints of the form:
+**
+** term <= ?
+** term == ?
+** term >= ?
+**
+** are interpreted. Less-than and less-than-or-equal are treated
+** identically, as are greater-than and greater-than-or-equal.
*/
static int fts5VocabBestIndexMethod(
sqlite3_vtab *pUnused,
@@ -203853,6 +206934,54 @@ static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){
return SQLITE_OK;
}
+static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
+ int rc = SQLITE_OK;
+
+ if( sqlite3Fts5IterEof(pCsr->pIter) ){
+ pCsr->bEof = 1;
+ }else{
+ const char *zTerm;
+ int nTerm;
+ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
+ if( pCsr->nLeTerm>=0 ){
+ int nCmp = MIN(nTerm, pCsr->nLeTerm);
+ int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
+ if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
+ pCsr->bEof = 1;
+ }
+ }
+
+ sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
+ }
+ return rc;
+}
+
+static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
+ int eDetail = pCsr->pConfig->eDetail;
+ int rc = SQLITE_OK;
+ Fts5IndexIter *pIter = pCsr->pIter;
+ i64 *pp = &pCsr->iInstPos;
+ int *po = &pCsr->iInstOff;
+
+ while( eDetail==FTS5_DETAIL_NONE
+ || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp)
+ ){
+ pCsr->iInstPos = 0;
+ pCsr->iInstOff = 0;
+
+ rc = sqlite3Fts5IterNextScan(pCsr->pIter);
+ if( rc==SQLITE_OK ){
+ rc = fts5VocabInstanceNewTerm(pCsr);
+ if( eDetail==FTS5_DETAIL_NONE ) break;
+ }
+ if( rc ){
+ pCsr->bEof = 1;
+ break;
+ }
+ }
+
+ return rc;
+}
/*
** Advance the cursor to the next row in the table.
@@ -203865,13 +206994,17 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
pCsr->rowid++;
+ if( pTab->eType==FTS5_VOCAB_INSTANCE ){
+ return fts5VocabInstanceNext(pCsr);
+ }
+
if( pTab->eType==FTS5_VOCAB_COL ){
for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
if( pCsr->aDoc[pCsr->iCol] ) break;
}
}
- if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
+ if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){
if( sqlite3Fts5IterEof(pCsr->pIter) ){
pCsr->bEof = 1;
}else{
@@ -203895,22 +207028,26 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
while( rc==SQLITE_OK ){
+ int eDetail = pCsr->pConfig->eDetail;
const u8 *pPos; int nPos; /* Position list */
i64 iPos = 0; /* 64-bit position read from poslist */
int iOff = 0; /* Current offset within position list */
pPos = pCsr->pIter->pData;
nPos = pCsr->pIter->nData;
- switch( pCsr->pConfig->eDetail ){
- case FTS5_DETAIL_FULL:
- pPos = pCsr->pIter->pData;
- nPos = pCsr->pIter->nData;
- if( pTab->eType==FTS5_VOCAB_ROW ){
+
+ switch( pTab->eType ){
+ case FTS5_VOCAB_ROW:
+ if( eDetail==FTS5_DETAIL_FULL ){
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
pCsr->aCnt[0]++;
}
- pCsr->aDoc[0]++;
- }else{
+ }
+ pCsr->aDoc[0]++;
+ break;
+
+ case FTS5_VOCAB_COL:
+ if( eDetail==FTS5_DETAIL_FULL ){
int iCol = -1;
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
int ii = FTS5_POS2COLUMN(iPos);
@@ -203924,13 +207061,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
iCol = ii;
}
}
- }
- break;
-
- case FTS5_DETAIL_COLUMNS:
- if( pTab->eType==FTS5_VOCAB_ROW ){
- pCsr->aDoc[0]++;
- }else{
+ }else if( eDetail==FTS5_DETAIL_COLUMNS ){
while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
assert_nc( iPos>=0 && iPos<nCol );
if( iPos>=nCol ){
@@ -203939,18 +207070,21 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
}
pCsr->aDoc[iPos]++;
}
+ }else{
+ assert( eDetail==FTS5_DETAIL_NONE );
+ pCsr->aDoc[0]++;
}
break;
- default:
- assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE );
- pCsr->aDoc[0]++;
+ default:
+ assert( pTab->eType==FTS5_VOCAB_INSTANCE );
break;
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IterNextScan(pCsr->pIter);
}
+ if( pTab->eType==FTS5_VOCAB_INSTANCE ) break;
if( rc==SQLITE_OK ){
zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
@@ -203980,7 +207114,9 @@ static int fts5VocabFilterMethod(
int nUnused, /* Number of elements in apVal */
sqlite3_value **apVal /* Arguments for the indexing scheme */
){
+ Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
+ int eType = pTab->eType;
int rc = SQLITE_OK;
int iVal = 0;
@@ -204020,11 +207156,16 @@ static int fts5VocabFilterMethod(
}
}
-
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
}
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
+ rc = fts5VocabInstanceNewTerm(pCsr);
+ }
+ if( rc==SQLITE_OK
+ && !pCsr->bEof
+ && (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE)
+ ){
rc = fts5VocabNextMethod(pCursor);
}
@@ -204066,13 +207207,41 @@ static int fts5VocabColumnMethod(
}else{
iVal = pCsr->aCnt[pCsr->iCol];
}
- }else{
+ }else if( eType==FTS5_VOCAB_ROW ){
assert( iCol==1 || iCol==2 );
if( iCol==1 ){
iVal = pCsr->aDoc[0];
}else{
iVal = pCsr->aCnt[0];
}
+ }else{
+ assert( eType==FTS5_VOCAB_INSTANCE );
+ switch( iCol ){
+ case 1:
+ sqlite3_result_int64(pCtx, pCsr->pIter->iRowid);
+ break;
+ case 2: {
+ int ii = -1;
+ if( eDetail==FTS5_DETAIL_FULL ){
+ ii = FTS5_POS2COLUMN(pCsr->iInstPos);
+ }else if( eDetail==FTS5_DETAIL_COLUMNS ){
+ ii = (int)pCsr->iInstPos;
+ }
+ if( ii>=0 && ii<pCsr->pConfig->nCol ){
+ const char *z = pCsr->pConfig->azCol[ii];
+ sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
+ }
+ break;
+ }
+ default: {
+ assert( iCol==3 );
+ if( eDetail==FTS5_DETAIL_FULL ){
+ int ii = FTS5_POS2OFFSET(pCsr->iInstPos);
+ sqlite3_result_int(pCtx, ii);
+ }
+ break;
+ }
+ }
}
if( iVal>0 ) sqlite3_result_int64(pCtx, iVal);
@@ -204432,3 +207601,10 @@ SQLITE_API int sqlite3_stmt_init(
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
/************** End of stmt.c ************************************************/
+#if __LINE__!=207604
+#undef SQLITE_SOURCE_ID
+#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2alt2"
+#endif
+/* Return the source-id for this library */
+SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+/************************** End of sqlite3.c ******************************/
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index 41ccc21983..d8138b709a 100644
--- a/src/3rdparty/sqlite/sqlite3.h
+++ b/src/3rdparty/sqlite/sqlite3.h
@@ -115,15 +115,17 @@ extern "C" {
** 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 a SHA1
-** or SHA3-256 hash of the entire source tree.
+** or SHA3-256 hash of the entire source tree. If the source code has
+** been edited in any way since it was last checked in, then the last
+** four hexadecimal digits of the hash may be modified.
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.20.1"
-#define SQLITE_VERSION_NUMBER 3020001
-#define SQLITE_SOURCE_ID "2017-08-24 16:21:36 8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34"
+#define SQLITE_VERSION "3.22.0"
+#define SQLITE_VERSION_NUMBER 3022000
+#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -139,7 +141,7 @@ extern "C" {
**
** <blockquote><pre>
** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
** </pre></blockquote>)^
**
@@ -149,9 +151,11 @@ extern "C" {
** function is provided for use in DLLs since DLL users usually do not have
** direct access to string constants within the DLL. ^The
** sqlite3_libversion_number() function returns an integer equal to
-** [SQLITE_VERSION_NUMBER]. ^The sqlite3_sourceid() function returns
+** [SQLITE_VERSION_NUMBER]. ^(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_SOURCE_ID] C preprocessor macro. Except if SQLite is built
+** using an edited copy of [the amalgamation], then the last four characters
+** of the hash might be different from [SQLITE_SOURCE_ID].)^
**
** See also: [sqlite_version()] and [sqlite_source_id()].
*/
@@ -432,7 +436,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_FULL 13 /* Insertion failed because database is full */
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
#define SQLITE_PROTOCOL 15 /* Database lock protocol error */
-#define SQLITE_EMPTY 16 /* Not used */
+#define SQLITE_EMPTY 16 /* Internal use only */
#define SQLITE_SCHEMA 17 /* The database schema changed */
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
@@ -466,6 +470,8 @@ SQLITE_API int sqlite3_exec(
** the most recent error can be obtained using
** [sqlite3_extended_errcode()].
*/
+#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
+#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
@@ -494,6 +500,9 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8))
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
+#define SQLITE_IOERR_BEGIN_ATOMIC (SQLITE_IOERR | (29<<8))
+#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
+#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
@@ -506,6 +515,8 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
+#define SQLITE_READONLY_CANTINIT (SQLITE_READONLY | (5<<8))
+#define SQLITE_READONLY_DIRECTORY (SQLITE_READONLY | (6<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -580,6 +591,11 @@ SQLITE_API int sqlite3_exec(
** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
** read-only media and cannot be changed even by processes with
** elevated privileges.
+**
+** The SQLITE_IOCAP_BATCH_ATOMIC property means that the underlying
+** filesystem supports doing multiple write operations atomically when those
+** write operations are bracketed by [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] and
+** [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE].
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -595,6 +611,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 0x00000800
#define SQLITE_IOCAP_POWERSAFE_OVERWRITE 0x00001000
#define SQLITE_IOCAP_IMMUTABLE 0x00002000
+#define SQLITE_IOCAP_BATCH_ATOMIC 0x00004000
/*
** CAPI3REF: File Locking Levels
@@ -729,6 +746,7 @@ struct sqlite3_file {
** <li> [SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN]
** <li> [SQLITE_IOCAP_POWERSAFE_OVERWRITE]
** <li> [SQLITE_IOCAP_IMMUTABLE]
+** <li> [SQLITE_IOCAP_BATCH_ATOMIC]
** </ul>
**
** The SQLITE_IOCAP_ATOMIC property means that all writes of
@@ -1012,6 +1030,40 @@ struct sqlite3_io_methods {
** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by
** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for
** this opcode.
+**
+** <li>[[SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]]
+** If the [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] opcode returns SQLITE_OK, then
+** the file descriptor is placed in "batch write mode", which
+** means all subsequent write operations will be deferred and done
+** atomically at the next [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]. Systems
+** that do not support batch atomic writes will return SQLITE_NOTFOUND.
+** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to
+** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or
+** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make
+** no VFS interface calls on the same [sqlite3_file] file descriptor
+** except for calls to the xWrite method and the xFileControl method
+** with [SQLITE_FCNTL_SIZE_HINT].
+**
+** <li>[[SQLITE_FCNTL_COMMIT_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] opcode causes all write
+** operations since the previous successful call to
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be performed atomically.
+** This file control returns [SQLITE_OK] if and only if the writes were
+** all performed successfully and have been committed to persistent storage.
+** ^Regardless of whether or not it is successful, this file control takes
+** the file descriptor out of batch write mode so that all subsequent
+** write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
+**
+** <li>[[SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE]]
+** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write
+** operations since the previous successful call to
+** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back.
+** ^This file control takes the file descriptor out of batch write mode
+** so that all subsequent write operations are independent.
+** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
+** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -1043,6 +1095,9 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_JOURNAL_POINTER 28
#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
#define SQLITE_FCNTL_PDB 30
+#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
+#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
+#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1080,12 +1135,18 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
** in the name of the object stands for "virtual file system". See
** the [VFS | VFS documentation] for further information.
**
-** The value of the iVersion field is initially 1 but may be larger in
-** future versions of SQLite. Additional fields may be appended to this
-** object when the iVersion value is increased. Note that the structure
-** of the sqlite3_vfs object changes in the transaction between
-** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
-** modified.
+** The VFS interface is sometimes extended by adding new methods onto
+** the end. Each time such an extension occurs, the iVersion field
+** is incremented. The iVersion value started out as 1 in
+** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2
+** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased
+** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields
+** may be appended to the sqlite3_vfs object and the iVersion value
+** may increase again in future versions of SQLite.
+** Note that the structure
+** of the sqlite3_vfs object changes in the transition from
+** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0]
+** and yet the iVersion field was not modified.
**
** The szOsFile field is the size of the subclassed [sqlite3_file]
** structure used by this VFS. mxPathname is the maximum length of
@@ -1613,6 +1674,16 @@ struct sqlite3_mem_methods {
** routines with a wrapper that simulations memory allocation failure or
** tracks memory usage, for example. </dd>
**
+** [[SQLITE_CONFIG_SMALL_MALLOC]] <dt>SQLITE_CONFIG_SMALL_MALLOC</dt>
+** <dd> ^The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of
+** type int, interpreted as a boolean, which if true provides a hint to
+** SQLite that it should avoid large memory allocations if possible.
+** SQLite will run faster if it is free to make large memory allocations,
+** but some application might prefer to run slower in exchange for
+** guarantees about memory fragmentation that are possible if large
+** allocations are avoided. This hint is normally off.
+** </dd>
+**
** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
** <dd> ^The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int,
** interpreted as a boolean, which enables or disables the collection of
@@ -1630,25 +1701,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
-** that SQLite can use for scratch memory. ^(There are three arguments
-** to SQLITE_CONFIG_SCRATCH: A pointer an 8-byte
-** aligned memory buffer from which the scratch allocations will be
-** drawn, the size of each scratch allocation (sz),
-** and the maximum number of scratch allocations (N).)^
-** The first argument must be a pointer to an 8-byte aligned buffer
-** of at least sz*N bytes of memory.
-** ^SQLite will not use more than one scratch buffers per thread.
-** ^SQLite will never request a scratch buffer that is more than 6
-** times the database page size.
-** ^If SQLite needs needs additional
-** scratch memory beyond what is provided by this configuration option, then
-** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
-** ^When the application provides any amount of scratch memory using
-** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
-** [sqlite3_malloc|heap allocations].
-** This can help [Robson proof|prevent memory allocation failures] due to heap
-** fragmentation in low-memory embedded systems.
+** <dd> The SQLITE_CONFIG_SCRATCH option is no longer used.
** </dd>
**
** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
@@ -1684,8 +1737,7 @@ struct sqlite3_mem_methods {
** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer
** that SQLite will use for all of its dynamic memory allocation needs
-** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
-** [SQLITE_CONFIG_PAGECACHE].
+** beyond those provided for by [SQLITE_CONFIG_PAGECACHE].
** ^The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled
** with either [SQLITE_ENABLE_MEMSYS3] or [SQLITE_ENABLE_MEMSYS5] and returns
** [SQLITE_ERROR] if invoked otherwise.
@@ -1878,7 +1930,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */
#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */
-#define SQLITE_CONFIG_SCRATCH 6 /* void*, int sz, int N */
+#define SQLITE_CONFIG_SCRATCH 6 /* No longer used */
#define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */
#define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */
#define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */
@@ -1899,6 +1951,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
+#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
/*
** CAPI3REF: Database Connection Configuration Options
@@ -2006,7 +2059,6 @@ struct sqlite3_mem_methods {
** 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>
-**
** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
@@ -2017,7 +2069,16 @@ struct sqlite3_mem_methods {
** the QPSG active, SQLite will always use the same query plan in the field as
** was used during testing in the lab.
** </dd>
-**
+** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
+** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
+** include output for any operations performed by trigger programs. This
+** option is used to set or clear (the default) a flag that governs this
+** behavior. The first parameter passed to this operation is an integer -
+** non-zero to enable output for trigger programs, or zero to disable it.
+** The second parameter is a pointer to an integer into which is written
+** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
+** it is not disabled, 1 if it is.
+** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@@ -2028,7 +2089,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
-
+#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
+#define SQLITE_DBCONFIG_MAX 1008 /* Largest DBCONFIG */
/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -2889,8 +2951,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** KEYWORDS: SQLITE_TRACE
**
** These constants identify classes of events that can be monitored
-** using the [sqlite3_trace_v2()] tracing logic. The third argument
-** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
+** using the [sqlite3_trace_v2()] tracing logic. The M argument
+** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
** the following constants. ^The first argument to the trace callback
** is one of the following constants.
**
@@ -3099,10 +3161,10 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** ^If [URI filename] interpretation is enabled, and the filename argument
** begins with "file:", then the filename is interpreted as a URI. ^URI
** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is
-** set in the fourth argument to sqlite3_open_v2(), or if it has
+** set in the third argument to sqlite3_open_v2(), or if it has
** been enabled globally using the [SQLITE_CONFIG_URI] option with the
** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option.
-** As of SQLite version 3.7.7, URI filename interpretation is turned off
+** URI filename interpretation is turned off
** by default, but future releases of SQLite might enable URI filename
** interpretation by default. See "[URI filenames]" for additional
** information.
@@ -3776,8 +3838,9 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
** implementation of [application-defined SQL functions] are protected.
** ^The sqlite3_value object returned by
** [sqlite3_column_value()] is unprotected.
-** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].
+** Unprotected sqlite3_value objects may only be used as arguments
+** to [sqlite3_result_value()], [sqlite3_bind_value()], and
+** [sqlite3_value_dup()].
** The [sqlite3_value_blob | sqlite3_value_type()] family of
** interfaces require protected sqlite3_value objects.
*/
@@ -4199,7 +4262,7 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
-** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1]),
+** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
@@ -4735,6 +4798,9 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** datatype of the value
** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
+** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
+** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
+** against a virtual table.
** </table></blockquote>
**
** <b>Details:</b>
@@ -4783,6 +4849,19 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed. Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
+** ^Within the [xUpdate] method of a [virtual table], the
+** sqlite3_value_nochange(X) interface returns true if and only if
+** the column corresponding to X is unchanged by the UPDATE operation
+** that the xUpdate method call was invoked to implement and if
+** and the prior [xColumn] method call that was invoked to extracted
+** the value for that column returned without setting a result (probably
+** because it queried [sqlite3_vtab_nochange()] and found that the column
+** was unchanging). ^Within an [xUpdate] method, any value for which
+** sqlite3_value_nochange(X) is true will in all other respects appear
+** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other
+** than within an [xUpdate] method call for an UPDATE statement, then
+** the return value is arbitrary and meaningless.
+**
** Please pay particular attention to the fact that the pointer returned
** from [sqlite3_value_blob()], [sqlite3_value_text()], or
** [sqlite3_value_text16()] can be invalidated by a subsequent call to
@@ -4805,6 +4884,7 @@ SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
/*
** CAPI3REF: Finding The Subtype Of SQL Values
@@ -6203,15 +6283,20 @@ struct sqlite3_index_info {
** an operator that is part of a constraint term in the wHERE clause of
** a query that uses a [virtual table].
*/
-#define SQLITE_INDEX_CONSTRAINT_EQ 2
-#define SQLITE_INDEX_CONSTRAINT_GT 4
-#define SQLITE_INDEX_CONSTRAINT_LE 8
-#define SQLITE_INDEX_CONSTRAINT_LT 16
-#define SQLITE_INDEX_CONSTRAINT_GE 32
-#define SQLITE_INDEX_CONSTRAINT_MATCH 64
-#define SQLITE_INDEX_CONSTRAINT_LIKE 65
-#define SQLITE_INDEX_CONSTRAINT_GLOB 66
-#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+#define SQLITE_INDEX_CONSTRAINT_EQ 2
+#define SQLITE_INDEX_CONSTRAINT_GT 4
+#define SQLITE_INDEX_CONSTRAINT_LE 8
+#define SQLITE_INDEX_CONSTRAINT_LT 16
+#define SQLITE_INDEX_CONSTRAINT_GE 32
+#define SQLITE_INDEX_CONSTRAINT_MATCH 64
+#define SQLITE_INDEX_CONSTRAINT_LIKE 65
+#define SQLITE_INDEX_CONSTRAINT_GLOB 66
+#define SQLITE_INDEX_CONSTRAINT_REGEXP 67
+#define SQLITE_INDEX_CONSTRAINT_NE 68
+#define SQLITE_INDEX_CONSTRAINT_ISNOT 69
+#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
+#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
+#define SQLITE_INDEX_CONSTRAINT_IS 72
/*
** CAPI3REF: Register A Virtual Table Implementation
@@ -6902,9 +6987,9 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** the xFileControl method. ^The return value of the xFileControl
** method becomes the return value of this routine.
**
-** ^The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes
+** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
** a pointer to the underlying [sqlite3_file] object to be written into
-** the space pointed to by the 4th parameter. ^The SQLITE_FCNTL_FILE_POINTER
+** the space pointed to by the 4th parameter. ^The [SQLITE_FCNTL_FILE_POINTER]
** case is a short-circuit path which does not actually invoke the
** underlying sqlite3_io_methods.xFileControl method.
**
@@ -6916,7 +7001,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
** an incorrect zDbName and an SQLITE_ERROR return from the underlying
** xFileControl method.
**
-** See also: [SQLITE_FCNTL_LOCKSTATE]
+** See also: [file control opcodes]
*/
SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
@@ -6963,7 +7048,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16
-#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
+#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
@@ -6973,7 +7058,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ISINIT 23
#define SQLITE_TESTCTRL_SORTER_MMAP 24
#define SQLITE_TESTCTRL_IMPOSTER 25
-#define SQLITE_TESTCTRL_LAST 25
+#define SQLITE_TESTCTRL_PARSER_COVERAGE 26
+#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
/*
** CAPI3REF: SQLite Runtime Status
@@ -7022,8 +7108,7 @@ SQLITE_API int sqlite3_status64(
** <dd>This parameter is the current amount of memory checked out
** using [sqlite3_malloc()], either directly or indirectly. The
** figure includes calls made to [sqlite3_malloc()] by the application
-** and internal memory usage by the SQLite library. Scratch memory
-** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
+** and internal memory usage by the SQLite library. Auxiliary page-cache
** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in
** this parameter. The amount returned is the sum of the allocation
** sizes as reported by the xSize method in [sqlite3_mem_methods].</dd>)^
@@ -7061,29 +7146,14 @@ SQLITE_API int sqlite3_status64(
** *pHighwater parameter to [sqlite3_status()] is of interest.
** The value written into the *pCurrent parameter is undefined.</dd>)^
**
-** [[SQLITE_STATUS_SCRATCH_USED]] ^(<dt>SQLITE_STATUS_SCRATCH_USED</dt>
-** <dd>This parameter returns the number of allocations used out of the
-** [scratch memory allocator] configured using
-** [SQLITE_CONFIG_SCRATCH]. The value returned is in allocations, not
-** in bytes. Since a single thread may only have one scratch allocation
-** outstanding at time, this parameter also reports the number of threads
-** using scratch memory at the same time.</dd>)^
+** [[SQLITE_STATUS_SCRATCH_USED]] <dt>SQLITE_STATUS_SCRATCH_USED</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_SCRATCH_OVERFLOW]] ^(<dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
-** <dd>This parameter returns the number of bytes of scratch memory
-** allocation which could not be satisfied by the [SQLITE_CONFIG_SCRATCH]
-** buffer and where forced to overflow to [sqlite3_malloc()]. The values
-** returned include overflows because the requested allocation was too
-** larger (that is, because the requested allocation was larger than the
-** "sz" parameter to [SQLITE_CONFIG_SCRATCH]) and because no scratch buffer
-** slots were available.
-** </dd>)^
-**
-** [[SQLITE_STATUS_SCRATCH_SIZE]] ^(<dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
-** <dd>This parameter records the largest memory allocation request
-** handed to [scratch memory allocator]. Only the value returned in the
-** *pHighwater parameter to [sqlite3_status()] is of interest.
-** The value written into the *pCurrent parameter is undefined.</dd>)^
+** <dd>No longer used.</dd>
+**
+** [[SQLITE_STATUS_SCRATCH_SIZE]] <dt>SQLITE_STATUS_SCRATCH_SIZE</dt>
+** <dd>No longer used.</dd>
**
** [[SQLITE_STATUS_PARSER_STACK]] ^(<dt>SQLITE_STATUS_PARSER_STACK</dt>
** <dd>The *pHighwater parameter records the deepest parser stack.
@@ -7096,12 +7166,12 @@ SQLITE_API int sqlite3_status64(
#define SQLITE_STATUS_MEMORY_USED 0
#define SQLITE_STATUS_PAGECACHE_USED 1
#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
-#define SQLITE_STATUS_SCRATCH_USED 3
-#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
+#define SQLITE_STATUS_SCRATCH_USED 3 /* NOT USED */
+#define SQLITE_STATUS_SCRATCH_OVERFLOW 4 /* NOT USED */
#define SQLITE_STATUS_MALLOC_SIZE 5
#define SQLITE_STATUS_PARSER_STACK 6
#define SQLITE_STATUS_PAGECACHE_SIZE 7
-#define SQLITE_STATUS_SCRATCH_SIZE 8
+#define SQLITE_STATUS_SCRATCH_SIZE 8 /* NOT USED */
#define SQLITE_STATUS_MALLOC_COUNT 9
/*
@@ -8244,6 +8314,40 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
/*
+** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
+**
+** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
+** method of a [virtual table], then it returns true if and only if the
+** column is being fetched as part of an UPDATE operation during which the
+** column value will not change. Applications might use this to substitute
+** a lighter-weight value to return that the corresponding [xUpdate] method
+** understands as a "no-change" value.
+**
+** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
+** the column is not changed by the UPDATE statement, they the xColumn
+** method can optionally return without setting a result, without calling
+** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
+** In that case, [sqlite3_value_nochange(X)] will return true for the
+** same column in the [xUpdate] method.
+*/
+SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
+
+/*
+** CAPI3REF: Determine The Collation For a Virtual Table Constraint
+**
+** This function may only be called from within a call to the [xBestIndex]
+** method of a [virtual table].
+**
+** The first argument must be the sqlite3_index_info object that is the
+** first parameter to the xBestIndex() method. The second argument must be
+** an index into the aConstraint[] array belonging to the sqlite3_index_info
+** structure passed to xBestIndex. This function returns a pointer to a buffer
+** containing the name of the collation sequence for the corresponding
+** constraint.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
+/*
** CAPI3REF: Conflict resolution modes
** KEYWORDS: {conflict resolution mode}
**
@@ -8970,6 +9074,35 @@ SQLITE_API 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.
+**
+** <h3>Special sqlite_stat1 Handling</h3>
+**
+** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to
+** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
+** <pre>
+** &nbsp; CREATE TABLE sqlite_stat1(tbl,idx,stat)
+** </pre>
+**
+** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are
+** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes
+** are recorded for rows for which (idx IS NULL) is true. However, for such
+** rows a zero-length blob (SQL value X'') is stored in the changeset or
+** patchset instead of a NULL value. This allows such changesets to be
+** manipulated by legacy implementations of sqlite3changeset_invert(),
+** concat() and similar.
+**
+** The sqlite3changeset_apply() function automatically converts the
+** zero-length blob back to a NULL value when updating the sqlite_stat1
+** table. However, if the application calls sqlite3changeset_new(),
+** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset
+** iterator directly (including on a changeset iterator passed to a
+** conflict-handler callback) then the X'' value is returned. The application
+** must translate X'' to NULL itself if required.
+**
+** Legacy (older than 3.22.0) versions of the sessions module cannot capture
+** changes made to the sqlite_stat1 table. Legacy versions of the
+** sqlite3changeset_apply() function silently ignore any modifications to the
+** sqlite_stat1 table that are part of a changeset or patchset.
*/
SQLITE_API int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
@@ -9198,8 +9331,8 @@ SQLITE_API int sqlite3session_diff(
*/
SQLITE_API int sqlite3session_patchset(
sqlite3_session *pSession, /* Session object */
- int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
- void **ppPatchset /* OUT: Buffer containing changeset */
+ int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
+ void **ppPatchset /* OUT: Buffer containing patchset */
);
/*
@@ -9966,12 +10099,12 @@ SQLITE_API int sqlite3changeset_apply(
**
** <table border=1 style="margin-left:8ex;margin-right:8ex">
** <tr><th>Streaming function<th>Non-streaming equivalent</th>
-** <tr><td>sqlite3changeset_apply_str<td>[sqlite3changeset_apply]
-** <tr><td>sqlite3changeset_concat_str<td>[sqlite3changeset_concat]
-** <tr><td>sqlite3changeset_invert_str<td>[sqlite3changeset_invert]
-** <tr><td>sqlite3changeset_start_str<td>[sqlite3changeset_start]
-** <tr><td>sqlite3session_changeset_str<td>[sqlite3session_changeset]
-** <tr><td>sqlite3session_patchset_str<td>[sqlite3session_patchset]
+** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply]
+** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat]
+** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert]
+** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start]
+** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset]
+** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset]
** </table>
**
** Non-streaming functions that accept changesets (or patchsets) as input