summaryrefslogtreecommitdiff
path: root/ext/sqlite3
diff options
context:
space:
mode:
authorScott MacVicar <scottmac@php.net>2009-06-15 13:23:59 +0000
committerScott MacVicar <scottmac@php.net>2009-06-15 13:23:59 +0000
commit532674945c2a9f8f3a367c68545d768398ec4924 (patch)
treeb6da4962dc265a57c577038539ad56619381b7ed /ext/sqlite3
parentbb55de47cd6a1f32b4e3465b7de5576cf4c96fc6 (diff)
downloadphp-git-532674945c2a9f8f3a367c68545d768398ec4924.tar.gz
MFH sync SQLite 3.6.15
Diffstat (limited to 'ext/sqlite3')
-rw-r--r--ext/sqlite3/libsqlite/sqlite3.c9334
-rw-r--r--ext/sqlite3/libsqlite/sqlite3.h182
2 files changed, 5469 insertions, 4047 deletions
diff --git a/ext/sqlite3/libsqlite/sqlite3.c b/ext/sqlite3/libsqlite/sqlite3.c
index f439a87fef..7b318447fa 100644
--- a/ext/sqlite3/libsqlite/sqlite3.c
+++ b/ext/sqlite3/libsqlite/sqlite3.c
@@ -4,7 +4,7 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.6.14.2. By combining all the individual C code files into this
+** version 3.6.15. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a one translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -15,13 +15,13 @@
** programs, you need this file and the "sqlite3.h" header file that defines
** the programming interface to the SQLite library. (If you do not have
** the "sqlite3.h" header file at hand, you will find a copy in the first
-** 5533 lines past this header comment.) Additional code files may be
+** 5615 lines past this header comment.) Additional code files may be
** needed if you want a wrapper to interface SQLite with your choice of
** programming language. The code for the "sqlite3" command-line shell
** is also in a separate file. This file contains only code for the core
** SQLite library.
**
-** This amalgamation was generated on 2009-05-25 12:49:40 UTC.
+** This amalgamation was generated on 2009-06-15 00:07:42 UTC.
*/
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
@@ -279,21 +279,36 @@
#endif
/*
- * This macro is used to "hide" some ugliness in casting an int
- * value to a ptr value under the MSVC 64-bit compiler. Casting
- * non 64-bit values to ptr types results in a "hard" error with
- * the MSVC 64-bit compiler which this attempts to avoid.
- *
- * A simple compiler pragma or casting sequence could not be found
- * to correct this in all situations, so this macro was introduced.
- *
- * It could be argued that the intptr_t type could be used in this
- * case, but that type is not available on all compilers, or
- * requires the #include of specific headers which differs between
- * platforms.
- */
-#define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
-#define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
+** This macro is used to "hide" some ugliness in casting an int
+** value to a ptr value under the MSVC 64-bit compiler. Casting
+** non 64-bit values to ptr types results in a "hard" error with
+** the MSVC 64-bit compiler which this attempts to avoid.
+**
+** A simple compiler pragma or casting sequence could not be found
+** to correct this in all situations, so this macro was introduced.
+**
+** It could be argued that the intptr_t type could be used in this
+** case, but that type is not available on all compilers, or
+** requires the #include of specific headers which differs between
+** platforms.
+**
+** Ticket #3860: The llvm-gcc-4.2 compiler from Apple chokes on
+** the ((void*)&((char*)0)[X]) construct. But MSVC chokes on ((void*)(X)).
+** So we have to define the macros in different ways depending on the
+** compiler.
+*/
+#if defined(__GNUC__)
+# if defined(HAVE_STDINT_H)
+# define SQLITE_INT_TO_PTR(X) ((void*)(intptr_t)(X))
+# define SQLITE_PTR_TO_INT(X) ((int)(intptr_t)(X))
+# else
+# define SQLITE_INT_TO_PTR(X) ((void*)(X))
+# define SQLITE_PTR_TO_INT(X) ((int)(X))
+# endif
+#else
+# define SQLITE_INT_TO_PTR(X) ((void*)&((char*)0)[X])
+# define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0))
+#endif
/*
** These #defines should enable >2GB file support on POSIX if the
@@ -601,8 +616,8 @@ extern "C" {
**
** Requirements: [H10011] [H10014]
*/
-#define SQLITE_VERSION "3.6.14.2"
-#define SQLITE_VERSION_NUMBER 3006014
+#define SQLITE_VERSION "3.6.15"
+#define SQLITE_VERSION_NUMBER 3006015
/*
** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
@@ -894,20 +909,20 @@ SQLITE_API int sqlite3_exec(
** in the 4th parameter to the xOpen method of the
** [sqlite3_vfs] object.
*/
-#define SQLITE_OPEN_READONLY 0x00000001
-#define SQLITE_OPEN_READWRITE 0x00000002
-#define SQLITE_OPEN_CREATE 0x00000004
-#define SQLITE_OPEN_DELETEONCLOSE 0x00000008
-#define SQLITE_OPEN_EXCLUSIVE 0x00000010
-#define SQLITE_OPEN_MAIN_DB 0x00000100
-#define SQLITE_OPEN_TEMP_DB 0x00000200
-#define SQLITE_OPEN_TRANSIENT_DB 0x00000400
-#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800
-#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000
-#define SQLITE_OPEN_SUBJOURNAL 0x00002000
-#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000
-#define SQLITE_OPEN_NOMUTEX 0x00008000
-#define SQLITE_OPEN_FULLMUTEX 0x00010000
+#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
+#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
+#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
+#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
+#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
+#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
+#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
+#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
+#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
+#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
/*
** CAPI3REF: Device Characteristics {H10240} <H11120>
@@ -1204,9 +1219,14 @@ typedef struct sqlite3_mutex sqlite3_mutex;
** deleted when it is closed. The [SQLITE_OPEN_DELETEONCLOSE]
** will be set for TEMP databases, journals and for subjournals.
**
-** The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
-** for exclusive access. This flag is set for all files except
-** for the main database file.
+** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
+** with the [SQLITE_OPEN_CREATE] flag, which are both directly
+** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
+** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
+** SQLITE_OPEN_CREATE, is used to indicate that file should always
+** be created, and that it is an error if it already exists.
+** It is <i>not</i> used to indicate the file should be opened
+** for exclusive access.
**
** At least szOsFile bytes of memory are allocated by SQLite
** to hold the [sqlite3_file] structure passed as the third
@@ -1533,12 +1553,14 @@ struct sqlite3_mem_methods {
**
** <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd>This option specifies a static memory buffer that SQLite can use for
-** scratch memory. There are three arguments: A pointer to the memory, the
-** size of each scratch buffer (sz), and the number of buffers (N). The sz
+** scratch memory. There are three arguments: A pointer an 8-byte
+** aligned memory buffer from which the scrach allocations will be
+** drawn, the size of each scratch allocation (sz),
+** and the maximum number of scratch allocations (N). The sz
** argument must be a multiple of 16. The sz parameter should be a few bytes
-** larger than the actual scratch space required due internal overhead.
-** The first
-** argument should point to an allocation of at least sz*N bytes of memory.
+** larger than the actual scratch space required due to internal overhead.
+** The first argument should pointer to an 8-byte aligned buffer
+** of at least sz*N bytes of memory.
** SQLite will use no more than one scratch buffer at once per thread, so
** N should be set to the expected maximum number of threads. The sz
** parameter should be 6 times the size of the largest database page size.
@@ -1552,29 +1574,37 @@ struct sqlite3_mem_methods {
** the database page cache with the default page cache implemenation.
** This configuration should not be used if an application-define page
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
-** There are three arguments to this option: A pointer to the
+** There are three arguments to this option: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
-** The sz argument must be a power of two between 512 and 32768. The first
+** The sz argument should be the size of the largest database page
+** (a power of two between 512 and 32768) plus a little extra for each
+** page header. The page header size is 20 to 40 bytes depending on
+** the host architecture. It is harmless, apart from the wasted memory,
+** to make sz a little too large. The first
** argument should point to an allocation of at least sz*N bytes of memory.
** SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache. If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.
** The implementation might use one or more of the N buffers to hold
-** memory accounting information. </dd>
+** memory accounting information. The pointer in the first argument must
+** be aligned to an 8-byte boundary or subsequent behavior of SQLite
+** will be undefined.</dd>
**
** <dt>SQLITE_CONFIG_HEAP</dt>
** <dd>This 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].
-** There are three arguments: A pointer to the memory, the number of
-** bytes in the memory buffer, and the minimum allocation size. If
-** the first pointer (the memory pointer) is NULL, then SQLite reverts
+** There are three arguments: An 8-byte aligned pointer to the memory,
+** the number of bytes in the memory buffer, and the minimum allocation size.
+** If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. If the
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
-** allocator is engaged to handle all of SQLites memory allocation needs.</dd>
+** allocator is engaged to handle all of SQLites memory allocation needs.
+** The first pointer (the memory pointer) must be aligned to an 8-byte
+** boundary or subsequent behavior of SQLite will be undefined.</dd>
**
** <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd>This option takes a single argument which is a pointer to an
@@ -1645,9 +1675,9 @@ struct sqlite3_mem_methods {
** <dd>This option takes three additional arguments that determine the
** [lookaside memory allocator] configuration for the [database connection].
** The first argument (the third parameter to [sqlite3_db_config()] is a
-** pointer to a memory buffer to use for lookaside memory. The first
-** argument may be NULL in which case SQLite will allocate the lookaside
-** buffer itself using [sqlite3_malloc()]. The second argument is the
+** pointer to an 8-byte aligned memory buffer to use for lookaside memory.
+** The first argument may be NULL in which case SQLite will allocate the
+** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the
** size of each lookaside buffer slot and the third argument is the number of
** slots. The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.</dd>
@@ -1779,9 +1809,9 @@ SQLITE_API int sqlite3_changes(sqlite3*);
** [CREATE TRIGGER | trigger] contexts. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
-** count does not rows of views that fire an [INSTEAD OF trigger], though if
-** the INSTEAD OF trigger makes changes of its own, those changes are
-** counted.
+** count does not include rows of views that fire an [INSTEAD OF trigger],
+** though if the INSTEAD OF trigger makes changes of its own, those changes
+** are counted.
** The changes are counted as soon as the statement that makes them is
** completed (when the statement handle is passed to [sqlite3_reset()] or
** [sqlite3_finalize()]).
@@ -3571,8 +3601,11 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** The third parameter (nArg)
** is the number of arguments that the SQL function or
-** aggregate takes. If this parameter is negative, then the SQL function or
-** aggregate may take any number of arguments.
+** aggregate takes. If this parameter is -1, then the SQL function or
+** aggregate may take any number of arguments between 0 and the limit
+** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
+** parameter is less than -1 or greater than 127 then the behavior is
+** undefined.
**
** The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
@@ -3623,7 +3656,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** statement in which the function is running.
**
** Requirements:
-** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16124] [H16127]
+** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16127]
** [H16130] [H16133] [H16136] [H16139] [H16142]
*/
SQLITE_API int sqlite3_create_function(
@@ -4238,11 +4271,11 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} <S60400>
**
** The sqlite3_commit_hook() interface registers a callback
-** function to be invoked whenever a transaction is committed.
+** function to be invoked whenever a transaction is [COMMIT | committed].
** Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** The sqlite3_rollback_hook() interface registers a callback
-** function to be invoked whenever a transaction is committed.
+** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
** Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** The pArg argument is passed through to the callback.
@@ -4262,6 +4295,12 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
**
** Registering a NULL function disables the callback.
**
+** When the commit hook callback routine returns zero, the [COMMIT]
+** operation is allowed to continue normally. If the commit hook
+** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
+** The rollback hook is invoked on a rollback that results from a commit
+** hook returning non-zero, just as it would be with any other rollback.
+**
** For the purposes of this API, a transaction is said to have been
** rolled back if an explicit "ROLLBACK" statement is executed, or
** an error or constraint causes an implicit rollback to occur.
@@ -4271,6 +4310,8 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
** rolled back because a commit callback returned non-zero.
** <todo> Check on this </todo>
**
+** See also the [sqlite3_update_hook()] interface.
+**
** Requirements:
** [H12951] [H12952] [H12953] [H12954] [H12955]
** [H12961] [H12962] [H12963] [H12964]
@@ -4302,6 +4343,13 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).
**
+** In the current implementation, the update hook
+** is not invoked when duplication rows are deleted because of an
+** [ON CONFLICT | ON CONFLICT REPLACE] clause. Nor is the update hook
+** invoked when rows are deleted using the [truncate optimization].
+** The exceptions defined in this paragraph might change in a future
+** release of SQLite.
+**
** The update hook implementation must not do anything that will modify
** the database connection that invoked the update hook. Any actions
** to modify the database connection must be deferred until after the
@@ -4312,6 +4360,9 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** If another function was previously registered, its pArg value
** is returned. Otherwise NULL is returned.
**
+** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
+** interfaces.
+**
** Requirements:
** [H12971] [H12973] [H12975] [H12977] [H12979] [H12981] [H12983] [H12986]
*/
@@ -4881,7 +4932,7 @@ typedef struct sqlite3_blob sqlite3_blob;
** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre> {END}
**
-** If the flags parameter is non-zero, the the BLOB is opened for read
+** If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. If it is zero, the BLOB is opened for read access.
**
** Note that the database name is not the filename that contains
@@ -4891,10 +4942,13 @@ typedef struct sqlite3_blob sqlite3_blob;
** For TEMP tables, the database name is "temp".
**
** On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and any value written
-** to *ppBlob should not be used by the caller.
+** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
+** to be a null pointer.
** This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()].
+** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
+** functions. Note that the *ppBlob variable is always initialized in a
+** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
+** regardless of the success or failure of this routine.
**
** If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -4907,6 +4961,19 @@ typedef struct sqlite3_blob sqlite3_blob;
** rollback by the expiration of the BLOB. Such changes will eventually
** commit if the transaction continues to completion.
**
+** Use the [sqlite3_blob_bytes()] interface to determine the size of
+** the opened blob. The size of a blob may not be changed by this
+** underface. Use the [UPDATE] SQL command to change the size of a
+** blob.
+**
+** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
+** and the built-in [zeroblob] SQL function can be used, if desired,
+** to create an empty, zero-filled blob in which to read or write using
+** this interface.
+**
+** To avoid a resource leak, every open [BLOB handle] should eventually
+** be released by a call to [sqlite3_blob_close()].
+**
** Requirements:
** [H17813] [H17814] [H17816] [H17819] [H17821] [H17824]
*/
@@ -4929,16 +4996,19 @@ SQLITE_API int sqlite3_blob_open(
** if there are no other BLOBs, no pending prepared statements, and the
** database connection is in [autocommit mode].
** If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit. {END}
+** until the close operation if they will fit.
**
** Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. {H17833} Any errors that occur during
+** at the time when the BLOB is closed. Any errors that occur during
** closing are reported as a non-zero return value.
**
** The BLOB is closed unconditionally. Even if this routine returns
** an error code, the BLOB is still closed.
**
+** Calling this routine with a null pointer (which as would be returned
+** by failed call to [sqlite3_blob_open()]) is a harmless no-op.
+**
** Requirements:
** [H17833] [H17836] [H17839]
*/
@@ -4947,8 +5017,15 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB {H17840} <S30230>
**
-** Returns the size in bytes of the BLOB accessible via the open
-** []BLOB handle] in its only argument.
+** Returns the size in bytes of the BLOB accessible via the
+** successfully opened [BLOB handle] in its only argument. The
+** incremental blob I/O routines can only read or overwriting existing
+** blob content; they cannot change the size of a blob.
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
**
** Requirements:
** [H17843]
@@ -4965,6 +5042,8 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
** If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is read. If N or iOffset is
** less than zero, [SQLITE_ERROR] is returned and no data is read.
+** The size of the blob (and hence the maximum value of N+iOffset)
+** can be determined using the [sqlite3_blob_bytes()] interface.
**
** An attempt to read from an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].
@@ -4972,6 +5051,13 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_write()].
+**
** Requirements:
** [H17853] [H17856] [H17859] [H17862] [H17863] [H17865] [H17868]
*/
@@ -4993,6 +5079,8 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written. If N is
** less than zero [SQLITE_ERROR] is returned and no data is written.
+** The size of the BLOB (and hence the maximum value of N+iOffset)
+** can be determined using the [sqlite3_blob_bytes()] interface.
**
** An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT]. Writes to the BLOB that occurred
@@ -5004,6 +5092,13 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_read()].
+**
** Requirements:
** [H17873] [H17874] [H17875] [H17876] [H17877] [H17879] [H17882] [H17885]
** [H17888]
@@ -5354,6 +5449,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
#define SQLITE_TESTCTRL_PENDING_BYTE 11
+#define SQLITE_TESTCTRL_ASSERT 12
+#define SQLITE_TESTCTRL_ALWAYS 13
/*
** CAPI3REF: SQLite Runtime Status {H17200} <S60200>
@@ -6438,6 +6535,14 @@ typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
typedef INT8_TYPE i8; /* 1-byte signed integer */
/*
+** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
+** that can be stored in a u32 without loss of data. The value
+** is 0x00000000ffffffff. But because of quirks of some compilers, we
+** have to specify the value in the less intuitive manner shown:
+*/
+#define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
+
+/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
@@ -6481,6 +6586,7 @@ SQLITE_PRIVATE const int sqlite3one;
*/
#define EIGHT_BYTE_ALIGNMENT(X) ((((char*)(X) - (char*)0)&7)==0)
+
/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
@@ -6585,6 +6691,7 @@ 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 FuncDef FuncDef;
typedef struct FuncDefHash FuncDefHash;
@@ -6680,7 +6787,7 @@ struct BtreeMutexArray {
SQLITE_PRIVATE int sqlite3BtreeOpen(
const char *zFilename, /* Name of database file to open */
sqlite3 *db, /* Associated database connection */
- Btree **, /* Return open Btree* here */
+ Btree **ppBtree, /* Return open Btree* here */
int flags, /* Flags */
int vfsFlags /* Flags passed through to VFS open */
);
@@ -6702,7 +6809,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
SQLITE_PRIVATE int sqlite3BtreeSyncDisabled(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree*,int,int,int);
+SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
@@ -6738,9 +6845,31 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
+SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
+
SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
+
+/*
+** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta
+** should be one of the following values. The integer values are assigned
+** to constants so that the offset of the corresponding field in an
+** SQLite database header may be found using the following formula:
+**
+** offset = 36 + (idx * 4)
+**
+** For example, the free-page-count field is located at byte offset 36 of
+** the database file header. The incr-vacuum-flag field is located at
+** byte offset 64 (== 36+4*7).
+*/
+#define BTREE_FREE_PAGE_COUNT 0
+#define BTREE_SCHEMA_VERSION 1
+#define BTREE_FILE_FORMAT 2
+#define BTREE_DEFAULT_CACHE_SIZE 3
+#define BTREE_LARGEST_ROOT_PAGE 4
+#define BTREE_TEXT_ENCODING 5
+#define BTREE_USER_VERSION 6
+#define BTREE_INCR_VACUUM 7
SQLITE_PRIVATE int sqlite3BtreeCursor(
Btree*, /* BTree containing table to open */
@@ -6779,7 +6908,6 @@ SQLITE_PRIVATE int sqlite3BtreeFlags(BtCursor*);
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes);
SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize);
SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE sqlite3 *sqlite3BtreeCursorDb(const BtCursor*);
SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt);
SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt);
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
@@ -7655,7 +7783,6 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
# define SQLITE_OS_WINCE 0
#endif
-#include <ctype.h>
/*
** Define the maximum size of a temporary filename
@@ -7940,9 +8067,11 @@ struct Db {
Btree *pBt; /* The B*Tree structure for this database file */
u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
u8 safety_level; /* How aggressive at syncing data to disk */
+ Schema *pSchema; /* Pointer to database schema (possibly shared) */
+#ifdef SQLITE_HAS_CODEC
void *pAux; /* Auxiliary data. Usually NULL */
void (*xFreeAux)(void*); /* Routine to free pAux */
- Schema *pSchema; /* Pointer to database schema (possibly shared) */
+#endif
};
/*
@@ -8260,7 +8389,7 @@ struct FuncDef {
** implemented by C function xFunc that accepts nArg arguments. The
** value passed as iArg is cast to a (void*) and made available
** as the user-data (sqlite3_user_data()) for the function. If
-** argument bNC is true, then the FuncDef.needCollate flag is set.
+** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal)
** Used to create an aggregate function definition implemented by
@@ -8277,13 +8406,16 @@ struct FuncDef {
** parameter.
*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*8, SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0}
+ {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0}
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
- {nArg, SQLITE_UTF8, bNC*8, pArg, 0, xFunc, 0, 0, #zName, 0}
+ {nArg, SQLITE_UTF8, bNC*SQLITE_FUNC_NEEDCOLL, \
+ pArg, 0, xFunc, 0, 0, #zName, 0}
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_UTF8, flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0}
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
- {nArg, SQLITE_UTF8, nc*8, SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0}
+ {nArg, SQLITE_UTF8, nc*SQLITE_FUNC_NEEDCOLL, \
+ SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0}
/*
** All current savepoints are stored in a linked list starting at
@@ -8324,6 +8456,7 @@ struct Module {
struct Column {
char *zName; /* Name of this column */
Expr *pDflt; /* Default value of this column */
+ char *zDflt; /* Original text of the default value */
char *zType; /* Data type for this column */
char *zColl; /* Collating sequence. If NULL, use the default */
u8 notNull; /* True if there is a NOT NULL constraint */
@@ -8669,10 +8802,8 @@ struct Index {
** and Token.n when Token.z==0.
*/
struct Token {
- const unsigned char *z; /* Text of the token. Not NULL-terminated! */
- unsigned dyn : 1; /* True for malloced memory, false for static */
- unsigned quoted : 1; /* True if token still has its quotes */
- unsigned n : 30; /* Number of characters in this token */
+ const char *z; /* Text of the token. Not NULL-terminated! */
+ unsigned int n; /* Number of characters in this token */
};
/*
@@ -8773,9 +8904,9 @@ struct AggInfo {
** help reduce memory requirements, sometimes an Expr object will be
** truncated. And to reduce the number of memory allocations, sometimes
** two or more Expr objects will be stored in a single memory allocation,
-** together with Expr.token and/or Expr.span strings.
+** together with Expr.zToken strings.
**
-** If the EP_Reduced, EP_SpanToken, and EP_TokenOnly flags are set when
+** If the EP_Reduced and EP_TokenOnly flags are set when
** an Expr object is truncated. When EP_Reduced is set, then all
** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
** are contained within the same memory allocation. Note, however, that
@@ -8785,22 +8916,17 @@ struct AggInfo {
struct Expr {
u8 op; /* Operation performed by this node */
char affinity; /* The affinity of the column or 0 if not a column */
- VVA_ONLY(u8 vvaFlags;) /* Flags used for VV&A only. EVVA_* below. */
u16 flags; /* Various flags. EP_* See below */
- Token token; /* An operand token */
+ union {
+ char *zToken; /* Token value. Zero terminated and dequoted */
+ int iValue; /* Integer value if EP_IntValue */
+ } u;
/* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
** access them will result in a segfault or malfunction.
*********************************************************************/
- Token span; /* Complete text of the expression */
-
- /* If the EP_SpanToken flag is set in the Expr.flags mask, then no
- ** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
- *********************************************************************/
-
Expr *pLeft; /* Left subnode */
Expr *pRight; /* Right subnode */
union {
@@ -8814,11 +8940,13 @@ struct Expr {
** access them will result in a segfault or malfunction.
*********************************************************************/
- int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the
- ** iColumn-th field of the iTable-th table. */
+ int iTable; /* TK_COLUMN: cursor number of table holding column
+ ** TK_REGISTER: register number */
+ i16 iColumn; /* TK_COLUMN: column index. -1 for rowid */
+ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
+ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */
+ u16 flags2; /* Second set of flags. EP2_... */
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
- int iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
- int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
Table *pTab; /* Table for TK_COLUMN expressions. */
#if SQLITE_MAX_EXPR_DEPTH>0
int nHeight; /* Height of the tree headed by this node */
@@ -8839,20 +8967,29 @@ struct Expr {
#define EP_ExpCollate 0x0100 /* Collating sequence specified explicitly */
#define EP_AnyAff 0x0200 /* Can take a cached column of any affinity */
#define EP_FixedDest 0x0400 /* Result needed in a specific register */
-#define EP_IntValue 0x0800 /* Integer value contained in iTable */
+#define EP_IntValue 0x0800 /* Integer value contained in u.iValue */
#define EP_xIsSelect 0x1000 /* x.pSelect is valid (otherwise x.pList is) */
#define EP_Reduced 0x2000 /* Expr struct is EXPR_REDUCEDSIZE bytes only */
#define EP_TokenOnly 0x4000 /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
-#define EP_SpanToken 0x8000 /* Expr size is EXPR_SPANTOKENSIZE bytes */
+#define EP_Static 0x8000 /* Held in memory not obtained from malloc() */
/*
-** The following are the meanings of bits in the Expr.vvaFlags field.
-** This information is only used when SQLite is compiled with
-** SQLITE_DEBUG defined.
+** The following are the meanings of bits in the Expr.flags2 field.
*/
-#ifndef NDEBUG
-#define EVVA_ReadOnlyToken 0x01 /* Expr.token.z is read-only */
+#define EP2_MallocedToken 0x0001 /* Need to sqlite3DbFree() Expr.zToken */
+#define EP2_Irreducible 0x0002 /* Cannot EXPRDUP_REDUCE this Expr */
+
+/*
+** The pseudo-routine sqlite3ExprSetIrreducible sets the EP2_Irreducible
+** flag on an expression structure. This flag is used for VV&A only. The
+** routine is implemented as a macro that only works when in debugging mode,
+** so as not to burden production code.
+*/
+#ifdef SQLITE_DEBUG
+# define ExprSetIrreducible(X) (X)->flags2 |= EP2_Irreducible
+#else
+# define ExprSetIrreducible(X)
#endif
/*
@@ -8871,15 +9008,13 @@ struct Expr {
*/
#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
#define EXPR_REDUCEDSIZE offsetof(Expr,iTable) /* Common features */
-#define EXPR_SPANTOKENSIZE offsetof(Expr,pLeft) /* Fewer features */
-#define EXPR_TOKENONLYSIZE offsetof(Expr,span) /* Smallest possible */
+#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
/*
** Flags passed to the sqlite3ExprDup() function. See the header comment
** above sqlite3ExprDup() for details.
*/
#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
-#define EXPRDUP_SPAN 0x0002 /* Make a copy of Expr.span */
/*
** A list of expressions. Each expression may optionally have a
@@ -8896,6 +9031,7 @@ struct ExprList {
struct ExprList_item {
Expr *pExpr; /* The list of expressions */
char *zName; /* Token associated with this expression */
+ char *zSpan; /* Original text of the expression */
u8 sortOrder; /* 1 for DESC or 0 for ASC */
u8 done; /* A flag to indicate when processing is finished */
u16 iCol; /* For ORDER BY, column number in result set */
@@ -8904,6 +9040,17 @@ 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:
**
@@ -9353,7 +9500,6 @@ struct Trigger {
Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */
IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
the <column-list> is stored here */
- Token nameToken; /* Token containing zName. Use during parsing only */
Schema *pSchema; /* Schema containing the trigger */
Schema *pTabSchema; /* Schema containing the table */
TriggerStep *step_list; /* Link list of trigger program steps */
@@ -9387,7 +9533,7 @@ struct Trigger {
* orconf -> stores the ON CONFLICT algorithm
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
* this stores a pointer to the SELECT statement. Otherwise NULL.
- * target -> A token holding the name of the table to insert into.
+ * target -> A token holding the quoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
* pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
@@ -9395,12 +9541,12 @@ struct Trigger {
* inserted into.
*
* (op == TK_DELETE)
- * target -> A token holding the name of the table to delete from.
+ * target -> A token holding the quoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
*
* (op == TK_UPDATE)
- * target -> A token holding the name of the table to update rows of.
+ * target -> A token holding the quoted name of the table to update rows of.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
* Otherwise NULL.
* pExprList -> A list of the columns to update and the expressions to update
@@ -9415,7 +9561,7 @@ struct TriggerStep {
Select *pSelect; /* Valid for SELECT and sometimes
INSERT steps (when pExprList == 0) */
- Token target; /* Valid for DELETE, UPDATE, INSERT steps */
+ Token target; /* Target table for DELETE, UPDATE, INSERT. Quoted */
Expr *pWhere; /* Valid for DELETE, UPDATE steps */
ExprList *pExprList; /* Valid for UPDATE statements and sometimes
INSERT steps (when pSelect == 0) */
@@ -9590,6 +9736,15 @@ SQLITE_PRIVATE int sqlite3Corrupt(void);
#endif
/*
+** The ctype.h header is needed for non-ASCII systems. It is also
+** needed by FTS3 when FTS3 is included in the amalgamation.
+*/
+#if !defined(SQLITE_ASCII) || \
+ (defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_AMALGAMATION))
+# include <ctype.h>
+#endif
+
+/*
** The following macros mimic the standard library functions toupper(),
** isspace(), isalnum(), isdigit() and isxdigit(), respectively. The
** sqlite versions only work for ASCII characters, regardless of locale.
@@ -9603,7 +9758,6 @@ SQLITE_PRIVATE int sqlite3Corrupt(void);
# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)])
#else
-# include <ctype.h>
# define sqlite3Toupper(x) toupper((unsigned char)(x))
# define sqlite3Isspace(x) isspace((unsigned char)(x))
# define sqlite3Isalnum(x) isalnum((unsigned char)(x))
@@ -9643,6 +9797,24 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void);
SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
SQLITE_PRIVATE int sqlite3MemoryAlarm(void (*)(void*, sqlite3_int64, int), void*, sqlite3_int64);
+/*
+** On systems with ample stack space and that support alloca(), make
+** use of alloca() to obtain space for large automatic objects. By default,
+** obtain space from malloc().
+**
+** The alloca() routine never returns NULL. This will cause code paths
+** that deal with sqlite3StackAlloc() failures to be unreachable.
+*/
+#ifdef SQLITE_USE_ALLOCA
+# define sqlite3StackAllocRaw(D,N) alloca(N)
+# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
+# define sqlite3StackFree(D,P)
+#else
+# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
+# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
+# define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
+#endif
+
#ifdef SQLITE_ENABLE_MEMSYS3
SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
#endif
@@ -9685,16 +9857,18 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse*);
SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
-SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*, int, Expr*, Expr*, const Token*);
+SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
+SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*);
+SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
-SQLITE_PRIVATE Expr *sqlite3RegisterExpr(Parse*,Token*);
SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
-SQLITE_PRIVATE void sqlite3ExprSpan(Expr*,Token*,Token*);
SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3ExprClear(sqlite3*, Expr*);
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*);
-SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*,Token*);
+SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
+SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
+SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
@@ -9710,14 +9884,14 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int);
SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*);
SQLITE_PRIVATE void sqlite3AddColumnType(Parse*,Token*);
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*);
+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,ExprSpan*);
SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*);
SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,Select*);
SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32);
SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32);
SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32);
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32);
+SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*);
SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*);
SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*);
SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*);
@@ -9824,7 +9998,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
-SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3*,Token*,const Token*);
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
@@ -9955,8 +10128,8 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
SQLITE_PRIVATE const char *sqlite3ErrStr(int);
SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
-SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char *,int,int);
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName);
+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 Expr *sqlite3ExprSetColl(Parse *pParse, Expr *, Token *);
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
@@ -9994,8 +10167,8 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int);
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
-SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
-SQLITE_PRIVATE char sqlite3AffinityType(const Token*);
+SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char*);
+SQLITE_PRIVATE char sqlite3AffinityType(const char*);
SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*);
SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*);
SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*);
@@ -10034,7 +10207,7 @@ SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
SQLITE_PRIVATE int sqlite3ParserStackPeak(void*);
#endif
-SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3*);
+SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*);
#ifndef SQLITE_OMIT_LOAD_EXTENSION
SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*);
#else
@@ -14833,8 +15006,45 @@ static int winMutexNotheld(sqlite3_mutex *p){
/*
** Initialize and deinitialize the mutex subsystem.
*/
-static int winMutexInit(void){ return SQLITE_OK; }
-static int winMutexEnd(void){ return SQLITE_OK; }
+static sqlite3_mutex winMutex_staticMutexes[6];
+static int winMutex_isInit = 0;
+/* As winMutexInit() and winMutexEnd() are called as part
+** of the sqlite3_initialize and sqlite3_shutdown()
+** processing, the "interlocked" magic is probably not
+** strictly necessary.
+*/
+static long winMutex_lock = 0;
+
+static int winMutexInit(void){
+ /* The first to increment to 1 does actual initialization */
+ if( InterlockedIncrement(&winMutex_lock)==1 ){
+ int i;
+ for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
+ InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
+ }
+ winMutex_isInit = 1;
+ }else{
+ while( !winMutex_isInit ){
+ Sleep(1);
+ }
+ }
+ return SQLITE_OK;
+}
+
+static int winMutexEnd(void){
+ /* The first to decrement to 0 does actual shutdown
+ ** (which should be the last to shutdown.) */
+ if( InterlockedDecrement(&winMutex_lock)==0 ){
+ if( winMutex_isInit==1 ){
+ int i;
+ for(i=0; i<sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]); i++){
+ DeleteCriticalSection(&winMutex_staticMutexes[i].mutex);
+ }
+ winMutex_isInit = 0;
+ }
+ }
+ return SQLITE_OK;
+}
/*
** The sqlite3_mutex_alloc() routine allocates a new
@@ -14882,30 +15092,17 @@ static sqlite3_mutex *winMutexAlloc(int iType){
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
- if( p ){
+ if( p ){
p->id = iType;
InitializeCriticalSection(&p->mutex);
}
break;
}
default: {
- static sqlite3_mutex staticMutexes[6];
- static int isInit = 0;
- while( !isInit ){
- static long lock = 0;
- if( InterlockedIncrement(&lock)==1 ){
- int i;
- for(i=0; i<sizeof(staticMutexes)/sizeof(staticMutexes[0]); i++){
- InitializeCriticalSection(&staticMutexes[i].mutex);
- }
- isInit = 1;
- }else{
- Sleep(1);
- }
- }
+ assert( winMutex_isInit==1 );
assert( iType-2 >= 0 );
- assert( iType-2 < sizeof(staticMutexes)/sizeof(staticMutexes[0]) );
- p = &staticMutexes[iType-2];
+ assert( iType-2 < sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]) );
+ p = &winMutex_staticMutexes[iType-2];
p->id = iType;
break;
}
@@ -15917,11 +16114,14 @@ static void appendSpace(StrAccum *pAccum, int N){
/*
** On machines with a small stack size, you can redefine the
-** SQLITE_PRINT_BUF_SIZE to be less than 350. But beware - for
-** smaller values some %f conversions may go into an infinite loop.
+** SQLITE_PRINT_BUF_SIZE to be less than 350.
*/
#ifndef SQLITE_PRINT_BUF_SIZE
-# define SQLITE_PRINT_BUF_SIZE 350
+# if defined(SQLITE_SMALL_STACK)
+# define SQLITE_PRINT_BUF_SIZE 50
+# else
+# define SQLITE_PRINT_BUF_SIZE 350
+# endif
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
@@ -17212,10 +17412,10 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
-SQLITE_PRIVATE int sqlite3VdbeSerialTypeLen(u32);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
-SQLITE_PRIVATE int sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
-SQLITE_PRIVATE int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
@@ -17893,6 +18093,7 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){
*/
SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
const char *z2 = z;
+ if( z==0 ) return 0;
while( *z2 ){ z2++; }
return 0x3fffffff & (int)(z2 - z);
}
@@ -17955,14 +18156,11 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
va_list ap;
sqlite3 *db = pParse->db;
pParse->nErr++;
- testcase( pParse->zErrMsg!=0 );
sqlite3DbFree(db, pParse->zErrMsg);
va_start(ap, zFormat);
pParse->zErrMsg = sqlite3VMPrintf(db, zFormat, ap);
va_end(ap);
- if( pParse->rc==SQLITE_OK ){
- pParse->rc = SQLITE_ERROR;
- }
+ pParse->rc = SQLITE_ERROR;
}
/*
@@ -18234,9 +18432,12 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum){
}
/*
-** The string zNum represents an unsigned integer. There might be some other
-** information following the integer too, but that part is ignored.
-** If the integer that the prefix of zNum represents will fit in a
+** The string zNum represents an unsigned integer. The zNum string
+** consists of one or more digit characters and is terminated by
+** a zero character. Any stray characters in zNum result in undefined
+** behavior.
+**
+** If the unsigned integer that zNum represents will fit in a
** 64-bit signed integer, return TRUE. Otherwise return FALSE.
**
** If the negFlag parameter is true, that means that zNum really represents
@@ -18248,7 +18449,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum){
** Leading zeros are ignored.
*/
SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
- int i, c;
+ int i;
int neg = 0;
assert( zNum[0]>='0' && zNum[0]<='9' ); /* zNum is an unsigned number */
@@ -18257,7 +18458,7 @@ SQLITE_PRIVATE int sqlite3FitsIn64Bits(const char *zNum, int negFlag){
while( *zNum=='0' ){
zNum++; /* Skip leading zeros. Ticket #2454 */
}
- for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
+ for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); }
if( i<19 ){
/* Guaranteed to fit if less than 19 digits */
return 1;
@@ -18550,6 +18751,10 @@ SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
/*
** Read a 32-bit variable-length integer from memory starting at p[0].
** Return the number of bytes read. The value is stored in *v.
+**
+** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
+** integer, then set *v to 0xffffffff.
+**
** A MACRO version, getVarint32, is provided which inlines the
** single-byte case. All code should use the MACRO version as
** this function assumes the single-byte case has already been handled.
@@ -18615,7 +18820,11 @@ SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
p -= 2;
n = sqlite3GetVarint(p, &v64);
assert( n>3 && n<=9 );
- *v = (u32)v64;
+ if( (v64 & SQLITE_MAX_U32)!=v64 ){
+ *v = 0xffffffff;
+ }else{
+ *v = (u32)v64;
+ }
return n;
}
@@ -19102,7 +19311,8 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, voi
new_elem->data = data;
pH->count++;
if( pH->count>=10 && pH->count > 2*pH->htsize ){
- if( rehash(pH, pH->count*2) && pH->htsize ){
+ if( rehash(pH, pH->count*2) ){
+ assert( pH->htsize>0 );
h = strHash(pKey, nKey) % pH->htsize;
}
}
@@ -25274,8 +25484,8 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
len = strlcat(lPath, "sqliteplocks", maxLen);
if( mkdir(lPath, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){
/* if mkdir fails, handle as lock file creation failure */
- int err = errno;
# ifdef SQLITE_DEBUG
+ int err = errno;
if( err!=EEXIST ){
fprintf(stderr, "proxyGetLockPath: mkdir(%s,0%o) error %d %s\n", lPath,
SQLITE_DEFAULT_PROXYDIR_PERMISSIONS, err, strerror(err));
@@ -28304,15 +28514,20 @@ bitvec_set_rehash:
if( p->nSet>=BITVEC_MXHASH ){
unsigned int j;
int rc;
- u32 aiValues[BITVEC_NINT];
- memcpy(aiValues, p->u.aHash, sizeof(aiValues));
- memset(p->u.apSub, 0, sizeof(aiValues));
- p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
- rc = sqlite3BitvecSet(p, i);
- for(j=0; j<BITVEC_NINT; j++){
- if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
+ u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
+ if( aiValues==0 ){
+ return SQLITE_NOMEM;
+ }else{
+ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+ memset(p->u.apSub, 0, sizeof(p->u.apSub));
+ p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
+ rc = sqlite3BitvecSet(p, i);
+ for(j=0; j<BITVEC_NINT; j++){
+ if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
+ }
+ sqlite3StackFree(0, aiValues);
+ return rc;
}
- return rc;
}
bitvec_set_end:
p->nSet++;
@@ -28322,8 +28537,11 @@ bitvec_set_end:
/*
** Clear the i-th bit.
+**
+** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
+** that BitvecClear can use to rebuilt its hash table.
*/
-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i){
+SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
assert( p!=0 );
assert( i>0 );
i--;
@@ -28339,9 +28557,9 @@ SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i){
p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
}else{
unsigned int j;
- u32 aiValues[BITVEC_NINT];
- memcpy(aiValues, p->u.aHash, sizeof(aiValues));
- memset(p->u.aHash, 0, sizeof(aiValues));
+ u32 *aiValues = pBuf;
+ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+ memset(p->u.aHash, 0, sizeof(p->u.aHash));
p->nSet = 0;
for(j=0; j<BITVEC_NINT; j++){
if( aiValues[j] && aiValues[j]!=(i+1) ){
@@ -28425,12 +28643,14 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
unsigned char *pV = 0;
int rc = -1;
int i, nx, pc, op;
+ void *pTmpSpace;
/* Allocate the Bitvec to be tested and a linear array of
** bits to act as the reference */
pBitvec = sqlite3BitvecCreate( sz );
pV = sqlite3_malloc( (sz+7)/8 + 1 );
- if( pBitvec==0 || pV==0 ) goto bitvec_end;
+ pTmpSpace = sqlite3_malloc(BITVEC_SZ);
+ if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end;
memset(pV, 0, (sz+7)/8 + 1);
/* Run the program */
@@ -28463,7 +28683,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
}
}else{
CLEARBIT(pV, (i+1));
- sqlite3BitvecClear(pBitvec, i+1);
+ sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
}
}
@@ -28484,6 +28704,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
/* Free allocated structure */
bitvec_end:
+ sqlite3_free(pTmpSpace);
sqlite3_free(pV);
sqlite3BitvecDestroy(pBitvec);
return rc;
@@ -29131,7 +29352,7 @@ struct PCache1 {
/*
** Each cache entry is represented by an instance of the following
** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated
-** directly after the structure in memory (see the PGHDR1_TO_PAGE()
+** directly before this structure in memory (see the PGHDR1_TO_PAGE()
** macro below).
*/
struct PgHdr1 {
@@ -29165,6 +29386,7 @@ static SQLITE_WSD struct PCacheGlobal {
int szSlot; /* Size of each free slot */
void *pStart, *pEnd; /* Bounds of pagecache malloc range */
PgFreeslot *pFree; /* Free page blocks */
+ int isInit; /* True if initialized */
} pcache1_g;
/*
@@ -29176,7 +29398,7 @@ static SQLITE_WSD struct PCacheGlobal {
/*
** When a PgHdr1 structure is allocated, the associated PCache1.szPage
-** bytes of data are located directly after it in memory (i.e. the total
+** bytes of data are located directly before it in memory (i.e. the total
** size of the allocation is sizeof(PgHdr1)+PCache1.szPage byte). The
** PGHDR1_TO_PAGE() macro takes a pointer to a PgHdr1 structure as
** an argument and returns a pointer to the associated block of szPage
@@ -29184,10 +29406,10 @@ static SQLITE_WSD struct PCacheGlobal {
** a pointer to a block of szPage bytes of data and the return value is
** a pointer to the associated PgHdr1 structure.
**
-** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(X))==X );
+** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
*/
-#define PGHDR1_TO_PAGE(p) (void *)(&((unsigned char *)p)[sizeof(PgHdr1)])
-#define PAGE_TO_PGHDR1(p) (PgHdr1 *)(&((unsigned char *)p)[-1*(int)sizeof(PgHdr1)])
+#define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
+#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
/*
** Macros to enter and leave the global LRU mutex.
@@ -29205,18 +29427,20 @@ static SQLITE_WSD struct PCacheGlobal {
** enough to contain 'n' buffers of 'sz' bytes each.
*/
SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
- PgFreeslot *p;
- sz = ROUNDDOWN8(sz);
- pcache1.szSlot = sz;
- pcache1.pStart = pBuf;
- pcache1.pFree = 0;
- while( n-- ){
- p = (PgFreeslot*)pBuf;
- p->pNext = pcache1.pFree;
- pcache1.pFree = p;
- pBuf = (void*)&((char*)pBuf)[sz];
+ if( pcache1.isInit ){
+ PgFreeslot *p;
+ sz = ROUNDDOWN8(sz);
+ pcache1.szSlot = sz;
+ pcache1.pStart = pBuf;
+ pcache1.pFree = 0;
+ while( n-- ){
+ p = (PgFreeslot*)pBuf;
+ p->pNext = pcache1.pFree;
+ pcache1.pFree = p;
+ pBuf = (void*)&((char*)pBuf)[sz];
+ }
+ pcache1.pEnd = pBuf;
}
- pcache1.pEnd = pBuf;
}
/*
@@ -29229,6 +29453,7 @@ static void *pcache1Alloc(int nByte){
void *p;
assert( sqlite3_mutex_held(pcache1.mutex) );
if( nByte<=pcache1.szSlot && pcache1.pFree ){
+ assert( pcache1.isInit );
p = (PgHdr1 *)pcache1.pFree;
pcache1.pFree = pcache1.pFree->pNext;
sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
@@ -29276,11 +29501,15 @@ static void pcache1Free(void *p){
*/
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
int nByte = sizeof(PgHdr1) + pCache->szPage;
- PgHdr1 *p = (PgHdr1 *)pcache1Alloc(nByte);
- if( p ){
+ void *pPg = pcache1Alloc(nByte);
+ PgHdr1 *p;
+ if( pPg ){
+ p = PAGE_TO_PGHDR1(pCache, pPg);
if( pCache->bPurgeable ){
pcache1.nCurrentPage++;
}
+ }else{
+ p = 0;
}
return p;
}
@@ -29293,7 +29522,7 @@ static void pcache1FreePage(PgHdr1 *p){
if( p->pCache->bPurgeable ){
pcache1.nCurrentPage--;
}
- pcache1Free(p);
+ pcache1Free(PGHDR1_TO_PAGE(p));
}
}
@@ -29437,7 +29666,7 @@ static void pcache1TruncateUnsafe(
PCache1 *pCache,
unsigned int iLimit
){
- TESTONLY( int nPage = 0; ) /* Used to assert pCache->nPage is correct */
+ TESTONLY( unsigned int nPage = 0; ) /* Used to assert pCache->nPage is correct */
unsigned int h;
assert( sqlite3_mutex_held(pcache1.mutex) );
for(h=0; h<pCache->nHash; h++){
@@ -29451,7 +29680,7 @@ static void pcache1TruncateUnsafe(
pcache1FreePage(pPage);
}else{
pp = &pPage->pNext;
- TESTONLY( nPage++ );
+ TESTONLY( nPage++; )
}
}
}
@@ -29466,10 +29695,12 @@ static void pcache1TruncateUnsafe(
*/
static int pcache1Init(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
+ assert( pcache1.isInit==0 );
memset(&pcache1, 0, sizeof(pcache1));
if( sqlite3GlobalConfig.bCoreMutex ){
pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
}
+ pcache1.isInit = 1;
return SQLITE_OK;
}
@@ -29478,7 +29709,8 @@ static int pcache1Init(void *NotUsed){
*/
static void pcache1Shutdown(void *NotUsed){
UNUSED_PARAMETER(NotUsed);
- /* no-op */
+ assert( pcache1.isInit!=0 );
+ memset(&pcache1, 0, sizeof(pcache1));
}
/*
@@ -29630,13 +29862,13 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){
if( pPage ){
unsigned int h = iKey % pCache->nHash;
- *(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
pCache->nPage++;
pPage->iKey = iKey;
pPage->pNext = pCache->apHash[h];
pPage->pCache = pCache;
pPage->pLruPrev = 0;
pPage->pLruNext = 0;
+ *(void **)(PGHDR1_TO_PAGE(pPage)) = 0;
pCache->apHash[h] = pPage;
}
@@ -29657,8 +29889,9 @@ fetch_out:
*/
static void pcache1Unpin(sqlite3_pcache *p, void *pPg, int reuseUnlikely){
PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = PAGE_TO_PGHDR1(pPg);
-
+ PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
+
+ assert( pPage->pCache==pCache );
pcache1EnterMutex();
/* It is an error to call this function if the page is already
@@ -29700,10 +29933,11 @@ static void pcache1Rekey(
unsigned int iNew
){
PCache1 *pCache = (PCache1 *)p;
- PgHdr1 *pPage = PAGE_TO_PGHDR1(pPg);
+ PgHdr1 *pPage = PAGE_TO_PGHDR1(pCache, pPg);
PgHdr1 **pp;
unsigned int h;
assert( pPage->iKey==iOld );
+ assert( pPage->pCache==pCache );
pcache1EnterMutex();
@@ -29798,7 +30032,7 @@ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
PgHdr1 *p;
pcache1EnterMutex();
while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){
- nFree += sqlite3MallocSize(p);
+ nFree += sqlite3MallocSize(PGHDR1_TO_PAGE(p));
pcache1PinPage(p);
pcache1RemoveFromHash(p);
pcache1FreePage(p);
@@ -29962,15 +30196,15 @@ struct RowSet {
*/
SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
RowSet *p;
- assert( N >= sizeof(*p) );
+ assert( N >= ROUND8(sizeof(*p)) );
p = pSpace;
p->pChunk = 0;
p->db = db;
p->pEntry = 0;
p->pLast = 0;
p->pTree = 0;
- p->pFresh = (struct RowSetEntry*)&p[1];
- p->nFresh = (u16)((N - sizeof(*p))/sizeof(struct RowSetEntry));
+ p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
+ p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
p->isSorted = 1;
p->iBatch = 0;
return p;
@@ -30364,11 +30598,14 @@ int sqlite3PagerTrace=1; /* True to enable tracing */
** A macro used for invoking the codec if there is one
*/
#ifdef SQLITE_HAS_CODEC
-# define CODEC1(P,D,N,X) if( P->xCodec!=0 ){ P->xCodec(P->pCodecArg,D,N,X); }
-# define CODEC2(P,D,N,X) ((char*)(P->xCodec!=0?P->xCodec(P->pCodecArg,D,N,X):D))
+# define CODEC1(P,D,N,X,E) \
+ if( P->xCodec && P->xCodec(P->pCodecArg,D,N,X)==0 ){ E; }
+# define CODEC2(P,D,N,X,E,O) \
+ if( P->xCodec==0 ){ O=(char*)D; }else \
+ if( (O=(char*)(P->xCodec(P->pCodecArg,D,N,X)))==0 ){ E; }
#else
-# define CODEC1(P,D,N,X) /* NO-OP */
-# define CODEC2(P,D,N,X) ((char*)D)
+# define CODEC1(P,D,N,X,E) /* NO-OP */
+# define CODEC2(P,D,N,X,E,O) O=(char*)D
#endif
/*
@@ -31856,7 +32093,7 @@ static int pager_playback_one_page(
}
/* Decode the page just read from disk */
- CODEC1(pPager, pData, pPg->pgno, 3);
+ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
sqlite3PcacheRelease(pPg);
}
return rc;
@@ -33148,8 +33385,11 @@ static int pager_write_pagelist(PgHdr *pList){
** set (set by sqlite3PagerDontWrite()).
*/
if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
- i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */
- char *pData = CODEC2(pPager, pList->pData, pgno, 6); /* Data to write */
+ i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */
+ char *pData; /* Data to write */
+
+ /* Encode the database */
+ CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
/* Write out the page data. */
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
@@ -33204,8 +33444,9 @@ static int subjournalPage(PgHdr *pPg){
if( isOpen(pPager->sjfd) ){
void *pData = pPg->pData;
i64 offset = pPager->nSubRec*(4+pPager->pageSize);
- char *pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
-
+ char *pData2;
+
+ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
assert( pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
@@ -33527,6 +33768,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
*/
tempFile = 1;
pPager->state = PAGER_EXCLUSIVE;
+ readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
}
/* The following call to PagerSetPagesize() serves to set the value of
@@ -33645,18 +33887,38 @@ static int hasHotJournal(Pager *pPager, int *pExists){
rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
if( rc==SQLITE_OK && exists ){
int locked; /* True if some process holds a RESERVED lock */
+
+ /* Race condition here: Another process might have been holding the
+ ** the RESERVED lock and have a journal open at the sqlite3OsAccess()
+ ** call above, but then delete the journal and drop the lock before
+ ** we get to the following sqlite3OsCheckReservedLock() call. If that
+ ** is the case, this routine might think there is a hot journal when
+ ** in fact there is none. This results in a false-positive which will
+ ** be dealt with by the playback routine. Ticket #3883.
+ */
rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
if( rc==SQLITE_OK && !locked ){
int nPage;
/* Check the size of the database file. If it consists of 0 pages,
** then delete the journal file. See the header comment above for
- ** the reasoning here.
+ ** the reasoning here. Delete the obsolete journal file under
+ ** a RESERVED lock to avoid race conditions and to avoid violating
+ ** [H33020].
*/
rc = sqlite3PagerPagecount(pPager, &nPage);
if( rc==SQLITE_OK ){
if( nPage==0 ){
- rc = sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+ sqlite3BeginBenignMalloc();
+ if( pPager->state>=PAGER_RESERVED
+ || sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){
+ sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+ assert( pPager->state>=PAGER_SHARED );
+ if( pPager->state==PAGER_SHARED ){
+ sqlite3OsUnlock(pPager->fd, SHARED_LOCK);
+ }
+ }
+ sqlite3EndBenignMalloc();
}else{
/* The journal file exists and no other connection has a reserved
** or greater lock on the database file. Now check that there is
@@ -33674,6 +33936,18 @@ static int hasHotJournal(Pager *pPager, int *pExists){
}
sqlite3OsClose(pPager->jfd);
*pExists = (first!=0);
+ }else if( rc==SQLITE_CANTOPEN ){
+ /* If we cannot open the rollback journal file in order to see if
+ ** its has a zero header, that might be due to an I/O error, or
+ ** it might be due to the race condition described above and in
+ ** ticket #3883. Either way, assume that the journal is hot.
+ ** This might be a false positive. But if it is, then the
+ ** automatic journal playback and recovery mechanism will deal
+ ** with it under an EXCLUSIVE lock where we do not need to
+ ** worry so much with race conditions.
+ */
+ *pExists = 1;
+ rc = SQLITE_OK;
}
}
}
@@ -33716,7 +33990,7 @@ static int readDbPage(PgHdr *pPg){
u8 *dbFileVers = &((u8*)pPg->pData)[24];
memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
}
- CODEC1(pPager, pPg->pData, pgno, 3);
+ CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
@@ -34414,7 +34688,7 @@ static int pager_write(PgHdr *pPg){
** contains the database locks. The following assert verifies
** that we do not. */
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
- pData2 = CODEC2(pPager, pData, pPg->pgno, 7);
+ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
cksum = pager_cksum(pPager, (u8*)pData2);
rc = write32bits(pPager->jfd, pPager->journalOff, pPg->pgno);
if( rc==SQLITE_OK ){
@@ -35395,7 +35669,8 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
if( rc!=SQLITE_OK ){
if( pPager->pInJournal && needSyncPgno<=pPager->dbOrigSize ){
- sqlite3BitvecClear(pPager->pInJournal, needSyncPgno);
+ assert( pPager->pTmpSpace!=0 );
+ sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
}
return rc;
}
@@ -36562,7 +36837,7 @@ static const char zMagicHeader[] = SQLITE_FILE_HEADER;
** macro.
*/
#if 0
-int sqlite3BtreeTrace=0; /* True to enable tracing */
+int sqlite3BtreeTrace=1; /* True to enable tracing */
# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);}
#else
# define TRACE(X)
@@ -37118,6 +37393,9 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){
return rc;
}
offset = PTRMAP_PTROFFSET(iPtrmap, key);
+ if( offset<0 ){
+ return SQLITE_CORRUPT_BKPT;
+ }
pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);
if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
@@ -37334,7 +37612,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
}
nSize += 4;
}
- nSize += (pIter - pCell);
+ nSize += (u32)(pIter - pCell);
/* The minimum size of any cell is 4 bytes. */
if( nSize<4 ){
@@ -37676,10 +37954,40 @@ SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage){
/* To many cells for a single page. The page must be corrupt */
return SQLITE_CORRUPT_BKPT;
}
-
+
+ /* A malformed database page might cause use to read past the end
+ ** of page when parsing a cell.
+ **
+ ** The following block of code checks early to see if a cell extends
+ ** past the end of a page boundary and causes SQLITE_CORRUPT to be
+ ** returned if it does.
+ */
+#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
+ {
+ int iCellFirst; /* First allowable cell index */
+ int iCellLast; /* Last possible cell index */
+ int i; /* Index into the cell pointer array */
+ int sz; /* Size of a cell */
+
+ iCellFirst = cellOffset + 2*pPage->nCell;
+ iCellLast = usableSize - 4;
+ if( !pPage->leaf ) iCellLast--;
+ for(i=0; i<pPage->nCell; i++){
+ pc = get2byte(&data[cellOffset+i*2]);
+ if( pc<iCellFirst || pc>iCellLast ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ sz = cellSizePtr(pPage, &data[pc]);
+ if( pc+sz>usableSize ){
+ return SQLITE_CORRUPT_BKPT;
+ }
+ }
+ }
+#endif
+
/* Compute the total free space on the page */
pc = get2byte(&data[hdr+1]);
- nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell);
+ nFree = data[hdr+7] + top;
while( pc>0 ){
u16 next, size;
if( pc>usableSize-4 ){
@@ -37695,11 +38003,18 @@ SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage){
nFree += size;
pc = next;
}
- pPage->nFree = (u16)nFree;
- if( nFree>=usableSize ){
- /* Free space cannot exceed total page size */
+
+ /* At this point, nFree contains the sum of the offset to the start
+ ** of the cell-content area plus the number of free bytes within
+ ** the cell-content area. If this is greater than the usable-size
+ ** of the page, then the page must be corrupted. This check also
+ ** serves to verify that the offset to the start of the cell-content
+ ** area, according to the page header, lies within the page.
+ */
+ if( nFree>usableSize ){
return SQLITE_CORRUPT_BKPT;
}
+ pPage->nFree = nFree - (cellOffset + 2*pPage->nCell);
#if 0
/* Check that all the offsets in the cell offset array are within range.
@@ -39182,6 +39497,7 @@ static int autoVacuumCommit(BtShared *pBt){
while( PTRMAP_ISPAGE(pBt, nFin) || nFin==PENDING_BYTE_PAGE(pBt) ){
nFin--;
}
+ if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
rc = incrVacuumStep(pBt, nFin, iFree);
@@ -39202,7 +39518,9 @@ static int autoVacuumCommit(BtShared *pBt){
return rc;
}
-#endif /* ifndef SQLITE_OMIT_AUTOVACUUM */
+#else /* ifndef SQLITE_OMIT_AUTOVACUUM */
+# define setChildPtrmaps(x) SQLITE_OK
+#endif
/*
** This routine does the first phase of a two-phase commit. This routine
@@ -40226,6 +40544,7 @@ static const unsigned char *fetchPayload(
** in the common case where no overflow pages are used.
*/
SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
if( pCur->eState==CURSOR_VALID ){
return (const void*)fetchPayload(pCur, pAmt, 0);
@@ -40233,6 +40552,7 @@ SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){
return 0;
}
SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
if( pCur->eState==CURSOR_VALID ){
return (const void*)fetchPayload(pCur, pAmt, 1);
@@ -40359,6 +40679,7 @@ static int moveToRoot(BtCursor *pCur){
if( pRoot->nCell==0 && !pRoot->leaf ){
Pgno subpage;
+ if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
assert( pRoot->pgno==1 );
subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
assert( subpage>0 );
@@ -40728,14 +41049,6 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
}
/*
-** Return the database connection handle for a cursor.
-*/
-SQLITE_PRIVATE sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- return pCur->pBtree->db;
-}
-
-/*
** Advance the cursor to the next entry in the database. If
** successful then set *pRes=0. If the cursor
** was already pointing to the last entry in the database before
@@ -40894,14 +41207,19 @@ static int allocateBtreePage(
){
MemPage *pPage1;
int rc;
- int n; /* Number of pages on the freelist */
+ u32 n; /* Number of pages on the freelist */
int k; /* Number of leaves on the trunk of the freelist */
MemPage *pTrunk = 0;
MemPage *pPrevTrunk = 0;
+ Pgno mxPage; /* Total size of the database file */
assert( sqlite3_mutex_held(pBt->mutex) );
pPage1 = pBt->pPage1;
+ mxPage = pagerPagecount(pBt);
n = get4byte(&pPage1->aData[36]);
+ if( n>mxPage ){
+ return SQLITE_CORRUPT_BKPT;
+ }
if( n>0 ){
/* There are pages on the freelist. Reuse one of those pages. */
Pgno iTrunk;
@@ -40912,7 +41230,7 @@ static int allocateBtreePage(
** the entire-list will be searched for that page.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( exact && nearby<=pagerPagecount(pBt) ){
+ if( exact && nearby<=mxPage ){
u8 eType;
assert( nearby>0 );
assert( pBt->autoVacuum );
@@ -40943,7 +41261,11 @@ static int allocateBtreePage(
}else{
iTrunk = get4byte(&pPage1->aData[32]);
}
- rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
+ if( iTrunk>mxPage ){
+ rc = SQLITE_CORRUPT_BKPT;
+ }else{
+ rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0);
+ }
if( rc ){
pTrunk = 0;
goto end_allocate_page;
@@ -40993,6 +41315,10 @@ static int allocateBtreePage(
*/
MemPage *pNewTrunk;
Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
+ if( iNewTrunk>mxPage ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto end_allocate_page;
+ }
rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
if( rc!=SQLITE_OK ){
goto end_allocate_page;
@@ -41047,6 +41373,10 @@ static int allocateBtreePage(
}
iPage = get4byte(&aData[8+closest*4]);
+ if( iPage>mxPage ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto end_allocate_page;
+ }
if( !searchList || iPage==nearby ){
int noContent;
Pgno nPage;
@@ -41130,6 +41460,8 @@ end_allocate_page:
return SQLITE_CORRUPT_BKPT;
}
(*ppPage)->isInit = 0;
+ }else{
+ *ppPage = 0;
}
return rc;
}
@@ -41566,7 +41898,6 @@ static int insertCell(
assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) );
pPage->aOvfl[j].pCell = pCell;
pPage->aOvfl[j].idx = (u16)i;
- pPage->nFree = 0;
}else{
int rc = sqlite3PagerWrite(pPage->pDbPage);
if( rc!=SQLITE_OK ){
@@ -41677,8 +42008,6 @@ static void assemblePage(
#define NN 1 /* Number of neighbors on either side of pPage */
#define NB (NN*2+1) /* Total pages involved in the balance */
-/* Forward reference */
-static int balance(BtCursor*, int);
#ifndef SQLITE_OMIT_QUICKBALANCE
/*
@@ -41697,57 +42026,66 @@ static int balance(BtCursor*, int);
** pPage is the leaf page which is the right-most page in the tree.
** pParent is its parent. pPage must have a single overflow entry
** which is also the right-most entry on the page.
+**
+** The pSpace buffer is used to store a temporary copy of the divider
+** cell that will be inserted into pParent. Such a cell consists of a 4
+** byte page number followed by a variable length integer. In other
+** words, at most 13 bytes. Hence the pSpace buffer must be at
+** least 13 bytes in size.
*/
-static int balance_quick(BtCursor *pCur){
- int rc;
- MemPage *pNew = 0;
- Pgno pgnoNew;
- u8 *pCell;
- u16 szCell;
- CellInfo info;
- MemPage *pPage = pCur->apPage[pCur->iPage];
- MemPage *pParent = pCur->apPage[pCur->iPage-1];
- BtShared *pBt = pPage->pBt;
- int parentIdx = pParent->nCell; /* pParent new divider cell index */
- int parentSize; /* Size of new divider cell */
- u8 parentCell[64]; /* Space for the new divider cell */
+static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
+ BtShared *const pBt = pPage->pBt; /* B-Tree Database */
+ MemPage *pNew = 0; /* Newly allocated page */
+ int rc; /* Return Code */
+ Pgno pgnoNew; /* Page number of pNew */
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+ assert( sqlite3PagerIswriteable(pParent->pDbPage) );
+ assert( pPage->nOverflow==1 );
+
+ if( pPage->nCell<=0 ) return SQLITE_CORRUPT_BKPT;
- /* Allocate a new page. Insert the overflow cell from pPage
- ** into it. Then remove the overflow cell from pPage.
+ /* Allocate a new page. This page will become the right-sibling of
+ ** pPage. Make the parent page writable, so that the new divider cell
+ ** may be inserted. If both these operations are successful, proceed.
*/
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
if( rc==SQLITE_OK ){
- pCell = pPage->aOvfl[0].pCell;
- szCell = cellSizePtr(pPage, pCell);
+
+ u8 *pOut = &pSpace[4];
+ u8 *pCell = pPage->aOvfl[0].pCell;
+ u16 szCell = cellSizePtr(pPage, pCell);
+ u8 *pStop;
+
assert( sqlite3PagerIswriteable(pNew->pDbPage) );
- zeroPage(pNew, pPage->aData[0]);
+ assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
+ zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
assemblePage(pNew, 1, &pCell, &szCell);
- pPage->nOverflow = 0;
- /* pPage is currently the right-child of pParent. Change this
- ** so that the right-child is the new page allocated above and
- ** pPage is the next-to-right child.
+ /* Create a divider cell to insert into pParent. The divider cell
+ ** consists of a 4-byte page number (the page number of pPage) and
+ ** a variable length key value (which must be the same value as the
+ ** largest key on pPage).
**
- ** Ignore the return value of the call to fillInCell(). fillInCell()
- ** may only return other than SQLITE_OK if it is required to allocate
- ** one or more overflow pages. Since an internal table B-Tree cell
- ** may never spill over onto an overflow page (it is a maximum of
- ** 13 bytes in size), it is not neccessary to check the return code.
- **
- ** Similarly, the insertCell() function cannot fail if the page
- ** being inserted into is already writable and the cell does not
- ** contain an overflow pointer. So ignore this return code too.
+ ** To find the largest key value on pPage, first find the right-most
+ ** cell on pPage. The first two fields of this cell are the
+ ** record-length (a variable length integer at most 32-bits in size)
+ ** and the key value (a variable length integer, may have any value).
+ ** The first of the while(...) loops below skips over the record-length
+ ** field. The second while(...) loop copies the key value from the
+ ** cell on pPage into the pSpace buffer.
*/
- assert( pPage->nCell>0 );
+ put4byte(pSpace, pPage->pgno);
pCell = findCell(pPage, pPage->nCell-1);
- sqlite3BtreeParseCellPtr(pPage, pCell, &info);
- fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
- assert( parentSize<64 );
- assert( sqlite3PagerIswriteable(pParent->pDbPage) );
- insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
- put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
+ pStop = &pCell[9];
+ while( (*(pCell++)&0x80) && pCell<pStop );
+ pStop = &pCell[9];
+ while( ((*(pOut++) = *(pCell++))&0x80) && pCell<pStop );
+
+ /* Insert the new divider cell into pParent */
+ insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), 0, 0);
+
+ /* Set the right-child pointer of pParent to point to the new page. */
put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
/* If this is an auto-vacuum database, update the pointer map
@@ -41765,31 +42103,6 @@ static int balance_quick(BtCursor *pCur){
releasePage(pNew);
}
- /* At this point the pPage->nFree variable is not set correctly with
- ** respect to the content of the page (because it was set to 0 by
- ** insertCell). So call sqlite3BtreeInitPage() to make sure it is
- ** correct.
- **
- ** This has to be done even if an error will be returned. Normally, if
- ** an error occurs during tree balancing, the contents of MemPage are
- ** not important, as they will be recalculated when the page is rolled
- ** back. But here, in balance_quick(), it is possible that pPage has
- ** not yet been marked dirty or written into the journal file. Therefore
- ** it will not be rolled back and so it is important to make sure that
- ** the page data and contents of MemPage are consistent.
- */
- pPage->isInit = 0;
- sqlite3BtreeInitPage(pPage);
- assert( pPage->nOverflow==0 );
-
- /* If everything else succeeded, balance the parent page, in
- ** case the divider cell inserted caused it to become overfull.
- */
- if( rc==SQLITE_OK ){
- releasePage(pPage);
- pCur->iPage--;
- rc = balance(pCur, 0);
- }
return rc;
}
#endif /* SQLITE_OMIT_QUICKBALANCE */
@@ -41820,20 +42133,16 @@ static int balance_quick(BtCursor *pCur){
** is called recursively on the parent.
**
** If this routine fails for any reason, it might leave the database
-** in a corrupted state. So if this routine fails, the database should
+** in a corrupted state. So if this routine fails, the database should
** be rolled back.
*/
-static int balance_nonroot(BtCursor *pCur){
- MemPage *pPage; /* The over or underfull page to balance */
- MemPage *pParent; /* The parent of pPage */
+static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){
BtShared *pBt; /* The whole database */
int nCell = 0; /* Number of cells in apCell[] */
int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */
int nOld = 0; /* Number of pages in apOld[] */
int nNew = 0; /* Number of pages in apNew[] */
- int nDiv; /* Number of cells in apDiv[] */
int i, j, k; /* Loop counters */
- int idx; /* Index of pPage in pParent->aCell[] */
int nxDiv; /* Next divider slot in pParent->aCell[] */
int rc; /* The return code */
int leafCorrection; /* 4 if pPage is a leaf. 0 if not */
@@ -41842,7 +42151,7 @@ static int balance_nonroot(BtCursor *pCur){
int pageFlags; /* Value of pPage->aData[0] */
int subtotal; /* Subtotal of bytes in cells on one page */
int iSpace1 = 0; /* First unused byte of aSpace1[] */
- int iSpace2 = 0; /* First unused byte of aSpace2[] */
+ int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */
int szScratch; /* Size of scratch memory requested */
MemPage *apOld[NB]; /* pPage and up to two siblings */
Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */
@@ -41856,84 +42165,30 @@ static int balance_nonroot(BtCursor *pCur){
u16 *szCell; /* Local size of all cells in apCell[] */
u8 *aCopy[NB]; /* Space for holding data of apCopy[] */
u8 *aSpace1; /* Space for copies of dividers cells before balance */
- u8 *aSpace2 = 0; /* Space for overflow dividers cells after balance */
u8 *aFrom = 0;
- pPage = pCur->apPage[pCur->iPage];
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- VVA_ONLY( pCur->pagesShuffled = 1 );
-
- /*
- ** Find the parent page.
- */
- assert( pCur->iPage>0 );
- assert( pPage->isInit );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) || pPage->nOverflow==1 );
- pBt = pPage->pBt;
- pParent = pCur->apPage[pCur->iPage-1];
- assert( pParent );
- if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
- goto balance_cleanup;
- }
+ pBt = pParent->pBt;
+ assert( sqlite3_mutex_held(pBt->mutex) );
+ assert( sqlite3PagerIswriteable(pParent->pDbPage) );
TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
-#ifndef SQLITE_OMIT_QUICKBALANCE
- /*
- ** A special case: If a new entry has just been inserted into a
- ** table (that is, a btree with integer keys and all data at the leaves)
- ** and the new entry is the right-most entry in the tree (it has the
- ** largest key) then use the special balance_quick() routine for
- ** balancing. balance_quick() is much faster and results in a tighter
- ** packing of data in the common case.
- */
- if( pPage->leaf &&
- pPage->intKey &&
- pPage->nOverflow==1 &&
- pPage->aOvfl[0].idx==pPage->nCell &&
- pParent->pgno!=1 &&
- get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno
- ){
- assert( pPage->intKey );
- /*
- ** TODO: Check the siblings to the left of pPage. It may be that
- ** they are not full and no new page is required.
- */
- return balance_quick(pCur);
- }
-#endif
-
- if( SQLITE_OK!=(rc = sqlite3PagerWrite(pPage->pDbPage)) ){
- goto balance_cleanup;
- }
-
- /*
- ** Find the cell in the parent page whose left child points back
- ** to pPage. The "idx" variable is the index of that cell. If pPage
- ** is the rightmost child of pParent then set idx to pParent->nCell
- */
- idx = pCur->aiIdx[pCur->iPage-1];
- assertParentIndex(pParent, idx, pPage->pgno);
-
- /*
- ** Find sibling pages to pPage and the cells in pParent that divide
- ** the siblings. An attempt is made to find NN siblings on either
- ** side of pPage. More siblings are taken from one side, however, if
- ** pPage there are fewer than NN siblings on the other side. If pParent
+ /* Find the sibling pages to balance. Also locate the cells in pParent
+ ** that divide the siblings. An attempt is made to find NN siblings on
+ ** either side of pPage. More siblings are taken from one side, however,
+ ** if there are fewer than NN siblings on the other side. If pParent
** has NB or fewer children then all children of pParent are taken.
*/
- nxDiv = idx - NN;
+ nxDiv = iParentIdx - NN;
if( nxDiv + NB > pParent->nCell ){
nxDiv = pParent->nCell - NB + 1;
}
if( nxDiv<0 ){
nxDiv = 0;
}
- nDiv = 0;
for(i=0, k=nxDiv; i<NB; i++, k++){
if( k<pParent->nCell ){
apDiv[i] = findCell(pParent, k);
- nDiv++;
assert( !pParent->leaf );
pgnoOld[i] = get4byte(apDiv[i]);
}else if( k==pParent->nCell ){
@@ -41943,7 +42198,6 @@ static int balance_nonroot(BtCursor *pCur){
}
rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i]);
if( rc ) goto balance_cleanup;
- /* apOld[i]->idxParent = k; */
apCopy[i] = 0;
assert( i==nOld );
nOld++;
@@ -41964,7 +42218,7 @@ static int balance_nonroot(BtCursor *pCur){
+ pBt->pageSize /* aSpace1 */
+ (ISAUTOVACUUM ? nMaxCells : 0); /* aFrom */
apCell = sqlite3ScratchMalloc( szScratch );
- if( apCell==0 ){
+ if( apCell==0 || aOvflSpace==0 ){
rc = SQLITE_NOMEM;
goto balance_cleanup;
}
@@ -41980,11 +42234,6 @@ static int balance_nonroot(BtCursor *pCur){
if( ISAUTOVACUUM ){
aFrom = &aSpace1[pBt->pageSize];
}
- aSpace2 = sqlite3PageMalloc(pBt->pageSize);
- if( aSpace2==0 ){
- rc = SQLITE_NOMEM;
- goto balance_cleanup;
- }
/*
** Make copies of the content of pPage and its siblings into aOld[].
@@ -42016,8 +42265,8 @@ static int balance_nonroot(BtCursor *pCur){
** leafData: 1 if pPage holds key+data and pParent holds only keys.
*/
nCell = 0;
- leafCorrection = pPage->leaf*4;
- leafData = pPage->hasData;
+ leafCorrection = apOld[0]->leaf*4;
+ leafData = apOld[0]->hasData;
for(i=0; i<nOld; i++){
MemPage *pOld = apCopy[i];
int limit = pOld->nCell+pOld->nOverflow;
@@ -42106,6 +42355,7 @@ static int balance_nonroot(BtCursor *pCur){
if( leafData ){ i--; }
subtotal = 0;
k++;
+ if( k>NB+1 ){ rc = SQLITE_CORRUPT; goto balance_cleanup; }
}
}
szNew[k] = subtotal;
@@ -42143,7 +42393,7 @@ static int balance_nonroot(BtCursor *pCur){
szNew[i-1] = szLeft;
}
- /* Either we found one or more cells (cntnew[0])>0) or we are the
+ /* Either we found one or more cells (cntnew[0])>0) or pPage is
** a virtual root page. A virtual root page is when the real root
** page is page 1 and we are the only child of that page.
*/
@@ -42152,8 +42402,11 @@ static int balance_nonroot(BtCursor *pCur){
/*
** Allocate k new pages. Reuse old pages where possible.
*/
- assert( pPage->pgno>1 );
- pageFlags = pPage->aData[0];
+ if( apOld[0]->pgno<=1 ){
+ rc = SQLITE_CORRUPT;
+ goto balance_cleanup;
+ }
+ pageFlags = apOld[0]->aData[0];
for(i=0; i<k; i++){
MemPage *pNew;
if( i<nOld ){
@@ -42274,7 +42527,7 @@ static int balance_nonroot(BtCursor *pCur){
assert( j<nMaxCells );
pCell = apCell[j];
sz = szCell[j] + leafCorrection;
- pTemp = &aSpace2[iSpace2];
+ pTemp = &aOvflSpace[iOvflSpace];
if( !pNew->leaf ){
memcpy(&pNew->aData[8], pCell, 4);
if( ISAUTOVACUUM
@@ -42295,10 +42548,7 @@ static int balance_nonroot(BtCursor *pCur){
j--;
sqlite3BtreeParseCellPtr(pNew, apCell[j], &info);
pCell = pTemp;
- rc = fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz);
- if( rc!=SQLITE_OK ){
- goto balance_cleanup;
- }
+ sz = 4 + putVarint(&pCell[4], info.nKey);
pTemp = 0;
}else{
pCell -= 4;
@@ -42318,9 +42568,9 @@ static int balance_nonroot(BtCursor *pCur){
sz = cellSizePtr(pParent, pCell);
}
}
- iSpace2 += sz;
+ iOvflSpace += sz;
assert( sz<=pBt->pageSize/4 );
- assert( iSpace2<=pBt->pageSize );
+ assert( iOvflSpace<=pBt->pageSize );
rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
if( rc!=SQLITE_OK ) goto balance_cleanup;
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
@@ -42381,16 +42631,11 @@ static int balance_nonroot(BtCursor *pCur){
apCell = 0;
TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n",
pPage->pgno, nOld, nNew, nCell));
- pPage->nOverflow = 0;
- releasePage(pPage);
- pCur->iPage--;
- rc = balance(pCur, 0);
/*
** Cleanup before returning.
*/
balance_cleanup:
- sqlite3PageFree(aSpace2);
sqlite3ScratchFree(apCell);
for(i=0; i<nOld; i++){
releasePage(apOld[i]);
@@ -42398,216 +42643,313 @@ balance_cleanup:
for(i=0; i<nNew; i++){
releasePage(apNew[i]);
}
- pCur->apPage[pCur->iPage]->nOverflow = 0;
return rc;
}
/*
-** This routine is called for the root page of a btree when the root
-** page contains no cells. This is an opportunity to make the tree
-** shallower by one level.
+** This function is used to copy the contents of the b-tree node stored
+** on page pFrom to page pTo. If page pFrom was not a leaf page, then
+** the pointer-map entries for each child page are updated so that the
+** parent page stored in the pointer map is page pTo. If pFrom contained
+** any cells with overflow page pointers, then the corresponding pointer
+** map entries are also updated so that the parent page is page pTo.
+**
+** If pFrom is currently carrying any overflow cells (entries in the
+** MemPage.aOvfl[] array), they are not copied to pTo.
+**
+** Before returning, page pTo is reinitialized using sqlite3BtreeInitPage().
+**
+** The performance of this function is not critical. It is only used by
+** the balance_shallower() and balance_deeper() procedures, neither of
+** which are called often under normal circumstances.
*/
-static int balance_shallower(BtCursor *pCur){
- MemPage *pPage; /* Root page of B-Tree */
- MemPage *pChild; /* The only child page of pPage */
- Pgno pgnoChild; /* Page number for pChild */
- int rc = SQLITE_OK; /* Return code from subprocedures */
- BtShared *pBt; /* The main BTree structure */
- int mxCellPerPage; /* Maximum number of cells per page */
- u8 **apCell; /* All cells from pages being balanced */
- u16 *szCell; /* Local size of all cells */
+static int copyNodeContent(MemPage *pFrom, MemPage *pTo){
+ BtShared * const pBt = pFrom->pBt;
+ u8 * const aFrom = pFrom->aData;
+ u8 * const aTo = pTo->aData;
+ int const iFromHdr = pFrom->hdrOffset;
+ int const iToHdr = ((pTo->pgno==1) ? 100 : 0);
+ int rc = SQLITE_OK;
+ int iData;
+
+ assert( pFrom->isInit );
+ assert( pFrom->nFree>=iToHdr );
+ assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize );
+
+ /* Copy the b-tree node content from page pFrom to page pTo. */
+ iData = get2byte(&aFrom[iFromHdr+5]);
+ memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData);
+ memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell);
+
+ /* Reinitialize page pTo so that the contents of the MemPage structure
+ ** match the new data. The initialization of pTo "cannot" fail, as the
+ ** data copied from pFrom is known to be valid. */
+ pTo->isInit = 0;
+ TESTONLY(rc = ) sqlite3BtreeInitPage(pTo);
+ assert( rc==SQLITE_OK );
- assert( pCur->iPage==0 );
- pPage = pCur->apPage[0];
+ /* If this is an auto-vacuum database, update the pointer-map entries
+ ** for any b-tree or overflow pages that pTo now contains the pointers to. */
+ if( ISAUTOVACUUM ){
+ rc = setChildPtrmaps(pTo);
+ }
+ return rc;
+}
- assert( pPage->nCell==0 );
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- pBt = pPage->pBt;
- mxCellPerPage = MX_CELL(pBt);
- apCell = sqlite3Malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) );
- if( apCell==0 ) return SQLITE_NOMEM;
- szCell = (u16*)&apCell[mxCellPerPage];
- if( pPage->leaf ){
- /* The table is completely empty */
- TRACE(("BALANCE: empty table %d\n", pPage->pgno));
- }else{
- /* The root page is empty but has one child. Transfer the
- ** information from that one child into the root page if it
- ** will fit. This reduces the depth of the tree by one.
- **
- ** If the root page is page 1, it has less space available than
- ** its child (due to the 100 byte header that occurs at the beginning
- ** of the database fle), so it might not be able to hold all of the
- ** information currently contained in the child. If this is the
- ** case, then do not do the transfer. Leave page 1 empty except
- ** for the right-pointer to the child page. The child page becomes
- ** the virtual root of the tree.
- */
- VVA_ONLY( pCur->pagesShuffled = 1 );
- pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- assert( pgnoChild>0 );
- assert( pgnoChild<=pagerPagecount(pPage->pBt) );
- rc = sqlite3BtreeGetPage(pPage->pBt, pgnoChild, &pChild, 0);
- if( rc ) goto end_shallow_balance;
- if( pPage->pgno==1 ){
- rc = sqlite3BtreeInitPage(pChild);
- if( rc ) goto end_shallow_balance;
- assert( pChild->nOverflow==0 );
- if( pChild->nFree>=100 ){
- /* The child information will fit on the root page, so do the
- ** copy */
- int i;
- zeroPage(pPage, pChild->aData[0]);
- for(i=0; i<pChild->nCell; i++){
- apCell[i] = findCell(pChild,i);
- szCell[i] = cellSizePtr(pChild, apCell[i]);
- }
- assemblePage(pPage, pChild->nCell, apCell, szCell);
- /* Copy the right-pointer of the child to the parent. */
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- put4byte(&pPage->aData[pPage->hdrOffset+8],
- get4byte(&pChild->aData[pChild->hdrOffset+8]));
+/*
+** This routine is called on the root page of a btree when the root
+** page contains no cells. This is an opportunity to make the tree
+** shallower by one level.
+*/
+static int balance_shallower(MemPage *pRoot){
+ /* The root page is empty but has one child. Transfer the
+ ** information from that one child into the root page if it
+ ** will fit. This reduces the depth of the tree by one.
+ **
+ ** If the root page is page 1, it has less space available than
+ ** its child (due to the 100 byte header that occurs at the beginning
+ ** of the database fle), so it might not be able to hold all of the
+ ** information currently contained in the child. If this is the
+ ** case, then do not do the transfer. Leave page 1 empty except
+ ** for the right-pointer to the child page. The child page becomes
+ ** the virtual root of the tree.
+ */
+ int rc = SQLITE_OK; /* Return code */
+ int const hdr = pRoot->hdrOffset; /* Offset of root page header */
+ MemPage *pChild; /* Only child of pRoot */
+ Pgno const pgnoChild = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
+
+ assert( pRoot->nCell==0 );
+ assert( sqlite3_mutex_held(pRoot->pBt->mutex) );
+ assert( !pRoot->leaf );
+ assert( pgnoChild>0 );
+ assert( pgnoChild<=pagerPagecount(pRoot->pBt) );
+ assert( hdr==0 || pRoot->pgno==1 );
+
+ rc = sqlite3BtreeGetPage(pRoot->pBt, pgnoChild, &pChild, 0);
+ if( rc==SQLITE_OK ){
+ if( pChild->nFree>=hdr ){
+ if( hdr ){
+ rc = defragmentPage(pChild);
+ }
+ if( rc==SQLITE_OK ){
+ rc = copyNodeContent(pChild, pRoot);
+ }
+ if( rc==SQLITE_OK ){
rc = freePage(pChild);
- TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno));
- }else{
- /* The child has more information that will fit on the root.
- ** The tree is already balanced. Do nothing. */
- TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno));
}
}else{
- memcpy(pPage->aData, pChild->aData, pPage->pBt->usableSize);
- pPage->isInit = 0;
- rc = sqlite3BtreeInitPage(pPage);
- assert( rc==SQLITE_OK );
- freePage(pChild);
- TRACE(("BALANCE: transfer child %d into root %d\n",
- pChild->pgno, pPage->pgno));
+ /* The child has more information that will fit on the root.
+ ** The tree is already balanced. Do nothing. */
+ TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno));
}
- assert( pPage->nOverflow==0 );
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( ISAUTOVACUUM && rc==SQLITE_OK ){
- rc = setChildPtrmaps(pPage);
- }
-#endif
releasePage(pChild);
}
-end_shallow_balance:
- sqlite3_free(apCell);
+
return rc;
}
/*
-** The root page is overfull
+** This function is called when the root page of a b-tree structure is
+** overfull (has one or more overflow pages).
+**
+** A new child page is allocated and the contents of the current root
+** page, including overflow cells, are copied into the child. The root
+** page is then overwritten to make it an empty page with the right-child
+** pointer pointing to the new page.
+**
+** Before returning, all pointer-map entries corresponding to pages
+** that the new child-page now contains pointers to are updated. The
+** entry corresponding to the new right-child pointer of the root
+** page is also updated.
**
-** When this happens, Create a new child page and copy the
-** contents of the root into the child. Then make the root
-** page an empty page with rightChild pointing to the new
-** child. Finally, call balance_internal() on the new child
-** to cause it to split.
+** If successful, *ppChild is set to contain a reference to the child
+** page and SQLITE_OK is returned. In this case the caller is required
+** to call releasePage() on *ppChild exactly once. If an error occurs,
+** an error code is returned and *ppChild is set to 0.
*/
-static int balance_deeper(BtCursor *pCur){
- int rc; /* Return value from subprocedures */
- MemPage *pPage; /* Pointer to the root page */
- MemPage *pChild; /* Pointer to a new child page */
- Pgno pgnoChild; /* Page number of the new child page */
- BtShared *pBt; /* The BTree */
- int usableSize; /* Total usable size of a page */
- u8 *data; /* Content of the parent page */
- u8 *cdata; /* Content of the child page */
- int hdr; /* Offset to page header in parent */
- int cbrk; /* Offset to content of first cell in parent */
+static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
+ int rc; /* Return value from subprocedures */
+ MemPage *pChild = 0; /* Pointer to a new child page */
+ Pgno pgnoChild; /* Page number of the new child page */
+ BtShared *pBt = pRoot->pBt; /* The BTree */
- assert( pCur->iPage==0 );
- assert( pCur->apPage[0]->nOverflow>0 );
-
- VVA_ONLY( pCur->pagesShuffled = 1 );
- pPage = pCur->apPage[0];
- pBt = pPage->pBt;
+ assert( pRoot->nOverflow>0 );
assert( sqlite3_mutex_held(pBt->mutex) );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- rc = allocateBtreePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0);
- if( rc ) return rc;
- assert( sqlite3PagerIswriteable(pChild->pDbPage) );
- usableSize = pBt->usableSize;
- data = pPage->aData;
- hdr = pPage->hdrOffset;
- cbrk = get2byte(&data[hdr+5]);
- cdata = pChild->aData;
- memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
- memcpy(&cdata[cbrk], &data[cbrk], usableSize-cbrk);
-
- assert( pChild->isInit==0 );
- rc = sqlite3BtreeInitPage(pChild);
- if( rc==SQLITE_OK ){
- int nCopy = pPage->nOverflow*sizeof(pPage->aOvfl[0]);
- memcpy(pChild->aOvfl, pPage->aOvfl, nCopy);
- pChild->nOverflow = pPage->nOverflow;
- if( pChild->nOverflow ){
- pChild->nFree = 0;
- }
- assert( pChild->nCell==pPage->nCell );
- assert( sqlite3PagerIswriteable(pPage->pDbPage) );
- zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF);
- put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild);
- TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno));
- if( ISAUTOVACUUM ){
- rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno);
-#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK ){
- rc = setChildPtrmaps(pChild);
- }
- if( rc ){
- pChild->nOverflow = 0;
- }
-#endif
- }
- }
- if( rc==SQLITE_OK ){
- pCur->iPage++;
- pCur->apPage[1] = pChild;
- pCur->aiIdx[0] = 0;
- rc = balance_nonroot(pCur);
- }else{
+ /* Make pRoot, the root page of the b-tree, writable. Allocate a new
+ ** page that will become the new right-child of pPage. Copy the contents
+ ** of the node stored on pRoot into the new child page.
+ */
+ if( SQLITE_OK!=(rc = sqlite3PagerWrite(pRoot->pDbPage))
+ || SQLITE_OK!=(rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0))
+ || SQLITE_OK!=(rc = copyNodeContent(pRoot, pChild))
+ || (ISAUTOVACUUM &&
+ SQLITE_OK!=(rc = ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno)))
+ ){
+ *ppChild = 0;
releasePage(pChild);
+ return rc;
}
+ assert( sqlite3PagerIswriteable(pChild->pDbPage) );
+ assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
+ assert( pChild->nCell==pRoot->nCell );
- return rc;
+ TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
+
+ /* Copy the overflow cells from pRoot to pChild */
+ memcpy(pChild->aOvfl, pRoot->aOvfl, pRoot->nOverflow*sizeof(pRoot->aOvfl[0]));
+ pChild->nOverflow = pRoot->nOverflow;
+
+ /* Zero the contents of pRoot. Then install pChild as the right-child. */
+ zeroPage(pRoot, pChild->aData[0] & ~PTF_LEAF);
+ put4byte(&pRoot->aData[pRoot->hdrOffset+8], pgnoChild);
+
+ *ppChild = pChild;
+ return SQLITE_OK;
}
/*
** The page that pCur currently points to has just been modified in
** some way. This function figures out if this modification means the
** tree needs to be balanced, and if so calls the appropriate balancing
-** routine.
-**
-** Parameter isInsert is true if a new cell was just inserted into the
-** page, or false otherwise.
+** routine. Balancing routines are:
+**
+** balance_quick()
+** balance_shallower()
+** balance_deeper()
+** balance_nonroot()
+**
+** If built with SQLITE_DEBUG, pCur->pagesShuffled is set to true if
+** balance_shallower(), balance_deeper() or balance_nonroot() is called.
+** If none of these functions are invoked, pCur->pagesShuffled is left
+** unmodified.
*/
-static int balance(BtCursor *pCur, int isInsert){
+static int balance(BtCursor *pCur){
int rc = SQLITE_OK;
- MemPage *pPage = pCur->apPage[pCur->iPage];
+ const int nMin = pCur->pBt->usableSize * 2 / 3;
+ u8 aBalanceQuickSpace[13];
+ u8 *pFree = 0;
- assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- if( pCur->iPage==0 ){
- rc = sqlite3PagerWrite(pPage->pDbPage);
- if( rc==SQLITE_OK && pPage->nOverflow>0 ){
- rc = balance_deeper(pCur);
- assert( pCur->apPage[0]==pPage );
- assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
- }
- if( rc==SQLITE_OK && pPage->nCell==0 ){
- rc = balance_shallower(pCur);
- assert( pCur->apPage[0]==pPage );
- assert( pPage->nOverflow==0 || rc!=SQLITE_OK );
- }
- }else{
- if( pPage->nOverflow>0 ||
- (!isInsert && pPage->nFree>pPage->pBt->usableSize*2/3) ){
- rc = balance_nonroot(pCur);
+ TESTONLY( int balance_quick_called = 0 );
+ TESTONLY( int balance_deeper_called = 0 );
+
+ do {
+ int iPage = pCur->iPage;
+ MemPage *pPage = pCur->apPage[iPage];
+
+ if( iPage==0 ){
+ if( pPage->nOverflow ){
+ /* The root page of the b-tree is overfull. In this case call the
+ ** balance_deeper() function to create a new child for the root-page
+ ** and copy the current contents of the root-page to it. The
+ ** next iteration of the do-loop will balance the child page.
+ */
+ assert( (balance_deeper_called++)==0 );
+ rc = balance_deeper(pPage, &pCur->apPage[1]);
+ if( rc==SQLITE_OK ){
+ pCur->iPage = 1;
+ pCur->aiIdx[0] = 0;
+ pCur->aiIdx[1] = 0;
+ assert( pCur->apPage[1]->nOverflow );
+ }
+ VVA_ONLY( pCur->pagesShuffled = 1 );
+ }else{
+ /* The root page of the b-tree is now empty. If the root-page is not
+ ** also a leaf page, it will have a single child page. Call
+ ** balance_shallower to attempt to copy the contents of the single
+ ** child-page into the root page (this may not be possible if the
+ ** root page is page 1).
+ **
+ ** Whether or not this is possible , the tree is now balanced.
+ ** Therefore is no next iteration of the do-loop.
+ */
+ if( pPage->nCell==0 && !pPage->leaf ){
+ rc = balance_shallower(pPage);
+ VVA_ONLY( pCur->pagesShuffled = 1 );
+ }
+ break;
+ }
+ }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
+ break;
+ }else{
+ MemPage * const pParent = pCur->apPage[iPage-1];
+ int const iIdx = pCur->aiIdx[iPage-1];
+
+ rc = sqlite3PagerWrite(pParent->pDbPage);
+ if( rc==SQLITE_OK ){
+#ifndef SQLITE_OMIT_QUICKBALANCE
+ if( pPage->hasData
+ && pPage->nOverflow==1
+ && pPage->aOvfl[0].idx==pPage->nCell
+ && pParent->pgno!=1
+ && pParent->nCell==iIdx
+ ){
+ /* Call balance_quick() to create a new sibling of pPage on which
+ ** to store the overflow cell. balance_quick() inserts a new cell
+ ** into pParent, which may cause pParent overflow. If this
+ ** happens, the next interation of the do-loop will balance pParent
+ ** use either balance_nonroot() or balance_deeper(). Until this
+ ** happens, the overflow cell is stored in the aBalanceQuickSpace[]
+ ** buffer.
+ **
+ ** The purpose of the following assert() is to check that only a
+ ** single call to balance_quick() is made for each call to this
+ ** function. If this were not verified, a subtle bug involving reuse
+ ** of the aBalanceQuickSpace[] might sneak in.
+ */
+ assert( (balance_quick_called++)==0 );
+ rc = balance_quick(pParent, pPage, aBalanceQuickSpace);
+ }else
+#endif
+ {
+ /* In this case, call balance_nonroot() to redistribute cells
+ ** between pPage and up to 2 of its sibling pages. This involves
+ ** modifying the contents of pParent, which may cause pParent to
+ ** become overfull or underfull. The next iteration of the do-loop
+ ** will balance the parent page to correct this.
+ **
+ ** If the parent page becomes overfull, the overflow cell or cells
+ ** are stored in the pSpace buffer allocated immediately below.
+ ** A subsequent iteration of the do-loop will deal with this by
+ ** calling balance_nonroot() (balance_deeper() may be called first,
+ ** but it doesn't deal with overflow cells - just moves them to a
+ ** different page). Once this subsequent call to balance_nonroot()
+ ** has completed, it is safe to release the pSpace buffer used by
+ ** the previous call, as the overflow cell data will have been
+ ** copied either into the body of a database page or into the new
+ ** pSpace buffer passed to the latter call to balance_nonroot().
+ */
+ u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
+ rc = balance_nonroot(pParent, iIdx, pSpace);
+ if( pFree ){
+ /* If pFree is not NULL, it points to the pSpace buffer used
+ ** by a previous call to balance_nonroot(). Its contents are
+ ** now stored either on real database pages or within the
+ ** new pSpace buffer, so it may be safely freed here. */
+ sqlite3PageFree(pFree);
+ }
+
+ /* The pSpace buffer will be freed after the next call to
+ ** balance_nonroot(), or just before this function returns, whichever
+ ** comes first. */
+ pFree = pSpace;
+ VVA_ONLY( pCur->pagesShuffled = 1 );
+ }
+ }
+
+ pPage->nOverflow = 0;
+
+ /* The next iteration of the do-loop balances the parent page. */
+ releasePage(pPage);
+ pCur->iPage--;
}
+ }while( rc==SQLITE_OK );
+
+ if( pFree ){
+ sqlite3PageFree(pFree);
}
return rc;
}
@@ -42754,6 +43096,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
pPage = pCur->apPage[pCur->iPage];
assert( pPage->intKey || nKey>=0 );
+ assert( pPage->intKey || nKey>=0 );
assert( pPage->leaf || !pPage->intKey );
TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
pCur->pgnoRoot, nKey, nData, pPage->pgno,
@@ -42788,47 +43131,42 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
}else if( loc<0 && pPage->nCell>0 ){
assert( pPage->leaf );
idx = ++pCur->aiIdx[pCur->iPage];
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
}else{
assert( pPage->leaf );
}
rc = insertCell(pPage, idx, newCell, szNew, 0, 0);
assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );
- /* If no error has occured, call balance() to deal with any overflow and
- ** move the cursor to point at the root of the table (since balance may
- ** have rearranged the table in such a way as to invalidate BtCursor.apPage[]
- ** or BtCursor.aiIdx[]).
+ /* If no error has occured and pPage has an overflow cell, call balance()
+ ** to redistribute the cells within the tree. Since balance() may move
+ ** the cursor, zero the BtCursor.info.nSize and BtCursor.validNKey
+ ** variables.
**
- ** Except, if all of the following are true, do nothing:
+ ** Previous versions of SQLite called moveToRoot() to move the cursor
+ ** back to the root page as balance() used to invalidate the contents
+ ** of BtCursor.apPage[] and BtCursor.aiIdx[]. This is no longer necessary,
+ ** as balance() always leaves the cursor pointing to a valid entry.
**
- ** * Inserting the new cell did not cause overflow,
- **
- ** * Before inserting the new cell the cursor was pointing at the
- ** largest key in an intkey B-Tree, and
- **
- ** * The key value associated with the new cell is now the largest
- ** in the B-Tree.
- **
- ** In this case the cursor can be safely left pointing at the (new)
- ** largest key value in the B-Tree. Doing so speeds up inserting a set
- ** of entries with increasing integer key values via a single cursor
- ** (comes up with "INSERT INTO ... SELECT ..." statements), as
- ** the next insert operation is not required to seek the cursor.
- */
- if( rc==SQLITE_OK
- && (pPage->nOverflow || !pCur->atLast || loc>=0 || !pCur->apPage[0]->intKey)
- ){
- rc = balance(pCur, 1);
- if( rc==SQLITE_OK ){
- moveToRoot(pCur);
- }
+ ** There is a subtle but important optimization here too. When inserting
+ ** multiple records into an intkey b-tree using a single cursor (as can
+ ** happen while processing an "INSERT INTO ... SELECT" statement), it
+ ** is advantageous to leave the cursor pointing to the last entry in
+ ** the b-tree if possible. If the cursor is left pointing to the last
+ ** entry in the table, and the next row inserted has an integer key
+ ** larger than the largest existing key, it is possible to insert the
+ ** row without seeking the cursor. This can be a big performance boost.
+ */
+ pCur->info.nSize = 0;
+ pCur->validNKey = 0;
+ if( rc==SQLITE_OK && pPage->nOverflow ){
+ pCur->atLast = 0;
+ rc = balance(pCur);
+
+ /* Must make sure nOverflow is reset to zero even if the balance()
+ ** fails. Internal data structure corruption will result otherwise. */
+ pCur->apPage[pCur->iPage]->nOverflow = 0;
}
-
- /* Must make sure nOverflow is reset to zero even if the balance()
- ** fails. Internal data structure corruption will result otherwise. */
- pCur->apPage[pCur->iPage]->nOverflow = 0;
+ assert( pCur->apPage[pCur->iPage]->nOverflow==0 );
end_insert:
return rc;
@@ -42975,7 +43313,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
put4byte(findOverflowCell(pPage, idx), pgnoChild);
VVA_ONLY( pCur->pagesShuffled = 0 );
- rc = balance(pCur, 0);
+ rc = balance(pCur);
}
if( rc==SQLITE_OK && leafCursorInvalid ){
@@ -43017,7 +43355,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
){
dropCell(pLeafPage, 0, szNext);
VVA_ONLY( leafCur.pagesShuffled = 0 );
- rc = balance(&leafCur, 0);
+ rc = balance(&leafCur);
assert( leafCursorInvalid || !leafCur.pagesShuffled
|| !pCur->pagesShuffled );
}
@@ -43028,7 +43366,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
pCur->pgnoRoot, pPage->pgno));
rc = dropCell(pPage, idx, cellSizePtr(pPage, pCell));
if( rc==SQLITE_OK ){
- rc = balance(pCur, 0);
+ rc = balance(pCur);
}
}
if( rc==SQLITE_OK ){
@@ -43079,7 +43417,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){
** root page of the new table should go. meta[3] is the largest root-page
** created so far, so the new root-page is (meta[3]+1).
*/
- rc = sqlite3BtreeGetMeta(p, 4, &pgnoRoot);
+ rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot);
if( rc!=SQLITE_OK ){
return rc;
}
@@ -43312,7 +43650,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){
#else
if( pBt->autoVacuum ){
Pgno maxRootPgno;
- rc = sqlite3BtreeGetMeta(p, 4, &maxRootPgno);
+ rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno);
if( rc!=SQLITE_OK ){
releasePage(pPage);
return rc;
@@ -43453,7 +43791,7 @@ SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
** access an autovacuumed database, then make the database readonly.
*/
#ifdef SQLITE_OMIT_AUTOVACUUM
- if( idx==4 && *pMeta>0 ) pBt->readOnly = 1;
+ if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ) pBt->readOnly = 1;
#endif
/* If there is currently an open transaction, grab a read-lock
@@ -43485,7 +43823,7 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
if( rc==SQLITE_OK ){
put4byte(&pP1[36 + idx*4], iMeta);
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( idx==7 ){
+ if( idx==BTREE_INCR_VACUUM ){
assert( pBt->autoVacuum || iMeta==0 );
assert( iMeta==0 || iMeta==1 );
pBt->incrVacuum = (u8)iMeta;
@@ -44322,15 +44660,24 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
int i = sqlite3FindDbName(pDb, zDb);
if( i==1 ){
- Parse sParse;
- memset(&sParse, 0, sizeof(sParse));
- sParse.db = pDb;
- if( sqlite3OpenTempDatabase(&sParse) ){
- sqlite3ErrorClear(&sParse);
- sqlite3Error(pErrorDb, sParse.rc, "%s", sParse.zErrMsg);
+ Parse *pParse;
+ int rc = 0;
+ pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
+ if( pParse==0 ){
+ sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
+ rc = SQLITE_NOMEM;
+ }else{
+ pParse->db = pDb;
+ if( sqlite3OpenTempDatabase(pParse) ){
+ sqlite3ErrorClear(pParse);
+ sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
+ rc = SQLITE_ERROR;
+ }
+ sqlite3StackFree(pErrorDb, pParse);
+ }
+ if( rc ){
return 0;
}
- assert( sParse.zErrMsg==0 );
}
if( i<0 ){
@@ -44415,7 +44762,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
*/
static int isFatalError(int rc){
- return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED);
+ return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED));
}
/*
@@ -44540,7 +44887,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2))
){
p->bDestLocked = 1;
- rc = sqlite3BtreeGetMeta(p->pDest, 1, &p->iDestSchema);
+ rc = sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema);
}
/* If there is no open read-transaction on the source database, open
@@ -44700,6 +45047,7 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
int rc; /* Value to return */
/* Enter the mutexes */
+ if( p==0 ) return SQLITE_OK;
sqlite3_mutex_enter(p->pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
mutex = p->pSrcDb->mutex;
@@ -45699,13 +46047,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
int key, /* If true, retrieve from the btree key, not data. */
Mem *pMem /* OUT: Return data in this Mem structure. */
){
- char *zData; /* Data from the btree layer */
- int available = 0; /* Number of bytes available on the local btree page */
- sqlite3 *db; /* Database connection */
- int rc = SQLITE_OK;
+ char *zData; /* Data from the btree layer */
+ int available = 0; /* Number of bytes available on the local btree page */
+ int rc = SQLITE_OK; /* Return code */
- db = sqlite3BtreeCursorDb(pCur);
- assert( sqlite3_mutex_held(db->mutex) );
+ /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert()
+ ** that both the BtShared and database handle mutexes are held. */
assert( (pMem->flags & MEM_RowSet)==0 );
if( key ){
zData = (char *)sqlite3BtreeKeyFetch(pCur, &available);
@@ -45825,10 +46172,15 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
op = pExpr->op;
if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){
- zVal = sqlite3DbStrNDup(db, (char*)pExpr->token.z, pExpr->token.n);
pVal = sqlite3ValueNew(db);
- if( !zVal || !pVal ) goto no_mem;
- sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+ if( pVal==0 ) goto no_mem;
+ if( ExprHasProperty(pExpr, EP_IntValue) ){
+ sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue);
+ }else{
+ zVal = sqlite3DbStrDup(db, pExpr->u.zToken);
+ if( zVal==0 ) goto no_mem;
+ sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
+ }
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
}else{
@@ -45847,14 +46199,13 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr(
#ifndef SQLITE_OMIT_BLOB_LITERAL
else if( op==TK_BLOB ){
int nVal;
- assert( pExpr->token.n>=3 );
- assert( pExpr->token.z[0]=='x' || pExpr->token.z[0]=='X' );
- assert( pExpr->token.z[1]=='\'' );
- assert( pExpr->token.z[pExpr->token.n-1]=='\'' );
+ assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
+ assert( pExpr->u.zToken[1]=='\'' );
pVal = sqlite3ValueNew(db);
if( !pVal ) goto no_mem;
- nVal = pExpr->token.n - 3;
- zVal = (char*)pExpr->token.z + 2;
+ zVal = &pExpr->u.zToken[2];
+ nVal = sqlite3Strlen30(zVal)-1;
+ assert( zVal[nVal]=='\'' );
sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2,
0, SQLITE_DYNAMIC);
}
@@ -46529,12 +46880,25 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
#endif /* NDEBUG */
/*
-** Return the opcode for a given address.
+** Return the opcode for a given address. If the address is -1, then
+** return the most recently inserted opcode.
+**
+** If a memory allocation error has occurred prior to the calling of this
+** routine, then a pointer to a dummy VdbeOp will be returned. That opcode
+** is readable and writable, but it has no effect. The return of a dummy
+** opcode allows the call to continue functioning after a OOM fault without
+** having to check to see if the return from this routine is a valid pointer.
*/
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
+ static VdbeOp dummy;
assert( p->magic==VDBE_MAGIC_INIT );
+ if( addr<0 ) addr = p->nOp - 1;
assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
- return ((addr>=0 && addr<p->nOp)?(&p->aOp[addr]):0);
+ if( p->db->mallocFailed ){
+ return &dummy;
+ }else{
+ return &p->aOp[addr];
+ }
}
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \
@@ -48018,7 +48382,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
/*
** Return the length of the data corresponding to the supplied serial-type.
*/
-SQLITE_PRIVATE int sqlite3VdbeSerialTypeLen(u32 serial_type){
+SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
if( serial_type>=12 ){
return (serial_type-12)/2;
}else{
@@ -48098,14 +48462,14 @@ static u64 floatSwap(u64 in){
** of bytes in the zero-filled tail is included in the return value only
** if those bytes were zeroed in buf[].
*/
-SQLITE_PRIVATE int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
- int len;
+ u32 len;
/* Integer and Real */
if( serial_type<=7 && serial_type>0 ){
u64 v;
- int i;
+ u32 i;
if( serial_type==7 ){
assert( sizeof(v)==sizeof(pMem->r) );
memcpy(&v, &pMem->r, sizeof(v));
@@ -48114,7 +48478,7 @@ SQLITE_PRIVATE int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
v = pMem->u.i;
}
len = i = sqlite3VdbeSerialTypeLen(serial_type);
- assert( len<=nBuf );
+ assert( len<=(u32)nBuf );
while( i-- ){
buf[i] = (u8)(v&0xFF);
v >>= 8;
@@ -48125,14 +48489,15 @@ SQLITE_PRIVATE int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
/* String or blob */
if( serial_type>=12 ){
assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
- == sqlite3VdbeSerialTypeLen(serial_type) );
+ == (int)sqlite3VdbeSerialTypeLen(serial_type) );
assert( pMem->n<=nBuf );
len = pMem->n;
memcpy(buf, pMem->z, len);
if( pMem->flags & MEM_Zero ){
len += pMem->u.nZero;
- if( len>nBuf ){
- len = nBuf;
+ assert( nBuf>=0 );
+ if( len > (u32)nBuf ){
+ len = (u32)nBuf;
}
memset(&buf[pMem->n], 0, len-pMem->n);
}
@@ -48147,7 +48512,7 @@ SQLITE_PRIVATE int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read.
*/
-SQLITE_PRIVATE int sqlite3VdbeSerialGet(
+SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
const unsigned char *buf, /* Buffer to deserialize from */
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
@@ -48225,7 +48590,7 @@ SQLITE_PRIVATE int sqlite3VdbeSerialGet(
return 0;
}
default: {
- int len = (serial_type-12)/2;
+ u32 len = (serial_type-12)/2;
pMem->z = (char *)buf;
pMem->n = len;
pMem->xDel = 0;
@@ -49371,8 +49736,23 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
vals = sqlite3_data_count(pStmt);
pOut = &pVm->pResultSet[i];
}else{
- /* ((double)0) In case of SQLITE_OMIT_FLOATING_POINT... */
- static const Mem nullMem = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
+ /* If the value passed as the second argument is out of range, return
+ ** a pointer to the following static Mem object which contains the
+ ** value SQL NULL. Even though the Mem structure contains an element
+ ** of type i64, on certain architecture (x86) with certain compiler
+ ** switches (-Os), gcc may align this Mem object on a 4-byte boundary
+ ** instead of an 8-byte one. This all works fine, except that when
+ ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
+ ** that a Mem structure is located on an 8-byte boundary. To prevent
+ ** this assert() from failing, when building with SQLITE_DEBUG defined
+ ** using gcc, force nullMem to be 8-byte aligned using the magical
+ ** __attribute__((aligned(8))) macro. */
+ static const Mem nullMem
+#if defined(SQLITE_DEBUG) && defined(__GNUC__)
+ __attribute__((aligned(8)))
+#endif
+ = {{0}, (double)0, 0, "", 0, MEM_Null, SQLITE_NULL, 0, 0, 0 };
+
if( pVm && ALWAYS(pVm->db) ){
sqlite3_mutex_enter(pVm->db->mutex);
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
@@ -50609,9 +50989,434 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
int nProgressOps = 0; /* Opcodes executed since progress callback. */
#endif
-
- /* Temporary space into which to unpack a record. */
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
+ /********************************************************************
+ ** Automatically generated code
+ **
+ ** The following union is automatically generated by the
+ ** vdbe-compress.tcl script. The purpose of this union is to
+ ** reduce the amount of stack space required by this function.
+ ** See comments in the vdbe-compress.tcl script for details.
+ */
+ union vdbeExecUnion {
+ struct OP_Yield_stack_vars {
+ int pcDest;
+ } aa;
+ struct OP_Variable_stack_vars {
+ int p1; /* Variable to copy from */
+ int p2; /* Register to copy to */
+ int n; /* Number of values left to copy */
+ Mem *pVar; /* Value being transferred */
+ } ab;
+ struct OP_Move_stack_vars {
+ char *zMalloc; /* Holding variable for allocated memory */
+ int n; /* Number of registers left to copy */
+ int p1; /* Register to copy from */
+ int p2; /* Register to copy to */
+ } ac;
+ struct OP_ResultRow_stack_vars {
+ Mem *pMem;
+ int i;
+ } ad;
+ struct OP_Concat_stack_vars {
+ i64 nByte;
+ } ae;
+ struct OP_Remainder_stack_vars {
+ int flags; /* Combined MEM_* flags from both inputs */
+ i64 iA; /* Integer value of left operand */
+ i64 iB; /* Integer value of right operand */
+ double rA; /* Real value of left operand */
+ double rB; /* Real value of right operand */
+ } af;
+ struct OP_Function_stack_vars {
+ int i;
+ Mem *pArg;
+ sqlite3_context ctx;
+ sqlite3_value **apVal;
+ int n;
+ } ag;
+ struct OP_ShiftRight_stack_vars {
+ i64 a;
+ i64 b;
+ } ah;
+ struct OP_Ge_stack_vars {
+ int flags;
+ int res;
+ char affinity;
+ } ai;
+ struct OP_Compare_stack_vars {
+ int n;
+ int i;
+ int p1;
+ int p2;
+ const KeyInfo *pKeyInfo;
+ int idx;
+ CollSeq *pColl; /* Collating sequence to use on this term */
+ int bRev; /* True for DESCENDING sort order */
+ } aj;
+ struct OP_Or_stack_vars {
+ int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+ int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+ } ak;
+ struct OP_IfNot_stack_vars {
+ int c;
+ } al;
+ struct OP_IsNull_stack_vars {
+ int n;
+ } am;
+ struct OP_Column_stack_vars {
+ u32 payloadSize; /* Number of bytes in the record */
+ i64 payloadSize64; /* Number of bytes in the record */
+ int p1; /* P1 value of the opcode */
+ int p2; /* column number to retrieve */
+ VdbeCursor *pC; /* The VDBE cursor */
+ char *zRec; /* Pointer to complete record-data */
+ BtCursor *pCrsr; /* The BTree cursor */
+ u32 *aType; /* aType[i] holds the numeric type of the i-th column */
+ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
+ int nField; /* number of fields in the record */
+ int len; /* The length of the serialized data for the column */
+ int i; /* Loop counter */
+ char *zData; /* Part of the record being decoded */
+ Mem *pDest; /* Where to write the extracted value */
+ Mem sMem; /* For storing the record being decoded */
+ u8 *zIdx; /* Index into header */
+ u8 *zEndHdr; /* Pointer to first byte after the header */
+ u32 offset; /* Offset into the data */
+ u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */
+ int szHdr; /* Size of the header size field at start of record */
+ int avail; /* Number of bytes of available data */
+ } an;
+ struct OP_Affinity_stack_vars {
+ char *zAffinity; /* The affinity to be applied */
+ Mem *pData0; /* First register to which to apply affinity */
+ Mem *pLast; /* Last register to which to apply affinity */
+ Mem *pRec; /* Current register */
+ } ao;
+ struct OP_MakeRecord_stack_vars {
+ u8 *zNewRecord; /* A buffer to hold the data for the new record */
+ Mem *pRec; /* The new record */
+ u64 nData; /* Number of bytes of data space */
+ int nHdr; /* Number of bytes of header space */
+ i64 nByte; /* Data space required for this record */
+ int nZero; /* Number of zero bytes at the end of the record */
+ int nVarint; /* Number of bytes in a varint */
+ u32 serial_type; /* Type field */
+ Mem *pData0; /* First field to be combined into the record */
+ Mem *pLast; /* Last field of the record */
+ int nField; /* Number of fields in the record */
+ char *zAffinity; /* The affinity string for the record */
+ int file_format; /* File format to use for encoding */
+ int i; /* Space used in zNewRecord[] */
+ int len; /* Length of a field */
+ } ap;
+ struct OP_Count_stack_vars {
+ i64 nEntry;
+ BtCursor *pCrsr;
+ } aq;
+ struct OP_Statement_stack_vars {
+ int i;
+ Btree *pBt;
+ } ar;
+ struct OP_Savepoint_stack_vars {
+ int p1; /* Value of P1 operand */
+ char *zName; /* Name of savepoint */
+ int nName;
+ Savepoint *pNew;
+ Savepoint *pSavepoint;
+ Savepoint *pTmp;
+ int iSavepoint;
+ int ii;
+ } as;
+ struct OP_AutoCommit_stack_vars {
+ int desiredAutoCommit;
+ int iRollback;
+ int turnOnAC;
+ } at;
+ struct OP_Transaction_stack_vars {
+ int i;
+ Btree *pBt;
+ } au;
+ struct OP_ReadCookie_stack_vars {
+ int iMeta;
+ int iDb;
+ int iCookie;
+ } av;
+ struct OP_SetCookie_stack_vars {
+ Db *pDb;
+ } aw;
+ struct OP_VerifyCookie_stack_vars {
+ int iMeta;
+ Btree *pBt;
+ } ax;
+ struct OP_OpenWrite_stack_vars {
+ int nField;
+ KeyInfo *pKeyInfo;
+ int i;
+ int p2;
+ int iDb;
+ int wrFlag;
+ Btree *pX;
+ VdbeCursor *pCur;
+ Db *pDb;
+ int flags;
+ } ay;
+ struct OP_OpenEphemeral_stack_vars {
+ int i;
+ VdbeCursor *pCx;
+ } az;
+ struct OP_OpenPseudo_stack_vars {
+ int i;
+ VdbeCursor *pCx;
+ } ba;
+ struct OP_Close_stack_vars {
+ int i;
+ } bb;
+ struct OP_SeekGt_stack_vars {
+ int i;
+ int res;
+ int oc;
+ VdbeCursor *pC;
+ UnpackedRecord r;
+ int nField;
+ i64 iKey; /* The rowid we are to seek to */
+ } bc;
+ struct OP_Seek_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ } bd;
+ struct OP_Found_stack_vars {
+ int i;
+ int alreadyExists;
+ VdbeCursor *pC;
+ int res;
+ UnpackedRecord *pIdxKey;
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
+ } be;
+ struct OP_IsUnique_stack_vars {
+ u16 ii;
+ VdbeCursor *pCx;
+ BtCursor *pCrsr;
+ u16 nField;
+ Mem *aMem;
+ UnpackedRecord r; /* B-Tree index search key */
+ i64 R; /* Rowid stored in register P3 */
+ } bf;
+ struct OP_NotExists_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ u64 iKey;
+ } bg;
+ struct OP_NewRowid_stack_vars {
+ int i;
+ i64 v;
+ VdbeCursor *pC;
+ int res;
+ int rx;
+ int cnt;
+ i64 x;
+ Mem *pMem;
+ } bh;
+ struct OP_Insert_stack_vars {
+ Mem *pData;
+ Mem *pKey;
+ i64 iKey; /* The integer ROWID or key for the record to be inserted */
+ int i;
+ VdbeCursor *pC;
+ int nZero;
+ int seekResult;
+ const char *zDb;
+ const char *zTbl;
+ int op;
+ } bi;
+ struct OP_Delete_stack_vars {
+ int i;
+ i64 iKey;
+ VdbeCursor *pC;
+ } bj;
+ struct OP_RowData_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ u32 n;
+ i64 n64;
+ } bk;
+ struct OP_Rowid_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ i64 v;
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+ } bl;
+ struct OP_NullRow_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ } bm;
+ struct OP_Last_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ } bn;
+ struct OP_Rewind_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ } bo;
+ struct OP_Next_stack_vars {
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int res;
+ } bp;
+ struct OP_IdxInsert_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ int nKey;
+ const char *zKey;
+ } bq;
+ struct OP_IdxDelete_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ BtCursor *pCrsr;
+ } br;
+ struct OP_IdxRowid_stack_vars {
+ int i;
+ BtCursor *pCrsr;
+ VdbeCursor *pC;
+ i64 rowid;
+ } bs;
+ struct OP_IdxGE_stack_vars {
+ int i;
+ VdbeCursor *pC;
+ int res;
+ UnpackedRecord r;
+ } bt;
+ struct OP_Destroy_stack_vars {
+ int iMoved;
+ int iCnt;
+ Vdbe *pVdbe;
+ int iDb;
+ } bu;
+ struct OP_Clear_stack_vars {
+ int nChange;
+ } bv;
+ struct OP_CreateTable_stack_vars {
+ int pgno;
+ int flags;
+ Db *pDb;
+ } bw;
+ struct OP_ParseSchema_stack_vars {
+ int iDb;
+ const char *zMaster;
+ char *zSql;
+ InitData initData;
+ } bx;
+ struct OP_IntegrityCk_stack_vars {
+ int nRoot; /* Number of tables to check. (Number of root pages.) */
+ int *aRoot; /* Array of rootpage numbers for tables to be checked */
+ int j; /* Loop counter */
+ int nErr; /* Number of errors reported */
+ char *z; /* Text of the error report */
+ Mem *pnErr; /* Register keeping track of errors remaining */
+ } by;
+ struct OP_RowSetAdd_stack_vars {
+ Mem *pIdx;
+ Mem *pVal;
+ } bz;
+ struct OP_RowSetRead_stack_vars {
+ Mem *pIdx;
+ i64 val;
+ } ca;
+ struct OP_RowSetTest_stack_vars {
+ int iSet;
+ int exists;
+ } cb;
+ struct OP_ContextPush_stack_vars {
+ int i;
+ Context *pContext;
+ } cc;
+ struct OP_ContextPop_stack_vars {
+ Context *pContext;
+ } cd;
+ struct OP_AggStep_stack_vars {
+ int n;
+ int i;
+ Mem *pMem;
+ Mem *pRec;
+ sqlite3_context ctx;
+ sqlite3_value **apVal;
+ } ce;
+ struct OP_AggFinal_stack_vars {
+ Mem *pMem;
+ } cf;
+ struct OP_IncrVacuum_stack_vars {
+ Btree *pBt;
+ } cg;
+ struct OP_TableLock_stack_vars {
+ int p1;
+ u8 isWriteLock;
+ } ch;
+ struct OP_VBegin_stack_vars {
+ sqlite3_vtab *pVtab;
+ } ci;
+ struct OP_VOpen_stack_vars {
+ VdbeCursor *pCur;
+ sqlite3_vtab_cursor *pVtabCursor;
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pModule;
+ } cj;
+ struct OP_VFilter_stack_vars {
+ int nArg;
+ int iQuery;
+ const sqlite3_module *pModule;
+ Mem *pQuery;
+ Mem *pArgc;
+ sqlite3_vtab_cursor *pVtabCursor;
+ sqlite3_vtab *pVtab;
+ VdbeCursor *pCur;
+ int res;
+ int i;
+ Mem **apArg;
+ } ck;
+ struct OP_VColumn_stack_vars {
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+ Mem *pDest;
+ sqlite3_context sContext;
+ } cl;
+ struct OP_VNext_stack_vars {
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+ int res;
+ VdbeCursor *pCur;
+ } cm;
+ struct OP_VRename_stack_vars {
+ sqlite3_vtab *pVtab;
+ Mem *pName;
+ } cn;
+ struct OP_VUpdate_stack_vars {
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pModule;
+ int nArg;
+ int i;
+ sqlite_int64 rowid;
+ Mem **apArg;
+ Mem *pX;
+ } co;
+ struct OP_Pagecount_stack_vars {
+ int p1;
+ int nPage;
+ Pager *pPager;
+ } cp;
+ struct OP_Trace_stack_vars {
+ char *zTrace;
+ } cq;
+ } u;
+ /* End automatically generated code
+ ********************************************************************/
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
assert( db->magic==SQLITE_MAGIC_BUSY );
@@ -50850,13 +51655,15 @@ case OP_Return: { /* in1 */
** Swap the program counter with the value in register P1.
*/
case OP_Yield: { /* in1 */
+#if 0 /* local variables moved into u.aa */
int pcDest;
+#endif /* local variables moved into u.aa */
assert( (pIn1->flags & MEM_Dyn)==0 );
pIn1->flags = MEM_Int;
- pcDest = (int)pIn1->u.i;
+ u.aa.pcDest = (int)pIn1->u.i;
pIn1->u.i = pc;
REGISTER_TRACE(pOp->p1, pIn1);
- pc = pcDest;
+ pc = u.aa.pcDest;
break;
}
@@ -51027,23 +51834,29 @@ case OP_Blob: { /* out2-prerelease */
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: {
- int j = pOp->p1 - 1;
- int k = pOp->p2;
- Mem *pVar;
- int n = pOp->p3;
- assert( j>=0 && j+n<=p->nVar );
- assert( k>=1 && k+n-1<=p->nMem );
+#if 0 /* local variables moved into u.ab */
+ int p1; /* Variable to copy from */
+ int p2; /* Register to copy to */
+ int n; /* Number of values left to copy */
+ Mem *pVar; /* Value being transferred */
+#endif /* local variables moved into u.ab */
+
+ u.ab.p1 = pOp->p1 - 1;
+ u.ab.p2 = pOp->p2;
+ u.ab.n = pOp->p3;
+ assert( u.ab.p1>=0 && u.ab.p1+u.ab.n<=p->nVar );
+ assert( u.ab.p2>=1 && u.ab.p2+u.ab.n-1<=p->nMem );
assert( pOp->p4.z==0 || pOp->p3==1 );
- while( n-- > 0 ){
- pVar = &p->aVar[j++];
- if( sqlite3VdbeMemTooBig(pVar) ){
+ while( u.ab.n-- > 0 ){
+ u.ab.pVar = &p->aVar[u.ab.p1++];
+ if( sqlite3VdbeMemTooBig(u.ab.pVar) ){
goto too_big;
}
- pOut = &p->aMem[k++];
+ pOut = &p->aMem[u.ab.p2++];
sqlite3VdbeMemReleaseExternal(pOut);
pOut->flags = MEM_Null;
- sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
+ sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
}
break;
@@ -51057,23 +51870,29 @@ case OP_Variable: {
** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
*/
case OP_Move: {
- char *zMalloc;
- int n = pOp->p3;
- int p1 = pOp->p1;
- int p2 = pOp->p2;
- assert( n>0 && p1>0 && p2>0 );
- assert( p1+n<=p2 || p2+n<=p1 );
-
- pIn1 = &p->aMem[p1];
- pOut = &p->aMem[p2];
- while( n-- ){
+#if 0 /* local variables moved into u.ac */
+ char *zMalloc; /* Holding variable for allocated memory */
+ int n; /* Number of registers left to copy */
+ int p1; /* Register to copy from */
+ int p2; /* Register to copy to */
+#endif /* local variables moved into u.ac */
+
+ u.ac.n = pOp->p3;
+ u.ac.p1 = pOp->p1;
+ u.ac.p2 = pOp->p2;
+ assert( u.ac.n>0 && u.ac.p1>0 && u.ac.p2>0 );
+ assert( u.ac.p1+u.ac.n<=u.ac.p2 || u.ac.p2+u.ac.n<=u.ac.p1 );
+
+ pIn1 = &p->aMem[u.ac.p1];
+ pOut = &p->aMem[u.ac.p2];
+ while( u.ac.n-- ){
assert( pOut<=&p->aMem[p->nMem] );
assert( pIn1<=&p->aMem[p->nMem] );
- zMalloc = pOut->zMalloc;
+ u.ac.zMalloc = pOut->zMalloc;
pOut->zMalloc = 0;
sqlite3VdbeMemMove(pOut, pIn1);
- pIn1->zMalloc = zMalloc;
- REGISTER_TRACE(p2++, pOut);
+ pIn1->zMalloc = u.ac.zMalloc;
+ REGISTER_TRACE(u.ac.p2++, pOut);
pIn1++;
pOut++;
}
@@ -51130,14 +51949,16 @@ case OP_SCopy: { /* in1 */
** row.
*/
case OP_ResultRow: {
+#if 0 /* local variables moved into u.ad */
Mem *pMem;
int i;
+#endif /* local variables moved into u.ad */
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 );
assert( pOp->p1+pOp->p2<=p->nMem+1 );
- /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
- ** DML statements invoke this opcode to return the number of rows
+ /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
+ ** DML statements invoke this opcode to return the number of rows
** modified to the user. This is the only way that a VM that
** opens a statement transaction may invoke this opcode.
**
@@ -51160,11 +51981,11 @@ case OP_ResultRow: {
** and have an assigned type. The results are de-ephemeralized as
** as side effect.
*/
- pMem = p->pResultSet = &p->aMem[pOp->p1];
- for(i=0; i<pOp->p2; i++){
- sqlite3VdbeMemNulTerminate(&pMem[i]);
- storeTypeInfo(&pMem[i], encoding);
- REGISTER_TRACE(pOp->p1+i, &pMem[i]);
+ u.ad.pMem = p->pResultSet = &p->aMem[pOp->p1];
+ for(u.ad.i=0; u.ad.i<pOp->p2; u.ad.i++){
+ sqlite3VdbeMemNulTerminate(&u.ad.pMem[u.ad.i]);
+ storeTypeInfo(&u.ad.pMem[u.ad.i], encoding);
+ REGISTER_TRACE(pOp->p1+u.ad.i, &u.ad.pMem[u.ad.i]);
}
if( db->mallocFailed ) goto no_mem;
@@ -51188,7 +52009,9 @@ case OP_ResultRow: {
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
+#if 0 /* local variables moved into u.ae */
i64 nByte;
+#endif /* local variables moved into u.ae */
assert( pIn1!=pOut );
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
@@ -51199,22 +52022,22 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
Stringify(pIn1, encoding);
ExpandBlob(pIn2);
Stringify(pIn2, encoding);
- nByte = pIn1->n + pIn2->n;
- if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.ae.nByte = pIn1->n + pIn2->n;
+ if( u.ae.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ae.nByte+2, pOut==pIn2) ){
goto no_mem;
}
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
- pOut->z[nByte] = 0;
- pOut->z[nByte+1] = 0;
+ pOut->z[u.ae.nByte] = 0;
+ pOut->z[u.ae.nByte+1] = 0;
pOut->flags |= MEM_Term;
- pOut->n = (int)nByte;
+ pOut->n = (int)u.ae.nByte;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
@@ -51258,70 +52081,75 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
- int flags;
+#if 0 /* local variables moved into u.af */
+ int flags; /* Combined MEM_* flags from both inputs */
+ i64 iA; /* Integer value of left operand */
+ i64 iB; /* Integer value of right operand */
+ double rA; /* Real value of left operand */
+ double rB; /* Real value of right operand */
+#endif /* local variables moved into u.af */
+
applyNumericAffinity(pIn1);
applyNumericAffinity(pIn2);
- flags = pIn1->flags | pIn2->flags;
- if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+ u.af.flags = pIn1->flags | pIn2->flags;
+ if( (u.af.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
- i64 a, b;
- a = pIn1->u.i;
- b = pIn2->u.i;
+ u.af.iA = pIn1->u.i;
+ u.af.iB = pIn2->u.i;
switch( pOp->opcode ){
- case OP_Add: b += a; break;
- case OP_Subtract: b -= a; break;
- case OP_Multiply: b *= a; break;
+ case OP_Add: u.af.iB += u.af.iA; break;
+ case OP_Subtract: u.af.iB -= u.af.iA; break;
+ case OP_Multiply: u.af.iB *= u.af.iA; break;
case OP_Divide: {
- if( a==0 ) goto arithmetic_result_is_null;
- /* Dividing the largest possible negative 64-bit integer (1<<63) by
+ if( u.af.iA==0 ) goto arithmetic_result_is_null;
+ /* Dividing the largest possible negative 64-bit integer (1<<63) by
** -1 returns an integer too large to store in a 64-bit data-type. On
** some architectures, the value overflows to (1<<63). On others,
** a SIGFPE is issued. The following statement normalizes this
- ** behavior so that all architectures behave as if integer
+ ** behavior so that all architectures behave as if integer
** overflow occurred.
*/
- if( a==-1 && b==SMALLEST_INT64 ) a = 1;
- b /= a;
+ if( u.af.iA==-1 && u.af.iB==SMALLEST_INT64 ) u.af.iA = 1;
+ u.af.iB /= u.af.iA;
break;
}
default: {
- if( a==0 ) goto arithmetic_result_is_null;
- if( a==-1 ) a = 1;
- b %= a;
+ if( u.af.iA==0 ) goto arithmetic_result_is_null;
+ if( u.af.iA==-1 ) u.af.iA = 1;
+ u.af.iB %= u.af.iA;
break;
}
}
- pOut->u.i = b;
+ pOut->u.i = u.af.iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
- double a, b;
- a = sqlite3VdbeRealValue(pIn1);
- b = sqlite3VdbeRealValue(pIn2);
+ u.af.rA = sqlite3VdbeRealValue(pIn1);
+ u.af.rB = sqlite3VdbeRealValue(pIn2);
switch( pOp->opcode ){
- case OP_Add: b += a; break;
- case OP_Subtract: b -= a; break;
- case OP_Multiply: b *= a; break;
+ case OP_Add: u.af.rB += u.af.rA; break;
+ case OP_Subtract: u.af.rB -= u.af.rA; break;
+ case OP_Multiply: u.af.rB *= u.af.rA; break;
case OP_Divide: {
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- if( a==(double)0 ) goto arithmetic_result_is_null;
- b /= a;
+ if( u.af.rA==(double)0 ) goto arithmetic_result_is_null;
+ u.af.rB /= u.af.rA;
break;
}
default: {
- i64 ia = (i64)a;
- i64 ib = (i64)b;
- if( ia==0 ) goto arithmetic_result_is_null;
- if( ia==-1 ) ia = 1;
- b = (double)(ib % ia);
+ u.af.iA = (i64)u.af.rA;
+ u.af.iB = (i64)u.af.rB;
+ if( u.af.iA==0 ) goto arithmetic_result_is_null;
+ if( u.af.iA==-1 ) u.af.iA = 1;
+ u.af.rB = (double)(u.af.iB % u.af.iA);
break;
}
}
- if( sqlite3IsNaN(b) ){
+ if( sqlite3IsNaN(u.af.rB) ){
goto arithmetic_result_is_null;
}
- pOut->r = b;
+ pOut->r = u.af.rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( (flags & MEM_Real)==0 ){
+ if( (u.af.flags & MEM_Real)==0 ){
sqlite3VdbeIntegerAffinity(pOut);
}
}
@@ -51365,58 +52193,61 @@ case OP_CollSeq: {
** See also: AggStep and AggFinal
*/
case OP_Function: {
+#if 0 /* local variables moved into u.ag */
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
- int n = pOp->p5;
+ int n;
+#endif /* local variables moved into u.ag */
- apVal = p->apArg;
- assert( apVal || n==0 );
+ u.ag.n = pOp->p5;
+ u.ag.apVal = p->apArg;
+ assert( u.ag.apVal || u.ag.n==0 );
- assert( n==0 || (pOp->p2>0 && pOp->p2+n<=p->nMem+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
- pArg = &p->aMem[pOp->p2];
- for(i=0; i<n; i++, pArg++){
- apVal[i] = pArg;
- storeTypeInfo(pArg, encoding);
- REGISTER_TRACE(pOp->p2, pArg);
+ assert( u.ag.n==0 || (pOp->p2>0 && pOp->p2+u.ag.n<=p->nMem+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ag.n );
+ u.ag.pArg = &p->aMem[pOp->p2];
+ for(u.ag.i=0; u.ag.i<u.ag.n; u.ag.i++, u.ag.pArg++){
+ u.ag.apVal[u.ag.i] = u.ag.pArg;
+ storeTypeInfo(u.ag.pArg, encoding);
+ REGISTER_TRACE(pOp->p2, u.ag.pArg);
}
assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
if( pOp->p4type==P4_FUNCDEF ){
- ctx.pFunc = pOp->p4.pFunc;
- ctx.pVdbeFunc = 0;
+ u.ag.ctx.pFunc = pOp->p4.pFunc;
+ u.ag.ctx.pVdbeFunc = 0;
}else{
- ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
- ctx.pFunc = ctx.pVdbeFunc->pFunc;
+ u.ag.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
+ u.ag.ctx.pFunc = u.ag.ctx.pVdbeFunc->pFunc;
}
assert( pOp->p3>0 && pOp->p3<=p->nMem );
pOut = &p->aMem[pOp->p3];
- ctx.s.flags = MEM_Null;
- ctx.s.db = db;
- ctx.s.xDel = 0;
- ctx.s.zMalloc = 0;
+ u.ag.ctx.s.flags = MEM_Null;
+ u.ag.ctx.s.db = db;
+ u.ag.ctx.s.xDel = 0;
+ u.ag.ctx.s.zMalloc = 0;
/* The output cell may already have a buffer allocated. Move
- ** the pointer to ctx.s so in case the user-function can use
+ ** the pointer to u.ag.ctx.s so in case the user-function can use
** the already allocated buffer instead of allocating a new one.
*/
- sqlite3VdbeMemMove(&ctx.s, pOut);
- MemSetTypeFlag(&ctx.s, MEM_Null);
+ sqlite3VdbeMemMove(&u.ag.ctx.s, pOut);
+ MemSetTypeFlag(&u.ag.ctx.s, MEM_Null);
- ctx.isError = 0;
- if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ u.ag.ctx.isError = 0;
+ if( u.ag.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- ctx.pColl = pOp[-1].p4.pColl;
+ u.ag.ctx.pColl = pOp[-1].p4.pColl;
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- (*ctx.pFunc->xFunc)(&ctx, n, apVal);
+ (*u.ag.ctx.pFunc->xFunc)(&u.ag.ctx, u.ag.n, u.ag.apVal);
if( sqlite3SafetyOn(db) ){
- sqlite3VdbeMemRelease(&ctx.s);
+ sqlite3VdbeMemRelease(&u.ag.ctx.s);
goto abort_due_to_misuse;
}
if( db->mallocFailed ){
@@ -51429,28 +52260,28 @@ case OP_Function: {
** fails also (the if(...) statement above). But if people are
** misusing sqlite, they have bigger problems than a leaked value.
*/
- sqlite3VdbeMemRelease(&ctx.s);
+ sqlite3VdbeMemRelease(&u.ag.ctx.s);
goto no_mem;
}
/* If any auxiliary data functions have been called by this user function,
** immediately call the destructor for any non-static values.
*/
- if( ctx.pVdbeFunc ){
- sqlite3VdbeDeleteAuxData(ctx.pVdbeFunc, pOp->p1);
- pOp->p4.pVdbeFunc = ctx.pVdbeFunc;
+ if( u.ag.ctx.pVdbeFunc ){
+ sqlite3VdbeDeleteAuxData(u.ag.ctx.pVdbeFunc, pOp->p1);
+ pOp->p4.pVdbeFunc = u.ag.ctx.pVdbeFunc;
pOp->p4type = P4_VDBEFUNC;
}
/* If the function returned an error, throw an exception */
- if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
- rc = ctx.isError;
+ if( u.ag.ctx.isError ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ag.ctx.s));
+ rc = u.ag.ctx.isError;
}
/* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(&ctx.s, encoding);
- sqlite3VdbeMemMove(pOut, &ctx.s);
+ sqlite3VdbeChangeEncoding(&u.ag.ctx.s, encoding);
+ sqlite3VdbeMemMove(pOut, &u.ag.ctx.s);
if( sqlite3VdbeMemTooBig(pOut) ){
goto too_big;
}
@@ -51489,22 +52320,25 @@ case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
- i64 a, b;
+#if 0 /* local variables moved into u.ah */
+ i64 a;
+ i64 b;
+#endif /* local variables moved into u.ah */
if( (pIn1->flags | pIn2->flags) & MEM_Null ){
sqlite3VdbeMemSetNull(pOut);
break;
}
- a = sqlite3VdbeIntValue(pIn2);
- b = sqlite3VdbeIntValue(pIn1);
+ u.ah.a = sqlite3VdbeIntValue(pIn2);
+ u.ah.b = sqlite3VdbeIntValue(pIn1);
switch( pOp->opcode ){
- case OP_BitAnd: a &= b; break;
- case OP_BitOr: a |= b; break;
- case OP_ShiftLeft: a <<= b; break;
+ case OP_BitAnd: u.ah.a &= u.ah.b; break;
+ case OP_BitOr: u.ah.a |= u.ah.b; break;
+ case OP_ShiftLeft: u.ah.a <<= u.ah.b; break;
default: assert( pOp->opcode==OP_ShiftRight );
- a >>= b; break;
+ u.ah.a >>= u.ah.b; break;
}
- pOut->u.i = a;
+ pOut->u.i = u.ah.a;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -51722,13 +52556,15 @@ case OP_Lt: /* same as TK_LT, jump, in1, in3 */
case OP_Le: /* same as TK_LE, jump, in1, in3 */
case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
+#if 0 /* local variables moved into u.ai */
int flags;
int res;
char affinity;
+#endif /* local variables moved into u.ai */
- flags = pIn1->flags|pIn3->flags;
+ u.ai.flags = pIn1->flags|pIn3->flags;
- if( flags&MEM_Null ){
+ if( u.ai.flags&MEM_Null ){
/* If either operand is NULL then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
*/
@@ -51742,32 +52578,32 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
break;
}
- affinity = pOp->p5 & SQLITE_AFF_MASK;
- if( affinity ){
- applyAffinity(pIn1, affinity, encoding);
- applyAffinity(pIn3, affinity, encoding);
+ u.ai.affinity = pOp->p5 & SQLITE_AFF_MASK;
+ if( u.ai.affinity ){
+ applyAffinity(pIn1, u.ai.affinity, encoding);
+ applyAffinity(pIn3, u.ai.affinity, encoding);
if( db->mallocFailed ) goto no_mem;
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
ExpandBlob(pIn1);
ExpandBlob(pIn3);
- res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+ u.ai.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
switch( pOp->opcode ){
- case OP_Eq: res = res==0; break;
- case OP_Ne: res = res!=0; break;
- case OP_Lt: res = res<0; break;
- case OP_Le: res = res<=0; break;
- case OP_Gt: res = res>0; break;
- default: res = res>=0; break;
+ case OP_Eq: u.ai.res = u.ai.res==0; break;
+ case OP_Ne: u.ai.res = u.ai.res!=0; break;
+ case OP_Lt: u.ai.res = u.ai.res<0; break;
+ case OP_Le: u.ai.res = u.ai.res<=0; break;
+ case OP_Gt: u.ai.res = u.ai.res>0; break;
+ default: u.ai.res = u.ai.res>=0; break;
}
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &p->aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = res;
+ pOut->u.i = u.ai.res;
REGISTER_TRACE(pOp->p2, pOut);
- }else if( res ){
+ }else if( u.ai.res ){
pc = pOp->p2-1;
}
break;
@@ -51804,27 +52640,35 @@ case OP_Permutation: {
** and strings are less than blobs.
*/
case OP_Compare: {
- int n = pOp->p3;
- int i, p1, p2;
- const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
- assert( n>0 );
- assert( pKeyInfo!=0 );
- p1 = pOp->p1;
- assert( p1>0 && p1+n<=p->nMem+1 );
- p2 = pOp->p2;
- assert( p2>0 && p2+n<=p->nMem+1 );
- for(i=0; i<n; i++){
- int idx = aPermute ? aPermute[i] : i;
- CollSeq *pColl; /* Collating sequence to use on this term */
- int bRev; /* True for DESCENDING sort order */
- REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);
- REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);
- assert( i<pKeyInfo->nField );
- pColl = pKeyInfo->aColl[i];
- bRev = pKeyInfo->aSortOrder[i];
- iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl);
+#if 0 /* local variables moved into u.aj */
+ int n;
+ int i;
+ int p1;
+ int p2;
+ const KeyInfo *pKeyInfo;
+ int idx;
+ CollSeq *pColl; /* Collating sequence to use on this term */
+ int bRev; /* True for DESCENDING sort order */
+#endif /* local variables moved into u.aj */
+
+ u.aj.n = pOp->p3;
+ u.aj.pKeyInfo = pOp->p4.pKeyInfo;
+ assert( u.aj.n>0 );
+ assert( u.aj.pKeyInfo!=0 );
+ u.aj.p1 = pOp->p1;
+ assert( u.aj.p1>0 && u.aj.p1+u.aj.n<=p->nMem+1 );
+ u.aj.p2 = pOp->p2;
+ assert( u.aj.p2>0 && u.aj.p2+u.aj.n<=p->nMem+1 );
+ for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++){
+ u.aj.idx = aPermute ? aPermute[u.aj.i] : u.aj.i;
+ REGISTER_TRACE(u.aj.p1+u.aj.idx, &p->aMem[u.aj.p1+u.aj.idx]);
+ REGISTER_TRACE(u.aj.p2+u.aj.idx, &p->aMem[u.aj.p2+u.aj.idx]);
+ assert( u.aj.i<u.aj.pKeyInfo->nField );
+ u.aj.pColl = u.aj.pKeyInfo->aColl[u.aj.i];
+ u.aj.bRev = u.aj.pKeyInfo->aSortOrder[u.aj.i];
+ iCompare = sqlite3MemCompare(&p->aMem[u.aj.p1+u.aj.idx], &p->aMem[u.aj.p2+u.aj.idx], u.aj.pColl);
if( iCompare ){
- if( bRev ) iCompare = -iCompare;
+ if( u.aj.bRev ) iCompare = -iCompare;
break;
}
}
@@ -51869,29 +52713,32 @@ case OP_Jump: { /* jump */
*/
case OP_And: /* same as TK_AND, in1, in2, out3 */
case OP_Or: { /* same as TK_OR, in1, in2, out3 */
- int v1, v2; /* 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+#if 0 /* local variables moved into u.ak */
+ int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+ int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
+#endif /* local variables moved into u.ak */
if( pIn1->flags & MEM_Null ){
- v1 = 2;
+ u.ak.v1 = 2;
}else{
- v1 = sqlite3VdbeIntValue(pIn1)!=0;
+ u.ak.v1 = sqlite3VdbeIntValue(pIn1)!=0;
}
if( pIn2->flags & MEM_Null ){
- v2 = 2;
+ u.ak.v2 = 2;
}else{
- v2 = sqlite3VdbeIntValue(pIn2)!=0;
+ u.ak.v2 = sqlite3VdbeIntValue(pIn2)!=0;
}
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
- v1 = and_logic[v1*3+v2];
+ u.ak.v1 = and_logic[u.ak.v1*3+u.ak.v2];
}else{
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
- v1 = or_logic[v1*3+v2];
+ u.ak.v1 = or_logic[u.ak.v1*3+u.ak.v2];
}
- if( v1==2 ){
+ if( u.ak.v1==2 ){
MemSetTypeFlag(pOut, MEM_Null);
}else{
- pOut->u.i = v1;
+ pOut->u.i = u.ak.v1;
MemSetTypeFlag(pOut, MEM_Int);
}
break;
@@ -51943,18 +52790,20 @@ case OP_BitNot: { /* same as TK_BITNOT, in1 */
*/
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
+#if 0 /* local variables moved into u.al */
int c;
+#endif /* local variables moved into u.al */
if( pIn1->flags & MEM_Null ){
- c = pOp->p3;
+ u.al.c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
- c = sqlite3VdbeIntValue(pIn1)!=0;
+ u.al.c = sqlite3VdbeIntValue(pIn1)!=0;
#else
- c = sqlite3VdbeRealValue(pIn1)!=0.0;
+ u.al.c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
- if( pOp->opcode==OP_IfNot ) c = !c;
+ if( pOp->opcode==OP_IfNot ) u.al.c = !u.al.c;
}
- if( c ){
+ if( u.al.c ){
pc = pOp->p2-1;
}
break;
@@ -51967,7 +52816,11 @@ case OP_IfNot: { /* jump, in1 */
** reg(P1+2), ..., reg(P1+P3-1).
*/
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
- int n = pOp->p3;
+#if 0 /* local variables moved into u.am */
+ int n;
+#endif /* local variables moved into u.am */
+
+ u.am.n = pOp->p3;
assert( pOp->p3==0 || pOp->p1>0 );
do{
if( (pIn1->flags & MEM_Null)!=0 ){
@@ -51975,7 +52828,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
break;
}
pIn1++;
- }while( --n > 0 );
+ }while( --u.am.n > 0 );
break;
}
@@ -52027,10 +52880,12 @@ case OP_SetNumColumns: {
** the result.
*/
case OP_Column: {
- int payloadSize; /* Number of bytes in the record */
- int p1 = pOp->p1; /* P1 value of the opcode */
- int p2 = pOp->p2; /* column number to retrieve */
- VdbeCursor *pC = 0;/* The VDBE cursor */
+#if 0 /* local variables moved into u.an */
+ u32 payloadSize; /* Number of bytes in the record */
+ i64 payloadSize64; /* Number of bytes in the record */
+ int p1; /* P1 value of the opcode */
+ int p2; /* column number to retrieve */
+ VdbeCursor *pC; /* The VDBE cursor */
char *zRec; /* Pointer to complete record-data */
BtCursor *pCrsr; /* The BTree cursor */
u32 *aType; /* aType[i] holds the numeric type of the i-th column */
@@ -52041,114 +52896,155 @@ case OP_Column: {
char *zData; /* Part of the record being decoded */
Mem *pDest; /* Where to write the extracted value */
Mem sMem; /* For storing the record being decoded */
-
- memset(&sMem, 0, sizeof(sMem));
- assert( p1<p->nCursor );
+ u8 *zIdx; /* Index into header */
+ u8 *zEndHdr; /* Pointer to first byte after the header */
+ u32 offset; /* Offset into the data */
+ u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */
+ int szHdr; /* Size of the header size field at start of record */
+ int avail; /* Number of bytes of available data */
+#endif /* local variables moved into u.an */
+
+
+ u.an.p1 = pOp->p1;
+ u.an.p2 = pOp->p2;
+ u.an.pC = 0;
+ memset(&u.an.sMem, 0, sizeof(u.an.sMem));
+ assert( u.an.p1<p->nCursor );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pDest = &p->aMem[pOp->p3];
- MemSetTypeFlag(pDest, MEM_Null);
+ u.an.pDest = &p->aMem[pOp->p3];
+ MemSetTypeFlag(u.an.pDest, MEM_Null);
- /* This block sets the variable payloadSize to be the total number of
+ /* This block sets the variable u.an.payloadSize to be the total number of
** bytes in the record.
**
- ** zRec is set to be the complete text of the record if it is available.
+ ** u.an.zRec is set to be the complete text of the record if it is available.
** The complete record text is always available for pseudo-tables
** If the record is stored in a cursor, the complete record text
- ** might be available in the pC->aRow cache. Or it might not be.
- ** If the data is unavailable, zRec is set to NULL.
+ ** might be available in the u.an.pC->aRow cache. Or it might not be.
+ ** If the data is unavailable, u.an.zRec is set to NULL.
**
** We also compute the number of columns in the record. For cursors,
** the number of columns is stored in the VdbeCursor.nField element.
*/
- pC = p->apCsr[p1];
- assert( pC!=0 );
+ u.an.pC = p->apCsr[u.an.p1];
+ assert( u.an.pC!=0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE
- assert( pC->pVtabCursor==0 );
+ assert( u.an.pC->pVtabCursor==0 );
#endif
- if( pC->pCursor!=0 ){
+ if( u.an.pC->pCursor!=0 ){
/* The record is stored in a B-Tree */
- rc = sqlite3VdbeCursorMoveto(pC);
+ rc = sqlite3VdbeCursorMoveto(u.an.pC);
if( rc ) goto abort_due_to_error;
- zRec = 0;
- pCrsr = pC->pCursor;
- if( pC->nullRow ){
- payloadSize = 0;
- }else if( pC->cacheStatus==p->cacheCtr ){
- payloadSize = pC->payloadSize;
- zRec = (char*)pC->aRow;
- }else if( pC->isIndex ){
- i64 payloadSize64;
- sqlite3BtreeKeySize(pCrsr, &payloadSize64);
- payloadSize = (int)payloadSize64;
+ u.an.zRec = 0;
+ u.an.pCrsr = u.an.pC->pCursor;
+ if( u.an.pC->nullRow ){
+ u.an.payloadSize = 0;
+ }else if( u.an.pC->cacheStatus==p->cacheCtr ){
+ u.an.payloadSize = u.an.pC->payloadSize;
+ u.an.zRec = (char*)u.an.pC->aRow;
+ }else if( u.an.pC->isIndex ){
+ sqlite3BtreeKeySize(u.an.pCrsr, &u.an.payloadSize64);
+ if( (u.an.payloadSize64 & SQLITE_MAX_U32)!=(u64)u.an.payloadSize64 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto abort_due_to_error;
+ }
+ u.an.payloadSize = (u32)u.an.payloadSize64;
}else{
- sqlite3BtreeDataSize(pCrsr, (u32 *)&payloadSize);
+ sqlite3BtreeDataSize(u.an.pCrsr, &u.an.payloadSize);
}
- nField = pC->nField;
+ u.an.nField = u.an.pC->nField;
}else{
- assert( pC->pseudoTable );
+ assert( u.an.pC->pseudoTable );
/* The record is the sole entry of a pseudo-table */
- payloadSize = pC->nData;
- zRec = pC->pData;
- pC->cacheStatus = CACHE_STALE;
- assert( payloadSize==0 || zRec!=0 );
- nField = pC->nField;
- pCrsr = 0;
+ u.an.payloadSize = u.an.pC->nData;
+ u.an.zRec = u.an.pC->pData;
+ u.an.pC->cacheStatus = CACHE_STALE;
+ assert( u.an.payloadSize==0 || u.an.zRec!=0 );
+ u.an.nField = u.an.pC->nField;
+ u.an.pCrsr = 0;
}
- /* If payloadSize is 0, then just store a NULL */
- if( payloadSize==0 ){
- assert( pDest->flags&MEM_Null );
+ /* If u.an.payloadSize is 0, then just store a NULL */
+ if( u.an.payloadSize==0 ){
+ assert( u.an.pDest->flags&MEM_Null );
goto op_column_out;
}
- if( payloadSize>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
+ if( u.an.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- assert( p2<nField );
+ assert( u.an.p2<u.an.nField );
/* Read and parse the table header. Store the results of the parse
** into the record header cache fields of the cursor.
*/
- aType = pC->aType;
- if( pC->cacheStatus==p->cacheCtr ){
- aOffset = pC->aOffset;
+ u.an.aType = u.an.pC->aType;
+ if( u.an.pC->cacheStatus==p->cacheCtr ){
+ u.an.aOffset = u.an.pC->aOffset;
}else{
- u8 *zIdx; /* Index into header */
- u8 *zEndHdr; /* Pointer to first byte after the header */
- int offset; /* Offset into the data */
- int szHdrSz; /* Size of the header size field at start of record */
- int avail = 0; /* Number of bytes of available data */
-
- assert(aType);
- pC->aOffset = aOffset = &aType[nField];
- pC->payloadSize = payloadSize;
- pC->cacheStatus = p->cacheCtr;
+ assert(u.an.aType);
+ u.an.avail = 0;
+ u.an.pC->aOffset = u.an.aOffset = &u.an.aType[u.an.nField];
+ u.an.pC->payloadSize = u.an.payloadSize;
+ u.an.pC->cacheStatus = p->cacheCtr;
/* Figure out how many bytes are in the header */
- if( zRec ){
- zData = zRec;
+ if( u.an.zRec ){
+ u.an.zData = u.an.zRec;
}else{
- if( pC->isIndex ){
- zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail);
+ if( u.an.pC->isIndex ){
+ u.an.zData = (char*)sqlite3BtreeKeyFetch(u.an.pCrsr, &u.an.avail);
}else{
- zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
+ u.an.zData = (char*)sqlite3BtreeDataFetch(u.an.pCrsr, &u.an.avail);
}
/* If KeyFetch()/DataFetch() managed to get the entire payload,
- ** save the payload in the pC->aRow cache. That will save us from
+ ** save the payload in the u.an.pC->aRow cache. That will save us from
** having to make additional calls to fetch the content portion of
** the record.
*/
- if( avail>=payloadSize ){
- zRec = zData;
- pC->aRow = (u8*)zData;
+ assert( u.an.avail>=0 );
+ if( u.an.payloadSize <= (u32)u.an.avail ){
+ u.an.zRec = u.an.zData;
+ u.an.pC->aRow = (u8*)u.an.zData;
}else{
- pC->aRow = 0;
+ u.an.pC->aRow = 0;
}
}
/* The following assert is true in all cases accept when
** the database file has been corrupted externally.
- ** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */
- szHdrSz = getVarint32((u8*)zData, offset);
+ ** assert( u.an.zRec!=0 || u.an.avail>=u.an.payloadSize || u.an.avail>=9 ); */
+ u.an.szHdr = getVarint32((u8*)u.an.zData, u.an.offset);
+
+ /* Make sure a corrupt database has not given us an oversize header.
+ ** Do this now to avoid an oversize memory allocation.
+ **
+ ** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
+ ** types use so much data space that there can only be 4096 and 32 of
+ ** them, respectively. So the maximum header length results from a
+ ** 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( u.an.offset > 98307 ){
+ rc = SQLITE_CORRUPT_BKPT;
+ goto op_column_out;
+ }
+
+ /* Compute in u.an.len the number of bytes of data we need to read in order
+ ** to get u.an.nField type values. u.an.offset is an upper bound on this. But
+ ** u.an.nField might be significantly less than the true number of columns
+ ** in the table, and in that case, 5*u.an.nField+3 might be smaller than u.an.offset.
+ ** We want to minimize u.an.len in order to limit the size of the memory
+ ** allocation, especially if a corrupt database file has caused u.an.offset
+ ** to be oversized. Offset is limited to 98307 above. But 98307 might
+ ** still exceed Robson memory allocation limits on some configurations.
+ ** On systems that cannot tolerate large memory allocations, u.an.nField*5+3
+ ** will likely be much smaller since u.an.nField will likely be less than
+ ** 20 or so. This insures that Robson memory allocation limits are
+ ** not exceeded even for corrupt database files.
+ */
+ u.an.len = u.an.nField*5 + 3;
+ if( u.an.len > (int)u.an.offset ) u.an.len = (int)u.an.offset;
/* The KeyFetch() or DataFetch() above are fast and will get the entire
** record header in most cases. But they will fail to get the complete
@@ -52156,104 +53052,105 @@ case OP_Column: {
** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
** acquire the complete header text.
*/
- if( !zRec && avail<offset ){
- sMem.flags = 0;
- sMem.db = 0;
- rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
+ if( !u.an.zRec && u.an.avail<u.an.len ){
+ u.an.sMem.flags = 0;
+ u.an.sMem.db = 0;
+ rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, 0, u.an.len, u.an.pC->isIndex, &u.an.sMem);
if( rc!=SQLITE_OK ){
goto op_column_out;
}
- zData = sMem.z;
+ u.an.zData = u.an.sMem.z;
}
- zEndHdr = (u8 *)&zData[offset];
- zIdx = (u8 *)&zData[szHdrSz];
+ u.an.zEndHdr = (u8 *)&u.an.zData[u.an.len];
+ u.an.zIdx = (u8 *)&u.an.zData[u.an.szHdr];
- /* Scan the header and use it to fill in the aType[] and aOffset[]
- ** arrays. aType[i] will contain the type integer for the i-th
- ** column and aOffset[i] will contain the offset from the beginning
- ** of the record to the start of the data for the i-th column
+ /* Scan the header and use it to fill in the u.an.aType[] and u.an.aOffset[]
+ ** arrays. u.an.aType[u.an.i] will contain the type integer for the u.an.i-th
+ ** column and u.an.aOffset[u.an.i] will contain the u.an.offset from the beginning
+ ** of the record to the start of the data for the u.an.i-th column
*/
- for(i=0; i<nField; i++){
- if( zIdx<zEndHdr ){
- aOffset[i] = offset;
- zIdx += getVarint32(zIdx, aType[i]);
- offset += sqlite3VdbeSerialTypeLen(aType[i]);
+ u.an.offset64 = u.an.offset;
+ for(u.an.i=0; u.an.i<u.an.nField; u.an.i++){
+ if( u.an.zIdx<u.an.zEndHdr ){
+ u.an.aOffset[u.an.i] = (u32)u.an.offset64;
+ u.an.zIdx += getVarint32(u.an.zIdx, u.an.aType[u.an.i]);
+ u.an.offset64 += sqlite3VdbeSerialTypeLen(u.an.aType[u.an.i]);
}else{
- /* If i is less that nField, then there are less fields in this
+ /* If u.an.i is less that u.an.nField, then there are less fields in this
** record than SetNumColumns indicated there are columns in the
- ** table. Set the offset for any extra columns not present in
+ ** table. Set the u.an.offset for any extra columns not present in
** the record to 0. This tells code below to store a NULL
** instead of deserializing a value from the record.
*/
- aOffset[i] = 0;
+ u.an.aOffset[u.an.i] = 0;
}
}
- sqlite3VdbeMemRelease(&sMem);
- sMem.flags = MEM_Null;
+ sqlite3VdbeMemRelease(&u.an.sMem);
+ u.an.sMem.flags = MEM_Null;
/* If we have read more header data than was contained in the header,
** or if the end of the last field appears to be past the end of the
** record, or if the end of the last field appears to be before the end
- ** of the record (when all fields present), then we must be dealing
+ ** of the record (when all fields present), then we must be dealing
** with a corrupt database.
*/
- if( zIdx>zEndHdr || offset>payloadSize
- || (zIdx==zEndHdr && offset!=payloadSize) ){
+ if( (u.an.zIdx > u.an.zEndHdr)|| (u.an.offset64 > u.an.payloadSize)
+ || (u.an.zIdx==u.an.zEndHdr && u.an.offset64!=(u64)u.an.payloadSize) ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_out;
}
}
- /* Get the column information. If aOffset[p2] is non-zero, then
- ** deserialize the value from the record. If aOffset[p2] is zero,
+ /* Get the column information. If u.an.aOffset[u.an.p2] is non-zero, then
+ ** deserialize the value from the record. If u.an.aOffset[u.an.p2] is zero,
** then there are not enough fields in the record to satisfy the
** request. In this case, set the value NULL or to P4 if P4 is
** a pointer to a Mem object.
*/
- if( aOffset[p2] ){
+ if( u.an.aOffset[u.an.p2] ){
assert( rc==SQLITE_OK );
- if( zRec ){
- sqlite3VdbeMemReleaseExternal(pDest);
- sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest);
+ if( u.an.zRec ){
+ sqlite3VdbeMemReleaseExternal(u.an.pDest);
+ sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest);
}else{
- len = sqlite3VdbeSerialTypeLen(aType[p2]);
- sqlite3VdbeMemMove(&sMem, pDest);
- rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem);
+ u.an.len = sqlite3VdbeSerialTypeLen(u.an.aType[u.an.p2]);
+ sqlite3VdbeMemMove(&u.an.sMem, u.an.pDest);
+ rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, u.an.aOffset[u.an.p2], u.an.len, u.an.pC->isIndex, &u.an.sMem);
if( rc!=SQLITE_OK ){
goto op_column_out;
}
- zData = sMem.z;
- sqlite3VdbeSerialGet((u8*)zData, aType[p2], pDest);
+ u.an.zData = u.an.sMem.z;
+ sqlite3VdbeSerialGet((u8*)u.an.zData, u.an.aType[u.an.p2], u.an.pDest);
}
- pDest->enc = encoding;
+ u.an.pDest->enc = encoding;
}else{
if( pOp->p4type==P4_MEM ){
- sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
+ sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static);
}else{
- assert( pDest->flags&MEM_Null );
+ assert( u.an.pDest->flags&MEM_Null );
}
}
/* If we dynamically allocated space to hold the data (in the
** sqlite3VdbeMemFromBtree() call above) then transfer control of that
- ** dynamically allocated space over to the pDest structure.
+ ** dynamically allocated space over to the u.an.pDest structure.
** This prevents a memory copy.
*/
- if( sMem.zMalloc ){
- assert( sMem.z==sMem.zMalloc );
- assert( !(pDest->flags & MEM_Dyn) );
- assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z );
- pDest->flags &= ~(MEM_Ephem|MEM_Static);
- pDest->flags |= MEM_Term;
- pDest->z = sMem.z;
- pDest->zMalloc = sMem.zMalloc;
+ if( u.an.sMem.zMalloc ){
+ assert( u.an.sMem.z==u.an.sMem.zMalloc );
+ assert( !(u.an.pDest->flags & MEM_Dyn) );
+ assert( !(u.an.pDest->flags & (MEM_Blob|MEM_Str)) || u.an.pDest->z==u.an.sMem.z );
+ u.an.pDest->flags &= ~(MEM_Ephem|MEM_Static);
+ u.an.pDest->flags |= MEM_Term;
+ u.an.pDest->z = u.an.sMem.z;
+ u.an.pDest->zMalloc = u.an.sMem.zMalloc;
}
- rc = sqlite3VdbeMemMakeWriteable(pDest);
+ rc = sqlite3VdbeMemMakeWriteable(u.an.pDest);
op_column_out:
- UPDATE_MAX_BLOBSIZE(pDest);
- REGISTER_TRACE(pOp->p3, pDest);
+ UPDATE_MAX_BLOBSIZE(u.an.pDest);
+ REGISTER_TRACE(pOp->p3, u.an.pDest);
break;
}
@@ -52266,14 +53163,19 @@ op_column_out:
** memory cell in the range.
*/
case OP_Affinity: {
- char *zAffinity = pOp->p4.z;
- Mem *pData0 = &p->aMem[pOp->p1];
- Mem *pLast = &pData0[pOp->p2-1];
- Mem *pRec;
-
- for(pRec=pData0; pRec<=pLast; pRec++){
- ExpandBlob(pRec);
- applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
+#if 0 /* local variables moved into u.ao */
+ char *zAffinity; /* The affinity to be applied */
+ Mem *pData0; /* First register to which to apply affinity */
+ Mem *pLast; /* Last register to which to apply affinity */
+ Mem *pRec; /* Current register */
+#endif /* local variables moved into u.ao */
+
+ u.ao.zAffinity = pOp->p4.z;
+ u.ao.pData0 = &p->aMem[pOp->p1];
+ u.ao.pLast = &u.ao.pData0[pOp->p2-1];
+ for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){
+ ExpandBlob(u.ao.pRec);
+ applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding);
}
break;
}
@@ -52297,107 +53199,113 @@ case OP_Affinity: {
** If P4 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
+#if 0 /* local variables moved into u.ap */
+ u8 *zNewRecord; /* A buffer to hold the data for the new record */
+ Mem *pRec; /* The new record */
+ u64 nData; /* Number of bytes of data space */
+ int nHdr; /* Number of bytes of header space */
+ i64 nByte; /* Data space required for this record */
+ int nZero; /* Number of zero bytes at the end of the record */
+ int nVarint; /* Number of bytes in a varint */
+ u32 serial_type; /* Type field */
+ Mem *pData0; /* First field to be combined into the record */
+ Mem *pLast; /* Last field of the record */
+ int nField; /* Number of fields in the record */
+ char *zAffinity; /* The affinity string for the record */
+ int file_format; /* File format to use for encoding */
+ int i; /* Space used in zNewRecord[] */
+ int len; /* Length of a field */
+#endif /* local variables moved into u.ap */
+
/* Assuming the record contains N fields, the record format looks
** like this:
**
** ------------------------------------------------------------------------
- ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
+ ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
** ------------------------------------------------------------------------
**
** Data(0) is taken from register P1. Data(1) comes from register P1+1
** and so froth.
**
- ** Each type field is a varint representing the serial type of the
+ ** Each type field is a varint representing the serial type of the
** corresponding data element (see sqlite3VdbeSerialType()). The
** hdr-size field is also a varint which is the offset from the beginning
** of the record to data0.
*/
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
- Mem *pRec; /* The new record */
- u64 nData = 0; /* Number of bytes of data space */
- int nHdr = 0; /* Number of bytes of header space */
- i64 nByte = 0; /* Data space required for this record */
- int nZero = 0; /* Number of zero bytes at the end of the record */
- int nVarint; /* Number of bytes in a varint */
- u32 serial_type; /* Type field */
- Mem *pData0; /* First field to be combined into the record */
- Mem *pLast; /* Last field of the record */
- int nField; /* Number of fields in the record */
- char *zAffinity; /* The affinity string for the record */
- int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
-
- nField = pOp->p1;
- zAffinity = pOp->p4.z;
- assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=p->nMem+1 );
- pData0 = &p->aMem[nField];
- nField = pOp->p2;
- pLast = &pData0[nField-1];
- file_format = p->minWriteFileFormat;
+ u.ap.nData = 0; /* Number of bytes of data space */
+ u.ap.nHdr = 0; /* Number of bytes of header space */
+ u.ap.nByte = 0; /* Data space required for this record */
+ u.ap.nZero = 0; /* Number of zero bytes at the end of the record */
+ u.ap.nField = pOp->p1;
+ u.ap.zAffinity = pOp->p4.z;
+ assert( u.ap.nField>0 && pOp->p2>0 && pOp->p2+u.ap.nField<=p->nMem+1 );
+ u.ap.pData0 = &p->aMem[u.ap.nField];
+ u.ap.nField = pOp->p2;
+ u.ap.pLast = &u.ap.pData0[u.ap.nField-1];
+ u.ap.file_format = p->minWriteFileFormat;
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
*/
- for(pRec=pData0; pRec<=pLast; pRec++){
- int len;
- if( zAffinity ){
- applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
+ for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){
+ if( u.ap.zAffinity ){
+ applyAffinity(u.ap.pRec, u.ap.zAffinity[u.ap.pRec-u.ap.pData0], encoding);
}
- if( pRec->flags&MEM_Zero && pRec->n>0 ){
- sqlite3VdbeMemExpandBlob(pRec);
+ if( u.ap.pRec->flags&MEM_Zero && u.ap.pRec->n>0 ){
+ sqlite3VdbeMemExpandBlob(u.ap.pRec);
}
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
- len = sqlite3VdbeSerialTypeLen(serial_type);
- nData += len;
- nHdr += sqlite3VarintLen(serial_type);
- if( pRec->flags & MEM_Zero ){
+ u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format);
+ u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.serial_type);
+ u.ap.nData += u.ap.len;
+ u.ap.nHdr += sqlite3VarintLen(u.ap.serial_type);
+ if( u.ap.pRec->flags & MEM_Zero ){
/* Only pure zero-filled BLOBs can be input to this Opcode.
** We do not allow blobs with a prefix and a zero-filled tail. */
- nZero += pRec->u.nZero;
- }else if( len ){
- nZero = 0;
+ u.ap.nZero += u.ap.pRec->u.nZero;
+ }else if( u.ap.len ){
+ u.ap.nZero = 0;
}
}
/* Add the initial header varint and total the size */
- nHdr += nVarint = sqlite3VarintLen(nHdr);
- if( nVarint<sqlite3VarintLen(nHdr) ){
- nHdr++;
+ u.ap.nHdr += u.ap.nVarint = sqlite3VarintLen(u.ap.nHdr);
+ if( u.ap.nVarint<sqlite3VarintLen(u.ap.nHdr) ){
+ u.ap.nHdr++;
}
- nByte = nHdr+nData-nZero;
- if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ u.ap.nByte = u.ap.nHdr+u.ap.nData-u.ap.nZero;
+ if( u.ap.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- /* Make sure the output register has a buffer large enough to store
+ /* Make sure the output register has a buffer large enough to store
** the new record. The output register (pOp->p3) is not allowed to
** be one of the input registers (because the following call to
** sqlite3VdbeMemGrow() could clobber the value before it is used).
*/
assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
pOut = &p->aMem[pOp->p3];
- if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)u.ap.nByte, 0) ){
goto no_mem;
}
- zNewRecord = (u8 *)pOut->z;
+ u.ap.zNewRecord = (u8 *)pOut->z;
/* Write the record */
- i = putVarint32(zNewRecord, nHdr);
- for(pRec=pData0; pRec<=pLast; pRec++){
- serial_type = sqlite3VdbeSerialType(pRec, file_format);
- i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
+ u.ap.i = putVarint32(u.ap.zNewRecord, u.ap.nHdr);
+ for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){
+ u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format);
+ u.ap.i += putVarint32(&u.ap.zNewRecord[u.ap.i], u.ap.serial_type); /* serial type */
}
- for(pRec=pData0; pRec<=pLast; pRec++){ /* serial data */
- i += sqlite3VdbeSerialPut(&zNewRecord[i], (int)(nByte-i), pRec,file_format);
+ for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ /* serial data */
+ u.ap.i += sqlite3VdbeSerialPut(&u.ap.zNewRecord[u.ap.i], (int)(u.ap.nByte-u.ap.i), u.ap.pRec,u.ap.file_format);
}
- assert( i==nByte );
+ assert( u.ap.i==u.ap.nByte );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pOut->n = (int)nByte;
+ pOut->n = (int)u.ap.nByte;
pOut->flags = MEM_Blob | MEM_Dyn;
pOut->xDel = 0;
- if( nZero ){
- pOut->u.nZero = nZero;
+ if( u.ap.nZero ){
+ pOut->u.nZero = u.ap.nZero;
pOut->flags |= MEM_Zero;
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
@@ -52413,15 +53321,19 @@ case OP_MakeRecord: {
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2-prerelease */
+#if 0 /* local variables moved into u.aq */
i64 nEntry;
- BtCursor *pCrsr = p->apCsr[pOp->p1]->pCursor;
- if( pCrsr ){
- rc = sqlite3BtreeCount(pCrsr, &nEntry);
+ BtCursor *pCrsr;
+#endif /* local variables moved into u.aq */
+
+ u.aq.pCrsr = p->apCsr[pOp->p1]->pCursor;
+ if( u.aq.pCrsr ){
+ rc = sqlite3BtreeCount(u.aq.pCrsr, &u.aq.nEntry);
}else{
- nEntry = 0;
+ u.aq.nEntry = 0;
}
pOut->flags = MEM_Int;
- pOut->u.i = nEntry;
+ pOut->u.i = u.aq.nEntry;
break;
}
#endif
@@ -52449,20 +53361,23 @@ case OP_Count: { /* out2-prerelease */
** has an index of 1.
*/
case OP_Statement: {
+#if 0 /* local variables moved into u.ar */
+ int i;
+ Btree *pBt;
+#endif /* local variables moved into u.ar */
if( db->autoCommit==0 || db->activeVdbeCnt>1 ){
- int i = pOp->p1;
- Btree *pBt;
- assert( i>=0 && i<db->nDb );
- assert( db->aDb[i].pBt!=0 );
- pBt = db->aDb[i].pBt;
- assert( sqlite3BtreeIsInTrans(pBt) );
- assert( (p->btreeMask & (1<<i))!=0 );
+ u.ar.i = pOp->p1;
+ assert( u.ar.i>=0 && u.ar.i<db->nDb );
+ assert( db->aDb[u.ar.i].pBt!=0 );
+ u.ar.pBt = db->aDb[u.ar.i].pBt;
+ assert( sqlite3BtreeIsInTrans(u.ar.pBt) );
+ assert( (p->btreeMask & (1<<u.ar.i))!=0 );
if( p->iStatement==0 ){
assert( db->nStatement>=0 && db->nSavepoint>=0 );
- db->nStatement++;
+ db->nStatement++;
p->iStatement = db->nSavepoint + db->nStatement;
}
- rc = sqlite3BtreeBeginStmt(pBt, p->iStatement);
+ rc = sqlite3BtreeBeginStmt(u.ar.pBt, p->iStatement);
}
break;
}
@@ -52474,35 +53389,45 @@ case OP_Statement: {
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
*/
case OP_Savepoint: {
- int p1 = pOp->p1;
- char *zName = pOp->p4.z; /* Name of savepoint */
+#if 0 /* local variables moved into u.as */
+ int p1; /* Value of P1 operand */
+ char *zName; /* Name of savepoint */
+ int nName;
+ Savepoint *pNew;
+ Savepoint *pSavepoint;
+ Savepoint *pTmp;
+ int iSavepoint;
+ int ii;
+#endif /* local variables moved into u.as */
+
+ u.as.p1 = pOp->p1;
+ u.as.zName = pOp->p4.z;
- /* Assert that the p1 parameter is valid. Also that if there is no open
- ** transaction, then there cannot be any savepoints.
+ /* Assert that the u.as.p1 parameter is valid. Also that if there is no open
+ ** transaction, then there cannot be any savepoints.
*/
assert( db->pSavepoint==0 || db->autoCommit==0 );
- assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK );
+ assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK );
assert( db->pSavepoint || db->isTransactionSavepoint==0 );
assert( checkSavepointCount(db) );
- if( p1==SAVEPOINT_BEGIN ){
+ if( u.as.p1==SAVEPOINT_BEGIN ){
if( db->writeVdbeCnt>0 ){
- /* A new savepoint cannot be created if there are active write
+ /* A new savepoint cannot be created if there are active write
** statements (i.e. open read/write incremental blob handles).
*/
sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else{
- int nName = sqlite3Strlen30(zName);
- Savepoint *pNew;
+ u.as.nName = sqlite3Strlen30(u.as.zName);
/* Create a new savepoint structure. */
- pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1);
- if( pNew ){
- pNew->zName = (char *)&pNew[1];
- memcpy(pNew->zName, zName, nName+1);
-
+ u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1);
+ if( u.as.pNew ){
+ u.as.pNew->zName = (char *)&u.as.pNew[1];
+ memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1);
+
/* If there is no open transaction, then mark this as a special
** "transaction savepoint". */
if( db->autoCommit ){
@@ -52511,48 +53436,47 @@ case OP_Savepoint: {
}else{
db->nSavepoint++;
}
-
+
/* Link the new savepoint into the database handle's list. */
- pNew->pNext = db->pSavepoint;
- db->pSavepoint = pNew;
+ u.as.pNew->pNext = db->pSavepoint;
+ db->pSavepoint = u.as.pNew;
}
}
}else{
- Savepoint *pSavepoint;
- int iSavepoint = 0;
+ u.as.iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
** an error is returned to the user. */
for(
- pSavepoint=db->pSavepoint;
- pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName);
- pSavepoint=pSavepoint->pNext
+ u.as.pSavepoint = db->pSavepoint;
+ u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName);
+ u.as.pSavepoint = u.as.pSavepoint->pNext
){
- iSavepoint++;
+ u.as.iSavepoint++;
}
- if( !pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
+ if( !u.as.pSavepoint ){
+ sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName);
rc = SQLITE_ERROR;
- }else if(
- db->writeVdbeCnt>0 || (p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1)
+ }else if(
+ db->writeVdbeCnt>0 || (u.as.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1)
){
- /* It is not possible to release (commit) a savepoint if there are
+ /* It is not possible to release (commit) a savepoint if there are
** active write statements. It is not possible to rollback a savepoint
** if there are any active statements at all.
*/
- sqlite3SetString(&p->zErrMsg, db,
+ sqlite3SetString(&p->zErrMsg, db,
"cannot %s savepoint - SQL statements in progress",
- (p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
+ (u.as.p1==SAVEPOINT_ROLLBACK ? "rollback": "release")
);
rc = SQLITE_BUSY;
}else{
/* Determine whether or not this is a transaction savepoint. If so,
- ** and this is a RELEASE command, then the current transaction
- ** is committed.
+ ** and this is a RELEASE command, then the current transaction
+ ** is committed.
*/
- int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint;
- if( isTransaction && p1==SAVEPOINT_RELEASE ){
+ int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint;
+ if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){
db->autoCommit = 1;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
@@ -52563,34 +53487,33 @@ case OP_Savepoint: {
db->isTransactionSavepoint = 0;
rc = p->rc;
}else{
- int ii;
- iSavepoint = db->nSavepoint - iSavepoint - 1;
- for(ii=0; ii<db->nDb; ii++){
- rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
+ u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1;
+ for(u.as.ii=0; u.as.ii<db->nDb; u.as.ii++){
+ rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
- if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+ if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetInternalSchema(db, 0);
}
}
-
- /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
+
+ /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
** savepoints nested inside of the savepoint being operated on. */
- while( db->pSavepoint!=pSavepoint ){
- Savepoint *pTmp = db->pSavepoint;
- db->pSavepoint = pTmp->pNext;
- sqlite3DbFree(db, pTmp);
+ while( db->pSavepoint!=u.as.pSavepoint ){
+ u.as.pTmp = db->pSavepoint;
+ db->pSavepoint = u.as.pTmp->pNext;
+ sqlite3DbFree(db, u.as.pTmp);
db->nSavepoint--;
}
/* If it is a RELEASE, then destroy the savepoint being operated on too */
- if( p1==SAVEPOINT_RELEASE ){
- assert( pSavepoint==db->pSavepoint );
- db->pSavepoint = pSavepoint->pNext;
- sqlite3DbFree(db, pSavepoint);
+ if( u.as.p1==SAVEPOINT_RELEASE ){
+ assert( u.as.pSavepoint==db->pSavepoint );
+ db->pSavepoint = u.as.pSavepoint->pNext;
+ sqlite3DbFree(db, u.as.pSavepoint);
if( !isTransaction ){
db->nSavepoint--;
}
@@ -52611,40 +53534,44 @@ case OP_Savepoint: {
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
- int desiredAutoCommit = pOp->p1;
- int rollback = pOp->p2;
- int turnOnAC = desiredAutoCommit && !db->autoCommit;
-
- assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
- assert( desiredAutoCommit==1 || rollback==0 );
-
+#if 0 /* local variables moved into u.at */
+ int desiredAutoCommit;
+ int iRollback;
+ int turnOnAC;
+#endif /* local variables moved into u.at */
+
+ u.at.desiredAutoCommit = pOp->p1;
+ u.at.iRollback = pOp->p2;
+ u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit;
+ assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 );
+ assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 );
assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
- if( turnOnAC && rollback && db->activeVdbeCnt>1 ){
+ if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){
/* If this instruction implements a ROLLBACK and other VMs are
** still running, and a transaction is active, return an error indicating
- ** that the other VMs must complete first.
+ ** that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- }else if( turnOnAC && !rollback && db->writeVdbeCnt>1 ){
+ }else if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>1 ){
/* If this instruction implements a COMMIT and other VMs are writing
- ** return an error indicating that the other VMs must complete first.
+ ** return an error indicating that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- }else if( desiredAutoCommit!=db->autoCommit ){
- if( rollback ){
- assert( desiredAutoCommit==1 );
+ }else if( u.at.desiredAutoCommit!=db->autoCommit ){
+ if( u.at.iRollback ){
+ assert( u.at.desiredAutoCommit==1 );
sqlite3RollbackAll(db);
db->autoCommit = 1;
}else{
- db->autoCommit = (u8)desiredAutoCommit;
+ db->autoCommit = (u8)u.at.desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
- db->autoCommit = (u8)(1-desiredAutoCommit);
+ db->autoCommit = (u8)(1-u.at.desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
@@ -52659,10 +53586,10 @@ case OP_AutoCommit: {
goto vdbe_return;
}else{
sqlite3SetString(&p->zErrMsg, db,
- (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
- (rollback)?"cannot rollback - no transaction is active":
+ (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":(
+ (u.at.iRollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
-
+
rc = SQLITE_ERROR;
}
break;
@@ -52690,15 +53617,18 @@ case OP_AutoCommit: {
** If P2 is zero, then a read-lock is obtained on the database file.
*/
case OP_Transaction: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.au */
+ int i;
Btree *pBt;
+#endif /* local variables moved into u.au */
- assert( i>=0 && i<db->nDb );
- assert( (p->btreeMask & (1<<i))!=0 );
- pBt = db->aDb[i].pBt;
+ u.au.i = pOp->p1;
+ assert( u.au.i>=0 && u.au.i<db->nDb );
+ assert( (p->btreeMask & (1<<u.au.i))!=0 );
+ u.au.pBt = db->aDb[u.au.i].pBt;
- if( pBt ){
- rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
+ if( u.au.pBt ){
+ rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
p->pc = pc;
p->rc = rc = SQLITE_BUSY;
@@ -52714,42 +53644,31 @@ case OP_Transaction: {
/* Opcode: ReadCookie P1 P2 P3 * *
**
** Read cookie number P3 from database P1 and write it into register P2.
-** P3==0 is the schema version. P3==1 is the database format.
-** P3==2 is the recommended pager cache size, and so forth. P1==0 is
+** P3==1 is the schema version. P3==2 is the database format.
+** P3==3 is the recommended pager cache size, and so forth. P1==0 is
** the main database file and P1==1 is the database file used to store
** temporary tables.
**
-** If P1 is negative, then this is a request to read the size of a
-** databases free-list. P3 must be set to 1 in this case. The actual
-** database accessed is ((P1+1)*-1). For example, a P1 parameter of -1
-** corresponds to database 0 ("main"), a P1 of -2 is database 1 ("temp").
-**
** There must be a read-lock on the database (either a transaction
** must be started or there must be an open cursor) before
** executing this instruction.
*/
case OP_ReadCookie: { /* out2-prerelease */
+#if 0 /* local variables moved into u.av */
int iMeta;
- int iDb = pOp->p1;
- int iCookie = pOp->p3;
+ int iDb;
+ int iCookie;
+#endif /* local variables moved into u.av */
+ u.av.iDb = pOp->p1;
+ u.av.iCookie = pOp->p3;
assert( pOp->p3<SQLITE_N_BTREE_META );
- if( iDb<0 ){
- iDb = (-1*(iDb+1));
- iCookie *= -1;
- }
- assert( iDb>=0 && iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- /* The indexing of meta values at the schema layer is off by one from
- ** the indexing in the btree layer. The btree considers meta[0] to
- ** be the number of free pages in the database (a read-only value)
- ** and meta[1] to be the schema cookie. The schema layer considers
- ** meta[1] to be the schema cookie. So we have to shift the index
- ** by one in the following statement.
- */
- rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, 1 + iCookie, (u32 *)&iMeta);
- pOut->u.i = iMeta;
+ assert( u.av.iDb>=0 && u.av.iDb<db->nDb );
+ assert( db->aDb[u.av.iDb].pBt!=0 );
+ assert( (p->btreeMask & (1<<u.av.iDb))!=0 );
+
+ rc = sqlite3BtreeGetMeta(db->aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta);
+ pOut->u.i = u.av.iMeta;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -52757,31 +53676,32 @@ case OP_ReadCookie: { /* out2-prerelease */
/* Opcode: SetCookie P1 P2 P3 * *
**
** Write the content of register P3 (interpreted as an integer)
-** into cookie number P2 of database P1.
-** P2==0 is the schema version. P2==1 is the database format.
-** P2==2 is the recommended pager cache size, and so forth. P1==0 is
-** the main database file and P1==1 is the database file used to store
-** temporary tables.
+** into cookie number P2 of database P1. P2==1 is the schema version.
+** P2==2 is the database format. P2==3 is the recommended pager cache
+** size, and so forth. P1==0 is the main database file and P1==1 is the
+** database file used to store temporary tables.
**
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: { /* in3 */
+#if 0 /* local variables moved into u.aw */
Db *pDb;
+#endif /* local variables moved into u.aw */
assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pDb = &db->aDb[pOp->p1];
- assert( pDb->pBt!=0 );
+ u.aw.pDb = &db->aDb[pOp->p1];
+ assert( u.aw.pDb->pBt!=0 );
sqlite3VdbeMemIntegerify(pIn3);
/* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(pDb->pBt, 1+pOp->p2, (int)pIn3->u.i);
- if( pOp->p2==0 ){
+ rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i);
+ if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
- pDb->pSchema->schema_cookie = (int)pIn3->u.i;
+ u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
db->flags |= SQLITE_InternChanges;
- }else if( pOp->p2==1 ){
+ }else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
- pDb->pSchema->file_format = (u8)pIn3->u.i;
+ u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i;
}
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
@@ -52808,21 +53728,23 @@ case OP_SetCookie: { /* in3 */
** invoked.
*/
case OP_VerifyCookie: {
+#if 0 /* local variables moved into u.ax */
int iMeta;
Btree *pBt;
+#endif /* local variables moved into u.ax */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pBt = db->aDb[pOp->p1].pBt;
- if( pBt ){
- rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&iMeta);
+ u.ax.pBt = db->aDb[pOp->p1].pBt;
+ if( u.ax.pBt ){
+ rc = sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta);
}else{
rc = SQLITE_OK;
- iMeta = 0;
+ u.ax.iMeta = 0;
}
- if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
+ if( rc==SQLITE_OK && u.ax.iMeta!=pOp->p2 ){
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
- /* If the schema-cookie from the database file matches the cookie
+ /* If the schema-cookie from the database file matches the cookie
** stored with the in-memory representation of the schema, do
** not reload the schema from the database file.
**
@@ -52832,10 +53754,10 @@ case OP_VerifyCookie: {
** prepared queries. If such a query is out-of-date, we do not want to
** discard the database schema, as the user code implementing the
** v-table would have to be ready for the sqlite3_vtab structure itself
- ** to be invalidated whenever sqlite3_step() is called from within
+ ** to be invalidated whenever sqlite3_step() is called from within
** a v-table method.
*/
- if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
+ if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){
sqlite3ResetInternalSchema(db, pOp->p1);
}
@@ -52885,7 +53807,8 @@ case OP_VerifyCookie: {
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
** structure, then said structure defines the content and collating
** sequence of the index being opened. Otherwise, if P4 is an integer
-** value, it is set to the number of columns in the table.
+** value, it is set to the number of columns in the table, or to the
+** largest index of any column of the table that is actually used.
**
** This instruction works just like OpenRead except that it opens the cursor
** in read/write mode. For a given table, there can be one or more read-only
@@ -52895,53 +53818,61 @@ case OP_VerifyCookie: {
*/
case OP_OpenRead:
case OP_OpenWrite: {
- int nField = 0;
- KeyInfo *pKeyInfo = 0;
- int i = pOp->p1;
- int p2 = pOp->p2;
- int iDb = pOp->p3;
+#if 0 /* local variables moved into u.ay */
+ int nField;
+ KeyInfo *pKeyInfo;
+ int i;
+ int p2;
+ int iDb;
int wrFlag;
Btree *pX;
VdbeCursor *pCur;
Db *pDb;
-
- assert( iDb>=0 && iDb<db->nDb );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- pDb = &db->aDb[iDb];
- pX = pDb->pBt;
- assert( pX!=0 );
+ int flags;
+#endif /* local variables moved into u.ay */
+
+ u.ay.nField = 0;
+ u.ay.pKeyInfo = 0;
+ u.ay.i = pOp->p1;
+ u.ay.p2 = pOp->p2;
+ u.ay.iDb = pOp->p3;
+ assert( u.ay.iDb>=0 && u.ay.iDb<db->nDb );
+ assert( (p->btreeMask & (1<<u.ay.iDb))!=0 );
+ u.ay.pDb = &db->aDb[u.ay.iDb];
+ u.ay.pX = u.ay.pDb->pBt;
+ assert( u.ay.pX!=0 );
if( pOp->opcode==OP_OpenWrite ){
- wrFlag = 1;
- if( pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = pDb->pSchema->file_format;
+ u.ay.wrFlag = 1;
+ if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){
+ p->minWriteFileFormat = u.ay.pDb->pSchema->file_format;
}
}else{
- wrFlag = 0;
+ u.ay.wrFlag = 0;
}
if( pOp->p5 ){
- assert( p2>0 );
- assert( p2<=p->nMem );
- pIn2 = &p->aMem[p2];
+ assert( u.ay.p2>0 );
+ assert( u.ay.p2<=p->nMem );
+ pIn2 = &p->aMem[u.ay.p2];
sqlite3VdbeMemIntegerify(pIn2);
- p2 = (int)pIn2->u.i;
- if( p2<2 ) {
+ u.ay.p2 = (int)pIn2->u.i;
+ if( u.ay.p2<2 ) {
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
- assert( i>=0 );
+ assert( u.ay.i>=0 );
if( pOp->p4type==P4_KEYINFO ){
- pKeyInfo = pOp->p4.pKeyInfo;
- pKeyInfo->enc = ENC(p->db);
- nField = pKeyInfo->nField+1;
+ u.ay.pKeyInfo = pOp->p4.pKeyInfo;
+ u.ay.pKeyInfo->enc = ENC(p->db);
+ u.ay.nField = u.ay.pKeyInfo->nField+1;
}else if( pOp->p4type==P4_INT32 ){
- nField = pOp->p4.i;
+ u.ay.nField = pOp->p4.i;
}
- pCur = allocateCursor(p, i, nField, iDb, 1);
- if( pCur==0 ) goto no_mem;
- pCur->nullRow = 1;
- rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
- pCur->pKeyInfo = pKeyInfo;
+ u.ay.pCur = allocateCursor(p, u.ay.i, u.ay.nField, u.ay.iDb, 1);
+ if( u.ay.pCur==0 ) goto no_mem;
+ u.ay.pCur->nullRow = 1;
+ rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor);
+ u.ay.pCur->pKeyInfo = u.ay.pKeyInfo;
switch( rc ){
case SQLITE_BUSY: {
@@ -52950,34 +53881,34 @@ case OP_OpenWrite: {
goto vdbe_return;
}
case SQLITE_OK: {
- int flags = sqlite3BtreeFlags(pCur->pCursor);
- /* Sanity checking. Only the lower four bits of the flags byte should
+ u.ay.flags = sqlite3BtreeFlags(u.ay.pCur->pCursor);
+ /* Sanity checking. Only the lower four bits of the u.ay.flags byte should
** be used. Bit 3 (mask 0x08) is unpredictable. The lower 3 bits
** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
** 2 (zerodata for indices). If these conditions are not met it can
** only mean that we are dealing with a corrupt database file
*/
- if( (flags & 0xf0)!=0 || ((flags & 0x07)!=5 && (flags & 0x07)!=2) ){
+ if( (u.ay.flags & 0xf0)!=0 || ((u.ay.flags & 0x07)!=5 && (u.ay.flags & 0x07)!=2) ){
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
- pCur->isTable = (flags & BTREE_INTKEY)!=0 ?1:0;
- pCur->isIndex = (flags & BTREE_ZERODATA)!=0 ?1:0;
+ u.ay.pCur->isTable = (u.ay.flags & BTREE_INTKEY)!=0 ?1:0;
+ u.ay.pCur->isIndex = (u.ay.flags & BTREE_ZERODATA)!=0 ?1:0;
/* If P4==0 it means we are expected to open a table. If P4!=0 then
** we expect to be opening an index. If this is not what happened,
** then the database is corrupt
*/
- if( (pCur->isTable && pOp->p4type==P4_KEYINFO)
- || (pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){
+ if( (u.ay.pCur->isTable && pOp->p4type==P4_KEYINFO)
+ || (u.ay.pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
break;
}
case SQLITE_EMPTY: {
- pCur->isTable = pOp->p4type!=P4_KEYINFO;
- pCur->isIndex = !pCur->isTable;
- pCur->pCursor = 0;
+ u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO;
+ u.ay.pCur->isIndex = !u.ay.pCur->isTable;
+ u.ay.pCur->pCursor = 0;
rc = SQLITE_OK;
break;
}
@@ -53007,23 +53938,26 @@ case OP_OpenWrite: {
** that created confusion with the whole virtual-table idea.
*/
case OP_OpenEphemeral: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.az */
+ int i;
VdbeCursor *pCx;
- static const int openFlags =
+#endif /* local variables moved into u.az */
+ static const int openFlags =
SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE |
SQLITE_OPEN_DELETEONCLOSE |
SQLITE_OPEN_TRANSIENT_DB;
- assert( i>=0 );
- pCx = allocateCursor(p, i, pOp->p2, -1, 1);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
+ u.az.i = pOp->p1;
+ assert( u.az.i>=0 );
+ u.az.pCx = allocateCursor(p, u.az.i, pOp->p2, -1, 1);
+ if( u.az.pCx==0 ) goto no_mem;
+ u.az.pCx->nullRow = 1;
rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags,
- &pCx->pBt);
+ &u.az.pCx->pBt);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
+ rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
@@ -53034,21 +53968,21 @@ case OP_OpenEphemeral: {
if( pOp->p4.pKeyInfo ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA);
+ rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_ZERODATA);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
- rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1,
- (KeyInfo*)pOp->p4.z, pCx->pCursor);
- pCx->pKeyInfo = pOp->p4.pKeyInfo;
- pCx->pKeyInfo->enc = ENC(p->db);
+ rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1,
+ (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor);
+ u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo;
+ u.az.pCx->pKeyInfo->enc = ENC(p->db);
}
- pCx->isTable = 0;
+ u.az.pCx->isTable = 0;
}else{
- rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
- pCx->isTable = 1;
+ rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor);
+ u.az.pCx->isTable = 1;
}
}
- pCx->isIndex = !pCx->isTable;
+ u.az.pCx->isIndex = !u.az.pCx->isTable;
break;
}
@@ -53076,16 +54010,20 @@ case OP_OpenEphemeral: {
** the pseudo-table.
*/
case OP_OpenPseudo: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.ba */
+ int i;
VdbeCursor *pCx;
- assert( i>=0 );
- pCx = allocateCursor(p, i, pOp->p3, -1, 0);
- if( pCx==0 ) goto no_mem;
- pCx->nullRow = 1;
- pCx->pseudoTable = 1;
- pCx->ephemPseudoTable = (u8)pOp->p2;
- pCx->isTable = 1;
- pCx->isIndex = 0;
+#endif /* local variables moved into u.ba */
+
+ u.ba.i = pOp->p1;
+ assert( u.ba.i>=0 );
+ u.ba.pCx = allocateCursor(p, u.ba.i, pOp->p3, -1, 0);
+ if( u.ba.pCx==0 ) goto no_mem;
+ u.ba.pCx->nullRow = 1;
+ u.ba.pCx->pseudoTable = 1;
+ u.ba.pCx->ephemPseudoTable = (u8)pOp->p2;
+ u.ba.pCx->isTable = 1;
+ u.ba.pCx->isIndex = 0;
break;
}
@@ -53095,10 +54033,13 @@ case OP_OpenPseudo: {
** currently open, this instruction is a no-op.
*/
case OP_Close: {
- int i = pOp->p1;
- assert( i>=0 && i<p->nCursor );
- sqlite3VdbeFreeCursor(p, p->apCsr[i]);
- p->apCsr[i] = 0;
+#if 0 /* local variables moved into u.bb */
+ int i;
+#endif /* local variables moved into u.bb */
+ u.bb.i = pOp->p1;
+ assert( u.bb.i>=0 && u.bb.i<p->nCursor );
+ sqlite3VdbeFreeCursor(p, p->apCsr[u.bb.i]);
+ p->apCsr[u.bb.i] = 0;
break;
}
@@ -53158,26 +54099,31 @@ case OP_SeekLt: /* jump, in3 */
case OP_SeekLe: /* jump, in3 */
case OP_SeekGe: /* jump, in3 */
case OP_SeekGt: { /* jump, in3 */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bc */
+ int i;
+ int res;
+ int oc;
VdbeCursor *pC;
+ UnpackedRecord r;
+ int nField;
+ i64 iKey; /* The rowid we are to seek to */
+#endif /* local variables moved into u.bc */
- assert( i>=0 && i<p->nCursor );
+ u.bc.i = pOp->p1;
+ assert( u.bc.i>=0 && u.bc.i<p->nCursor );
assert( pOp->p2!=0 );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( pC->pCursor!=0 ){
- int res, oc;
- oc = pOp->opcode;
- pC->nullRow = 0;
- if( pC->isTable ){
- i64 iKey; /* The rowid we are to seek to */
-
+ u.bc.pC = p->apCsr[u.bc.i];
+ assert( u.bc.pC!=0 );
+ if( u.bc.pC->pCursor!=0 ){
+ u.bc.oc = pOp->opcode;
+ u.bc.pC->nullRow = 0;
+ if( u.bc.pC->isTable ){
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so covert it. */
applyNumericAffinity(pIn3);
- iKey = sqlite3VdbeIntValue(pIn3);
- pC->rowidIsValid = 0;
+ u.bc.iKey = sqlite3VdbeIntValue(pIn3);
+ u.bc.pC->rowidIsValid = 0;
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
@@ -53192,92 +54138,91 @@ case OP_SeekGt: { /* jump, in3 */
** point number. */
assert( (pIn3->flags & MEM_Real)!=0 );
- if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){
+ if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){
/* The P3 value is to large in magnitude to be expressed as an
** integer. */
- res = 1;
+ u.bc.res = 1;
if( pIn3->r<0 ){
- if( oc==OP_SeekGt || oc==OP_SeekGe ){
- rc = sqlite3BtreeFirst(pC->pCursor, &res);
+ if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekGe ){
+ rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}else{
- if( oc==OP_SeekLt || oc==OP_SeekLe ){
- rc = sqlite3BtreeLast(pC->pCursor, &res);
+ if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ){
+ rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
- if( res ){
+ if( u.bc.res ){
pc = pOp->p2 - 1;
}
break;
- }else if( oc==OP_SeekLt || oc==OP_SeekGe ){
+ }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){
/* Use the ceiling() function to convert real->int */
- if( pIn3->r > (double)iKey ) iKey++;
+ if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++;
}else{
/* Use the floor() function to convert real->int */
- assert( oc==OP_SeekLe || oc==OP_SeekGt );
- if( pIn3->r < (double)iKey ) iKey--;
+ assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt );
+ if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--;
}
- }
- rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
+ }
+ rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( res==0 ){
- pC->rowidIsValid = 1;
- pC->lastRowid = iKey;
+ if( u.bc.res==0 ){
+ u.bc.pC->rowidIsValid = 1;
+ u.bc.pC->lastRowid = u.bc.iKey;
}
}else{
- UnpackedRecord r;
- int nField = pOp->p4.i;
+ u.bc.nField = pOp->p4.i;
assert( pOp->p4type==P4_INT32 );
- assert( nField>0 );
- r.pKeyInfo = pC->pKeyInfo;
- r.nField = (u16)nField;
- if( oc==OP_SeekGt || oc==OP_SeekLe ){
- r.flags = UNPACKED_INCRKEY;
+ assert( u.bc.nField>0 );
+ u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo;
+ u.bc.r.nField = (u16)u.bc.nField;
+ if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){
+ u.bc.r.flags = UNPACKED_INCRKEY;
}else{
- r.flags = 0;
+ u.bc.r.flags = 0;
}
- r.aMem = &p->aMem[pOp->p3];
- rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
+ u.bc.r.aMem = &p->aMem[pOp->p3];
+ rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- pC->rowidIsValid = 0;
+ u.bc.pC->rowidIsValid = 0;
}
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+ u.bc.pC->deferredMoveto = 0;
+ u.bc.pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
- if( oc==OP_SeekGe || oc==OP_SeekGt ){
- if( res<0 || (res==0 && oc==OP_SeekGt) ){
- rc = sqlite3BtreeNext(pC->pCursor, &res);
+ if( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt ){
+ if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){
+ rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
- pC->rowidIsValid = 0;
+ u.bc.pC->rowidIsValid = 0;
}else{
- res = 0;
+ u.bc.res = 0;
}
}else{
- assert( oc==OP_SeekLt || oc==OP_SeekLe );
- if( res>0 || (res==0 && oc==OP_SeekLt) ){
- rc = sqlite3BtreePrevious(pC->pCursor, &res);
+ assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe );
+ if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){
+ rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
- pC->rowidIsValid = 0;
+ u.bc.pC->rowidIsValid = 0;
}else{
- /* res might be negative because the table is empty. Check to
+ /* u.bc.res might be negative because the table is empty. Check to
** see if this is the case.
*/
- res = sqlite3BtreeEof(pC->pCursor);
+ u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor);
}
}
assert( pOp->p2>0 );
- if( res ){
+ if( u.bc.res ){
pc = pOp->p2 - 1;
}
- }else if( !pC->pseudoTable ){
+ }else if( !u.bc.pC->pseudoTable ){
/* This happens when attempting to open the sqlite3_master table
** for read access returns SQLITE_EMPTY. In this case always
** take the jump (since there are no records in the table).
@@ -53297,18 +54242,21 @@ case OP_SeekGt: { /* jump, in3 */
** occur, no unnecessary I/O happens.
*/
case OP_Seek: { /* in2 */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bd */
+ int i;
VdbeCursor *pC;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( pC->pCursor!=0 ){
- assert( pC->isTable );
- pC->nullRow = 0;
- pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 1;
+#endif /* local variables moved into u.bd */
+
+ u.bd.i = pOp->p1;
+ assert( u.bd.i>=0 && u.bd.i<p->nCursor );
+ u.bd.pC = p->apCsr[u.bd.i];
+ assert( u.bd.pC!=0 );
+ if( u.bd.pC->pCursor!=0 ){
+ assert( u.bd.pC->isTable );
+ u.bd.pC->nullRow = 0;
+ u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
+ u.bd.pC->rowidIsValid = 0;
+ u.bd.pC->deferredMoveto = 1;
}
break;
}
@@ -53346,38 +54294,44 @@ case OP_Seek: { /* in2 */
*/
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
- int i = pOp->p1;
- int alreadyExists = 0;
+#if 0 /* local variables moved into u.be */
+ int i;
+ int alreadyExists;
VdbeCursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor!=0 ){
- int res;
- UnpackedRecord *pIdxKey;
+ int res;
+ UnpackedRecord *pIdxKey;
+ char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7];
+#endif /* local variables moved into u.be */
+
+ u.be.i = pOp->p1;
+ u.be.alreadyExists = 0;
+ assert( u.be.i>=0 && u.be.i<p->nCursor );
+ assert( p->apCsr[u.be.i]!=0 );
+ if( (u.be.pC = p->apCsr[u.be.i])->pCursor!=0 ){
- assert( pC->isTable==0 );
+ assert( u.be.pC->isTable==0 );
assert( pIn3->flags & MEM_Blob );
- pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z,
- aTempRec, sizeof(aTempRec));
- if( pIdxKey==0 ){
+ u.be.pIdxKey = sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z,
+ u.be.aTempRec, sizeof(u.be.aTempRec));
+ if( u.be.pIdxKey==0 ){
goto no_mem;
}
if( pOp->opcode==OP_Found ){
- pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
+ u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
}
- rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
- sqlite3VdbeDeleteUnpackedRecord(pIdxKey);
+ rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res);
+ sqlite3VdbeDeleteUnpackedRecord(u.be.pIdxKey);
if( rc!=SQLITE_OK ){
break;
}
- alreadyExists = (res==0);
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+ u.be.alreadyExists = (u.be.res==0);
+ u.be.pC->deferredMoveto = 0;
+ u.be.pC->cacheStatus = CACHE_STALE;
}
if( pOp->opcode==OP_Found ){
- if( alreadyExists ) pc = pOp->p2 - 1;
+ if( u.be.alreadyExists ) pc = pOp->p2 - 1;
}else{
- if( !alreadyExists ) pc = pOp->p2 - 1;
+ if( !u.be.alreadyExists ) pc = pOp->p2 - 1;
}
break;
}
@@ -53408,57 +54362,59 @@ case OP_Found: { /* jump, in3 */
** See also: NotFound, NotExists, Found
*/
case OP_IsUnique: { /* jump, in3 */
+#if 0 /* local variables moved into u.bf */
u16 ii;
VdbeCursor *pCx;
BtCursor *pCrsr;
u16 nField;
- Mem *aMem = &p->aMem[pOp->p4.i];
+ Mem *aMem;
+ UnpackedRecord r; /* B-Tree index search key */
+ i64 R; /* Rowid stored in register P3 */
+#endif /* local variables moved into u.bf */
+ u.bf.aMem = &p->aMem[pOp->p4.i];
/* Assert that the values of parameters P1 and P4 are in range. */
assert( pOp->p4type==P4_INT32 );
assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
/* Find the index cursor. */
- pCx = p->apCsr[pOp->p1];
- assert( pCx->deferredMoveto==0 );
- pCx->seekResult = 0;
- pCx->cacheStatus = CACHE_STALE;
- pCrsr = pCx->pCursor;
+ u.bf.pCx = p->apCsr[pOp->p1];
+ assert( u.bf.pCx->deferredMoveto==0 );
+ u.bf.pCx->seekResult = 0;
+ u.bf.pCx->cacheStatus = CACHE_STALE;
+ u.bf.pCrsr = u.bf.pCx->pCursor;
/* If any of the values are NULL, take the jump. */
- nField = pCx->pKeyInfo->nField;
- for(ii=0; ii<nField; ii++){
- if( aMem[ii].flags & MEM_Null ){
+ u.bf.nField = u.bf.pCx->pKeyInfo->nField;
+ for(u.bf.ii=0; u.bf.ii<u.bf.nField; u.bf.ii++){
+ if( u.bf.aMem[u.bf.ii].flags & MEM_Null ){
pc = pOp->p2 - 1;
- pCrsr = 0;
+ u.bf.pCrsr = 0;
break;
}
}
- assert( (aMem[nField].flags & MEM_Null)==0 );
-
- if( pCrsr!=0 ){
- UnpackedRecord r; /* B-Tree index search key */
- i64 R; /* Rowid stored in register P3 */
+ assert( (u.bf.aMem[u.bf.nField].flags & MEM_Null)==0 );
+ if( u.bf.pCrsr!=0 ){
/* Populate the index search key. */
- r.pKeyInfo = pCx->pKeyInfo;
- r.nField = nField + 1;
- r.flags = UNPACKED_PREFIX_SEARCH;
- r.aMem = aMem;
+ u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo;
+ u.bf.r.nField = u.bf.nField + 1;
+ u.bf.r.flags = UNPACKED_PREFIX_SEARCH;
+ u.bf.r.aMem = u.bf.aMem;
- /* Extract the value of R from register P3. */
+ /* Extract the value of u.bf.R from register P3. */
sqlite3VdbeMemIntegerify(pIn3);
- R = pIn3->u.i;
+ u.bf.R = pIn3->u.i;
/* Search the B-Tree index. If no conflicting record is found, jump
** to P2. Otherwise, copy the rowid of the conflicting record to
** register P3 and fall through to the next instruction. */
- rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &pCx->seekResult);
- if( (r.flags & UNPACKED_PREFIX_SEARCH) || r.rowid==R ){
+ rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult);
+ if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){
pc = pOp->p2 - 1;
}else{
- pIn3->u.i = r.rowid;
+ pIn3->u.i = u.bf.r.rowid;
}
}
break;
@@ -53479,36 +54435,41 @@ case OP_IsUnique: { /* jump, in3 */
** See also: Found, NotFound, IsUnique
*/
case OP_NotExists: { /* jump, in3 */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bg */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- int res = 0;
- u64 iKey;
+ int res;
+ u64 iKey;
+#endif /* local variables moved into u.bg */
+
+ u.bg.i = pOp->p1;
+ assert( u.bg.i>=0 && u.bg.i<p->nCursor );
+ assert( p->apCsr[u.bg.i]!=0 );
+ if( (u.bg.pCrsr = (u.bg.pC = p->apCsr[u.bg.i])->pCursor)!=0 ){
+ u.bg.res = 0;
assert( pIn3->flags & MEM_Int );
- assert( p->apCsr[i]->isTable );
- iKey = intToKey(pIn3->u.i);
- rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
- pC->lastRowid = pIn3->u.i;
- pC->rowidIsValid = res==0 ?1:0;
- pC->nullRow = 0;
- pC->cacheStatus = CACHE_STALE;
- pC->deferredMoveto = 0;
- if( res!=0 ){
+ assert( p->apCsr[u.bg.i]->isTable );
+ u.bg.iKey = intToKey(pIn3->u.i);
+ rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
+ u.bg.pC->lastRowid = pIn3->u.i;
+ u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
+ u.bg.pC->nullRow = 0;
+ u.bg.pC->cacheStatus = CACHE_STALE;
+ u.bg.pC->deferredMoveto = 0;
+ if( u.bg.res!=0 ){
pc = pOp->p2 - 1;
- assert( pC->rowidIsValid==0 );
+ assert( u.bg.pC->rowidIsValid==0 );
}
- pC->seekResult = res;
- }else if( !pC->pseudoTable ){
- /* This happens when an attempt to open a read cursor on the
+ u.bg.pC->seekResult = u.bg.res;
+ }else if( !u.bg.pC->pseudoTable ){
+ /* This happens when an attempt to open a read cursor on the
** sqlite_master table returns SQLITE_EMPTY.
*/
- assert( pC->isTable );
+ assert( u.bg.pC->isTable );
pc = pOp->p2 - 1;
- assert( pC->rowidIsValid==0 );
- pC->seekResult = 0;
+ assert( u.bg.pC->rowidIsValid==0 );
+ u.bg.pC->seekResult = 0;
}
break;
}
@@ -53545,12 +54506,24 @@ case OP_Sequence: { /* out2-prerelease */
** AUTOINCREMENT feature.
*/
case OP_NewRowid: { /* out2-prerelease */
- int i = pOp->p1;
- i64 v = 0;
+#if 0 /* local variables moved into u.bh */
+ int i;
+ i64 v;
VdbeCursor *pC;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor==0 ){
+ int res;
+ int rx;
+ int cnt;
+ i64 x;
+ Mem *pMem;
+#endif /* local variables moved into u.bh */
+
+ u.bh.i = pOp->p1;
+ u.bh.v = 0;
+ u.bh.res = 0;
+ u.bh.rx = SQLITE_OK;
+ assert( u.bh.i>=0 && u.bh.i<p->nCursor );
+ assert( p->apCsr[u.bh.i]!=0 );
+ if( (u.bh.pC = p->apCsr[u.bh.i])->pCursor==0 ){
/* The zero initialization above is all that is needed */
}else{
/* The next rowid or record number (different terms for the same
@@ -53567,7 +54540,7 @@ case OP_NewRowid: { /* out2-prerelease */
** and try again, up to 1000 times.
**
** For a table with less than 2 billion entries, the probability
- ** of not finding a unused rowid is about 1.0e-300. This is a
+ ** of not finding a unused rowid is about 1.0e-300. This is a
** non-zero probability, but it is still vanishingly small and should
** never cause a problem. You are much, much more likely to have a
** hardware failure than for this algorithm to fail.
@@ -53576,7 +54549,7 @@ case OP_NewRowid: { /* out2-prerelease */
** source of random numbers. Is a library function like lrand48()
** good enough? Maybe. Maybe not. It's hard to know whether there
** might be subtle bugs is some implementations of lrand48() that
- ** could cause problems. To avoid uncertainty, SQLite uses its own
+ ** could cause problems. To avoid uncertainty, SQLite uses its own
** random number generator based on the RC4 algorithm.
**
** To promote locality of reference for repetitive inserts, the
@@ -53584,16 +54557,14 @@ case OP_NewRowid: { /* out2-prerelease */
** larger than the previous rowid. This has been shown experimentally
** to double the speed of the COPY operation.
*/
- int res=0, rx=SQLITE_OK, cnt;
- i64 x;
- cnt = 0;
- if( (sqlite3BtreeFlags(pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
+ u.bh.cnt = 0;
+ if( (sqlite3BtreeFlags(u.bh.pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) !=
BTREE_INTKEY ){
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
- assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
- assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );
+ assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_INTKEY)!=0 );
+ assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_ZERODATA)==0 );
#ifdef SQLITE_32BIT_ROWID
# define MAX_ROWID 0x7fffffff
@@ -53605,75 +54576,74 @@ case OP_NewRowid: { /* out2-prerelease */
# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif
- if( !pC->useRandomRowid ){
- v = sqlite3BtreeGetCachedRowid(pC->pCursor);
- if( v==0 ){
- rc = sqlite3BtreeLast(pC->pCursor, &res);
+ if( !u.bh.pC->useRandomRowid ){
+ u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor);
+ if( u.bh.v==0 ){
+ rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( res ){
- v = 1;
+ if( u.bh.res ){
+ u.bh.v = 1;
}else{
- sqlite3BtreeKeySize(pC->pCursor, &v);
- v = keyToInt(v);
- if( v==MAX_ROWID ){
- pC->useRandomRowid = 1;
+ sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v);
+ u.bh.v = keyToInt(u.bh.v);
+ if( u.bh.v==MAX_ROWID ){
+ u.bh.pC->useRandomRowid = 1;
}else{
- v++;
+ u.bh.v++;
}
}
}
#ifndef SQLITE_OMIT_AUTOINCREMENT
if( pOp->p3 ){
- Mem *pMem;
assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */
- pMem = &p->aMem[pOp->p3];
- REGISTER_TRACE(pOp->p3, pMem);
- sqlite3VdbeMemIntegerify(pMem);
- assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
- if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
+ u.bh.pMem = &p->aMem[pOp->p3];
+ REGISTER_TRACE(pOp->p3, u.bh.pMem);
+ sqlite3VdbeMemIntegerify(u.bh.pMem);
+ assert( (u.bh.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
+ if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){
rc = SQLITE_FULL;
goto abort_due_to_error;
}
- if( v<pMem->u.i+1 ){
- v = pMem->u.i + 1;
+ if( u.bh.v<u.bh.pMem->u.i+1 ){
+ u.bh.v = u.bh.pMem->u.i + 1;
}
- pMem->u.i = v;
+ u.bh.pMem->u.i = u.bh.v;
}
#endif
- sqlite3BtreeSetCachedRowid(pC->pCursor, v<MAX_ROWID ? v+1 : 0);
+ sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0);
}
- if( pC->useRandomRowid ){
+ if( u.bh.pC->useRandomRowid ){
assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */
- v = db->priorNewRowid;
- cnt = 0;
+ u.bh.v = db->priorNewRowid;
+ u.bh.cnt = 0;
do{
- if( cnt==0 && (v&0xffffff)==v ){
- v++;
+ if( u.bh.cnt==0 && (u.bh.v&0xffffff)==u.bh.v ){
+ u.bh.v++;
}else{
- sqlite3_randomness(sizeof(v), &v);
- if( cnt<5 ) v &= 0xffffff;
+ sqlite3_randomness(sizeof(u.bh.v), &u.bh.v);
+ if( u.bh.cnt<5 ) u.bh.v &= 0xffffff;
}
- if( v==0 ) continue;
- x = intToKey(v);
- rx = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)x, 0, &res);
- cnt++;
- }while( cnt<100 && rx==SQLITE_OK && res==0 );
- db->priorNewRowid = v;
- if( rx==SQLITE_OK && res==0 ){
+ if( u.bh.v==0 ) continue;
+ u.bh.x = intToKey(u.bh.v);
+ u.bh.rx = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.x, 0, &u.bh.res);
+ u.bh.cnt++;
+ }while( u.bh.cnt<100 && u.bh.rx==SQLITE_OK && u.bh.res==0 );
+ db->priorNewRowid = u.bh.v;
+ if( u.bh.rx==SQLITE_OK && u.bh.res==0 ){
rc = SQLITE_FULL;
goto abort_due_to_error;
}
}
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+ u.bh.pC->rowidIsValid = 0;
+ u.bh.pC->deferredMoveto = 0;
+ u.bh.pC->cacheStatus = CACHE_STALE;
}
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = v;
+ pOut->u.i = u.bh.v;
break;
}
@@ -53704,78 +54674,87 @@ case OP_NewRowid: { /* out2-prerelease */
** for indices is OP_IdxInsert.
*/
case OP_Insert: {
- Mem *pData = &p->aMem[pOp->p2];
- Mem *pKey = &p->aMem[pOp->p3];
-
+#if 0 /* local variables moved into u.bi */
+ Mem *pData;
+ Mem *pKey;
i64 iKey; /* The integer ROWID or key for the record to be inserted */
- int i = pOp->p1;
+ int i;
VdbeCursor *pC;
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- assert( pC->pCursor!=0 || pC->pseudoTable );
- assert( pKey->flags & MEM_Int );
- assert( pC->isTable );
- REGISTER_TRACE(pOp->p2, pData);
- REGISTER_TRACE(pOp->p3, pKey);
-
- iKey = intToKey(pKey->u.i);
+ int nZero;
+ int seekResult;
+ const char *zDb;
+ const char *zTbl;
+ int op;
+#endif /* local variables moved into u.bi */
+
+ u.bi.pData = &p->aMem[pOp->p2];
+ u.bi.pKey = &p->aMem[pOp->p3];
+ u.bi.i = pOp->p1;
+ assert( u.bi.i>=0 && u.bi.i<p->nCursor );
+ u.bi.pC = p->apCsr[u.bi.i];
+ assert( u.bi.pC!=0 );
+ assert( u.bi.pC->pCursor!=0 || u.bi.pC->pseudoTable );
+ assert( u.bi.pKey->flags & MEM_Int );
+ assert( u.bi.pC->isTable );
+ REGISTER_TRACE(pOp->p2, u.bi.pData);
+ REGISTER_TRACE(pOp->p3, u.bi.pKey);
+
+ u.bi.iKey = intToKey(u.bi.pKey->u.i);
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
- if( pData->flags & MEM_Null ){
- pData->z = 0;
- pData->n = 0;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = u.bi.pKey->u.i;
+ if( u.bi.pData->flags & MEM_Null ){
+ u.bi.pData->z = 0;
+ u.bi.pData->n = 0;
}else{
- assert( pData->flags & (MEM_Blob|MEM_Str) );
+ assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) );
}
- if( pC->pseudoTable ){
- if( !pC->ephemPseudoTable ){
- sqlite3DbFree(db, pC->pData);
+ if( u.bi.pC->pseudoTable ){
+ if( !u.bi.pC->ephemPseudoTable ){
+ sqlite3DbFree(db, u.bi.pC->pData);
}
- pC->iKey = iKey;
- pC->nData = pData->n;
- if( pData->z==pData->zMalloc || pC->ephemPseudoTable ){
- pC->pData = pData->z;
- if( !pC->ephemPseudoTable ){
- pData->flags &= ~MEM_Dyn;
- pData->flags |= MEM_Ephem;
- pData->zMalloc = 0;
+ u.bi.pC->iKey = u.bi.iKey;
+ u.bi.pC->nData = u.bi.pData->n;
+ if( u.bi.pData->z==u.bi.pData->zMalloc || u.bi.pC->ephemPseudoTable ){
+ u.bi.pC->pData = u.bi.pData->z;
+ if( !u.bi.pC->ephemPseudoTable ){
+ u.bi.pData->flags &= ~MEM_Dyn;
+ u.bi.pData->flags |= MEM_Ephem;
+ u.bi.pData->zMalloc = 0;
}
}else{
- pC->pData = sqlite3Malloc( pC->nData+2 );
- if( !pC->pData ) goto no_mem;
- memcpy(pC->pData, pData->z, pC->nData);
- pC->pData[pC->nData] = 0;
- pC->pData[pC->nData+1] = 0;
+ u.bi.pC->pData = sqlite3Malloc( u.bi.pC->nData+2 );
+ if( !u.bi.pC->pData ) goto no_mem;
+ memcpy(u.bi.pC->pData, u.bi.pData->z, u.bi.pC->nData);
+ u.bi.pC->pData[u.bi.pC->nData] = 0;
+ u.bi.pC->pData[u.bi.pC->nData+1] = 0;
}
- pC->nullRow = 0;
+ u.bi.pC->nullRow = 0;
}else{
- int nZero;
- int seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
- if( pData->flags & MEM_Zero ){
- nZero = pData->u.nZero;
+ u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0);
+ if( u.bi.pData->flags & MEM_Zero ){
+ u.bi.nZero = u.bi.pData->u.nZero;
}else{
- nZero = 0;
+ u.bi.nZero = 0;
}
- sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
- rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
- pData->z, pData->n, nZero,
- pOp->p5 & OPFLAG_APPEND, seekResult
+ sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
+ rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey,
+ u.bi.pData->z, u.bi.pData->n, u.bi.nZero,
+ pOp->p5 & OPFLAG_APPEND, u.bi.seekResult
);
}
-
- pC->rowidIsValid = 0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
+
+ u.bi.pC->rowidIsValid = 0;
+ u.bi.pC->deferredMoveto = 0;
+ u.bi.pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[pC->iDb].zName;
- const char *zTbl = pOp->p4.z;
- int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
- assert( pC->isTable );
- db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
- assert( pC->iDb>=0 );
+ u.bi.zDb = db->aDb[u.bi.pC->iDb].zName;
+ u.bi.zTbl = pOp->p4.z;
+ u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+ assert( u.bi.pC->isTable );
+ db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey);
+ assert( u.bi.pC->iDb>=0 );
}
break;
}
@@ -53801,36 +54780,40 @@ case OP_Insert: {
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {
- int i = pOp->p1;
- i64 iKey = 0;
+#if 0 /* local variables moved into u.bj */
+ int i;
+ i64 iKey;
VdbeCursor *pC;
+#endif /* local variables moved into u.bj */
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
+ u.bj.i = pOp->p1;
+ u.bj.iKey = 0;
+ assert( u.bj.i>=0 && u.bj.i<p->nCursor );
+ u.bj.pC = p->apCsr[u.bj.i];
+ assert( u.bj.pC!=0 );
+ assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
- /* If the update-hook will be invoked, set iKey to the rowid of the
+ /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the
** row being deleted.
*/
if( db->xUpdateCallback && pOp->p4.z ){
- assert( pC->isTable );
- assert( pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
- iKey = pC->lastRowid;
+ assert( u.bj.pC->isTable );
+ assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
+ u.bj.iKey = u.bj.pC->lastRowid;
}
- rc = sqlite3VdbeCursorMoveto(pC);
+ rc = sqlite3VdbeCursorMoveto(u.bj.pC);
if( rc ) goto abort_due_to_error;
- sqlite3BtreeSetCachedRowid(pC->pCursor, 0);
- rc = sqlite3BtreeDelete(pC->pCursor);
- pC->cacheStatus = CACHE_STALE;
+ sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0);
+ rc = sqlite3BtreeDelete(u.bj.pC->pCursor);
+ u.bj.pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- const char *zDb = db->aDb[pC->iDb].zName;
+ const char *zDb = db->aDb[u.bj.pC->iDb].zName;
const char *zTbl = pOp->p4.z;
- db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, iKey);
- assert( pC->iDb>=0 );
+ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey);
+ assert( u.bj.pC->iDb>=0 );
}
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
break;
@@ -53873,48 +54856,51 @@ case OP_ResetCount: {
*/
case OP_RowKey:
case OP_RowData: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bk */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
u32 n;
+ i64 n64;
+#endif /* local variables moved into u.bk */
+ u.bk.i = pOp->p1;
pOut = &p->aMem[pOp->p2];
/* Note that RowKey and RowData are really exactly the same instruction */
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC->isTable || pOp->opcode==OP_RowKey );
- assert( pC->isIndex || pOp->opcode==OP_RowData );
- assert( pC!=0 );
- assert( pC->nullRow==0 );
- assert( pC->pseudoTable==0 );
- assert( pC->pCursor!=0 );
- pCrsr = pC->pCursor;
- rc = sqlite3VdbeCursorMoveto(pC);
+ assert( u.bk.i>=0 && u.bk.i<p->nCursor );
+ u.bk.pC = p->apCsr[u.bk.i];
+ assert( u.bk.pC->isTable || pOp->opcode==OP_RowKey );
+ assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData );
+ assert( u.bk.pC!=0 );
+ assert( u.bk.pC->nullRow==0 );
+ assert( u.bk.pC->pseudoTable==0 );
+ assert( u.bk.pC->pCursor!=0 );
+ u.bk.pCrsr = u.bk.pC->pCursor;
+ rc = sqlite3VdbeCursorMoveto(u.bk.pC);
if( rc ) goto abort_due_to_error;
- if( pC->isIndex ){
- i64 n64;
- assert( !pC->isTable );
- sqlite3BtreeKeySize(pCrsr, &n64);
- if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( u.bk.pC->isIndex ){
+ assert( !u.bk.pC->isTable );
+ sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64);
+ if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- n = (int)n64;
+ u.bk.n = (u32)u.bk.n64;
}else{
- sqlite3BtreeDataSize(pCrsr, &n);
- if( (int)n>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n);
+ if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
}
- if( sqlite3VdbeMemGrow(pOut, n, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){
goto no_mem;
}
- pOut->n = n;
+ pOut->n = u.bk.n;
MemSetTypeFlag(pOut, MEM_Blob);
- if( pC->isIndex ){
- rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
+ if( u.bk.pC->isIndex ){
+ rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z);
}else{
- rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
+ rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z);
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
@@ -53931,46 +54917,49 @@ case OP_RowData: {
** one opcode now works for both table types.
*/
case OP_Rowid: { /* out2-prerelease */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bl */
+ int i;
VdbeCursor *pC;
i64 v;
+ sqlite3_vtab *pVtab;
+ const sqlite3_module *pModule;
+#endif /* local variables moved into u.bl */
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( pC->nullRow ){
+ u.bl.i = pOp->p1;
+ assert( u.bl.i>=0 && u.bl.i<p->nCursor );
+ u.bl.pC = p->apCsr[u.bl.i];
+ assert( u.bl.pC!=0 );
+ if( u.bl.pC->nullRow ){
/* Do nothing so that reg[P2] remains NULL */
break;
- }else if( pC->deferredMoveto ){
- v = pC->movetoTarget;
- }else if( pC->pseudoTable ){
- v = keyToInt(pC->iKey);
+ }else if( u.bl.pC->deferredMoveto ){
+ u.bl.v = u.bl.pC->movetoTarget;
+ }else if( u.bl.pC->pseudoTable ){
+ u.bl.v = keyToInt(u.bl.pC->iKey);
#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( pC->pVtabCursor ){
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- pVtab = pC->pVtabCursor->pVtab;
- pModule = pVtab->pModule;
- assert( pModule->xRowid );
+ }else if( u.bl.pC->pVtabCursor ){
+ u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab;
+ u.bl.pModule = u.bl.pVtab->pModule;
+ assert( u.bl.pModule->xRowid );
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xRowid(pC->pVtabCursor, &v);
+ rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.bl.pVtab->zErrMsg;
+ u.bl.pVtab->zErrMsg = 0;
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
- rc = sqlite3VdbeCursorMoveto(pC);
+ rc = sqlite3VdbeCursorMoveto(u.bl.pC);
if( rc ) goto abort_due_to_error;
- if( pC->rowidIsValid ){
- v = pC->lastRowid;
+ if( u.bl.pC->rowidIsValid ){
+ u.bl.v = u.bl.pC->lastRowid;
}else{
- assert( pC->pCursor!=0 );
- sqlite3BtreeKeySize(pC->pCursor, &v);
- v = keyToInt(v);
+ assert( u.bl.pC->pCursor!=0 );
+ sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v);
+ u.bl.v = keyToInt(u.bl.v);
}
}
- pOut->u.i = v;
+ pOut->u.i = u.bl.v;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -53982,16 +54971,19 @@ case OP_Rowid: { /* out2-prerelease */
** write a NULL.
*/
case OP_NullRow: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bm */
+ int i;
VdbeCursor *pC;
+#endif /* local variables moved into u.bm */
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- pC->nullRow = 1;
- pC->rowidIsValid = 0;
- if( pC->pCursor ){
- sqlite3BtreeClearCursor(pC->pCursor);
+ u.bm.i = pOp->p1;
+ assert( u.bm.i>=0 && u.bm.i<p->nCursor );
+ u.bm.pC = p->apCsr[u.bm.i];
+ assert( u.bm.pC!=0 );
+ u.bm.pC->nullRow = 1;
+ u.bm.pC->rowidIsValid = 0;
+ if( u.bm.pC->pCursor ){
+ sqlite3BtreeClearCursor(u.bm.pC->pCursor);
}
break;
}
@@ -54005,22 +54997,25 @@ case OP_NullRow: {
** to the following instruction.
*/
case OP_Last: { /* jump */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bn */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- pCrsr = pC->pCursor;
- assert( pCrsr!=0 );
- rc = sqlite3BtreeLast(pCrsr, &res);
- pC->nullRow = (u8)res;
- pC->deferredMoveto = 0;
- pC->rowidIsValid = 0;
- pC->cacheStatus = CACHE_STALE;
- if( res && pOp->p2>0 ){
+#endif /* local variables moved into u.bn */
+
+ u.bn.i = pOp->p1;
+ assert( u.bn.i>=0 && u.bn.i<p->nCursor );
+ u.bn.pC = p->apCsr[u.bn.i];
+ assert( u.bn.pC!=0 );
+ u.bn.pCrsr = u.bn.pC->pCursor;
+ assert( u.bn.pCrsr!=0 );
+ rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res);
+ u.bn.pC->nullRow = (u8)u.bn.res;
+ u.bn.pC->deferredMoveto = 0;
+ u.bn.pC->rowidIsValid = 0;
+ u.bn.pC->cacheStatus = CACHE_STALE;
+ if( u.bn.res && pOp->p2>0 ){
pc = pOp->p2 - 1;
}
break;
@@ -54056,26 +55051,29 @@ case OP_Sort: { /* jump */
** to the following instruction.
*/
case OP_Rewind: { /* jump */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bo */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
-
- assert( i>=0 && i<p->nCursor );
- pC = p->apCsr[i];
- assert( pC!=0 );
- if( (pCrsr = pC->pCursor)!=0 ){
- rc = sqlite3BtreeFirst(pCrsr, &res);
- pC->atFirst = res==0 ?1:0;
- pC->deferredMoveto = 0;
- pC->cacheStatus = CACHE_STALE;
- pC->rowidIsValid = 0;
+#endif /* local variables moved into u.bo */
+
+ u.bo.i = pOp->p1;
+ assert( u.bo.i>=0 && u.bo.i<p->nCursor );
+ u.bo.pC = p->apCsr[u.bo.i];
+ assert( u.bo.pC!=0 );
+ if( (u.bo.pCrsr = u.bo.pC->pCursor)!=0 ){
+ rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res);
+ u.bo.pC->atFirst = u.bo.res==0 ?1:0;
+ u.bo.pC->deferredMoveto = 0;
+ u.bo.pC->cacheStatus = CACHE_STALE;
+ u.bo.pC->rowidIsValid = 0;
}else{
- res = 1;
+ u.bo.res = 1;
}
- pC->nullRow = (u8)res;
+ u.bo.pC->nullRow = (u8)u.bo.res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
- if( res ){
+ if( u.bo.res ){
pc = pOp->p2 - 1;
}
break;
@@ -54103,32 +55101,34 @@ case OP_Rewind: { /* jump */
*/
case OP_Prev: /* jump */
case OP_Next: { /* jump */
+#if 0 /* local variables moved into u.bp */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
+#endif /* local variables moved into u.bp */
CHECK_FOR_INTERRUPT;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- pC = p->apCsr[pOp->p1];
- if( pC==0 ){
+ u.bp.pC = p->apCsr[pOp->p1];
+ if( u.bp.pC==0 ){
break; /* See ticket #2273 */
}
- pCrsr = pC->pCursor;
- assert( pCrsr );
- res = 1;
- assert( pC->deferredMoveto==0 );
- rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
- sqlite3BtreePrevious(pCrsr, &res);
- pC->nullRow = (u8)res;
- pC->cacheStatus = CACHE_STALE;
- if( res==0 ){
+ u.bp.pCrsr = u.bp.pC->pCursor;
+ assert( u.bp.pCrsr );
+ u.bp.res = 1;
+ assert( u.bp.pC->deferredMoveto==0 );
+ rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(u.bp.pCrsr, &u.bp.res) :
+ sqlite3BtreePrevious(u.bp.pCrsr, &u.bp.res);
+ u.bp.pC->nullRow = (u8)u.bp.res;
+ u.bp.pC->cacheStatus = CACHE_STALE;
+ if( u.bp.res==0 ){
pc = pOp->p2 - 1;
if( pOp->p5 ) p->aCounter[pOp->p5-1]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
}
- pC->rowidIsValid = 0;
+ u.bp.pC->rowidIsValid = 0;
break;
}
@@ -54145,23 +55145,29 @@ case OP_Next: { /* jump */
** for tables is OP_Insert.
*/
case OP_IdxInsert: { /* in2 */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bq */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
+ int nKey;
+ const char *zKey;
+#endif /* local variables moved into u.bq */
+
+ u.bq.i = pOp->p1;
+ assert( u.bq.i>=0 && u.bq.i<p->nCursor );
+ assert( p->apCsr[u.bq.i]!=0 );
assert( pIn2->flags & MEM_Blob );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- assert( pC->isTable==0 );
+ if( (u.bq.pCrsr = (u.bq.pC = p->apCsr[u.bq.i])->pCursor)!=0 ){
+ assert( u.bq.pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
- int nKey = pIn2->n;
- const char *zKey = pIn2->z;
- rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+ u.bq.nKey = pIn2->n;
+ u.bq.zKey = pIn2->z;
+ rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3,
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0)
);
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
+ assert( u.bq.pC->deferredMoveto==0 );
+ u.bq.pC->cacheStatus = CACHE_STALE;
}
}
break;
@@ -54174,26 +55180,30 @@ case OP_IdxInsert: { /* in2 */
** index opened by cursor P1.
*/
case OP_IdxDelete: {
- int i = pOp->p1;
+#if 0 /* local variables moved into u.br */
+ int i;
VdbeCursor *pC;
BtCursor *pCrsr;
+#endif /* local variables moved into u.br */
+
+ u.br.i = pOp->p1;
assert( pOp->p3>0 );
assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 );
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
+ assert( u.br.i>=0 && u.br.i<p->nCursor );
+ assert( p->apCsr[u.br.i]!=0 );
+ if( (u.br.pCrsr = (u.br.pC = p->apCsr[u.br.i])->pCursor)!=0 ){
int res;
UnpackedRecord r;
- r.pKeyInfo = pC->pKeyInfo;
+ r.pKeyInfo = u.br.pC->pKeyInfo;
r.nField = (u16)pOp->p3;
r.flags = 0;
r.aMem = &p->aMem[pOp->p2];
- rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
+ rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &r, 0, 0, &res);
if( rc==SQLITE_OK && res==0 ){
- rc = sqlite3BtreeDelete(pCrsr);
+ rc = sqlite3BtreeDelete(u.br.pCrsr);
}
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
+ assert( u.br.pC->deferredMoveto==0 );
+ u.br.pC->cacheStatus = CACHE_STALE;
}
break;
}
@@ -54207,26 +55217,28 @@ case OP_IdxDelete: {
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: { /* out2-prerelease */
- int i = pOp->p1;
+#if 0 /* local variables moved into u.bs */
+ int i;
BtCursor *pCrsr;
VdbeCursor *pC;
-
-
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){
- i64 rowid;
- rc = sqlite3VdbeCursorMoveto(pC);
+ i64 rowid;
+#endif /* local variables moved into u.bs */
+
+ u.bs.i = pOp->p1;
+ assert( u.bs.i>=0 && u.bs.i<p->nCursor );
+ assert( p->apCsr[u.bs.i]!=0 );
+ if( (u.bs.pCrsr = (u.bs.pC = p->apCsr[u.bs.i])->pCursor)!=0 ){
+ rc = sqlite3VdbeCursorMoveto(u.bs.pC);
if( rc ) goto abort_due_to_error;
- assert( pC->deferredMoveto==0 );
- assert( pC->isTable==0 );
- if( !pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
+ assert( u.bs.pC->deferredMoveto==0 );
+ assert( u.bs.pC->isTable==0 );
+ if( !u.bs.pC->nullRow ){
+ rc = sqlite3VdbeIdxRowid(u.bs.pCrsr, &u.bs.rowid);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = rowid;
+ pOut->u.i = u.bs.rowid;
}
}
break;
@@ -54260,33 +55272,36 @@ case OP_IdxRowid: { /* out2-prerelease */
*/
case OP_IdxLT: /* jump, in3 */
case OP_IdxGE: { /* jump, in3 */
- int i= pOp->p1;
+#if 0 /* local variables moved into u.bt */
+ int i;
VdbeCursor *pC;
-
- assert( i>=0 && i<p->nCursor );
- assert( p->apCsr[i]!=0 );
- if( (pC = p->apCsr[i])->pCursor!=0 ){
- int res;
- UnpackedRecord r;
- assert( pC->deferredMoveto==0 );
+ int res;
+ UnpackedRecord r;
+#endif /* local variables moved into u.bt */
+
+ u.bt.i = pOp->p1;
+ assert( u.bt.i>=0 && u.bt.i<p->nCursor );
+ assert( p->apCsr[u.bt.i]!=0 );
+ if( (u.bt.pC = p->apCsr[u.bt.i])->pCursor!=0 ){
+ assert( u.bt.pC->deferredMoveto==0 );
assert( pOp->p5==0 || pOp->p5==1 );
assert( pOp->p4type==P4_INT32 );
- r.pKeyInfo = pC->pKeyInfo;
- r.nField = (u16)pOp->p4.i;
+ u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
+ u.bt.r.nField = (u16)pOp->p4.i;
if( pOp->p5 ){
- r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
+ u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID;
}else{
- r.flags = UNPACKED_IGNORE_ROWID;
+ u.bt.r.flags = UNPACKED_IGNORE_ROWID;
}
- r.aMem = &p->aMem[pOp->p3];
- rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res);
+ u.bt.r.aMem = &p->aMem[pOp->p3];
+ rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res);
if( pOp->opcode==OP_IdxLT ){
- res = -res;
+ u.bt.res = -u.bt.res;
}else{
assert( pOp->opcode==OP_IdxGE );
- res++;
+ u.bt.res++;
}
- if( res>0 ){
+ if( u.bt.res>0 ){
pc = pOp->p2 - 1 ;
}
}
@@ -54314,32 +55329,35 @@ case OP_IdxGE: { /* jump, in3 */
** See also: Clear
*/
case OP_Destroy: { /* out2-prerelease */
+#if 0 /* local variables moved into u.bu */
int iMoved;
int iCnt;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
Vdbe *pVdbe;
- iCnt = 0;
- for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
- if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 ){
- iCnt++;
+ int iDb;
+#endif /* local variables moved into u.bu */
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ u.bu.iCnt = 0;
+ for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){
+ if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){
+ u.bu.iCnt++;
}
}
#else
- iCnt = db->activeVdbeCnt;
+ u.bu.iCnt = db->activeVdbeCnt;
#endif
- if( iCnt>1 ){
+ if( u.bu.iCnt>1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
}else{
- int iDb = pOp->p3;
- assert( iCnt==1 );
- assert( (p->btreeMask & (1<<iDb))!=0 );
- rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
+ u.bu.iDb = pOp->p3;
+ assert( u.bu.iCnt==1 );
+ assert( (p->btreeMask & (1<<u.bu.iDb))!=0 );
+ rc = sqlite3BtreeDropTable(db->aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved);
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = iMoved;
+ pOut->u.i = u.bu.iMoved;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && iMoved!=0 ){
- sqlite3RootPageMoved(&db->aDb[iDb], iMoved, pOp->p1);
+ if( rc==SQLITE_OK && u.bu.iMoved!=0 ){
+ sqlite3RootPageMoved(&db->aDb[u.bu.iDb], u.bu.iMoved, pOp->p1);
}
#endif
}
@@ -54365,15 +55383,19 @@ case OP_Destroy: { /* out2-prerelease */
** See also: Destroy
*/
case OP_Clear: {
- int nChange = 0;
+#if 0 /* local variables moved into u.bv */
+ int nChange;
+#endif /* local variables moved into u.bv */
+
+ u.bv.nChange = 0;
assert( (p->btreeMask & (1<<pOp->p2))!=0 );
rc = sqlite3BtreeClearTable(
- db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
+ db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0)
);
if( pOp->p3 ){
- p->nChange += nChange;
+ p->nChange += u.bv.nChange;
if( pOp->p3>0 ){
- p->aMem[pOp->p3].u.i += nChange;
+ p->aMem[pOp->p3].u.i += u.bv.nChange;
}
}
break;
@@ -54403,21 +55425,25 @@ case OP_Clear: {
*/
case OP_CreateIndex: /* out2-prerelease */
case OP_CreateTable: { /* out2-prerelease */
- int pgno = 0;
+#if 0 /* local variables moved into u.bw */
+ int pgno;
int flags;
Db *pDb;
+#endif /* local variables moved into u.bw */
+
+ u.bw.pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pDb = &db->aDb[pOp->p1];
- assert( pDb->pBt!=0 );
+ u.bw.pDb = &db->aDb[pOp->p1];
+ assert( u.bw.pDb->pBt!=0 );
if( pOp->opcode==OP_CreateTable ){
- /* flags = BTREE_INTKEY; */
- flags = BTREE_LEAFDATA|BTREE_INTKEY;
+ /* u.bw.flags = BTREE_INTKEY; */
+ u.bw.flags = BTREE_LEAFDATA|BTREE_INTKEY;
}else{
- flags = BTREE_ZERODATA;
+ u.bw.flags = BTREE_ZERODATA;
}
- rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
- pOut->u.i = pgno;
+ rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags);
+ pOut->u.i = u.bw.pgno;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -54435,8 +55461,15 @@ case OP_CreateTable: { /* out2-prerelease */
** then runs the new virtual machine. It is thus a re-entrant opcode.
*/
case OP_ParseSchema: {
- int iDb = pOp->p1;
- assert( iDb>=0 && iDb<db->nDb );
+#if 0 /* local variables moved into u.bx */
+ int iDb;
+ const char *zMaster;
+ char *zSql;
+ InitData initData;
+#endif /* local variables moved into u.bx */
+
+ u.bx.iDb = pOp->p1;
+ assert( u.bx.iDb>=0 && u.bx.iDb<db->nDb );
/* If pOp->p2 is 0, then this opcode is being executed to read a
** single row, for example the row corresponding to a new index
@@ -54446,42 +55479,40 @@ case OP_ParseSchema: {
** with the rest of the schema when it is required.
**
** Although the mutex on the BtShared object that corresponds to
- ** database iDb (the database containing the sqlite_master table
+ ** database u.bx.iDb (the database containing the sqlite_master table
** read by this instruction) is currently held, it is necessary to
** obtain the mutexes on all attached databases before checking if
- ** the schema of iDb is loaded. This is because, at the start of
- ** the sqlite3_exec() call below, SQLite will invoke
+ ** the schema of u.bx.iDb is loaded. This is because, at the start of
+ ** the sqlite3_exec() call below, SQLite will invoke
** sqlite3BtreeEnterAll(). If all mutexes are not already held, the
- ** iDb mutex may be temporarily released to avoid deadlock. If
- ** this happens, then some other thread may delete the in-memory
- ** schema of database iDb before the SQL statement runs. The schema
+ ** u.bx.iDb mutex may be temporarily released to avoid deadlock. If
+ ** this happens, then some other thread may delete the in-memory
+ ** schema of database u.bx.iDb before the SQL statement runs. The schema
** will not be reloaded becuase the db->init.busy flag is set. This
** can result in a "no such table: sqlite_master" or "malformed
** database schema" error being returned to the user.
*/
- assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
+ assert( sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) );
sqlite3BtreeEnterAll(db);
- if( pOp->p2 || DbHasProperty(db, iDb, DB_SchemaLoaded) ){
- const char *zMaster = SCHEMA_TABLE(iDb);
- char *zSql;
- InitData initData;
- initData.db = db;
- initData.iDb = pOp->p1;
- initData.pzErrMsg = &p->zErrMsg;
- zSql = sqlite3MPrintf(db,
+ if( pOp->p2 || DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ){
+ u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb);
+ u.bx.initData.db = db;
+ u.bx.initData.iDb = pOp->p1;
+ u.bx.initData.pzErrMsg = &p->zErrMsg;
+ u.bx.zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
- db->aDb[iDb].zName, zMaster, pOp->p4.z);
- if( zSql==0 ){
+ db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z);
+ if( u.bx.zSql==0 ){
rc = SQLITE_NOMEM;
}else{
(void)sqlite3SafetyOff(db);
assert( db->init.busy==0 );
db->init.busy = 1;
- initData.rc = SQLITE_OK;
+ u.bx.initData.rc = SQLITE_OK;
assert( !db->mallocFailed );
- rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
- if( rc==SQLITE_OK ) rc = initData.rc;
- sqlite3DbFree(db, zSql);
+ rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0);
+ if( rc==SQLITE_OK ) rc = u.bx.initData.rc;
+ sqlite3DbFree(db, u.bx.zSql);
db->init.busy = 0;
(void)sqlite3SafetyOn(db);
}
@@ -54490,7 +55521,7 @@ case OP_ParseSchema: {
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
- break;
+ break;
}
#if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER)
@@ -54501,9 +55532,8 @@ case OP_ParseSchema: {
** the analysis to be used when preparing all subsequent queries.
*/
case OP_LoadAnalysis: {
- int iDb = pOp->p1;
- assert( iDb>=0 && iDb<db->nDb );
- rc = sqlite3AnalysisLoad(db, iDb);
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ rc = sqlite3AnalysisLoad(db, pOp->p1);
break;
}
#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */
@@ -54567,39 +55597,41 @@ case OP_DropTrigger: {
** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
+#if 0 /* local variables moved into u.by */
int nRoot; /* Number of tables to check. (Number of root pages.) */
int *aRoot; /* Array of rootpage numbers for tables to be checked */
int j; /* Loop counter */
int nErr; /* Number of errors reported */
char *z; /* Text of the error report */
Mem *pnErr; /* Register keeping track of errors remaining */
-
- nRoot = pOp->p2;
- assert( nRoot>0 );
- aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
- if( aRoot==0 ) goto no_mem;
+#endif /* local variables moved into u.by */
+
+ u.by.nRoot = pOp->p2;
+ assert( u.by.nRoot>0 );
+ u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) );
+ if( u.by.aRoot==0 ) goto no_mem;
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pnErr = &p->aMem[pOp->p3];
- assert( (pnErr->flags & MEM_Int)!=0 );
- assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
+ u.by.pnErr = &p->aMem[pOp->p3];
+ assert( (u.by.pnErr->flags & MEM_Int)!=0 );
+ assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
pIn1 = &p->aMem[pOp->p1];
- for(j=0; j<nRoot; j++){
- aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]);
+ for(u.by.j=0; u.by.j<u.by.nRoot; u.by.j++){
+ u.by.aRoot[u.by.j] = (int)sqlite3VdbeIntValue(&pIn1[u.by.j]);
}
- aRoot[j] = 0;
+ u.by.aRoot[u.by.j] = 0;
assert( pOp->p5<db->nDb );
assert( (p->btreeMask & (1<<pOp->p5))!=0 );
- z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
- (int)pnErr->u.i, &nErr);
- sqlite3DbFree(db, aRoot);
- pnErr->u.i -= nErr;
+ u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot,
+ (int)u.by.pnErr->u.i, &u.by.nErr);
+ sqlite3DbFree(db, u.by.aRoot);
+ u.by.pnErr->u.i -= u.by.nErr;
sqlite3VdbeMemSetNull(pIn1);
- if( nErr==0 ){
- assert( z==0 );
- }else if( z==0 ){
+ if( u.by.nErr==0 ){
+ assert( u.by.z==0 );
+ }else if( u.by.z==0 ){
goto no_mem;
}else{
- sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
+ sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
sqlite3VdbeChangeEncoding(pIn1, encoding);
@@ -54615,18 +55647,20 @@ case OP_IntegrityCk: {
** An assertion fails if P2 is not an integer.
*/
case OP_RowSetAdd: { /* in2 */
+#if 0 /* local variables moved into u.bz */
Mem *pIdx;
Mem *pVal;
+#endif /* local variables moved into u.bz */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
- pIdx = &p->aMem[pOp->p1];
+ u.bz.pIdx = &p->aMem[pOp->p1];
assert( pOp->p2>0 && pOp->p2<=p->nMem );
- pVal = &p->aMem[pOp->p2];
- assert( (pVal->flags & MEM_Int)!=0 );
- if( (pIdx->flags & MEM_RowSet)==0 ){
- sqlite3VdbeMemSetRowSet(pIdx);
- if( (pIdx->flags & MEM_RowSet)==0 ) goto no_mem;
+ u.bz.pVal = &p->aMem[pOp->p2];
+ assert( (u.bz.pVal->flags & MEM_Int)!=0 );
+ if( (u.bz.pIdx->flags & MEM_RowSet)==0 ){
+ sqlite3VdbeMemSetRowSet(u.bz.pIdx);
+ if( (u.bz.pIdx->flags & MEM_RowSet)==0 ) goto no_mem;
}
- sqlite3RowSetInsert(pIdx->u.pRowSet, pVal->u.i);
+ sqlite3RowSetInsert(u.bz.pIdx->u.pRowSet, u.bz.pVal->u.i);
break;
}
@@ -54637,22 +55671,24 @@ case OP_RowSetAdd: { /* in2 */
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: { /* jump, out3 */
+#if 0 /* local variables moved into u.ca */
Mem *pIdx;
i64 val;
+#endif /* local variables moved into u.ca */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
CHECK_FOR_INTERRUPT;
- pIdx = &p->aMem[pOp->p1];
+ u.ca.pIdx = &p->aMem[pOp->p1];
pOut = &p->aMem[pOp->p3];
- if( (pIdx->flags & MEM_RowSet)==0
- || sqlite3RowSetNext(pIdx->u.pRowSet, &val)==0
+ if( (u.ca.pIdx->flags & MEM_RowSet)==0
+ || sqlite3RowSetNext(u.ca.pIdx->u.pRowSet, &u.ca.val)==0
){
/* The boolean index is empty */
- sqlite3VdbeMemSetNull(pIdx);
+ sqlite3VdbeMemSetNull(u.ca.pIdx);
pc = pOp->p2 - 1;
}else{
/* A value was pulled from the index */
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- sqlite3VdbeMemSetInt64(pOut, val);
+ sqlite3VdbeMemSetInt64(pOut, u.ca.val);
}
break;
}
@@ -54681,7 +55717,12 @@ case OP_RowSetRead: { /* jump, out3 */
** inserted as part of some other set).
*/
case OP_RowSetTest: { /* jump, in1, in3 */
- int iSet = pOp->p4.i;
+#if 0 /* local variables moved into u.cb */
+ int iSet;
+ int exists;
+#endif /* local variables moved into u.cb */
+
+ u.cb.iSet = pOp->p4.i;
assert( pIn3->flags&MEM_Int );
/* If there is anything other than a rowset object in memory cell P1,
@@ -54693,18 +55734,17 @@ case OP_RowSetTest: { /* jump, in1, in3 */
}
assert( pOp->p4type==P4_INT32 );
- assert( iSet==-1 || iSet>=0 );
- if( iSet ){
- int exists;
- exists = sqlite3RowSetTest(pIn1->u.pRowSet,
- (u8)(iSet>=0 ? iSet & 0xf : 0xff),
+ assert( u.cb.iSet==-1 || u.cb.iSet>=0 );
+ if( u.cb.iSet ){
+ u.cb.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
+ (u8)(u.cb.iSet>=0 ? u.cb.iSet & 0xf : 0xff),
pIn3->u.i);
- if( exists ){
+ if( u.cb.exists ){
pc = pOp->p2 - 1;
break;
}
}
- if( iSet>=0 ){
+ if( u.cb.iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
}
break;
@@ -54719,20 +55759,23 @@ case OP_RowSetTest: { /* jump, in1, in3 */
** count, and the current statement change count.
*/
case OP_ContextPush: {
- int i = p->contextStackTop++;
+#if 0 /* local variables moved into u.cc */
+ int i;
Context *pContext;
+#endif /* local variables moved into u.cc */
- assert( i>=0 );
+ u.cc.i = p->contextStackTop++;
+ assert( u.cc.i>=0 );
/* FIX ME: This should be allocated as part of the vdbe at compile-time */
- if( i>=p->contextStackDepth ){
- p->contextStackDepth = i+1;
+ if( u.cc.i>=p->contextStackDepth ){
+ p->contextStackDepth = u.cc.i+1;
p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack,
- sizeof(Context)*(i+1));
+ sizeof(Context)*(u.cc.i+1));
if( p->contextStack==0 ) goto no_mem;
}
- pContext = &p->contextStack[i];
- pContext->lastRowid = db->lastRowid;
- pContext->nChange = p->nChange;
+ u.cc.pContext = &p->contextStack[u.cc.i];
+ u.cc.pContext->lastRowid = db->lastRowid;
+ u.cc.pContext->nChange = p->nChange;
break;
}
@@ -54743,10 +55786,13 @@ case OP_ContextPush: {
** change count, and the current statement change count.
*/
case OP_ContextPop: {
- Context *pContext = &p->contextStack[--p->contextStackTop];
+#if 0 /* local variables moved into u.cd */
+ Context *pContext;
+#endif /* local variables moved into u.cd */
+ u.cd.pContext = &p->contextStack[--p->contextStackTop];
assert( p->contextStackTop>=0 );
- db->lastRowid = pContext->lastRowid;
- p->nChange = pContext->nChange;
+ db->lastRowid = u.cd.pContext->lastRowid;
+ p->nChange = u.cd.pContext->nChange;
break;
}
#endif /* #ifndef SQLITE_OMIT_TRIGGER */
@@ -54826,43 +55872,47 @@ case OP_IfZero: { /* jump, in1 */
** successors.
*/
case OP_AggStep: {
- int n = pOp->p5;
+#if 0 /* local variables moved into u.ce */
+ int n;
int i;
- Mem *pMem, *pRec;
+ Mem *pMem;
+ Mem *pRec;
sqlite3_context ctx;
sqlite3_value **apVal;
-
- assert( n>=0 );
- pRec = &p->aMem[pOp->p2];
- apVal = p->apArg;
- assert( apVal || n==0 );
- for(i=0; i<n; i++, pRec++){
- apVal[i] = pRec;
- storeTypeInfo(pRec, encoding);
- }
- ctx.pFunc = pOp->p4.pFunc;
+#endif /* local variables moved into u.ce */
+
+ u.ce.n = pOp->p5;
+ assert( u.ce.n>=0 );
+ u.ce.pRec = &p->aMem[pOp->p2];
+ u.ce.apVal = p->apArg;
+ assert( u.ce.apVal || u.ce.n==0 );
+ for(u.ce.i=0; u.ce.i<u.ce.n; u.ce.i++, u.ce.pRec++){
+ u.ce.apVal[u.ce.i] = u.ce.pRec;
+ storeTypeInfo(u.ce.pRec, encoding);
+ }
+ u.ce.ctx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- ctx.pMem = pMem = &p->aMem[pOp->p3];
- pMem->n++;
- ctx.s.flags = MEM_Null;
- ctx.s.z = 0;
- ctx.s.zMalloc = 0;
- ctx.s.xDel = 0;
- ctx.s.db = db;
- ctx.isError = 0;
- ctx.pColl = 0;
- if( ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
+ u.ce.ctx.pMem = u.ce.pMem = &p->aMem[pOp->p3];
+ u.ce.pMem->n++;
+ u.ce.ctx.s.flags = MEM_Null;
+ u.ce.ctx.s.z = 0;
+ u.ce.ctx.s.zMalloc = 0;
+ u.ce.ctx.s.xDel = 0;
+ u.ce.ctx.s.db = db;
+ u.ce.ctx.isError = 0;
+ u.ce.ctx.pColl = 0;
+ if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- ctx.pColl = pOp[-1].p4.pColl;
+ u.ce.ctx.pColl = pOp[-1].p4.pColl;
}
- (ctx.pFunc->xStep)(&ctx, n, apVal);
- if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
- rc = ctx.isError;
+ (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal);
+ if( u.ce.ctx.isError ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s));
+ rc = u.ce.ctx.isError;
}
- sqlite3VdbeMemRelease(&ctx.s);
+ sqlite3VdbeMemRelease(&u.ce.ctx.s);
break;
}
@@ -54879,17 +55929,19 @@ case OP_AggStep: {
** the step function was not previously called.
*/
case OP_AggFinal: {
+#if 0 /* local variables moved into u.cf */
Mem *pMem;
+#endif /* local variables moved into u.cf */
assert( pOp->p1>0 && pOp->p1<=p->nMem );
- pMem = &p->aMem[pOp->p1];
- assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
- rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
+ u.cf.pMem = &p->aMem[pOp->p1];
+ assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+ rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc);
if( rc==SQLITE_ERROR ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem));
}
- sqlite3VdbeChangeEncoding(pMem, encoding);
- UPDATE_MAX_BLOBSIZE(pMem);
- if( sqlite3VdbeMemTooBig(pMem) ){
+ sqlite3VdbeChangeEncoding(u.cf.pMem, encoding);
+ UPDATE_MAX_BLOBSIZE(u.cf.pMem);
+ if( sqlite3VdbeMemTooBig(u.cf.pMem) ){
goto too_big;
}
break;
@@ -54919,12 +55971,14 @@ case OP_Vacuum: {
** P2. Otherwise, fall through to the next instruction.
*/
case OP_IncrVacuum: { /* jump */
+#if 0 /* local variables moved into u.cg */
Btree *pBt;
+#endif /* local variables moved into u.cg */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (1<<pOp->p1))!=0 );
- pBt = db->aDb[pOp->p1].pBt;
- rc = sqlite3BtreeIncrVacuum(pBt);
+ u.cg.pBt = db->aDb[pOp->p1].pBt;
+ rc = sqlite3BtreeIncrVacuum(u.cg.pBt);
if( rc==SQLITE_DONE ){
pc = pOp->p2 - 1;
rc = SQLITE_OK;
@@ -54967,12 +56021,17 @@ case OP_Expire: {
** used to generate an error message if the lock cannot be obtained.
*/
case OP_TableLock: {
- int p1 = pOp->p1;
- u8 isWriteLock = (u8)pOp->p3;
- assert( p1>=0 && p1<db->nDb );
- assert( (p->btreeMask & (1<<p1))!=0 );
- assert( isWriteLock==0 || isWriteLock==1 );
- rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
+#if 0 /* local variables moved into u.ch */
+ int p1;
+ u8 isWriteLock;
+#endif /* local variables moved into u.ch */
+
+ u.ch.p1 = pOp->p1;
+ u.ch.isWriteLock = (u8)pOp->p3;
+ assert( u.ch.p1>=0 && u.ch.p1<db->nDb );
+ assert( (p->btreeMask & (1<<u.ch.p1))!=0 );
+ assert( u.ch.isWriteLock==0 || u.ch.isWriteLock==1 );
+ rc = sqlite3BtreeLockTable(db->aDb[u.ch.p1].pBt, pOp->p2, u.ch.isWriteLock);
if( (rc&0xFF)==SQLITE_LOCKED ){
const char *z = pOp->p4.z;
sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
@@ -54992,12 +56051,15 @@ case OP_TableLock: {
** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- rc = sqlite3VtabBegin(db, pVtab);
- if( pVtab ){
+#if 0 /* local variables moved into u.ci */
+ sqlite3_vtab *pVtab;
+#endif /* local variables moved into u.ci */
+ u.ci.pVtab = pOp->p4.pVtab;
+ rc = sqlite3VtabBegin(db, u.ci.pVtab);
+ if( u.ci.pVtab ){
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.ci.pVtab->zErrMsg;
+ u.ci.pVtab->zErrMsg = 0;
}
break;
}
@@ -55037,31 +56099,36 @@ case OP_VDestroy: {
** table and stores that cursor in P1.
*/
case OP_VOpen: {
- VdbeCursor *pCur = 0;
- sqlite3_vtab_cursor *pVtabCursor = 0;
-
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
-
- assert(pVtab && pModule);
+#if 0 /* local variables moved into u.cj */
+ VdbeCursor *pCur;
+ sqlite3_vtab_cursor *pVtabCursor;
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pModule;
+#endif /* local variables moved into u.cj */
+
+ u.cj.pCur = 0;
+ u.cj.pVtabCursor = 0;
+ u.cj.pVtab = pOp->p4.pVtab;
+ u.cj.pModule = (sqlite3_module *)u.cj.pVtab->pModule;
+ assert(u.cj.pVtab && u.cj.pModule);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xOpen(pVtab, &pVtabCursor);
+ rc = u.cj.pModule->xOpen(u.cj.pVtab, &u.cj.pVtabCursor);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.cj.pVtab->zErrMsg;
+ u.cj.pVtab->zErrMsg = 0;
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
- pVtabCursor->pVtab = pVtab;
+ u.cj.pVtabCursor->pVtab = u.cj.pVtab;
/* Initialise vdbe cursor object */
- pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
- if( pCur ){
- pCur->pVtabCursor = pVtabCursor;
- pCur->pModule = pVtabCursor->pVtab->pModule;
+ u.cj.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
+ if( u.cj.pCur ){
+ u.cj.pCur->pVtabCursor = u.cj.pVtabCursor;
+ u.cj.pCur->pModule = u.cj.pVtabCursor->pVtab->pModule;
}else{
db->mallocFailed = 1;
- pModule->xClose(pVtabCursor);
+ u.cj.pModule->xClose(u.cj.pVtabCursor);
}
}
break;
@@ -55088,56 +56155,62 @@ case OP_VOpen: {
** A jump is made to P2 if the result set after filtering would be empty.
*/
case OP_VFilter: { /* jump */
+#if 0 /* local variables moved into u.ck */
int nArg;
int iQuery;
const sqlite3_module *pModule;
- Mem *pQuery = &p->aMem[pOp->p3];
- Mem *pArgc = &pQuery[1];
+ Mem *pQuery;
+ Mem *pArgc;
sqlite3_vtab_cursor *pVtabCursor;
sqlite3_vtab *pVtab;
-
- VdbeCursor *pCur = p->apCsr[pOp->p1];
-
- REGISTER_TRACE(pOp->p3, pQuery);
- assert( pCur->pVtabCursor );
- pVtabCursor = pCur->pVtabCursor;
- pVtab = pVtabCursor->pVtab;
- pModule = pVtab->pModule;
+ VdbeCursor *pCur;
+ int res;
+ int i;
+ Mem **apArg;
+#endif /* local variables moved into u.ck */
+
+ u.ck.pQuery = &p->aMem[pOp->p3];
+ u.ck.pArgc = &u.ck.pQuery[1];
+ u.ck.pCur = p->apCsr[pOp->p1];
+ REGISTER_TRACE(pOp->p3, u.ck.pQuery);
+ assert( u.ck.pCur->pVtabCursor );
+ u.ck.pVtabCursor = u.ck.pCur->pVtabCursor;
+ u.ck.pVtab = u.ck.pVtabCursor->pVtab;
+ u.ck.pModule = u.ck.pVtab->pModule;
/* Grab the index number and argc parameters */
- assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
- nArg = (int)pArgc->u.i;
- iQuery = (int)pQuery->u.i;
+ assert( (u.ck.pQuery->flags&MEM_Int)!=0 && u.ck.pArgc->flags==MEM_Int );
+ u.ck.nArg = (int)u.ck.pArgc->u.i;
+ u.ck.iQuery = (int)u.ck.pQuery->u.i;
/* Invoke the xFilter method */
{
- int res = 0;
- int i;
- Mem **apArg = p->apArg;
- for(i = 0; i<nArg; i++){
- apArg[i] = &pArgc[i+1];
- storeTypeInfo(apArg[i], 0);
+ u.ck.res = 0;
+ u.ck.apArg = p->apArg;
+ for(u.ck.i = 0; u.ck.i<u.ck.nArg; u.ck.i++){
+ u.ck.apArg[u.ck.i] = &u.ck.pArgc[u.ck.i+1];
+ storeTypeInfo(u.ck.apArg[u.ck.i], 0);
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
+ sqlite3VtabLock(u.ck.pVtab);
p->inVtabMethod = 1;
- rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
+ rc = u.ck.pModule->xFilter(u.ck.pVtabCursor, u.ck.iQuery, pOp->p4.z, u.ck.nArg, u.ck.apArg);
p->inVtabMethod = 0;
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
+ p->zErrMsg = u.ck.pVtab->zErrMsg;
+ u.ck.pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, u.ck.pVtab);
if( rc==SQLITE_OK ){
- res = pModule->xEof(pVtabCursor);
+ u.ck.res = u.ck.pModule->xEof(u.ck.pVtabCursor);
}
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( res ){
+ if( u.ck.res ){
pc = pOp->p2 - 1;
}
}
- pCur->nullRow = 0;
+ u.ck.pCur->nullRow = 0;
break;
}
@@ -55151,51 +56224,53 @@ case OP_VFilter: { /* jump */
** P1 cursor is pointing to into register P3.
*/
case OP_VColumn: {
+#if 0 /* local variables moved into u.cl */
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
Mem *pDest;
sqlite3_context sContext;
+#endif /* local variables moved into u.cl */
VdbeCursor *pCur = p->apCsr[pOp->p1];
assert( pCur->pVtabCursor );
assert( pOp->p3>0 && pOp->p3<=p->nMem );
- pDest = &p->aMem[pOp->p3];
+ u.cl.pDest = &p->aMem[pOp->p3];
if( pCur->nullRow ){
- sqlite3VdbeMemSetNull(pDest);
+ sqlite3VdbeMemSetNull(u.cl.pDest);
break;
}
- pVtab = pCur->pVtabCursor->pVtab;
- pModule = pVtab->pModule;
- assert( pModule->xColumn );
- memset(&sContext, 0, sizeof(sContext));
+ u.cl.pVtab = pCur->pVtabCursor->pVtab;
+ u.cl.pModule = u.cl.pVtab->pModule;
+ assert( u.cl.pModule->xColumn );
+ memset(&u.cl.sContext, 0, sizeof(u.cl.sContext));
/* The output cell may already have a buffer allocated. Move
- ** the current contents to sContext.s so in case the user-function
- ** can use the already allocated buffer instead of allocating a
+ ** the current contents to u.cl.sContext.s so in case the user-function
+ ** can use the already allocated buffer instead of allocating a
** new one.
*/
- sqlite3VdbeMemMove(&sContext.s, pDest);
- MemSetTypeFlag(&sContext.s, MEM_Null);
+ sqlite3VdbeMemMove(&u.cl.sContext.s, u.cl.pDest);
+ MemSetTypeFlag(&u.cl.sContext.s, MEM_Null);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
+ rc = u.cl.pModule->xColumn(pCur->pVtabCursor, &u.cl.sContext, pOp->p2);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
+ p->zErrMsg = u.cl.pVtab->zErrMsg;
+ u.cl.pVtab->zErrMsg = 0;
/* Copy the result of the function to the P3 register. We
** do this regardless of whether or not an error occurred to ensure any
- ** dynamic allocation in sContext.s (a Mem struct) is released.
+ ** dynamic allocation in u.cl.sContext.s (a Mem struct) is released.
*/
- sqlite3VdbeChangeEncoding(&sContext.s, encoding);
- REGISTER_TRACE(pOp->p3, pDest);
- sqlite3VdbeMemMove(pDest, &sContext.s);
- UPDATE_MAX_BLOBSIZE(pDest);
+ sqlite3VdbeChangeEncoding(&u.cl.sContext.s, encoding);
+ REGISTER_TRACE(pOp->p3, u.cl.pDest);
+ sqlite3VdbeMemMove(u.cl.pDest, &u.cl.sContext.s);
+ UPDATE_MAX_BLOBSIZE(u.cl.pDest);
if( sqlite3SafetyOn(db) ){
goto abort_due_to_misuse;
}
- if( sqlite3VdbeMemTooBig(pDest) ){
+ if( sqlite3VdbeMemTooBig(u.cl.pDest) ){
goto too_big;
}
break;
@@ -55210,40 +56285,44 @@ case OP_VColumn: {
** the end of its result set, then fall through to the next instruction.
*/
case OP_VNext: { /* jump */
+#if 0 /* local variables moved into u.cm */
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
- int res = 0;
+ int res;
+ VdbeCursor *pCur;
+#endif /* local variables moved into u.cm */
- VdbeCursor *pCur = p->apCsr[pOp->p1];
- assert( pCur->pVtabCursor );
- if( pCur->nullRow ){
+ u.cm.res = 0;
+ u.cm.pCur = p->apCsr[pOp->p1];
+ assert( u.cm.pCur->pVtabCursor );
+ if( u.cm.pCur->nullRow ){
break;
}
- pVtab = pCur->pVtabCursor->pVtab;
- pModule = pVtab->pModule;
- assert( pModule->xNext );
+ u.cm.pVtab = u.cm.pCur->pVtabCursor->pVtab;
+ u.cm.pModule = u.cm.pVtab->pModule;
+ assert( u.cm.pModule->xNext );
/* Invoke the xNext() method of the module. There is no way for the
** underlying implementation to return an error if one occurs during
- ** xNext(). Instead, if an error occurs, true is returned (indicating that
+ ** xNext(). Instead, if an error occurs, true is returned (indicating that
** data is available) and the error code returned when xColumn or
** some other method is next invoked on the save virtual table cursor.
*/
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
+ sqlite3VtabLock(u.cm.pVtab);
p->inVtabMethod = 1;
- rc = pModule->xNext(pCur->pVtabCursor);
+ rc = u.cm.pModule->xNext(u.cm.pCur->pVtabCursor);
p->inVtabMethod = 0;
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
+ p->zErrMsg = u.cm.pVtab->zErrMsg;
+ u.cm.pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, u.cm.pVtab);
if( rc==SQLITE_OK ){
- res = pModule->xEof(pCur->pVtabCursor);
+ u.cm.res = u.cm.pModule->xEof(u.cm.pCur->pVtabCursor);
}
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
- if( !res ){
+ if( !u.cm.res ){
/* If there is data, jump to P2 */
pc = pOp->p2 - 1;
}
@@ -55259,20 +56338,25 @@ case OP_VNext: { /* jump */
** in register P1 is passed as the zName argument to the xRename method.
*/
case OP_VRename: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- Mem *pName = &p->aMem[pOp->p1];
- assert( pVtab->pModule->xRename );
- REGISTER_TRACE(pOp->p1, pName);
+#if 0 /* local variables moved into u.cn */
+ sqlite3_vtab *pVtab;
+ Mem *pName;
+#endif /* local variables moved into u.cn */
+
+ u.cn.pVtab = pOp->p4.pVtab;
+ u.cn.pName = &p->aMem[pOp->p1];
+ assert( u.cn.pVtab->pModule->xRename );
+ REGISTER_TRACE(pOp->p1, u.cn.pName);
- Stringify(pName, encoding);
+ Stringify(u.cn.pName, encoding);
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
- rc = pVtab->pModule->xRename(pVtab, pName->z);
+ sqlite3VtabLock(u.cn.pVtab);
+ rc = u.cn.pVtab->pModule->xRename(u.cn.pVtab, u.cn.pName->z);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
+ p->zErrMsg = u.cn.pVtab->zErrMsg;
+ u.cn.pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, u.cn.pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
break;
@@ -55304,34 +56388,42 @@ case OP_VRename: {
** is set to the value of the rowid for the row just inserted.
*/
case OP_VUpdate: {
- sqlite3_vtab *pVtab = pOp->p4.pVtab;
- sqlite3_module *pModule = (sqlite3_module *)pVtab->pModule;
- int nArg = pOp->p2;
+#if 0 /* local variables moved into u.co */
+ sqlite3_vtab *pVtab;
+ sqlite3_module *pModule;
+ int nArg;
+ int i;
+ sqlite_int64 rowid;
+ Mem **apArg;
+ Mem *pX;
+#endif /* local variables moved into u.co */
+
+ u.co.pVtab = pOp->p4.pVtab;
+ u.co.pModule = (sqlite3_module *)u.co.pVtab->pModule;
+ u.co.nArg = pOp->p2;
assert( pOp->p4type==P4_VTAB );
- if( pModule->xUpdate==0 ){
+ if( u.co.pModule->xUpdate==0 ){
sqlite3SetString(&p->zErrMsg, db, "read-only table");
rc = SQLITE_ERROR;
}else{
- int i;
- sqlite_int64 rowid;
- Mem **apArg = p->apArg;
- Mem *pX = &p->aMem[pOp->p3];
- for(i=0; i<nArg; i++){
- storeTypeInfo(pX, 0);
- apArg[i] = pX;
- pX++;
+ u.co.apArg = p->apArg;
+ u.co.pX = &p->aMem[pOp->p3];
+ for(u.co.i=0; u.co.i<u.co.nArg; u.co.i++){
+ storeTypeInfo(u.co.pX, 0);
+ u.co.apArg[u.co.i] = u.co.pX;
+ u.co.pX++;
}
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
- sqlite3VtabLock(pVtab);
- rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
+ sqlite3VtabLock(u.co.pVtab);
+ rc = u.co.pModule->xUpdate(u.co.pVtab, u.co.nArg, u.co.apArg, &u.co.rowid);
sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = pVtab->zErrMsg;
- pVtab->zErrMsg = 0;
- sqlite3VtabUnlock(db, pVtab);
+ p->zErrMsg = u.co.pVtab->zErrMsg;
+ u.co.pVtab->zErrMsg = 0;
+ sqlite3VtabUnlock(db, u.co.pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( pOp->p1 && rc==SQLITE_OK ){
- assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
- db->lastRowid = rowid;
+ assert( u.co.nArg>1 && u.co.apArg[0] && (u.co.apArg[0]->flags&MEM_Null) );
+ db->lastRowid = u.co.rowid;
}
p->nChange++;
}
@@ -55345,14 +56437,18 @@ case OP_VUpdate: {
** Write the current number of pages in database P1 to memory cell P2.
*/
case OP_Pagecount: { /* out2-prerelease */
- int p1 = pOp->p1;
+#if 0 /* local variables moved into u.cp */
+ int p1;
int nPage;
- Pager *pPager = sqlite3BtreePager(db->aDb[p1].pBt);
+ Pager *pPager;
+#endif /* local variables moved into u.cp */
- rc = sqlite3PagerPagecount(pPager, &nPage);
+ u.cp.p1 = pOp->p1;
+ u.cp.pPager = sqlite3BtreePager(db->aDb[u.cp.p1].pBt);
+ rc = sqlite3PagerPagecount(u.cp.pPager, &u.cp.nPage);
if( rc==SQLITE_OK ){
pOut->flags = MEM_Int;
- pOut->u.i = nPage;
+ pOut->u.i = u.cp.nPage;
}
break;
}
@@ -55365,14 +56461,18 @@ case OP_Pagecount: { /* out2-prerelease */
** the UTF-8 string contained in P4 is emitted on the trace callback.
*/
case OP_Trace: {
- char *zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
- if( zTrace ){
+#if 0 /* local variables moved into u.cq */
+ char *zTrace;
+#endif /* local variables moved into u.cq */
+
+ u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+ if( u.cq.zTrace ){
if( db->xTrace ){
- db->xTrace(db->pTraceArg, zTrace);
+ db->xTrace(db->pTraceArg, u.cq.zTrace);
}
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0 ){
- sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
+ sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace);
}
#endif /* SQLITE_DEBUG */
}
@@ -55584,39 +56684,46 @@ SQLITE_API int sqlite3_blob_open(
Vdbe *v = 0;
int rc = SQLITE_OK;
- char zErr[128];
+ char *zErr = 0;
+ Table *pTab;
+ Parse *pParse;
- zErr[0] = 0;
+ *ppBlob = 0;
sqlite3_mutex_enter(db->mutex);
+ pParse = sqlite3StackAllocRaw(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM;
+ goto blob_open_out;
+ }
do {
- Parse sParse;
- Table *pTab;
-
- memset(&sParse, 0, sizeof(Parse));
- sParse.db = db;
+ memset(pParse, 0, sizeof(Parse));
+ pParse->db = db;
if( sqlite3SafetyOn(db) ){
+ sqlite3DbFree(db, zErr);
+ sqlite3StackFree(db, pParse);
sqlite3_mutex_leave(db->mutex);
return SQLITE_MISUSE;
}
sqlite3BtreeEnterAll(db);
- pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb);
+ pTab = sqlite3LocateTable(pParse, 0, zTable, zDb);
if( pTab && IsVirtual(pTab) ){
pTab = 0;
- sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable);
+ sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable);
}
#ifndef SQLITE_OMIT_VIEW
if( pTab && pTab->pSelect ){
pTab = 0;
- sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable);
+ sqlite3ErrorMsg(pParse, "cannot open view: %s", zTable);
}
#endif
if( !pTab ){
- if( sParse.zErrMsg ){
- sqlite3_snprintf(sizeof(zErr), zErr, "%s", sParse.zErrMsg);
+ if( pParse->zErrMsg ){
+ sqlite3DbFree(db, zErr);
+ zErr = pParse->zErrMsg;
+ pParse->zErrMsg = 0;
}
- sqlite3DbFree(db, sParse.zErrMsg);
rc = SQLITE_ERROR;
(void)sqlite3SafetyOff(db);
sqlite3BtreeLeaveAll(db);
@@ -55630,7 +56737,8 @@ SQLITE_API int sqlite3_blob_open(
}
}
if( iCol==pTab->nCol ){
- sqlite3_snprintf(sizeof(zErr), zErr, "no such column: \"%s\"", zColumn);
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
rc = SQLITE_ERROR;
(void)sqlite3SafetyOff(db);
sqlite3BtreeLeaveAll(db);
@@ -55647,7 +56755,8 @@ SQLITE_API int sqlite3_blob_open(
int j;
for(j=0; j<pIdx->nColumn; j++){
if( pIdx->aiColumn[j]==iCol ){
- sqlite3_snprintf(sizeof(zErr), zErr,
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db,
"cannot open indexed column for writing");
rc = SQLITE_ERROR;
(void)sqlite3SafetyOff(db);
@@ -55677,9 +56786,10 @@ SQLITE_API int sqlite3_blob_open(
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
** parameter of the other to pTab->tnum.
*/
- sqlite3VdbeChangeToNoop(v, (flags ? 2 : 3), 1);
- sqlite3VdbeChangeP2(v, (flags ? 3 : 2), pTab->tnum);
- sqlite3VdbeChangeP3(v, (flags ? 3 : 2), iDb);
+ flags = !!flags;
+ sqlite3VdbeChangeToNoop(v, 3 - flags, 1);
+ sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 2 + flags, iDb);
/* Configure the number of columns. Configure the cursor to
** think that the table has one more column than it really
@@ -55688,7 +56798,7 @@ SQLITE_API int sqlite3_blob_open(
** we can invoke OP_Column to fill in the vdbe cursors type
** and offset cache without causing any IO.
*/
- sqlite3VdbeChangeP4(v, flags ? 3 : 2, SQLITE_INT_TO_PTR(pTab->nCol+1), P4_INT32);
+ sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
sqlite3VdbeChangeP2(v, 6, pTab->nCol);
if( !db->mallocFailed ){
sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
@@ -55697,7 +56807,7 @@ SQLITE_API int sqlite3_blob_open(
sqlite3BtreeLeaveAll(db);
rc = sqlite3SafetyOff(db);
- if( rc!=SQLITE_OK || db->mallocFailed ){
+ if( NEVER(rc!=SQLITE_OK) || db->mallocFailed ){
goto blob_open_out;
}
@@ -55706,7 +56816,8 @@ SQLITE_API int sqlite3_blob_open(
if( rc!=SQLITE_ROW ){
nAttempt++;
rc = sqlite3_finalize((sqlite3_stmt *)v);
- sqlite3_snprintf(sizeof(zErr), zErr, sqlite3_errmsg(db));
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, sqlite3_errmsg(db));
v = 0;
}
} while( nAttempt<5 && rc==SQLITE_SCHEMA );
@@ -55720,7 +56831,8 @@ SQLITE_API int sqlite3_blob_open(
u32 type = v->apCsr[0]->aType[iCol];
if( type<12 ){
- sqlite3_snprintf(sizeof(zErr), zErr, "cannot open value of type %s",
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, "cannot open value of type %s",
type==0?"null": type==7?"real": "integer"
);
rc = SQLITE_ERROR;
@@ -55743,16 +56855,18 @@ SQLITE_API int sqlite3_blob_open(
*ppBlob = (sqlite3_blob *)pBlob;
rc = SQLITE_OK;
}else if( rc==SQLITE_OK ){
- sqlite3_snprintf(sizeof(zErr), zErr, "no such rowid: %lld", iRow);
+ sqlite3DbFree(db, zErr);
+ zErr = sqlite3MPrintf(db, "no such rowid: %lld", iRow);
rc = SQLITE_ERROR;
}
blob_open_out:
- zErr[sizeof(zErr)-1] = '\0';
if( v && (rc!=SQLITE_OK || db->mallocFailed) ){
sqlite3VdbeFinalize(v);
}
- sqlite3Error(db, rc, (rc==SQLITE_OK?0:zErr));
+ sqlite3Error(db, rc, zErr);
+ sqlite3DbFree(db, zErr);
+ sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
@@ -55767,11 +56881,15 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
int rc;
sqlite3 *db;
- db = p->db;
- sqlite3_mutex_enter(db->mutex);
- rc = sqlite3_finalize(p->pStmt);
- sqlite3DbFree(db, p);
- sqlite3_mutex_leave(db->mutex);
+ if( p ){
+ db = p->db;
+ sqlite3_mutex_enter(db->mutex);
+ rc = sqlite3_finalize(p->pStmt);
+ sqlite3DbFree(db, p);
+ sqlite3_mutex_leave(db->mutex);
+ }else{
+ rc = SQLITE_OK;
+ }
return rc;
}
@@ -55788,8 +56906,10 @@ static int blobReadWrite(
int rc;
Incrblob *p = (Incrblob *)pBlob;
Vdbe *v;
- sqlite3 *db = p->db;
+ sqlite3 *db;
+ if( p==0 ) return SQLITE_MISUSE;
+ db = p->db;
sqlite3_mutex_enter(db->mutex);
v = (Vdbe*)p->pStmt;
@@ -55845,7 +56965,7 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int
*/
SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
Incrblob *p = (Incrblob *)pBlob;
- return p->nByte;
+ return p ? p->nByte : 0;
}
#endif /* #ifndef SQLITE_OMIT_INCRBLOB */
@@ -56396,11 +57516,10 @@ SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
int rc;
if( pExpr==0 ) return WRC_Continue;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
- testcase( ExprHasProperty(pExpr, EP_SpanToken) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc==WRC_Continue
- && !ExprHasAnyProperty(pExpr,EP_TokenOnly|EP_SpanToken) ){
+ && !ExprHasAnyProperty(pExpr,EP_TokenOnly) ){
if( sqlite3WalkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( sqlite3WalkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -56556,16 +57675,28 @@ static void resolveAlias(
assert( pOrig!=0 );
assert( pOrig->flags & EP_Resolved );
db = pParse->db;
- pDup = sqlite3ExprDup(db, pOrig, 0);
- if( pDup==0 ) return;
- sqlite3TokenCopy(db, &pDup->token, &pOrig->token);
- if( pDup->op!=TK_COLUMN && zType[0]!='G' ){
+ if( pOrig->op!=TK_COLUMN && zType[0]!='G' ){
+ pDup = sqlite3ExprDup(db, pOrig, 0);
pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0);
if( pDup==0 ) return;
if( pEList->a[iCol].iAlias==0 ){
pEList->a[iCol].iAlias = (u16)(++pParse->nAlias);
}
pDup->iTable = pEList->a[iCol].iAlias;
+ }else if( ExprHasProperty(pOrig, EP_IntValue) || pOrig->u.zToken==0 ){
+ pDup = sqlite3ExprDup(db, pOrig, 0);
+ if( pDup==0 ) return;
+ }else{
+ char *zToken = pOrig->u.zToken;
+ pOrig->u.zToken = 0;
+ pDup = sqlite3ExprDup(db, pOrig, 0);
+ pOrig->u.zToken = zToken;
+ if( pDup==0 ) return;
+ if( zToken ){
+ assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 );
+ pDup->flags2 |= EP2_MallocedToken;
+ pDup->u.zToken = sqlite3DbStrDup(db, zToken);
+ }
}
if( pExpr->flags & EP_ExpCollate ){
pDup->pColl = pExpr->pColl;
@@ -56593,10 +57724,10 @@ static void resolveAlias(
** pExpr->pLeft Any expression this points to is deleted
** pExpr->pRight Any expression this points to is deleted.
**
-** The pDbToken is the name of the database (the "X"). This value may be
+** The zDb variable is the name of the database (the "X"). This value may be
** NULL meaning that name is of the form Y.Z or Z. Any available database
-** can be used. The pTableToken is the name of the table (the "Y"). This
-** value can be NULL if pDbToken is also NULL. If pTableToken is NULL it
+** can be used. The zTable variable is the name of the table (the "Y"). This
+** value can be NULL if zDb is also NULL. If zTable is NULL it
** means that the form of the name is Z and that columns from any table
** can be used.
**
@@ -56605,15 +57736,12 @@ static void resolveAlias(
*/
static int lookupName(
Parse *pParse, /* The parsing context */
- Token *pDbToken, /* Name of the database containing table, or NULL */
- Token *pTableToken, /* Name of table containing column, or NULL */
- Token *pColumnToken, /* Name of the column. */
+ const char *zDb, /* Name of the database containing table, or NULL */
+ const char *zTab, /* Name of table containing column, or NULL */
+ const char *zCol, /* Name of the column. */
NameContext *pNC, /* The name context used to resolve the name */
Expr *pExpr /* Make this EXPR node point to the selected column */
){
- char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */
- char *zTab = 0; /* Name of the table. The "Y" in X.Y.Z or Y.Z */
- char *zCol = 0; /* Name of the column. The "Z" */
int i, j; /* Loop counters */
int cnt = 0; /* Number of matching column names */
int cntTab = 0; /* Number of matching table names */
@@ -56623,20 +57751,14 @@ static int lookupName(
NameContext *pTopNC = pNC; /* First namecontext in the list */
Schema *pSchema = 0; /* Schema of the expression */
- assert( pNC ); /* the name context cannot be NULL. */
- assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
-
- /* Dequote and zero-terminate the names */
- zDb = sqlite3NameFromToken(db, pDbToken);
- zTab = sqlite3NameFromToken(db, pTableToken);
- zCol = sqlite3NameFromToken(db, pColumnToken);
- if( db->mallocFailed ){
- goto lookupname_end;
- }
+ assert( pNC ); /* the name context cannot be NULL. */
+ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */
+ assert( ~ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
/* Initialize the node to no-match */
pExpr->iTable = -1;
pExpr->pTab = 0;
+ ExprSetIrreducible(pExpr);
/* Start at the inner-most context and move outward until a match is found */
while( pNC && cnt==0 ){
@@ -56680,7 +57802,7 @@ static int lookupName(
pMatch = pItem;
pSchema = pTab->pSchema;
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
- pExpr->iColumn = j==pTab->iPKey ? -1 : j;
+ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
if( i<pSrcList->nSrc-1 ){
if( pItem[1].jointype & JT_NATURAL ){
/* If this match occurred in the left table of a natural join,
@@ -56736,7 +57858,7 @@ static int lookupName(
for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) {
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
cnt++;
- pExpr->iColumn = iCol==pTab->iPKey ? -1 : iCol;
+ pExpr->iColumn = iCol==pTab->iPKey ? -1 : (i16)iCol;
pExpr->pTab = pTab;
if( iCol>=0 ){
testcase( iCol==31 );
@@ -56786,14 +57908,13 @@ static int lookupName(
pOrig = pEList->a[j].pExpr;
if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
- sqlite3DbFree(db, zCol);
return 2;
}
resolveAlias(pParse, pEList, j, pExpr, "");
cnt = 1;
pMatch = 0;
assert( zTab==0 && zDb==0 );
- goto lookupname_end_2;
+ goto lookupname_end;
}
}
}
@@ -56817,7 +57938,6 @@ static int lookupName(
** fields are not changed in any context.
*/
if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){
- sqlite3DbFree(db, zCol);
pExpr->op = TK_STRING;
pExpr->pTab = 0;
return 0;
@@ -56856,18 +57976,14 @@ static int lookupName(
pMatch->colUsed |= ((Bitmask)1)<<n;
}
-lookupname_end:
/* Clean up and return
*/
- sqlite3DbFree(db, zDb);
- sqlite3DbFree(db, zTab);
sqlite3ExprDelete(db, pExpr->pLeft);
pExpr->pLeft = 0;
sqlite3ExprDelete(db, pExpr->pRight);
pExpr->pRight = 0;
pExpr->op = TK_COLUMN;
-lookupname_end_2:
- sqlite3DbFree(db, zCol);
+lookupname_end:
if( cnt==1 ){
assert( pNC!=0 );
sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
@@ -56940,7 +58056,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
/* A lone identifier is the name of a column.
*/
case TK_ID: {
- lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr);
+ lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
return WRC_Prune;
}
@@ -56948,24 +58064,24 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
** Or a database, table and column: ID.ID.ID
*/
case TK_DOT: {
- Token *pColumn;
- Token *pTable;
- Token *pDb;
+ const char *zColumn;
+ const char *zTable;
+ const char *zDb;
Expr *pRight;
/* if( pSrcList==0 ) break; */
pRight = pExpr->pRight;
if( pRight->op==TK_ID ){
- pDb = 0;
- pTable = &pExpr->pLeft->token;
- pColumn = &pRight->token;
+ zDb = 0;
+ zTable = pExpr->pLeft->u.zToken;
+ zColumn = pRight->u.zToken;
}else{
assert( pRight->op==TK_DOT );
- pDb = &pExpr->pLeft->token;
- pTable = &pRight->pLeft->token;
- pColumn = &pRight->pRight->token;
+ zDb = pExpr->pLeft->u.zToken;
+ zTable = pRight->pLeft->u.zToken;
+ zColumn = pRight->pRight->u.zToken;
}
- lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr);
+ lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr);
return WRC_Prune;
}
@@ -56985,8 +58101,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
u8 enc = ENC(pParse->db); /* The database encoding */
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- zId = (char*)pExpr->token.z;
- nId = pExpr->token.n;
+ zId = pExpr->u.zToken;
+ nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0);
@@ -57087,20 +58203,16 @@ static int resolveAsName(
){
int i; /* Loop counter */
- if( pE->op==TK_ID || (pE->op==TK_STRING && pE->token.z[0]!='\'') ){
- sqlite3 *db = pParse->db;
- char *zCol = sqlite3NameFromToken(db, &pE->token);
- if( zCol==0 ){
- return -1;
- }
+ UNUSED_PARAMETER(pParse);
+
+ if( pE->op==TK_ID || (pE->op==TK_STRING && pE->u.zToken[0]!='\'') ){
+ char *zCol = pE->u.zToken;
for(i=0; i<pEList->nExpr; i++){
char *zAs = pEList->a[i].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
- sqlite3DbFree(db, zCol);
return i+1;
}
}
- sqlite3DbFree(db, zCol);
}
return 0;
}
@@ -57251,11 +58363,11 @@ static int resolveCompoundOrderBy(
CollSeq *pColl = pE->pColl;
int flags = pE->flags & EP_ExpCollate;
sqlite3ExprDelete(db, pE);
- pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0, 0, 0);
+ pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
if( pE==0 ) return 1;
pE->pColl = pColl;
pE->flags |= EP_IntValue | flags;
- pE->iTable = iCol;
+ pE->u.iValue = iCol;
pItem->iCol = (u16)iCol;
pItem->done = 1;
}else{
@@ -57629,7 +58741,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
#if SQLITE_MAX_EXPR_DEPTH>0
pNC->pParse->nHeight -= pExpr->nHeight;
#endif
- if( pNC->nErr>0 ){
+ if( pNC->nErr>0 || w.pParse->nErr>0 ){
ExprSetProperty(pExpr, EP_Error);
}
if( pNC->hasAgg ){
@@ -57711,7 +58823,8 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
}
#ifndef SQLITE_OMIT_CAST
if( op==TK_CAST ){
- return sqlite3AffinityType(&pExpr->token);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ return sqlite3AffinityType(pExpr->u.zToken);
}
#endif
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER)
@@ -57740,7 +58853,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pColl
sqlite3 *db = pParse->db;
zColl = sqlite3NameFromToken(db, pCollName);
if( pExpr && zColl ){
- pColl = sqlite3LocateCollSeq(pParse, zColl, -1);
+ pColl = sqlite3LocateCollSeq(pParse, zColl);
if( pColl ){
pExpr->pColl = pColl;
pExpr->flags |= EP_ExpCollate;
@@ -57757,7 +58870,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pColl
SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
CollSeq *pColl = 0;
Expr *p = pExpr;
- while( p ){
+ while( ALWAYS(p) ){
int op;
pColl = p->pColl;
if( pColl ) break;
@@ -57770,7 +58883,7 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
if( j>=0 ){
sqlite3 *db = pParse->db;
zColl = p->pTab->aCol[j].zColl;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0);
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
pExpr->pColl = pColl;
}
break;
@@ -58047,70 +59160,122 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
/*
+** This routine is the core allocator for Expr nodes.
+**
** Construct a new expression node and return a pointer to it. Memory
-** for this node is obtained from sqlite3_malloc(). The calling function
+** for this node and for the pToken argument is a single allocation
+** obtained from sqlite3DbMalloc(). The calling function
** is responsible for making sure the node eventually gets freed.
+**
+** If dequote is true, then the token (if it exists) is dequoted.
+** If dequote is false, no dequoting is performance. The deQuote
+** parameter is ignored if pToken is NULL or if the token does not
+** appear to be quoted. If the quotes were of the form "..." (double-quotes)
+** then the EP_DblQuoted flag is set on the expression node.
+**
+** Special case: If op==TK_INTEGER and pToken points to a string that
+** can be translated into a 32-bit integer, then the token is not
+** stored in u.zToken. Instead, the integer values is written
+** into u.iValue and the EP_IntValue flag is set. No extra storage
+** is allocated to hold the integer text and the dequote flag is ignored.
*/
-SQLITE_PRIVATE Expr *sqlite3Expr(
+SQLITE_PRIVATE Expr *sqlite3ExprAlloc(
sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
int op, /* Expression opcode */
- Expr *pLeft, /* Left operand */
- Expr *pRight, /* Right operand */
- const Token *pToken /* Argument token */
+ const Token *pToken, /* Token argument. Might be NULL */
+ int dequote /* True to dequote */
){
Expr *pNew;
- pNew = sqlite3DbMallocZero(db, sizeof(Expr));
- if( pNew==0 ){
- /* When malloc fails, delete pLeft and pRight. Expressions passed to
- ** this function must always be allocated with sqlite3Expr() for this
- ** reason.
- */
- sqlite3ExprDelete(db, pLeft);
- sqlite3ExprDelete(db, pRight);
- return 0;
- }
- pNew->op = (u8)op;
- pNew->pLeft = pLeft;
- pNew->pRight = pRight;
- pNew->iAgg = -1;
- pNew->span.z = (u8*)"";
+ int nExtra = 0;
+ int iValue = 0;
+
if( pToken ){
- int c;
- assert( pToken->dyn==0 );
- pNew->span = *pToken;
- if( pToken->n>=2
- && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
- sqlite3TokenCopy(db, &pNew->token, pToken);
- if( pNew->token.z ){
- pNew->token.n = sqlite3Dequote((char*)pNew->token.z);
- assert( pNew->token.n==(unsigned)sqlite3Strlen30((char*)pNew->token.z) );
- }
- if( c=='"' ) pNew->flags |= EP_DblQuoted;
- }else{
- pNew->token = *pToken;
+ if( op!=TK_INTEGER || pToken->z==0
+ || sqlite3GetInt32(pToken->z, &iValue)==0 ){
+ nExtra = pToken->n+1;
}
- pNew->token.quoted = 0;
- }else if( pLeft ){
- if( pRight ){
- if( pRight->span.dyn==0 && pLeft->span.dyn==0 ){
- sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
+ }
+ pNew = sqlite3DbMallocZero(db, sizeof(Expr)+nExtra);
+ if( pNew ){
+ pNew->op = (u8)op;
+ pNew->iAgg = -1;
+ if( pToken ){
+ if( nExtra==0 ){
+ pNew->flags |= EP_IntValue;
+ pNew->u.iValue = iValue;
+ }else{
+ int c;
+ pNew->u.zToken = (char*)&pNew[1];
+ memcpy(pNew->u.zToken, pToken->z, pToken->n);
+ pNew->u.zToken[pToken->n] = 0;
+ if( dequote && nExtra>=3
+ && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
+ sqlite3Dequote(pNew->u.zToken);
+ if( c=='"' ) pNew->flags |= EP_DblQuoted;
+ }
}
+ }
+#if SQLITE_MAX_EXPR_DEPTH>0
+ pNew->nHeight = 1;
+#endif
+ }
+ return pNew;
+}
+
+/*
+** Allocate a new expression node from a zero-terminated token that has
+** already been dequoted.
+*/
+SQLITE_PRIVATE Expr *sqlite3Expr(
+ sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */
+ int op, /* Expression opcode */
+ const char *zToken /* Token argument. Might be NULL */
+){
+ Token x;
+ x.z = zToken;
+ x.n = zToken ? sqlite3Strlen30(zToken) : 0;
+ return sqlite3ExprAlloc(db, op, &x, 0);
+}
+
+/*
+** Attach subtrees pLeft and pRight to the Expr node pRoot.
+**
+** If pRoot==NULL that means that a memory allocation error has occurred.
+** In that case, delete the subtrees pLeft and pRight.
+*/
+SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
+ sqlite3 *db,
+ Expr *pRoot,
+ Expr *pLeft,
+ Expr *pRight
+){
+ if( pRoot==0 ){
+ assert( db->mallocFailed );
+ sqlite3ExprDelete(db, pLeft);
+ sqlite3ExprDelete(db, pRight);
+ }else{
+ if( pRight ){
+ pRoot->pRight = pRight;
if( pRight->flags & EP_ExpCollate ){
- pNew->flags |= EP_ExpCollate;
- pNew->pColl = pRight->pColl;
+ pRoot->flags |= EP_ExpCollate;
+ pRoot->pColl = pRight->pColl;
}
}
- if( pLeft->flags & EP_ExpCollate ){
- pNew->flags |= EP_ExpCollate;
- pNew->pColl = pLeft->pColl;
+ if( pLeft ){
+ pRoot->pLeft = pLeft;
+ if( pLeft->flags & EP_ExpCollate ){
+ pRoot->flags |= EP_ExpCollate;
+ pRoot->pColl = pLeft->pColl;
+ }
}
+ exprSetHeight(pRoot);
}
-
- exprSetHeight(pNew);
- return pNew;
}
/*
+** Allocate a Expr node which joins up to two subtrees.
+**
+** The
** Works like sqlite3Expr() except that it takes an extra Parse*
** argument and notifies the associated connection object if malloc fails.
*/
@@ -58121,36 +59286,8 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
Expr *pRight, /* Right operand */
const Token *pToken /* Argument token */
){
- Expr *p = sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
- if( p ){
- sqlite3ExprCheckHeight(pParse, p->nHeight);
- }
- return p;
-}
-
-/*
-** When doing a nested parse, you 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.
-**
-** This routine is called by the parser to deal with on of those terms.
-** It immediately generates code to store the value in a memory location.
-** The returns an expression that will code to extract the value from
-** that memory location as needed.
-*/
-SQLITE_PRIVATE Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){
- Vdbe *v = pParse->pVdbe;
- Expr *p;
- if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken);
- return sqlite3PExpr(pParse, TK_NULL, 0, 0, 0);
- }
- if( v==0 ) return 0;
- p = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, pToken);
- if( p==0 ){
- return 0; /* Malloc failed */
- }
- p->iTable = atoi((char*)&pToken->z[1]);
+ Expr *p = sqlite3ExprAlloc(pParse->db, op, pToken, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
return p;
}
@@ -58164,24 +59301,9 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){
}else if( pRight==0 ){
return pLeft;
}else{
- return sqlite3Expr(db, TK_AND, pLeft, pRight, 0);
- }
-}
-
-/*
-** Set the Expr.span field of the given expression to span all
-** text between the two given tokens. Both tokens must be pointing
-** at the same string.
-*/
-SQLITE_PRIVATE void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
- assert( pRight!=0 );
- assert( pLeft!=0 );
- if( pExpr ){
- pExpr->span.z = pLeft->z;
- /* The following assert() may fail when this is called
- ** via sqlite3PExpr()/sqlite3Expr() from addWhereTerm(). */
- /* assert(pRight->z >= pLeft->z); */
- pExpr->span.n = pRight->n + (unsigned)(pRight->z - pLeft->z);
+ Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0);
+ sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight);
+ return pNew;
}
}
@@ -58193,17 +59315,13 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
Expr *pNew;
sqlite3 *db = pParse->db;
assert( pToken );
- pNew = sqlite3DbMallocZero(db, sizeof(Expr) );
+ pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
if( pNew==0 ){
sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
return 0;
}
- pNew->op = TK_FUNCTION;
pNew->x.pList = pList;
assert( !ExprHasProperty(pNew, EP_xIsSelect) );
- assert( pToken->dyn==0 );
- pNew->span = *pToken;
- sqlite3TokenCopy(db, &pNew->token, pToken);
sqlite3ExprSetHeight(pParse, pNew);
return pNew;
}
@@ -58219,28 +59337,29 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
** sure "nnn" is not too be to avoid a denial of service attack when
** the SQL statement comes from an external source.
**
-** Wildcards of the form ":aaa" or "$aaa" are assigned the same number
+** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
** as the previous instance of the same wildcard. Or if this is the first
** instance of the wildcard, the next sequenial variable number is
** assigned.
*/
SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
- Token *pToken;
sqlite3 *db = pParse->db;
+ const char *z;
if( pExpr==0 ) return;
- pToken = &pExpr->token;
- assert( pToken->n>=1 );
- assert( pToken->z!=0 );
- assert( pToken->z[0]!=0 );
- if( pToken->n==1 ){
+ assert( !ExprHasAnyProperty(pExpr, EP_IntValue|EP_Reduced|EP_TokenOnly) );
+ z = pExpr->u.zToken;
+ assert( z!=0 );
+ assert( z[0]!=0 );
+ if( z[1]==0 ){
/* Wildcard of the form "?". Assign the next variable number */
+ assert( z[0]=='?' );
pExpr->iTable = ++pParse->nVar;
- }else if( pToken->z[0]=='?' ){
+ }else if( z[0]=='?' ){
/* Wildcard of the form "?nnn". Convert "nnn" to an integer and
** use it as the variable number */
int i;
- pExpr->iTable = i = atoi((char*)&pToken->z[1]);
+ pExpr->iTable = i = atoi((char*)&z[1]);
testcase( i==0 );
testcase( i==1 );
testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
@@ -58253,18 +59372,17 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
pParse->nVar = i;
}
}else{
- /* Wildcards of the form ":aaa" or "$aaa". Reuse the same variable
+ /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable
** number as the prior appearance of the same name, or if the name
** has never appeared before, reuse the same variable number
*/
int i;
u32 n;
- n = pToken->n;
+ n = sqlite3Strlen30(z);
for(i=0; i<pParse->nVarExpr; i++){
- Expr *pE;
- if( (pE = pParse->apVarExpr[i])!=0
- && pE->token.n==n
- && memcmp(pE->token.z, pToken->z, n)==0 ){
+ Expr *pE = pParse->apVarExpr[i];
+ assert( pE!=0 );
+ if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){
pExpr->iTable = pE->iTable;
break;
}
@@ -58296,19 +59414,13 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
** Substructure is deleted.
*/
SQLITE_PRIVATE void sqlite3ExprClear(sqlite3 *db, Expr *p){
- if( p->token.dyn ) sqlite3DbFree(db, (char*)p->token.z);
- if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){
- if( p->span.dyn ) sqlite3DbFree(db, (char*)p->span.z);
- if( ExprHasProperty(p, EP_Reduced) ){
- /* Subtrees are part of the same memory allocation when EP_Reduced set */
- if( p->pLeft ) sqlite3ExprClear(db, p->pLeft);
- if( p->pRight ) sqlite3ExprClear(db, p->pRight);
- }else{
- /* Subtrees are separate allocations when EP_Reduced is clear */
- sqlite3ExprDelete(db, p->pLeft);
- sqlite3ExprDelete(db, p->pRight);
+ assert( p!=0 );
+ if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ sqlite3ExprDelete(db, p->pLeft);
+ sqlite3ExprDelete(db, p->pRight);
+ if( !ExprHasProperty(p, EP_Reduced) && (p->flags2 & EP2_MallocedToken)!=0 ){
+ sqlite3DbFree(db, p->u.zToken);
}
- /* x.pSelect and x.pList are always separately allocated */
if( ExprHasProperty(p, EP_xIsSelect) ){
sqlite3SelectDelete(db, p->x.pSelect);
}else{
@@ -58323,7 +59435,9 @@ SQLITE_PRIVATE void sqlite3ExprClear(sqlite3 *db, Expr *p){
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
if( p==0 ) return;
sqlite3ExprClear(db, p);
- sqlite3DbFree(db, p);
+ if( !ExprHasProperty(p, EP_Static) ){
+ sqlite3DbFree(db, p);
+ }
}
/*
@@ -58333,44 +59447,72 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
*/
static int exprStructSize(Expr *p){
if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
- if( ExprHasProperty(p, EP_SpanToken) ) return EXPR_SPANTOKENSIZE;
if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
return EXPR_FULLSIZE;
}
/*
-** sqlite3ExprDup() has been called to create a copy of expression p with
-** the EXPRDUP_XXX flags passed as the second argument. This function
-** returns the space required for the copy of the Expr structure only.
-** This is always one of EXPR_FULLSIZE, EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
+** The dupedExpr*Size() routines each return the number of bytes required
+** to store a copy of an expression or expression tree. They differ in
+** how much of the tree is measured.
+**
+** dupedExprStructSize() Size of only the Expr structure
+** dupedExprNodeSize() Size of Expr + space for token
+** dupedExprSize() Expr + token + subtree components
+**
+***************************************************************************
+**
+** The dupedExprStructSize() function returns two values OR-ed together:
+** (1) the space required for a copy of the Expr structure only and
+** (2) the EP_xxx flags that indicate what the structure size should be.
+** The return values is always one of:
+**
+** EXPR_FULLSIZE
+** EXPR_REDUCEDSIZE | EP_Reduced
+** EXPR_TOKENONLYSIZE | EP_TokenOnly
+**
+** The size of the structure can be found by masking the return value
+** of this routine with 0xfff. The flags can be found by masking the
+** return value with EP_Reduced|EP_TokenOnly.
+**
+** Note that with flags==EXPRDUP_REDUCE, this routines works on full-size
+** (unreduced) Expr objects as they or originally constructed by the parser.
+** During expression analysis, extra information is computed and moved into
+** later parts of teh Expr object and that extra information might get chopped
+** off if the expression is reduced. Note also that it does not work to
+** make a EXPRDUP_REDUCE copy of a reduced expression. It is only legal
+** to reduce a pristine expression tree from the parser. The implementation
+** of dupedExprStructSize() contain multiple assert() statements that attempt
+** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
int nSize;
+ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
if( 0==(flags&EXPRDUP_REDUCE) ){
nSize = EXPR_FULLSIZE;
- }else if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
- nSize = EXPR_REDUCEDSIZE;
- }else if( flags&EXPRDUP_SPAN ){
- nSize = EXPR_SPANTOKENSIZE;
}else{
- nSize = EXPR_TOKENONLYSIZE;
+ assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasProperty(p, EP_FromJoin) );
+ assert( (p->flags2 & EP2_MallocedToken)==0 );
+ assert( (p->flags2 & EP2_Irreducible)==0 );
+ if( p->pLeft || p->pRight || p->pColl || p->x.pList ){
+ nSize = EXPR_REDUCEDSIZE | EP_Reduced;
+ }else{
+ nSize = EXPR_TOKENONLYSIZE | EP_TokenOnly;
+ }
}
return nSize;
}
/*
-** sqlite3ExprDup() has been called to create a copy of expression p with
-** the EXPRDUP_XXX passed as the second argument. This function returns
-** the space in bytes required to store the copy of the Expr structure
-** and the copies of the Expr.token.z and Expr.span.z (if applicable)
-** string buffers.
+** This function returns the space in bytes required to store the copy
+** of the Expr structure and a copy of the Expr.u.zToken string (if that
+** string is defined.)
*/
static int dupedExprNodeSize(Expr *p, int flags){
- int nByte = dupedExprStructSize(p, flags) + (p->token.z ? p->token.n + 1 : 0);
- if( (flags&EXPRDUP_SPAN)!=0
- && (p->token.z!=p->span.z || p->token.n!=p->span.n)
- ){
- nByte += p->span.n;
+ int nByte = dupedExprStructSize(p, flags) & 0xfff;
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ nByte += sqlite3Strlen30(p->u.zToken)+1;
}
return ROUND8(nByte);
}
@@ -58381,9 +59523,7 @@ static int dupedExprNodeSize(Expr *p, int flags){
** mask containing EXPRDUP_XXX flags.
**
** The value returned includes space to create a copy of the Expr struct
-** itself and the buffer referred to by Expr.token, if any. If the
-** EXPRDUP_SPAN flag is set, then space to create a copy of the buffer
-** refered to by Expr.span is also included.
+** itself and the buffer referred to by Expr.u.zToken, if any.
**
** If the EXPRDUP_REDUCE flag is set, then the return value includes
** space to duplicate all Expr nodes in the tree formed by Expr.pLeft
@@ -58395,8 +59535,7 @@ static int dupedExprSize(Expr *p, int flags){
if( p ){
nByte = dupedExprNodeSize(p, flags);
if( flags&EXPRDUP_REDUCE ){
- int f = flags&(~EXPRDUP_SPAN);
- nByte += dupedExprSize(p->pLeft, f) + dupedExprSize(p->pRight, f);
+ nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
}
}
return nByte;
@@ -58405,7 +59544,7 @@ static int dupedExprSize(Expr *p, int flags){
/*
** This function is similar to sqlite3ExprDup(), except that if pzBuffer
** is not NULL then *pzBuffer is assumed to point to a buffer large enough
-** to store the copy of expression p, the copies of p->token and p->span
+** to store the copy of expression p, the copies of p->u.zToken
** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte passed the
** portion of the buffer copied into by this function.
@@ -58413,15 +59552,16 @@ static int dupedExprSize(Expr *p, int flags){
static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
Expr *pNew = 0; /* Value to return */
if( p ){
- const int isRequireSpan = (flags&EXPRDUP_SPAN);
const int isReduced = (flags&EXPRDUP_REDUCE);
u8 *zAlloc;
+ u32 staticFlag = 0;
assert( pzBuffer==0 || isReduced );
/* Figure out where to write the new Expr structure. */
if( pzBuffer ){
zAlloc = *pzBuffer;
+ staticFlag = EP_Static;
}else{
zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags));
}
@@ -58431,10 +59571,16 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
/* Set nNewSize to the size allocated for the structure pointed to
** by pNew. This is either EXPR_FULLSIZE, EXPR_REDUCEDSIZE or
** EXPR_TOKENONLYSIZE. nToken is set to the number of bytes consumed
- ** by the copy of the p->token.z string (if any).
+ ** by the copy of the p->u.zToken string (if any).
*/
- const int nNewSize = dupedExprStructSize(p, flags);
- const int nToken = (p->token.z ? p->token.n + 1 : 0);
+ const unsigned nStructSize = dupedExprStructSize(p, flags);
+ const int nNewSize = nStructSize & 0xfff;
+ int nToken;
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ nToken = sqlite3Strlen30(p->u.zToken) + 1;
+ }else{
+ nToken = 0;
+ }
if( isReduced ){
assert( ExprHasProperty(p, EP_Reduced)==0 );
memcpy(zAlloc, p, nNewSize);
@@ -58444,41 +59590,18 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize);
}
- /* Set the EP_Reduced and EP_TokenOnly flags appropriately. */
- pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_SpanToken);
- switch( nNewSize ){
- case EXPR_REDUCEDSIZE: pNew->flags |= EP_Reduced; break;
- case EXPR_TOKENONLYSIZE: pNew->flags |= EP_TokenOnly; break;
- case EXPR_SPANTOKENSIZE: pNew->flags |= EP_SpanToken; break;
- }
+ /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. */
+ pNew->flags &= ~(EP_Reduced|EP_TokenOnly|EP_Static);
+ pNew->flags |= nStructSize & (EP_Reduced|EP_TokenOnly);
+ pNew->flags |= staticFlag;
- /* Copy the p->token string, if any. */
+ /* Copy the p->u.zToken string, if any. */
if( nToken ){
- unsigned char *zToken = &zAlloc[nNewSize];
- memcpy(zToken, p->token.z, nToken-1);
- zToken[nToken-1] = '\0';
- pNew->token.dyn = 0;
- pNew->token.z = zToken;
+ char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize];
+ memcpy(zToken, p->u.zToken, nToken);
}
if( 0==((p->flags|pNew->flags) & EP_TokenOnly) ){
- /* Fill in the pNew->span token, if required. */
- if( isRequireSpan ){
- if( p->token.z!=p->span.z || p->token.n!=p->span.n ){
- pNew->span.z = &zAlloc[nNewSize+nToken];
- memcpy((char *)pNew->span.z, p->span.z, p->span.n);
- pNew->span.dyn = 0;
- }else{
- pNew->span.z = pNew->token.z;
- pNew->span.n = pNew->token.n;
- }
- }else{
- pNew->span.z = 0;
- pNew->span.n = 0;
- }
- }
-
- if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_SpanToken)) ){
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
if( ExprHasProperty(p, EP_xIsSelect) ){
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, isReduced);
@@ -58488,7 +59611,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/* Fill in pNew->pLeft and pNew->pRight. */
- if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly|EP_SpanToken) ){
+ if( ExprHasAnyProperty(pNew, EP_Reduced|EP_TokenOnly) ){
zAlloc += dupedExprNodeSize(p, flags);
if( ExprHasProperty(pNew, EP_Reduced) ){
pNew->pLeft = exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc);
@@ -58497,10 +59620,14 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
if( pzBuffer ){
*pzBuffer = zAlloc;
}
- }else if( !ExprHasAnyProperty(p, EP_TokenOnly|EP_SpanToken) ){
- pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
- pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+ }else{
+ pNew->flags2 = 0;
+ if( !ExprHasAnyProperty(p, EP_TokenOnly) ){
+ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0);
+ pNew->pRight = sqlite3ExprDup(db, p->pRight, 0);
+ }
}
+
}
}
return pNew;
@@ -58518,12 +59645,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
**
** Any tables that the SrcList might point to are not duplicated.
**
-** The flags parameter contains a combination of the EXPRDUP_XXX flags. If
-** the EXPRDUP_SPAN flag is set in the argument parameter, then the
-** Expr.span field of the input expression is copied. If EXPRDUP_SPAN is
-** clear, then the Expr.span field of the returned expression structure
-** is zeroed.
-**
+** The flags parameter contains a combination of the EXPRDUP_XXX flags.
** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
** truncated version of the usual Expr structure that will be stored as
** part of the in-memory representation of the database schema.
@@ -58531,16 +59653,6 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
return exprDup(db, p, flags, 0);
}
-SQLITE_PRIVATE void sqlite3TokenCopy(sqlite3 *db, Token *pTo, const Token *pFrom){
- if( pTo->dyn ) sqlite3DbFree(db, (char*)pTo->z);
- if( pFrom->z ){
- pTo->n = pFrom->n;
- pTo->z = (u8*)sqlite3DbStrNDup(db, (char*)pFrom->z, pFrom->n);
- pTo->dyn = 1;
- }else{
- pTo->z = 0;
- }
-}
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
ExprList *pNew;
struct ExprList_item *pItem, *pOldItem;
@@ -58561,6 +59673,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags)
Expr *pOldExpr = pOldItem->pExpr;
pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr, flags);
pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
+ pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
pItem->sortOrder = pOldItem->sortOrder;
pItem->done = 0;
pItem->iCol = pOldItem->iCol;
@@ -58635,10 +59748,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
if( p==0 ) return 0;
pNew = sqlite3DbMallocRaw(db, sizeof(*p) );
if( pNew==0 ) return 0;
- /* Always make a copy of the span for top-level expressions in the
- ** expression list. The logic in SELECT processing that determines
- ** the names of columns in the result set needs this information */
- pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags|EXPRDUP_SPAN);
+ pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags);
pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags);
@@ -58668,12 +59778,15 @@ 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.
+**
+** 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.
*/
SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to append. Might be NULL */
- Expr *pExpr, /* Expression to be appended */
- Token *pName /* AS keyword for the expression */
+ Expr *pExpr /* Expression to be appended. Might be NULL */
){
sqlite3 *db = pParse->db;
if( pList==0 ){
@@ -58694,12 +59807,10 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(
pList->nAlloc = sqlite3DbMallocSize(db, a)/sizeof(a[0]);
}
assert( pList->a!=0 );
- if( pExpr || pName ){
+ if( 1 ){
struct ExprList_item *pItem = &pList->a[pList->nExpr++];
memset(pItem, 0, sizeof(*pItem));
- pItem->zName = sqlite3NameFromToken(db, pName);
pItem->pExpr = pExpr;
- pItem->iAlias = 0;
}
return pList;
@@ -58711,6 +59822,56 @@ no_mem:
}
/*
+** Set the ExprList.a[].zName element of the most recently added item
+** on the expression list.
+**
+** pList might be NULL following an OOM error. But pName should never be
+** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
+** is set.
+*/
+SQLITE_PRIVATE void sqlite3ExprListSetName(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List to which to add the span. */
+ Token *pName, /* Name to be added */
+ int dequote /* True to cause the name to be dequoted */
+){
+ assert( pList!=0 || pParse->db->mallocFailed!=0 );
+ if( pList ){
+ struct ExprList_item *pItem;
+ assert( pList->nExpr>0 );
+ pItem = &pList->a[pList->nExpr-1];
+ assert( pItem->zName==0 );
+ pItem->zName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
+ if( dequote && pItem->zName ) sqlite3Dequote(pItem->zName);
+ }
+}
+
+/*
+** Set the ExprList.a[].zSpan element of the most recently added item
+** on the expression list.
+**
+** pList might be NULL following an OOM error. But pSpan should never be
+** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag
+** is set.
+*/
+SQLITE_PRIVATE void sqlite3ExprListSetSpan(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* List to which to add the span. */
+ ExprSpan *pSpan /* The span to be added */
+){
+ 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));
+ }
+}
+
+/*
** If the expression list pEList contains more than iLimit elements,
** leave an error message in pParse.
*/
@@ -58739,6 +59900,7 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
sqlite3ExprDelete(db, pItem->pExpr);
sqlite3DbFree(db, pItem->zName);
+ sqlite3DbFree(db, pItem->zSpan);
}
sqlite3DbFree(db, pList->a);
sqlite3DbFree(db, pList);
@@ -58777,12 +59939,6 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
case TK_COLUMN:
case TK_AGG_FUNCTION:
case TK_AGG_COLUMN:
-#ifndef SQLITE_OMIT_SUBQUERY
- case TK_SELECT:
- case TK_EXISTS:
- testcase( pExpr->op==TK_SELECT );
- testcase( pExpr->op==TK_EXISTS );
-#endif
testcase( pExpr->op==TK_ID );
testcase( pExpr->op==TK_COLUMN );
testcase( pExpr->op==TK_AGG_FUNCTION );
@@ -58790,6 +59946,8 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
pWalker->u.i = 0;
return WRC_Abort;
default:
+ testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
+ testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
return WRC_Continue;
}
}
@@ -58851,12 +60009,13 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
int rc = 0;
if( p->flags & EP_IntValue ){
- *pValue = p->iTable;
+ *pValue = p->u.iValue;
return 1;
}
switch( p->op ){
case TK_INTEGER: {
- rc = sqlite3GetInt32((char*)p->token.z, pValue);
+ rc = sqlite3GetInt32(p->u.zToken, pValue);
+ assert( rc==0 );
break;
}
case TK_UPLUS: {
@@ -58874,9 +60033,11 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
default: break;
}
if( rc ){
+ assert( ExprHasAnyProperty(p, EP_Reduced|EP_TokenOnly)
+ || (p->flags2 & EP2_MallocedToken)==0 );
p->op = TK_INTEGER;
p->flags |= EP_IntValue;
- p->iTable = *pValue;
+ p->u.iValue = *pValue;
}
return rc;
}
@@ -58892,14 +60053,16 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){
}
/*
-** Return true if the IN operator optimization is enabled and
-** the SELECT statement p exists and is of the
-** simple form:
+** Return true if we are able to the IN operator optimization on a
+** query of the form
**
-** SELECT <column> FROM <table>
+** x IN (SELECT ...)
+**
+** Where the SELECT... clause is as specified by the parameter to this
+** routine.
**
-** If this is the case, it may be possible to use an existing table
-** or index instead of generating an epheremal table.
+** The Select object passed in has already been preprocessed and no
+** errors have been found.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static int isCandidateForInOpt(Select *p){
@@ -58909,19 +60072,21 @@ static int isCandidateForInOpt(Select *p){
if( p==0 ) return 0; /* right-hand side of IN is SELECT */
if( p->pPrior ) return 0; /* Not a compound SELECT */
if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
- return 0; /* No DISTINCT keyword and no aggregate functions */
+ testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
+ testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
+ return 0; /* No DISTINCT keyword and no aggregate functions */
}
- if( p->pGroupBy ) return 0; /* Has no GROUP BY clause */
+ assert( p->pGroupBy==0 ); /* Has no GROUP BY clause */
if( p->pLimit ) return 0; /* Has no LIMIT clause */
- if( p->pOffset ) return 0;
+ assert( p->pOffset==0 ); /* No LIMIT means no OFFSET */
if( p->pWhere ) return 0; /* Has no WHERE clause */
pSrc = p->pSrc;
assert( pSrc!=0 );
if( pSrc->nSrc!=1 ) return 0; /* Single term in FROM clause */
- if( pSrc->a[0].pSelect ) return 0; /* FROM clause is not a subquery */
+ if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */
pTab = pSrc->a[0].pTab;
- if( pTab==0 ) return 0;
- if( pTab->pSelect ) return 0; /* FROM clause is not a view */
+ if( NEVER(pTab==0) ) return 0;
+ assert( pTab->pSelect==0 ); /* FROM clause is not a view */
if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */
pEList = p->pEList;
if( pEList->nExpr!=1 ) return 0; /* One column in the result set */
@@ -58936,45 +60101,45 @@ static int isCandidateForInOpt(Select *p){
** either to test for membership of the (...) set or to iterate through
** its members, skipping duplicates.
**
-** The cursor opened on the structure (database table, database index
+** The index of the cursor opened on the b-tree (database table, database index
** or ephermal table) is stored in pX->iTable before this function returns.
-** The returned value indicates the structure type, as follows:
+** The returned value of this function indicates the b-tree type, as follows:
**
** IN_INDEX_ROWID - The cursor was opened on a database table.
** IN_INDEX_INDEX - The cursor was opened on a database index.
** IN_INDEX_EPH - The cursor was opened on a specially created and
** populated epheremal table.
**
-** An existing structure may only be used if the SELECT is of the simple
+** An existing b-tree may only be used if the SELECT is of the simple
** form:
**
** SELECT <column> FROM <table>
**
-** If prNotFound parameter is 0, then the structure will be used to iterate
+** If the prNotFound parameter is 0, then the b-tree will be used to iterate
** through the set members, skipping any duplicates. In this case an
** epheremal table must be used unless the selected <column> is guaranteed
** to be unique - either because it is an INTEGER PRIMARY KEY or it
-** is unique by virtue of a constraint or implicit index.
+** has a UNIQUE constraint or UNIQUE index.
**
-** If the prNotFound parameter is not 0, then the structure will be used
+** If the prNotFound parameter is not 0, then the b-tree will be used
** for fast set membership tests. In this case an epheremal table must
** be used unless <column> is an INTEGER PRIMARY KEY or an index can
** be found with <column> as its left-most column.
**
-** When the structure is being used for set membership tests, the user
+** When the b-tree is being used for membership tests, the calling function
** needs to know whether or not the structure contains an SQL NULL
** value in order to correctly evaluate expressions like "X IN (Y, Z)".
-** If there is a chance that the structure may contain a NULL value at
+** If there is a chance that the b-tree might contain a NULL value at
** runtime, then a register is allocated and the register number written
-** to *prNotFound. If there is no chance that the structure contains a
+** to *prNotFound. If there is no chance that the b-tree contains a
** NULL value, then *prNotFound is left unchanged.
**
** If a register is allocated and its location stored in *prNotFound, then
-** its initial value is NULL. If the structure does not remain constant
-** for the duration of the query (i.e. the set is a correlated sub-select),
-** the value of the allocated register is reset to NULL each time the
-** structure is repopulated. This allows the caller to use vdbe code
-** equivalent to the following:
+** its initial value is NULL. If the b-tree does not remain constant
+** for the duration of the query (i.e. the SELECT that generates the b-tree
+** is a correlated subquery) then the value of the allocated register is
+** reset to NULL each time the b-tree is repopulated. This allows the
+** caller to use vdbe code equivalent to the following:
**
** if( register==NULL ){
** has_null = <test if data structure contains null>
@@ -58986,21 +60151,17 @@ static int isCandidateForInOpt(Select *p){
*/
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
- Select *p;
- int eType = 0;
- int iTab = pParse->nTab++;
- int mustBeUnique = !prNotFound;
+ Select *p; /* SELECT to the right of IN operator */
+ int eType = 0; /* Type of RHS table. IN_INDEX_* */
+ int iTab = pParse->nTab++; /* Cursor of the RHS table */
+ int mustBeUnique = (prNotFound==0); /* True if RHS must be unique */
- /* The follwing if(...) expression is true if the SELECT is of the
- ** simple form:
- **
- ** SELECT <column> FROM <table>
- **
- ** If this is the case, it may be possible to use an existing table
- ** or index instead of generating an epheremal table.
+ /* Check to see if an existing table or index can be used to
+ ** satisfy the query. This is preferable to generating a new
+ ** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
- if( isCandidateForInOpt(p) ){
+ if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
Expr *pExpr = p->pEList->a[0].pExpr; /* Expression <column> */
int iCol = pExpr->iColumn; /* Index of column <column> */
@@ -59033,7 +60194,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
}else{
Index *pIdx; /* Iterator variable */
- /* The collation sequence used by the comparison. If an index is to
+ /* The collation sequence used by the comparison. If an index is to
** be used in place of a temp-table, it must be ordered according
** to this collation sequence. */
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pExpr);
@@ -59047,7 +60208,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
for(pIdx=pTab->pIndex; pIdx && eType==0 && affinity_ok; pIdx=pIdx->pNext){
if( (pIdx->aiColumn[0]==iCol)
- && (pReq==sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], -1, 0))
+ && sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
&& (!mustBeUnique || (pIdx->nColumn==1 && pIdx->onError!=OE_None))
){
int iMem = ++pParse->nMem;
@@ -59076,6 +60237,9 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
}
if( eType==0 ){
+ /* Could not found an existing able or index to use as the RHS b-tree.
+ ** We will have to generate an ephemeral table to do the job.
+ */
int rMayHaveNull = 0;
eType = IN_INDEX_EPH;
if( prNotFound ){
@@ -59108,17 +60272,29 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
** to some integer key column of a table B-Tree. In this case, use an
** intkey B-Tree to store the set of IN(...) values instead of the usual
** (slower) variable length keys B-Tree.
+**
+** If rMayHaveNull is non-zero, that means that the operation is an IN
+** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
+** Furthermore, the IN is in a WHERE clause and that we really want
+** to iterate over the RHS of the IN operator in order to quickly locate
+** all corresponding LHS elements. All this routine does is initialize
+** the register given by rMayHaveNull to NULL. Calling routines will take
+** care of changing this register value to non-NULL if the RHS is NULL-free.
+**
+** If rMayHaveNull is zero, that means that the subquery is being used
+** for membership testing only. There is no need to initialize any
+** registers to indicate the presense or absence of NULLs on the RHS.
*/
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE void sqlite3CodeSubselect(
- Parse *pParse,
- Expr *pExpr,
- int rMayHaveNull,
- int isRowid
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The IN, SELECT, or EXISTS operator */
+ int rMayHaveNull, /* Register that records whether NULLs exist in RHS */
+ int isRowid /* If true, LHS of IN operator is a rowid */
){
int testAddr = 0; /* One-time test address */
Vdbe *v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
+ if( NEVER(v==0) ) return;
sqlite3ExprCachePush(pParse);
/* This code must be run in its entirety every time it is encountered
@@ -59186,11 +60362,11 @@ SQLITE_PRIVATE void sqlite3CodeSubselect(
return;
}
pEList = pExpr->x.pSelect->pEList;
- if( pEList && pEList->nExpr>0 ){
+ if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
pEList->a[0].pExpr);
}
- }else if( pExpr->x.pList ){
+ }else if( pExpr->x.pList!=0 ){
/* Case 2: expr IN (exprlist)
**
** For each expression, build an index key from the evaluation and
@@ -59246,14 +60422,21 @@ SQLITE_PRIVATE void sqlite3CodeSubselect(
}
case TK_EXISTS:
- case TK_SELECT: {
- /* This has to be a scalar SELECT. Generate code to put the
+ case TK_SELECT:
+ default: {
+ /* If this has to be a scalar SELECT. Generate code to put the
** value of this select in a memory cell and record the number
- ** of the memory cell in iColumn.
+ ** of the memory cell in iColumn. If this is an EXISTS, write
+ ** an integer 0 (not exists) or 1 (exists) into a memory cell
+ ** and record that memory cell in iColumn.
*/
- static const Token one = { (u8*)"1", 0, 0, 1 };
- Select *pSel;
- SelectDest dest;
+ static const Token one = { "1", 1 }; /* Token for literal value 1 */
+ Select *pSel; /* SELECT statement to encode */
+ SelectDest dest; /* How to deal with SELECt result */
+
+ testcase( pExpr->op==TK_EXISTS );
+ testcase( pExpr->op==TK_SELECT );
+ assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
assert( ExprHasProperty(pExpr, EP_xIsSelect) );
pSel = pExpr->x.pSelect;
@@ -59272,7 +60455,8 @@ SQLITE_PRIVATE void sqlite3CodeSubselect(
if( sqlite3Select(pParse, pSel, &dest) ){
return;
}
- pExpr->iColumn = dest.iParm;
+ pExpr->iColumn = (i16)dest.iParm;
+ ExprSetIrreducible(pExpr);
break;
}
}
@@ -59305,11 +60489,8 @@ static char *dup8bytes(Vdbe *v, const char *in){
** z[n] character is guaranteed to be something that does not look
** like the continuation of the number.
*/
-static void codeReal(Vdbe *v, const char *z, int n, int negateFlag, int iMem){
- assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
- assert( !z || !sqlite3Isdigit(z[n]) );
- UNUSED_PARAMETER(n);
- if( z ){
+static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
+ if( ALWAYS(z!=0) ){
double value;
char *zV;
sqlite3AtoF(z, &value);
@@ -59333,19 +60514,14 @@ static void codeReal(Vdbe *v, const char *z, int n, int negateFlag, int iMem){
** like the continuation of the number.
*/
static void codeInteger(Vdbe *v, Expr *pExpr, int negFlag, int iMem){
- const char *z;
if( pExpr->flags & EP_IntValue ){
- int i = pExpr->iTable;
+ int i = pExpr->u.iValue;
if( negFlag ) i = -i;
sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
- }else if( (z = (char*)pExpr->token.z)!=0 ){
- int i;
- int n = pExpr->token.n;
- assert( !sqlite3Isdigit(z[n]) );
- if( sqlite3GetInt32(z, &i) ){
- if( negFlag ) i = -i;
- sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
- }else if( sqlite3FitsIn64Bits(z, negFlag) ){
+ }else{
+ const char *z = pExpr->u.zToken;
+ assert( z!=0 );
+ if( sqlite3FitsIn64Bits(z, negFlag) ){
i64 value;
char *zV;
sqlite3Atoi64(z, &value);
@@ -59353,7 +60529,7 @@ static void codeInteger(Vdbe *v, Expr *pExpr, int negFlag, int iMem){
zV = dup8bytes(v, (char*)&value);
sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
}else{
- codeReal(v, z, n, negFlag, iMem);
+ codeReal(v, z, negFlag, iMem);
}
}
}
@@ -59381,6 +60557,9 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
int idxLru;
struct yColCache *p;
+ assert( iReg>0 ); /* Register numbers are always positive */
+ assert( iCol>=-1 && iCol<32768 ); /* Finite column numbers */
+
/* First replace any existing entry */
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iTable==iTab && p->iColumn==iCol ){
@@ -59392,7 +60571,6 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
return;
}
}
- if( iReg<=0 ) return;
/* Find an empty slot and replace it */
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
@@ -59417,7 +60595,7 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
minLru = p->lru;
}
}
- if( idxLru>=0 ){
+ if( ALWAYS(idxLru>=0) ){
p = &pParse->aColCache[idxLru];
p->iLevel = pParse->iCacheLevel;
p->iTable = iTab;
@@ -59519,10 +60697,6 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg>0 && p->iTable==iTable && p->iColumn==iColumn
&& (!p->affChange || allowAffChng) ){
-#if 0
- sqlite3VdbeAddOp0(v, OP_Noop);
- VdbeComment((v, "OPT: tab%d.col%d -> r%d", iTable, iColumn, p->iReg));
-#endif
p->lru = pParse->iCacheCnt++;
sqlite3ExprCachePinRegister(pParse, p->iReg);
return p->iReg;
@@ -59531,9 +60705,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(
assert( v!=0 );
if( iColumn<0 ){
sqlite3VdbeAddOp2(v, OP_Rowid, iTable, iReg);
- }else if( pTab==0 ){
- sqlite3VdbeAddOp3(v, OP_Column, iTable, iColumn, iReg);
- }else{
+ }else if( ALWAYS(pTab!=0) ){
int op = IsVirtual(pTab) ? OP_VColumn : OP_Column;
sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg);
sqlite3ColumnDefault(v, pTab, iColumn);
@@ -59585,7 +60757,7 @@ SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, in
SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
struct yColCache *p;
- if( iFrom==iTo ) return;
+ if( NEVER(iFrom==iTo) ) return;
sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
int x = p->iReg;
@@ -59601,7 +60773,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n
*/
SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
int i;
- if( iFrom==iTo ) return;
+ if( NEVER(iFrom==iTo) ) return;
for(i=0; i<nReg; i++){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
}
@@ -59627,15 +60799,15 @@ static int usedAsColumnCache(Parse *pParse, int iFrom, int iTo){
** convert the last instruction from OP_SCopy to OP_Copy.
*/
SQLITE_PRIVATE void sqlite3ExprHardCopy(Parse *pParse, int iReg, int nReg){
- int addr;
VdbeOp *pOp;
Vdbe *v;
+ assert( pParse->db->mallocFailed==0 );
v = pParse->pVdbe;
- addr = sqlite3VdbeCurrentAddr(v);
- pOp = sqlite3VdbeGetOp(v, addr-1);
- assert( pOp || pParse->db->mallocFailed );
- if( pOp && pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
+ assert( v!=0 );
+ pOp = sqlite3VdbeGetOp(v, -1);
+ assert( pOp!=0 );
+ if( pOp->opcode==OP_SCopy && pOp->p1>=iReg && pOp->p1<iReg+nReg ){
pOp->opcode = OP_Copy;
}
}
@@ -59706,12 +60878,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
int regFree1 = 0; /* If non-zero free this temporary register */
int regFree2 = 0; /* If non-zero free this temporary register */
int r1, r2, r3, r4; /* Various register numbers */
- sqlite3 *db;
+ sqlite3 *db = pParse->db; /* The database connection */
- db = pParse->db;
- assert( v!=0 || db->mallocFailed );
assert( target>0 && target<=pParse->nMem );
- if( v==0 ) return 0;
+ if( v==0 ){
+ assert( pParse->db->mallocFailed );
+ return 0;
+ }
if( pExpr==0 ){
op = TK_NULL;
@@ -59751,12 +60924,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
break;
}
case TK_FLOAT: {
- codeReal(v, (char*)pExpr->token.z, pExpr->token.n, 0, target);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ codeReal(v, pExpr->u.zToken, 0, target);
break;
}
case TK_STRING: {
- sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0,
- (char*)pExpr->token.z, pExpr->token.n);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ sqlite3VdbeAddOp4(v, OP_String8, 0, target, 0, pExpr->u.zToken, 0);
break;
}
case TK_NULL: {
@@ -59768,23 +60942,24 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
int n;
const char *z;
char *zBlob;
- assert( pExpr->token.n>=3 );
- assert( pExpr->token.z[0]=='x' || pExpr->token.z[0]=='X' );
- assert( pExpr->token.z[1]=='\'' );
- assert( pExpr->token.z[pExpr->token.n-1]=='\'' );
- n = pExpr->token.n - 3;
- z = (char*)pExpr->token.z + 2;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
+ assert( pExpr->u.zToken[1]=='\'' );
+ z = &pExpr->u.zToken[2];
+ n = sqlite3Strlen30(z) - 1;
+ assert( z[n]=='\'' );
zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n);
sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC);
break;
}
#endif
case TK_VARIABLE: {
- int iPrior;
VdbeOp *pOp;
- if( pExpr->token.n<=1
- && (iPrior = sqlite3VdbeCurrentAddr(v)-1)>=0
- && (pOp = sqlite3VdbeGetOp(v, iPrior))->opcode==OP_Variable
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ assert( pExpr->u.zToken!=0 );
+ assert( pExpr->u.zToken[0]!=0 );
+ if( pExpr->u.zToken[1]==0
+ && (pOp = sqlite3VdbeGetOp(v, -1))->opcode==OP_Variable
&& pOp->p1+pOp->p3==pExpr->iTable
&& pOp->p2+pOp->p3==target
&& pOp->p4.z==0
@@ -59797,8 +60972,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
pOp->p3++;
}else{
sqlite3VdbeAddOp3(v, OP_Variable, pExpr->iTable, target, 1);
- if( pExpr->token.n>1 ){
- sqlite3VdbeChangeP4(v, -1, (char*)pExpr->token.z, pExpr->token.n);
+ if( pExpr->u.zToken[1]!=0 ){
+ sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
}
}
break;
@@ -59816,7 +60991,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
/* Expressions of the form: CAST(pLeft AS token) */
int aff, to_op;
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
- aff = sqlite3AffinityType(&pExpr->token);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ aff = sqlite3AffinityType(pExpr->u.zToken);
to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
assert( to_op==OP_ToText || aff!=SQLITE_AFF_TEXT );
assert( to_op==OP_ToBlob || aff!=SQLITE_AFF_NONE );
@@ -59909,7 +61085,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
Expr *pLeft = pExpr->pLeft;
assert( pLeft );
if( pLeft->op==TK_FLOAT ){
- codeReal(v, (char*)pLeft->token.z, pLeft->token.n, 1, target);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ codeReal(v, pLeft->u.zToken, 1, target);
}else if( pLeft->op==TK_INTEGER ){
codeInteger(v, pLeft, 1, target);
}else{
@@ -59952,8 +61129,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
case TK_AGG_FUNCTION: {
AggInfo *pInfo = pExpr->pAggInfo;
if( pInfo==0 ){
- sqlite3ErrorMsg(pParse, "misuse of aggregate: %T",
- &pExpr->span);
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken);
}else{
inReg = pInfo->aFunc[pExpr->iAgg].iMem;
}
@@ -59974,14 +61151,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
testcase( op==TK_CONST_FUNC );
testcase( op==TK_FUNCTION );
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ){
+ if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
pFarg = 0;
}else{
pFarg = pExpr->x.pList;
}
nFarg = pFarg ? pFarg->nExpr : 0;
- zId = (char*)pExpr->token.z;
- nId = pExpr->token.n;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ zId = pExpr->u.zToken;
+ nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
assert( pDef!=0 );
if( pFarg ){
@@ -60009,8 +61187,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr);
}
#endif
- for(i=0; i<nFarg && i<32; i++){
- if( sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
+ for(i=0; i<nFarg; i++){
+ if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
constMask |= (1<<i);
}
if( (pDef->flags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
@@ -60035,9 +61213,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
case TK_SELECT: {
testcase( op==TK_EXISTS );
testcase( op==TK_SELECT );
- if( pExpr->iColumn==0 ){
- sqlite3CodeSubselect(pParse, pExpr, 0, 0);
- }
+ sqlite3CodeSubselect(pParse, pExpr, 0, 0);
inReg = pExpr->iColumn;
break;
}
@@ -60192,7 +61368,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
** or if there is no matching Ei, the ELSE term Y, or if there is
** no ELSE term, NULL.
*/
- case TK_CASE: {
+ default: assert( op==TK_CASE ); {
int endLabel; /* GOTO label for end of CASE stmt */
int nextCase; /* GOTO label for next WHEN clause */
int nExpr; /* 2x number of WHEN terms */
@@ -60214,7 +61390,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
endLabel = sqlite3VdbeMakeLabel(v);
if( (pX = pExpr->pLeft)!=0 ){
cacheX = *pX;
- testcase( pX->op==TK_COLUMN || pX->op==TK_REGISTER );
+ testcase( pX->op==TK_COLUMN );
+ testcase( pX->op==TK_REGISTER );
cacheX.iTable = sqlite3ExprCodeTemp(pParse, pX, &regFree1);
testcase( regFree1==0 );
cacheX.op = TK_REGISTER;
@@ -60231,7 +61408,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
pTest = aListelem[i].pExpr;
}
nextCase = sqlite3VdbeMakeLabel(v);
- testcase( pTest->op==TK_COLUMN || pTest->op==TK_REGISTER );
+ testcase( pTest->op==TK_COLUMN );
sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
testcase( aListelem[i+1].pExpr->op==TK_REGISTER );
@@ -60263,8 +61440,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
assert( pExpr->affinity==OE_Rollback ||
pExpr->affinity == OE_Abort ||
pExpr->affinity == OE_Fail );
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->affinity, 0,
- (char*)pExpr->token.z, pExpr->token.n);
+ pExpr->u.zToken, 0);
} else {
assert( pExpr->affinity == OE_Ignore );
sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0);
@@ -60335,7 +61513,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targe
int inReg;
inReg = sqlite3ExprCode(pParse, pExpr, target);
assert( target>0 );
- if( pExpr->op!=TK_REGISTER ){
+ /* This routine is called for terms to INSERT or UPDATE. And the only
+ ** other place where expressions can be converted into TK_REGISTER is
+ ** in WHERE clause processing. So as currently implemented, there is
+ ** no way for a TK_REGISTER to exist here. But it seems prudent to
+ ** keep the ALWAYS() in case the conditions above change with future
+ ** modifications or enhancements. */
+ if( ALWAYS(pExpr->op!=TK_REGISTER) ){
int iMem;
iMem = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
@@ -60392,10 +61576,10 @@ static int isAppropriateForFactoring(Expr *p){
return 0;
}
case TK_UMINUS: {
- if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
- return 0;
- }
- break;
+ if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){
+ return 0;
+ }
+ break;
}
default: {
break;
@@ -60414,7 +61598,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
Parse *pParse = pWalker->pParse;
switch( pExpr->op ){
case TK_REGISTER: {
- return 1;
+ return WRC_Prune;
}
case TK_FUNCTION:
case TK_AGG_FUNCTION:
@@ -60429,7 +61613,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
int i = pList->nExpr;
struct ExprList_item *pItem = pList->a;
for(; i>0; i--, pItem++){
- if( pItem->pExpr ) pItem->pExpr->flags |= EP_FixedDest;
+ if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest;
}
}
break;
@@ -60439,7 +61623,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){
int r1 = ++pParse->nMem;
int r2;
r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
- if( r1!=r2 ) sqlite3ReleaseTempReg(pParse, r1);
+ if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1);
pExpr->op = TK_REGISTER;
pExpr->iTable = r2;
return WRC_Prune;
@@ -60488,7 +61672,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
}else{
sqlite3ExprCode(pParse, pItem->pExpr, target+i);
}
- if( doHardCopy ){
+ if( doHardCopy && !pParse->db->mallocFailed ){
sqlite3ExprHardCopy(pParse, target, n);
}
}
@@ -60517,7 +61701,8 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( v==0 || pExpr==0 ) return;
+ if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
+ if( NEVER(pExpr==0) ) return; /* No way this can happen */
op = pExpr->op;
switch( op ){
case TK_AND: {
@@ -60641,7 +61826,8 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
int r1, r2;
assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
- if( v==0 || pExpr==0 ) return;
+ if( NEVER(v==0) ) return; /* Existance of VDBE checked by caller */
+ if( pExpr==0 ) return;
/* The value of pExpr->op and op are related as follows:
**
@@ -60789,6 +61975,8 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
if( pA==0||pB==0 ){
return pB==pA;
}
+ assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
+ assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
return 0;
}
@@ -60809,10 +61997,13 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
}
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
- if( pA->op!=TK_COLUMN && pA->token.z ){
- if( pB->token.z==0 ) return 0;
- if( pB->token.n!=pA->token.n ) return 0;
- if( sqlite3StrNICmp((char*)pA->token.z,(char*)pB->token.z,pB->token.n)!=0 ){
+ if( ExprHasProperty(pA, EP_IntValue) ){
+ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
+ return 0;
+ }
+ }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
+ if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 0;
+ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 0;
}
}
@@ -60875,10 +62066,11 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_COLUMN );
/* Check to see if the column is in one of the tables in the FROM
** clause of the aggregate query */
- if( pSrcList ){
+ if( ALWAYS(pSrcList!=0) ){
struct SrcList_item *pItem = pSrcList->a;
for(i=0; i<pSrcList->nSrc; i++, pItem++){
struct AggInfo_col *pCol;
+ assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
if( pExpr->iTable==pItem->iCursor ){
/* If we reach this point, it means that pExpr refers to a table
** that is in the FROM clause of the aggregate query.
@@ -60927,9 +62119,10 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
** Convert the pExpr to be a TK_AGG_COLUMN referring to that
** pAggInfo->aCol[] entry.
*/
+ ExprSetIrreducible(pExpr);
pExpr->pAggInfo = pAggInfo;
pExpr->op = TK_AGG_COLUMN;
- pExpr->iAgg = k;
+ pExpr->iAgg = (i16)k;
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
@@ -60959,8 +62152,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
pItem = &pAggInfo->aFunc[i];
pItem->pExpr = pExpr;
pItem->iMem = ++pParse->nMem;
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
pItem->pFunc = sqlite3FindFunction(pParse->db,
- (char*)pExpr->token.z, pExpr->token.n,
+ pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
@@ -60971,7 +62165,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
- pExpr->iAgg = i;
+ assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(pExpr);
+ pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
}
@@ -61004,6 +62200,7 @@ SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
w.xExprCallback = analyzeAggregate;
w.xSelectCallback = analyzeAggregatesInSelect;
w.u.pNC = pNC;
+ assert( pNC->pSrcList!=0 );
sqlite3WalkExpr(&w, pExpr);
}
@@ -61147,7 +62344,7 @@ static void renameTableFunc(
}
/* Store the token that zCsr points to in tname. */
- tname.z = zCsr;
+ tname.z = (char*)zCsr;
tname.n = len;
/* Advance zCsr to the next token. Store that token type in 'token',
@@ -61160,7 +62357,7 @@ static void renameTableFunc(
assert( len>0 );
} while( token!=TK_LP && token!=TK_USING );
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql,
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
@@ -61206,7 +62403,7 @@ static void renameTriggerFunc(
}
/* Store the token that zCsr points to in tname. */
- tname.z = zCsr;
+ tname.z = (char*)zCsr;
tname.n = len;
/* Advance zCsr to the next token. Store that token type in 'token',
@@ -61236,7 +62433,7 @@ static void renameTriggerFunc(
/* Variable tname now contains the token that is the old table-name
** in the CREATE TRIGGER statement.
*/
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql,
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
@@ -61508,6 +62705,31 @@ exit_rename_table:
/*
+** Generate code to make sure the file format number is at least minFormat.
+** The generated code will increase the file format number if necessary.
+*/
+SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
+ Vdbe *v;
+ v = sqlite3GetVdbe(pParse);
+ /* The VDBE should have been allocated before this routine is called.
+ ** If that allocation failed, we would have quit before reaching this
+ ** point */
+ if( ALWAYS(v) ){
+ int r1 = sqlite3GetTempReg(pParse);
+ int r2 = sqlite3GetTempReg(pParse);
+ int j1;
+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
+ sqlite3VdbeUsesBtree(v, iDb);
+ sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
+ j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
+ sqlite3VdbeJumpHere(v, j1);
+ sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempReg(pParse, r2);
+ }
+}
+
+/*
** This function is called after an "ALTER TABLE ... ADD" statement
** has been parsed. Argument pColDef contains the text of the new
** column definition.
@@ -61692,6 +62914,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
pCol->zColl = 0;
pCol->zType = 0;
pCol->pDflt = 0;
+ pCol->zDflt = 0;
}
pNew->pSchema = db->aDb[iDb].pSchema;
pNew->addColOffset = pTab->addColOffset;
@@ -62187,7 +63410,7 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
if( pExpr->op!=TK_ID ){
rc = sqlite3ResolveExprNames(pName, pExpr);
if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pName->pParse, "invalid name: \"%T\"", &pExpr->span);
+ sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
return SQLITE_ERROR;
}
}else{
@@ -62444,21 +63667,6 @@ static void codeAttach(
sqlite3* db = pParse->db;
int regArgs;
-#ifndef SQLITE_OMIT_AUTHORIZATION
- assert( db->mallocFailed || pAuthArg );
- if( pAuthArg ){
- char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span);
- if( !zAuthArg ){
- goto attach_end;
- }
- rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
- sqlite3DbFree(db, zAuthArg);
- if(rc!=SQLITE_OK ){
- goto attach_end;
- }
- }
-#endif /* SQLITE_OMIT_AUTHORIZATION */
-
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
@@ -62471,6 +63679,20 @@ static void codeAttach(
goto attach_end;
}
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ if( pAuthArg ){
+ char *zAuthArg = pAuthArg->u.zToken;
+ if( NEVER(zAuthArg==0) ){
+ goto attach_end;
+ }
+ rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
+ if(rc!=SQLITE_OK ){
+ goto attach_end;
+ }
+ }
+#endif /* SQLITE_OMIT_AUTHORIZATION */
+
+
v = sqlite3GetVdbe(pParse);
regArgs = sqlite3GetTempRange(pParse, 4);
sqlite3ExprCode(pParse, pFilename, regArgs);
@@ -62633,7 +63855,7 @@ SQLITE_PRIVATE int sqlite3FixExpr(
Expr *pExpr /* The expression to be fixed to one database */
){
while( pExpr ){
- if( ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_SpanToken) ) break;
+ if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
}else{
@@ -62991,10 +64213,7 @@ SQLITE_PRIVATE void sqlite3TableLock(
int nBytes;
TableLock *p;
- if( iDb<0 ){
- return;
- }
-
+ assert( iDb>=0 );
for(i=0; i<pParse->nTableLock; i++){
p = &pParse->aTableLock[i];
if( p->iDb==iDb && p->iTab==iTab ){
@@ -63026,9 +64245,8 @@ static void codeTableLocks(Parse *pParse){
int i;
Vdbe *pVdbe;
- if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){
- return;
- }
+ pVdbe = sqlite3GetVdbe(pParse);
+ assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */
for(i=0; i<pParse->nTableLock; i++){
TableLock *p = &pParse->aTableLock[i];
@@ -63108,7 +64326,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
/* Get the VDBE program ready for execution
*/
- if( v && pParse->nErr==0 && !db->mallocFailed ){
+ if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
#ifdef SQLITE_DEBUG
FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
sqlite3VdbeTrace(v, trace);
@@ -63250,11 +64468,9 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
+ assert( pSchema );
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
- assert( pSchema || (j==1 && !db->aDb[1].pBt) );
- if( pSchema ){
- p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
- }
+ p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
if( p ) break;
}
return p;
@@ -63265,6 +64481,7 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha
*/
static void freeIndex(Index *p){
sqlite3 *db = p->pTable->dbMem;
+ /* testcase( db==0 ); */
sqlite3DbFree(db, p->zColAff);
sqlite3DbFree(db, p);
}
@@ -63300,13 +64517,19 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char
len = sqlite3Strlen30(zIdxName);
pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);
- if( pIndex ){
+ /* Justification of ALWAYS(): This routine is only called from the
+ ** OP_DropIndex opcode. And there is no way that opcode will ever run
+ ** unless the corresponding index is in the symbol table. */
+ if( ALWAYS(pIndex) ){
if( pIndex->pTable->pIndex==pIndex ){
pIndex->pTable->pIndex = pIndex->pNext;
}else{
Index *p;
- for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
- if( p && p->pNext==pIndex ){
+ /* Justification of ALWAYS(); The index must be on the list of
+ ** indices. */
+ p = pIndex->pTable->pIndex;
+ while( ALWAYS(p) && p->pNext!=pIndex ){ p = p->pNext; }
+ if( ALWAYS(p && p->pNext==pIndex) ){
p->pNext = pIndex->pNext;
}
}
@@ -63351,6 +64574,7 @@ SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
** schema hash tables and therefore do not have to make any changes
** to any of those tables.
*/
+#ifdef SQLITE_HAS_CODEC
for(i=0; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
@@ -63358,6 +64582,7 @@ SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
pDb->pAux = 0;
}
}
+#endif
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
@@ -63393,11 +64618,13 @@ static void sqliteResetColumnNames(Table *pTable){
int i;
Column *pCol;
sqlite3 *db = pTable->dbMem;
+ testcase( db==0 );
assert( pTable!=0 );
if( (pCol = pTable->aCol)!=0 ){
for(i=0; i<pTable->nCol; i++, pCol++){
sqlite3DbFree(db, pCol->zName);
sqlite3ExprDelete(db, pCol->pDflt);
+ sqlite3DbFree(db, pCol->zDflt);
sqlite3DbFree(db, pCol->zType);
sqlite3DbFree(db, pCol->zColl);
}
@@ -63423,6 +64650,7 @@ SQLITE_PRIVATE void sqlite3DeleteTable(Table *pTable){
if( pTable==0 ) return;
db = pTable->dbMem;
+ testcase( db==0 );
/* Do not delete the table until the reference count reaches zero. */
pTable->nRef--;
@@ -63495,7 +64723,7 @@ SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
char *zName;
if( pName ){
zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n);
- if( pName->quoted ) sqlite3Dequote(zName);
+ sqlite3Dequote(zName);
}else{
zName = 0;
}
@@ -63577,7 +64805,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
int iDb; /* Database holding the object */
sqlite3 *db = pParse->db;
- if( pName2 && pName2->n>0 ){
+ if( ALWAYS(pName2!=0) && pName2->n>0 ){
if( db->init.busy ) {
sqlite3ErrorMsg(pParse, "corrupt database");
pParse->nErr++;
@@ -63742,8 +64970,8 @@ SQLITE_PRIVATE void sqlite3StartTable(
pTable->iPKey = -1;
pTable->pSchema = db->aDb[iDb].pSchema;
pTable->nRef = 1;
- pTable->dbMem = db->lookaside.bEnabled ? db : 0;
- if( pParse->pNewTable ) sqlite3DeleteTable(pParse->pNewTable);
+ pTable->dbMem = 0;
+ assert( pParse->pNewTable==0 );
pParse->pNewTable = pTable;
/* If this is the magic sqlite_sequence table used by autoincrement,
@@ -63782,15 +65010,15 @@ SQLITE_PRIVATE void sqlite3StartTable(
reg1 = pParse->regRowid = ++pParse->nMem;
reg2 = pParse->regRoot = ++pParse->nMem;
reg3 = ++pParse->nMem;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, 1); /* file_format */
+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
1 : SQLITE_MAX_FILE_FORMAT;
sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 1, reg3);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 4, reg3);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
sqlite3VdbeJumpHere(v, j1);
/* This just creates a place-holder record in the sqlite_master table.
@@ -63899,10 +65127,9 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName){
*/
SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
Table *p;
- int i;
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- if( i>=0 ) p->aCol[i].notNull = (u8)onError;
+ p = pParse->pNewTable;
+ if( p==0 || NEVER(p->nCol<1) ) return;
+ p->aCol[p->nCol-1].notNull = (u8)onError;
}
/*
@@ -63930,14 +65157,12 @@ SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){
** If none of the substrings in the above table are found,
** SQLITE_AFF_NUMERIC is returned.
*/
-SQLITE_PRIVATE char sqlite3AffinityType(const Token *pType){
+SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn){
u32 h = 0;
char aff = SQLITE_AFF_NUMERIC;
- const unsigned char *zIn = pType->z;
- const unsigned char *zEnd = &pType->z[pType->n];
- while( zIn!=zEnd ){
- h = (h<<8) + sqlite3UpperToLower[*zIn];
+ if( zIn ) while( zIn[0] ){
+ h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff];
zIn++;
if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */
aff = SQLITE_AFF_TEXT;
@@ -63979,18 +65204,14 @@ SQLITE_PRIVATE char sqlite3AffinityType(const Token *pType){
*/
SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
Table *p;
- int i;
Column *pCol;
- sqlite3 *db;
- if( (p = pParse->pNewTable)==0 ) return;
- i = p->nCol-1;
- if( i<0 ) return;
- pCol = &p->aCol[i];
- db = pParse->db;
- sqlite3DbFree(db, pCol->zType);
- pCol->zType = sqlite3NameFromToken(db, pType);
- pCol->affinity = sqlite3AffinityType(pType);
+ p = pParse->pNewTable;
+ if( p==0 || NEVER(p->nCol<1) ) return;
+ pCol = &p->aCol[p->nCol-1];
+ assert( pCol->zType==0 );
+ pCol->zType = sqlite3NameFromToken(pParse->db, pType);
+ pCol->affinity = sqlite3AffinityType(pCol->zType);
}
/*
@@ -64003,13 +65224,14 @@ SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
-SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
+SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
- if( (p = pParse->pNewTable)!=0 ){
+ p = pParse->pNewTable;
+ if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pExpr) ){
+ if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
@@ -64018,10 +65240,13 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, Expr *pExpr){
** is required by pragma table_info.
*/
sqlite3ExprDelete(db, pCol->pDflt);
- pCol->pDflt = sqlite3ExprDup(db, pExpr, EXPRDUP_REDUCE|EXPRDUP_SPAN);
+ pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
+ sqlite3DbFree(db, pCol->zDflt);
+ pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
+ (int)(pSpan->zEnd - pSpan->zStart));
}
}
- sqlite3ExprDelete(db, pExpr);
+ sqlite3ExprDelete(db, pSpan->pExpr);
}
/*
@@ -64110,14 +65335,12 @@ SQLITE_PRIVATE void sqlite3AddCheckConstraint(
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
if( pTab && !IN_DECLARE_VTAB ){
- /* The CHECK expression must be duplicated so that tokens refer
- ** to malloced space and not the (ephemeral) text of the CREATE TABLE
- ** statement */
- pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck,
- sqlite3ExprDup(db, pCheckExpr, 0));
- }
+ pTab->pCheck = sqlite3ExprAnd(db, pTab->pCheck, pCheckExpr);
+ }else
#endif
- sqlite3ExprDelete(db, pCheckExpr);
+ {
+ sqlite3ExprDelete(db, pCheckExpr);
+ }
}
/*
@@ -64136,7 +65359,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
zColl = sqlite3NameFromToken(db, pToken);
if( !zColl ) return;
- if( sqlite3LocateCollSeq(pParse, zColl, -1) ){
+ if( sqlite3LocateCollSeq(pParse, zColl) ){
Index *pIdx;
p->aCol[i].zColl = zColl;
@@ -64172,21 +65395,20 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){
** This routine is a wrapper around sqlite3FindCollSeq(). This routine
** invokes the collation factory if the named collation cannot be found
** and generates an error message.
+**
+** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq()
*/
-SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){
+SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){
sqlite3 *db = pParse->db;
u8 enc = ENC(db);
u8 initbusy = db->init.busy;
CollSeq *pColl;
- pColl = sqlite3FindCollSeq(db, enc, zName, nName, initbusy);
+ pColl = sqlite3FindCollSeq(db, enc, zName, initbusy);
if( !initbusy && (!pColl || !pColl->xCmp) ){
- pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
+ pColl = sqlite3GetCollSeq(db, pColl, zName);
if( !pColl ){
- if( nName<0 ){
- nName = sqlite3Strlen30(zName);
- }
- sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
+ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
pColl = 0;
}
}
@@ -64216,7 +65438,7 @@ SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){
sqlite3 *db = pParse->db;
Vdbe *v = pParse->pVdbe;
sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 0, r1);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
sqlite3ReleaseTempReg(pParse, r1);
}
@@ -64237,61 +65459,6 @@ static int identLength(const char *z){
}
/*
-** This function is a wrapper around sqlite3GetToken() used by
-** isValidDimension(). This function differs from sqlite3GetToken() in
-** that:
-**
-** * Whitespace is ignored, and
-** * The output variable *peToken is set to 0 if the end of the
-** nul-terminated input string is reached.
-*/
-static int getTokenNoSpace(unsigned char *z, int *peToken){
- int n = 0;
- while( sqlite3Isspace(z[n]) ) n++;
- if( !z[n] ){
- *peToken = 0;
- return 0;
- }
- return n + sqlite3GetToken(&z[n], peToken);
-}
-
-/*
-** Parameter z points to a nul-terminated string. Return true if, when
-** whitespace is ignored, the contents of this string matches one of
-** the following patterns:
-**
-** ""
-** "(number)"
-** "(number,number)"
-*/
-static int isValidDimension(unsigned char *z){
- int eToken;
- int n = 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken ){
- if( eToken!=TK_LP ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_PLUS || eToken==TK_MINUS ){
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_COMMA ){
- n += getTokenNoSpace(&z[n], &eToken);
- if( eToken==TK_PLUS || eToken==TK_MINUS ){
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_INTEGER && eToken!=TK_FLOAT ) return 0;
- n += getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken!=TK_RP ) return 0;
- getTokenNoSpace(&z[n], &eToken);
- }
- if( eToken ) return 0;
- return 1;
-}
-
-/*
** The first parameter is a pointer to an output buffer. The second
** parameter is a pointer to an integer that contains the offset at
** which to write into the output buffer. This function copies the
@@ -64304,7 +65471,7 @@ static int isValidDimension(unsigned char *z){
** then it is copied to the output buffer exactly as it is. Otherwise,
** it is quoted using double-quotes.
*/
-static void identPut(char *z, int *pIdx, char *zSignedIdent, int isTypename){
+static void identPut(char *z, int *pIdx, char *zSignedIdent){
unsigned char *zIdent = (unsigned char*)zSignedIdent;
int i, j, needQuote;
i = *pIdx;
@@ -64314,21 +65481,7 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent, int isTypename){
}
needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
if( !needQuote ){
- if( isTypename ){
- /* If this is a type-name, allow a little more flexibility. In SQLite,
- ** a type-name is specified as:
- **
- ** ids [ids] [(number [, number])]
- **
- ** where "ids" is either a quoted string or a simple identifier (in the
- ** above notation, [] means optional). It is a bit tricky to check
- ** for all cases, but it is good to avoid unnecessarily quoting common
- ** typenames like VARCHAR(10).
- */
- needQuote = !isValidDimension(&zIdent[j]);
- }else{
- needQuote = zIdent[j];
- }
+ needQuote = zIdent[j];
}
if( needQuote ) z[i++] = '"';
@@ -64349,18 +65502,14 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent, int isTypename){
static char *createTableStmt(sqlite3 *db, Table *p){
int i, k, n;
char *zStmt;
- char *zSep, *zSep2, *zEnd, *z;
+ char *zSep, *zSep2, *zEnd;
Column *pCol;
n = 0;
for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
- n += identLength(pCol->zName);
- z = pCol->zType;
- if( z ){
- n += identLength(z);
- }
+ n += identLength(pCol->zName) + 5;
}
n += identLength(p->zName);
- if( n<50 ){
+ if( n<50 ){
zSep = "";
zSep2 = ",";
zEnd = ")";
@@ -64377,18 +65526,38 @@ static char *createTableStmt(sqlite3 *db, Table *p){
}
sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
k = sqlite3Strlen30(zStmt);
- identPut(zStmt, &k, p->zName, 0);
+ identPut(zStmt, &k, p->zName);
zStmt[k++] = '(';
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
+ static const char * const azType[] = {
+ /* SQLITE_AFF_TEXT */ " TEXT",
+ /* SQLITE_AFF_NONE */ "",
+ /* SQLITE_AFF_NUMERIC */ " NUM",
+ /* SQLITE_AFF_INTEGER */ " INT",
+ /* SQLITE_AFF_REAL */ " REAL"
+ };
+ int len;
+ const char *zType;
+
sqlite3_snprintf(n-k, &zStmt[k], zSep);
k += sqlite3Strlen30(&zStmt[k]);
zSep = zSep2;
- identPut(zStmt, &k, pCol->zName, 0);
- if( (z = pCol->zType)!=0 ){
- zStmt[k++] = ' ';
- assert( (int)(sqlite3Strlen30(z)+k+1)<=n );
- identPut(zStmt, &k, z, 1);
- }
+ identPut(zStmt, &k, pCol->zName);
+ assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 );
+ assert( pCol->affinity-SQLITE_AFF_TEXT < sizeof(azType)/sizeof(azType[0]) );
+ testcase( pCol->affinity==SQLITE_AFF_TEXT );
+ testcase( pCol->affinity==SQLITE_AFF_NONE );
+ testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
+ testcase( pCol->affinity==SQLITE_AFF_INTEGER );
+ testcase( pCol->affinity==SQLITE_AFF_REAL );
+
+ zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
+ len = sqlite3Strlen30(zType);
+ assert( pCol->affinity==SQLITE_AFF_NONE
+ || pCol->affinity==sqlite3AffinityType(zType) );
+ memcpy(&zStmt[k], zType, len);
+ k += len;
+ assert( k<=n );
}
sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
return zStmt;
@@ -64424,7 +65593,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
sqlite3 *db = pParse->db;
int iDb;
- if( (pEnd==0 && pSelect==0) || pParse->nErr || db->mallocFailed ) {
+ if( (pEnd==0 && pSelect==0) || db->mallocFailed ){
return;
}
p = pParse->pNewTable;
@@ -64480,7 +65649,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */
v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
+ if( NEVER(v==0) ) return;
sqlite3VdbeAddOp1(v, OP_Close, 0);
@@ -64587,7 +65756,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
/* Add the table to the in-memory representation of the database.
*/
- if( db->init.busy && pParse->nErr==0 ){
+ if( db->init.busy ){
Table *pOld;
Schema *pSchema = p->pSchema;
pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
@@ -64631,7 +65800,7 @@ SQLITE_PRIVATE void sqlite3CreateView(
){
Table *p;
int n;
- const unsigned char *z;
+ const char *z;
Token sEnd;
DbFixer sFix;
Token *pName;
@@ -64645,10 +65814,12 @@ SQLITE_PRIVATE void sqlite3CreateView(
}
sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
- if( p==0 || pParse->nErr ){
+ if( p==0 ){
sqlite3SelectDelete(db, pSelect);
return;
}
+ assert( pParse->nErr==0 ); /* If sqlite3StartTable return non-NULL then
+ ** there could not have been an error */
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite3SchemaToIndex(db, p->pSchema);
if( sqlite3FixInit(&sFix, pParse, iDb, "view", pName)
@@ -64676,13 +65847,13 @@ SQLITE_PRIVATE void sqlite3CreateView(
** the end.
*/
sEnd = pParse->sLastToken;
- if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
+ if( ALWAYS(sEnd.z[0]!=0) && sEnd.z[0]!=';' ){
sEnd.z += sEnd.n;
}
sEnd.n = 0;
n = (int)(sEnd.z - pBegin->z);
- z = (const unsigned char*)pBegin->z;
- while( n>0 && (z[n-1]==';' || sqlite3Isspace(z[n-1])) ){ n--; }
+ z = pBegin->z;
+ while( ALWAYS(n>0) && sqlite3Isspace(z[n-1]) ){ n--; }
sEnd.z = &z[n-1];
sEnd.n = 1;
@@ -64728,8 +65899,13 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
** CREATE VIEW one AS SELECT * FROM two;
** CREATE VIEW two AS SELECT * FROM one;
**
- ** Actually, this error is caught previously and so the following test
- ** should always fail. But we will leave it in place just to be safe.
+ ** Actually, the error above is now caught prior to reaching this point.
+ ** But the following test is still important as it does come up
+ ** in the following:
+ **
+ ** CREATE TABLE main.ex1(a);
+ ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1;
+ ** SELECT * FROM temp.ex1;
*/
if( pTable->nCol<0 ){
sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
@@ -64858,7 +66034,8 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
** reflect this.
**
** The "#NNN" in the SQL is a special constant that means whatever value
- ** is in register NNN. See sqlite3RegisterExpr().
+ ** is in register NNN. See grammar rules associated with the TK_REGISTER
+ ** token for additional information.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
@@ -64936,9 +66113,10 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
sqlite3 *db = pParse->db;
int iDb;
- if( pParse->nErr || db->mallocFailed ){
+ if( db->mallocFailed ){
goto exit_drop_table;
}
+ assert( pParse->nErr==0 );
assert( pName->nSrc==1 );
pTab = sqlite3LocateTable(pParse, isView,
pName->a[0].zName, pName->a[0].zDatabase);
@@ -65023,9 +66201,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
- if( v ){
- sqlite3VdbeAddOp0(v, OP_VBegin);
- }
+ sqlite3VdbeAddOp0(v, OP_VBegin);
}
#endif
@@ -65125,10 +66301,10 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey(
char *z;
assert( pTo!=0 );
- if( p==0 || pParse->nErr || IN_DECLARE_VTAB ) goto fk_end;
+ if( p==0 || IN_DECLARE_VTAB ) goto fk_end;
if( pFromCol==0 ){
int iCol = p->nCol-1;
- if( iCol<0 ) goto fk_end;
+ if( NEVER(iCol<0) ) goto fk_end;
if( pToCol && pToCol->nExpr!=1 ){
sqlite3ErrorMsg(pParse, "foreign key on %s"
" should reference only one column of table %T",
@@ -65345,7 +66521,12 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
int nExtra = 0;
char *zExtra;
- if( pParse->nErr || db->mallocFailed || IN_DECLARE_VTAB ){
+ assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
+ assert( pParse->nErr==0 ); /* Never called with prior errors */
+ if( db->mallocFailed || IN_DECLARE_VTAB ){
+ goto exit_create_index;
+ }
+ if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
@@ -65369,7 +66550,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
if( !db->init.busy ){
pTab = sqlite3SrcListLookup(pParse, pTblName);
- if( pName2 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
+ if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
iDb = 1;
}
}
@@ -65394,7 +66575,8 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
}
pDb = &db->aDb[iDb];
- if( pTab==0 || pParse->nErr ) goto exit_create_index;
+ assert( pTab!=0 );
+ assert( pParse->nErr==0 );
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
&& memcmp(&pTab->zName[7],"altertab_",9)!=0 ){
sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
@@ -65428,13 +66610,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
*/
if( pName ){
zName = sqlite3NameFromToken(db, pName);
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
if( zName==0 ) goto exit_create_index;
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto exit_create_index;
}
if( !db->init.busy ){
- if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto exit_create_index;
if( sqlite3FindTable(db, zName, 0)!=0 ){
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
@@ -65477,11 +66657,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** So create a fake list to simulate this.
*/
if( pList==0 ){
- nullId.z = (u8*)pTab->aCol[pTab->nCol-1].zName;
+ nullId.z = pTab->aCol[pTab->nCol-1].zName;
nullId.n = sqlite3Strlen30((char*)nullId.z);
- nullId.quoted = 0;
- pList = sqlite3ExprListAppend(pParse, 0, 0, &nullId);
+ pList = sqlite3ExprListAppend(pParse, 0, 0);
if( pList==0 ) goto exit_create_index;
+ sqlite3ExprListSetName(pParse, pList, &nullId, 0);
pList->a[0].sortOrder = (u8)sortOrder;
}
@@ -65489,10 +66669,14 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** specified collation sequence names.
*/
for(i=0; i<pList->nExpr; i++){
- Expr *pExpr;
- CollSeq *pColl;
- if( (pExpr = pList->a[i].pExpr)!=0 && (pColl = pExpr->pColl)!=0 ){
- nExtra += (1 + sqlite3Strlen30(pColl->zName));
+ Expr *pExpr = pList->a[i].pExpr;
+ if( pExpr ){
+ CollSeq *pColl = pExpr->pColl;
+ /* Either pColl!=0 or there was an OOM failure. But if an OOM
+ ** failure we have quit before reaching this point. */
+ if( ALWAYS(pColl) ){
+ nExtra += (1 + sqlite3Strlen30(pColl->zName));
+ }
}
}
@@ -65537,6 +66721,12 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
/* Scan the names of the columns of the table to be indexed and
** load the column indices into the Index structure. Report an error
** if any column is not found.
+ **
+ ** TODO: Add a test to make sure that the same column is not named
+ ** more than once within the same index. Only the first instance of
+ ** the column will ever be used by the optimizer. Note that using the
+ ** same column more than once cannot be an error because that would
+ ** break backwards compatibility - it needs to be a warning.
*/
for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
const char *zColName = pListItem->zName;
@@ -65552,25 +66742,28 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
pTab->zName, zColName);
goto exit_create_index;
}
- /* TODO: Add a test to make sure that the same column is not named
- ** more than once within the same index. Only the first instance of
- ** the column will ever be used by the optimizer. Note that using the
- ** same column more than once cannot be an error because that would
- ** break backwards compatibility - it needs to be a warning.
- */
pIndex->aiColumn[i] = j;
- if( pListItem->pExpr && pListItem->pExpr->pColl ){
- assert( pListItem->pExpr->pColl );
+ /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of
+ ** the way the "idxlist" non-terminal is constructed by the parser,
+ ** if pListItem->pExpr is not null then either pListItem->pExpr->pColl
+ ** must exist or else there must have been an OOM error. But if there
+ ** was an OOM error, we would never reach this point. */
+ if( pListItem->pExpr && ALWAYS(pListItem->pExpr->pColl) ){
+ int nColl;
+ zColl = pListItem->pExpr->pColl->zName;
+ nColl = sqlite3Strlen30(zColl) + 1;
+ assert( nExtra>=nColl );
+ memcpy(zExtra, zColl, nColl);
zColl = zExtra;
- sqlite3_snprintf(nExtra, zExtra, "%s", pListItem->pExpr->pColl->zName);
- zExtra += (sqlite3Strlen30(zColl) + 1);
+ zExtra += nColl;
+ nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
if( !zColl ){
zColl = db->pDfltColl->zName;
}
}
- if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl, -1) ){
+ if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
@@ -65592,6 +66785,14 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** so, don't bother creating this one. This only applies to
** automatically created indices. Users can do as they wish with
** explicit indices.
+ **
+ ** Two UNIQUE or PRIMARY KEY constraints are considered equivalent
+ ** (and thus suppressing the second one) even if they have different
+ ** sort orders.
+ **
+ ** If there are different collating sequences or if the columns of
+ ** the constraint occur in different orders, then the constraints are
+ ** considered distinct and both result in separate indices.
*/
Index *pIdx;
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -65602,10 +66803,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
if( pIdx->nColumn!=pIndex->nColumn ) continue;
for(k=0; k<pIdx->nColumn; k++){
- const char *z1 = pIdx->azColl[k];
- const char *z2 = pIndex->azColl[k];
+ const char *z1;
+ const char *z2;
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
- if( pIdx->aSortOrder[k]!=pIndex->aSortOrder[k] ) break;
+ z1 = pIdx->azColl[k];
+ z2 = pIndex->azColl[k];
if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
}
if( k==pIdx->nColumn ){
@@ -65664,7 +66866,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
** has just been created, it contains no data and the index initialization
** step can be skipped.
*/
- else if( db->init.busy==0 ){
+ else{ /* if( db->init.busy==0 ) */
Vdbe *v;
char *zStmt;
int iMem = ++pParse->nMem;
@@ -65681,7 +66883,8 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
*/
- if( pStart && pEnd ){
+ if( pStart ){
+ assert( pEnd!=0 );
/* A named index with an explicit CREATE INDEX statement */
zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
onError==OE_None ? "" : " UNIQUE",
@@ -65719,8 +66922,9 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
/* When adding an index to the list of indices for a table, make
** sure all indices labeled OE_Replace come after all those labeled
- ** OE_Ignore. This is necessary for the correct operation of UPDATE
- ** and INSERT.
+ ** OE_Ignore. This is necessary for the correct constraint check
+ ** processing (in sqlite3GenerateConstraintChecks()) as part of
+ ** UPDATE and INSERT statements.
*/
if( db->init.busy || pTblName==0 ){
if( onError!=OE_Replace || pTab->pIndex==0
@@ -65751,28 +66955,6 @@ exit_create_index:
}
/*
-** Generate code to make sure the file format number is at least minFormat.
-** The generated code will increase the file format number if necessary.
-*/
-SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
- Vdbe *v;
- v = sqlite3GetVdbe(pParse);
- if( v ){
- int r1 = sqlite3GetTempReg(pParse);
- int r2 = sqlite3GetTempReg(pParse);
- int j1;
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, 1);
- sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
- j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 1, r2);
- sqlite3VdbeJumpHere(v, j1);
- sqlite3ReleaseTempReg(pParse, r1);
- sqlite3ReleaseTempReg(pParse, r2);
- }
-}
-
-/*
** Fill the Index.aiRowEst[] array with default information - information
** to be used when we have not run the ANALYZE command.
**
@@ -65817,7 +66999,8 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists
sqlite3 *db = pParse->db;
int iDb;
- if( pParse->nErr || db->mallocFailed ){
+ assert( pParse->nErr==0 ); /* Never called with prior errors */
+ if( db->mallocFailed ){
goto exit_drop_index;
}
assert( pName->nSrc==1 );
@@ -66008,10 +67191,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
/* Sanity checking on calling parameters */
assert( iStart>=0 );
assert( nExtra>=1 );
- if( pSrc==0 || iStart>pSrc->nSrc ){
- assert( db->mallocFailed );
- return pSrc;
- }
+ assert( pSrc!=0 );
+ assert( iStart<=pSrc->nSrc );
/* Allocate additional space if needed */
if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
@@ -66049,7 +67230,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
/*
** Append a new table name to the given SrcList. Create a new SrcList if
-** need be. A new entry is created in the SrcList even if pToken is NULL.
+** need be. A new entry is created in the SrcList even if pTable is NULL.
**
** A SrcList is returned, or NULL if there is an OOM error. The returned
** SrcList might be the same as the SrcList that was input or it might be
@@ -66073,7 +67254,13 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
**
** sqlite3SrcListAppend(D,A,B,C);
**
-** Then C is the table name and B is the database name.
+** Then C is the table name and B is the database name. If C is defined
+** then so is B. In other words, we never have a case where:
+**
+** sqlite3SrcListAppend(D,A,0,C);
+**
+** Both pTable and pDatabase are assumed to be quoted. They are dequoted
+** before being added to the SrcList.
*/
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
sqlite3 *db, /* Connection to notify of malloc failures */
@@ -66082,6 +67269,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
Token *pDatabase /* Database of the table */
){
struct SrcList_item *pItem;
+ assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */
if( pList==0 ){
pList = sqlite3DbMallocZero(db, sizeof(SrcList) );
if( pList==0 ) return 0;
@@ -66096,7 +67284,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(
if( pDatabase && pDatabase->z==0 ){
pDatabase = 0;
}
- if( pDatabase && pTable ){
+ if( pDatabase ){
Token *pTemp = pDatabase;
pDatabase = pTable;
pTable = pTemp;
@@ -66173,14 +67361,15 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
struct SrcList_item *pItem;
sqlite3 *db = pParse->db;
p = sqlite3SrcListAppend(db, p, pTable, pDatabase);
- if( p==0 || p->nSrc==0 ){
+ if( p==0 || NEVER(p->nSrc==0) ){
sqlite3ExprDelete(db, pOn);
sqlite3IdListDelete(db, pUsing);
sqlite3SelectDelete(db, pSubquery);
return p;
}
pItem = &p->a[p->nSrc-1];
- if( pAlias && pAlias->n ){
+ assert( pAlias!=0 );
+ if( pAlias->n ){
pItem->zAlias = sqlite3NameFromToken(db, pAlias);
}
pItem->pSelect = pSubquery;
@@ -66194,7 +67383,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
** element of the source-list passed as the second argument.
*/
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){
- if( pIndexedBy && p && p->nSrc>0 ){
+ assert( pIndexedBy!=0 );
+ if( p && ALWAYS(p->nSrc>0) ){
struct SrcList_item *pItem = &p->a[p->nSrc-1];
assert( pItem->notIndexed==0 && pItem->zIndex==0 );
if( pIndexedBy->n==1 && !pIndexedBy->z ){
@@ -66240,10 +67430,13 @@ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){
Vdbe *v;
int i;
- if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
- if( pParse->nErr || db->mallocFailed ) return;
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
-
+ assert( pParse!=0 );
+ db = pParse->db;
+ assert( db!=0 );
+/* if( db->aDb[0].pBt==0 ) return; */
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
+ return;
+ }
v = sqlite3GetVdbe(pParse);
if( !v ) return;
if( type!=TK_DEFERRED ){
@@ -66262,10 +67455,13 @@ SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
sqlite3 *db;
Vdbe *v;
- if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
- if( pParse->nErr || db->mallocFailed ) return;
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
-
+ assert( pParse!=0 );
+ db = pParse->db;
+ assert( db!=0 );
+/* if( db->aDb[0].pBt==0 ) return; */
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
+ return;
+ }
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
@@ -66279,10 +67475,13 @@ SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
sqlite3 *db;
Vdbe *v;
- if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
- if( pParse->nErr || db->mallocFailed ) return;
- if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
-
+ assert( pParse!=0 );
+ db = pParse->db;
+ assert( db!=0 );
+/* if( db->aDb[0].pBt==0 ) return; */
+ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
+ return;
+ }
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
@@ -66402,12 +67601,13 @@ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
** necessary to undo a write and the checkpoint should not be set.
*/
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
- Vdbe *v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
sqlite3CodeVerifySchema(pParse, iDb);
pParse->writeMask |= 1<<iDb;
if( setStatement && pParse->nested==0 ){
- sqlite3VdbeAddOp1(v, OP_Statement, iDb);
+ /* Every place where this routine is called with setStatement!=0 has
+ ** already successfully created a VDBE. */
+ assert( pParse->pVdbe );
+ sqlite3VdbeAddOp1(pParse->pVdbe, OP_Statement, iDb);
}
}
@@ -66418,9 +67618,11 @@ SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement,
#ifndef SQLITE_OMIT_REINDEX
static int collationMatch(const char *zColl, Index *pIndex){
int i;
+ assert( zColl!=0 );
for(i=0; i<pIndex->nColumn; i++){
const char *z = pIndex->azColl[i];
- if( z==zColl || (z && zColl && 0==sqlite3StrICmp(z, zColl)) ){
+ assert( z!=0 );
+ if( 0==sqlite3StrICmp(z, zColl) ){
return 1;
}
}
@@ -66499,20 +67701,18 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
return;
}
- if( pName1==0 || pName1->z==0 ){
+ if( pName1==0 ){
reindexDatabases(pParse, 0);
return;
- }else if( pName2==0 || pName2->z==0 ){
+ }else if( NEVER(pName2==0) || pName2->z==0 ){
char *zColl;
assert( pName1->z );
zColl = sqlite3NameFromToken(pParse->db, pName1);
if( !zColl ) return;
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0);
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
if( pColl ){
- if( zColl ){
- reindexDatabases(pParse, zColl);
- sqlite3DbFree(db, zColl);
- }
+ reindexDatabases(pParse, zColl);
+ sqlite3DbFree(db, zColl);
return;
}
sqlite3DbFree(db, zColl);
@@ -66563,7 +67763,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
for(i=0; i<nCol; i++){
char *zColl = pIdx->azColl[i];
assert( zColl );
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl, -1);
+ pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
pKey->nField = (u16)nCol;
@@ -66602,11 +67802,10 @@ SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
** in the database text encoding of name zName, length nName.
** If the collation sequence
*/
-static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
+static void callCollNeeded(sqlite3 *db, const char *zName){
assert( !db->xCollNeeded || !db->xCollNeeded16 );
- if( nName<0 ) nName = sqlite3Strlen30(zName);
if( db->xCollNeeded ){
- char *zExternal = sqlite3DbStrNDup(db, zName, nName);
+ char *zExternal = sqlite3DbStrDup(db, zName);
if( !zExternal ) return;
db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal);
sqlite3DbFree(db, zExternal);
@@ -66615,7 +67814,7 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
if( db->xCollNeeded16 ){
char const *zExternal;
sqlite3_value *pTmp = sqlite3ValueNew(db);
- sqlite3ValueSetStr(pTmp, nName, zName, SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC);
zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE);
if( zExternal ){
db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal);
@@ -66635,11 +67834,10 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
CollSeq *pColl2;
char *z = pColl->zName;
- int n = sqlite3Strlen30(z);
int i;
static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 };
for(i=0; i<3; i++){
- pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, n, 0);
+ pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0);
if( pColl2->xCmp!=0 ){
memcpy(pColl, pColl2, sizeof(CollSeq));
pColl->xDel = 0; /* Do not copy the destructor */
@@ -66661,25 +67859,26 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){
** The return value is either the collation sequence to be used in database
** db for collation type name zName, length nName, or NULL, if no collation
** sequence can be found.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
- sqlite3* db,
- CollSeq *pColl,
- const char *zName,
- int nName
+ sqlite3* db, /* The database connection */
+ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */
+ const char *zName /* Collating sequence name */
){
CollSeq *p;
p = pColl;
if( !p ){
- p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
+ p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
}
if( !p || !p->xCmp ){
/* No collation sequence of this type for this encoding is registered.
** Call the collation factory to see if it can supply us with one.
*/
- callCollNeeded(db, zName, nName);
- p = sqlite3FindCollSeq(db, ENC(db), zName, nName, 0);
+ callCollNeeded(db, zName);
+ p = sqlite3FindCollSeq(db, ENC(db), zName, 0);
}
if( p && !p->xCmp && synthCollSeq(db, p) ){
p = 0;
@@ -66702,7 +67901,7 @@ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(
SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
if( pColl ){
const char *zName = pColl->zName;
- CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName, -1);
+ CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName);
if( !p ){
if( pParse->nErr==0 ){
sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName);
@@ -66731,13 +67930,12 @@ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
** each collation sequence structure.
*/
static CollSeq *findCollSeqEntry(
- sqlite3 *db,
- const char *zName,
- int nName,
- int create
+ sqlite3 *db, /* Database connection */
+ const char *zName, /* Name of the collating sequence */
+ int create /* Create a new entry if true */
){
CollSeq *pColl;
- if( nName<0 ) nName = sqlite3Strlen30(zName);
+ int nName = sqlite3Strlen30(zName);
pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
if( 0==pColl && create ){
@@ -66781,17 +67979,18 @@ static CollSeq *findCollSeqEntry(
** this routine. sqlite3LocateCollSeq() invokes the collation factory
** if necessary and generates an error message if the collating sequence
** cannot be found.
+**
+** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq()
*/
SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(
sqlite3 *db,
u8 enc,
const char *zName,
- int nName,
int create
){
CollSeq *pColl;
if( zName ){
- pColl = findCollSeqEntry(db, zName, nName, create);
+ pColl = findCollSeqEntry(db, zName, create);
}else{
pColl = db->pDfltColl;
}
@@ -66874,6 +68073,7 @@ SQLITE_PRIVATE void sqlite3FuncDefInsert(
int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
pOther = functionSearch(pHash, h, pDef->zName, nName);
if( pOther ){
+ assert( pOther!=pDef && pOther->pNext!=pDef );
pDef->pNext = pOther->pNext;
pOther->pNext = pDef;
}else{
@@ -67116,13 +68316,18 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
pDup = sqlite3SelectDup(db, pView->pSelect, 0);
if( pWhere ){
SrcList *pFrom;
- Token viewName;
pWhere = sqlite3ExprDup(db, pWhere, 0);
- viewName.z = (u8*)pView->zName;
- viewName.n = (unsigned int)sqlite3Strlen30((const char*)viewName.z);
- viewName.quoted = 0;
- pFrom = sqlite3SrcListAppendFromTerm(pParse, 0, 0, 0, &viewName, pDup, 0,0);
+ pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
+ if( pFrom ){
+ assert( pFrom->nSrc==1 );
+ pFrom->a[0].zAlias = sqlite3DbStrDup(db, pView->zName);
+ pFrom->a[0].pSelect = pDup;
+ assert( pFrom->a[0].pOn==0 );
+ assert( pFrom->a[0].pUsing==0 );
+ }else{
+ sqlite3SelectDelete(db, pDup);
+ }
pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
@@ -67182,9 +68387,9 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
** );
*/
- pSelectRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
+ pSelectRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pSelectRowid == 0 ) goto limit_where_cleanup_2;
- pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid, 0);
+ pEList = sqlite3ExprListAppend(pParse, 0, pSelectRowid);
if( pEList == 0 ) goto limit_where_cleanup_2;
/* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree
@@ -67201,7 +68406,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
if( pSelect == 0 ) return 0;
/* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */
- pWhereRowid = sqlite3Expr(pParse->db, TK_ROW, 0, 0, 0);
+ pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
if( pInClause == 0 ) goto limit_where_cleanup_1;
@@ -67892,7 +69097,7 @@ static void substrFunc(
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
int n = 0;
double r;
- char zBuf[500]; /* larger than the %f representation of the largest double */
+ char *zBuf;
assert( argc==1 || argc==2 );
if( argc==2 ){
if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
@@ -67902,9 +69107,14 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
}
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
r = sqlite3_value_double(argv[0]);
- sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
- sqlite3AtoF(zBuf, &r);
- sqlite3_result_double(context, r);
+ zBuf = sqlite3_mprintf("%.*f",n,r);
+ if( zBuf==0 ){
+ sqlite3_result_error_nomem(context);
+ }else{
+ sqlite3AtoF(zBuf, &r);
+ sqlite3_free(zBuf);
+ sqlite3_result_double(context, r);
+ }
}
#endif
@@ -69013,8 +70223,9 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
- SQLITE_UTF8, 0);
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken,
+ sqlite3Strlen30(pExpr->u.zToken),
+ 2, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
@@ -69987,7 +71198,7 @@ SQLITE_PRIVATE void sqlite3Insert(
}else{
VdbeOp *pOp;
sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
- pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1);
+ pOp = sqlite3VdbeGetOp(v, -1);
if( ALWAYS(pOp) && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
appendFlag = 1;
pOp->opcode = OP_NewRowid;
@@ -71768,6 +72979,9 @@ static int sqlite3LoadExtension(
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
void **aHandle;
+ const int nMsg = 300;
+
+ if( pzErrMsg ) *pzErrMsg = 0;
/* Ticket #1863. To avoid a creating security problems for older
** applications that relink against newer versions of SQLite, the
@@ -71789,12 +73003,14 @@ static int sqlite3LoadExtension(
handle = sqlite3OsDlOpen(pVfs, zFile);
if( handle==0 ){
if( pzErrMsg ){
- char zErr[256];
- zErr[sizeof(zErr)-1] = '\0';
- sqlite3_snprintf(sizeof(zErr)-1, zErr,
- "unable to open shared library [%s]", zFile);
- sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
- *pzErrMsg = sqlite3DbStrDup(0, zErr);
+ zErrmsg = sqlite3StackAllocZero(db, nMsg);
+ if( zErrmsg ){
+ sqlite3_snprintf(nMsg, zErrmsg,
+ "unable to open shared library [%s]", zFile);
+ sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
+ *pzErrMsg = sqlite3DbStrDup(0, zErrmsg);
+ sqlite3StackFree(db, zErrmsg);
+ }
}
return SQLITE_ERROR;
}
@@ -71802,12 +73018,14 @@ static int sqlite3LoadExtension(
sqlite3OsDlSym(pVfs, handle, zProc);
if( xInit==0 ){
if( pzErrMsg ){
- char zErr[256];
- zErr[sizeof(zErr)-1] = '\0';
- sqlite3_snprintf(sizeof(zErr)-1, zErr,
- "no entry point [%s] in shared library [%s]", zProc,zFile);
- sqlite3OsDlError(pVfs, sizeof(zErr)-1, zErr);
- *pzErrMsg = sqlite3DbStrDup(0, zErr);
+ zErrmsg = sqlite3StackAllocZero(db, nMsg);
+ if( zErrmsg ){
+ sqlite3_snprintf(nMsg, zErrmsg,
+ "no entry point [%s] in shared library [%s]", zProc,zFile);
+ sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
+ *pzErrMsg = sqlite3DbStrDup(0, zErrmsg);
+ sqlite3StackFree(db, zErrmsg);
+ }
sqlite3OsDlClose(pVfs, handle);
}
return SQLITE_ERROR;
@@ -71843,6 +73061,7 @@ SQLITE_API int sqlite3_load_extension(
int rc;
sqlite3_mutex_enter(db->mutex);
rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg);
+ rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
@@ -71979,20 +73198,21 @@ SQLITE_API void sqlite3_reset_auto_extension(void){
/*
** Load all automatic extensions.
+**
+** If anything goes wrong, set an error in the database connection.
*/
-SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3 *db){
+SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
int i;
int go = 1;
- int rc = SQLITE_OK;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
wsdAutoextInit;
if( wsdAutoext.nExt==0 ){
/* Common case: early out without every having to acquire a mutex */
- return SQLITE_OK;
+ return;
}
for(i=0; go; i++){
- char *zErrmsg = 0;
+ char *zErrmsg;
#if SQLITE_THREADSAFE
sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
#endif
@@ -72005,15 +73225,14 @@ SQLITE_PRIVATE int sqlite3AutoLoadExtensions(sqlite3 *db){
wsdAutoext.aExt[i];
}
sqlite3_mutex_leave(mutex);
+ zErrmsg = 0;
if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){
sqlite3Error(db, SQLITE_ERROR,
"automatic extension loading failed: %s", zErrmsg);
go = 0;
- rc = SQLITE_ERROR;
- sqlite3_free(zErrmsg);
}
+ sqlite3_free(zErrmsg);
}
- return rc;
}
/************** End of loadext.c *********************************************/
@@ -72337,7 +73556,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
*/
if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){
static const VdbeOpList getCacheSize[] = {
- { OP_ReadCookie, 0, 1, 2}, /* 0 */
+ { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 0 */
{ OP_IfPos, 1, 6, 0},
{ OP_Integer, 0, 2, 0},
{ OP_Subtract, 1, 2, 1},
@@ -72360,11 +73579,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( size<0 ) size = -size;
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
- sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, 2);
+ sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, 2, BTREE_DEFAULT_CACHE_SIZE);
addr = sqlite3VdbeAddOp2(v, OP_IfPos, 2, 0);
sqlite3VdbeAddOp2(v, OP_Integer, -size, 1);
sqlite3VdbeJumpHere(v, addr);
- sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, 2, 1);
+ sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
pDb->pSchema->cache_size = size;
sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
}
@@ -72601,12 +73820,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
** that this really is an auto-vacuum capable database.
*/
static const VdbeOpList setMeta6[] = {
- { OP_Transaction, 0, 1, 0}, /* 0 */
- { OP_ReadCookie, 0, 1, 3}, /* 1 */
- { OP_If, 1, 0, 0}, /* 2 */
- { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
- { OP_Integer, 0, 1, 0}, /* 4 */
- { OP_SetCookie, 0, 6, 1}, /* 5 */
+ { OP_Transaction, 0, 1, 0}, /* 0 */
+ { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
+ { OP_If, 1, 0, 0}, /* 2 */
+ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */
+ { OP_Integer, 0, 1, 0}, /* 4 */
+ { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
};
int iAddr;
iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
@@ -72859,10 +74078,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
pCol->zType ? pCol->zType : "", 0);
sqlite3VdbeAddOp2(v, OP_Integer, (pCol->notNull ? 1 : 0), 4);
- if( pCol->pDflt ){
- const Token *p = &pCol->pDflt->span;
- assert( p->z );
- sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)p->z, p->n);
+ if( pCol->zDflt ){
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, (char*)pCol->zDflt, 0);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, 5);
}
@@ -73294,23 +74511,21 @@ SQLITE_PRIVATE void sqlite3Pragma(
|| sqlite3StrICmp(zLeft, "user_version")==0
|| sqlite3StrICmp(zLeft, "freelist_count")==0
){
- int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */
+ int iCookie; /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
sqlite3VdbeUsesBtree(v, iDb);
switch( zLeft[0] ){
- case 's': case 'S':
- iCookie = 0;
- break;
case 'f': case 'F':
- iCookie = 1;
- iDb = (-1*(iDb+1));
- assert(iDb<=0);
+ iCookie = BTREE_FREE_PAGE_COUNT;
+ break;
+ case 's': case 'S':
+ iCookie = BTREE_SCHEMA_VERSION;
break;
default:
- iCookie = 5;
+ iCookie = BTREE_USER_VERSION;
break;
}
- if( zRight && iDb>=0 ){
+ if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
/* Write the specified cookie value */
static const VdbeOpList setCookie[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
@@ -73584,7 +74799,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
Table *pTab;
Db *pDb;
char const *azArg[4];
- int meta[10];
+ int meta[5];
InitData initData;
char const *zMasterSchema;
char const *zMasterName = SCHEMA_TABLE(iDb);
@@ -73669,10 +74884,6 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
sqlite3BtreeEnter(pDb->pBt);
rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
if( rc==SQLITE_EMPTY ) rc = SQLITE_OK;
- if( rc!=SQLITE_OK ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto initone_error_out;
- }
/* Get the database meta information.
**
@@ -73682,37 +74893,35 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
** meta[2] Size of the page cache.
** meta[3] Use freelist if 0. Autovacuum if greater than zero.
** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE
- ** meta[5] The user cookie. Used by the application.
- ** meta[6] Incremental-vacuum flag.
- ** meta[7]
- ** meta[8]
- ** meta[9]
**
** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to
** the possible values of meta[4].
*/
- for(i=0; i<ArraySize(meta); i++){
+ for(i=0; rc==SQLITE_OK && i<ArraySize(meta); i++){
rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
- if( rc ){
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
- goto initone_error_out;
- }
}
- pDb->pSchema->schema_cookie = meta[0];
+ if( rc ){
+ sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
+ goto initone_error_out;
+ }
+ pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1];
/* If opening a non-empty database, check the text encoding. For the
** main database, set sqlite3.enc to the encoding of the main database.
** For an attached db, it is an error if the encoding is not the same
** as sqlite3.enc.
*/
- if( meta[4] ){ /* text encoding */
+ if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
if( iDb==0 ){
+ u8 encoding;
/* If opening the main database, set ENC(db). */
- ENC(db) = (u8)meta[4];
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
+ encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
+ if( encoding==0 ) encoding = SQLITE_UTF8;
+ ENC(db) = encoding;
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
}else{
/* If opening an attached database, the encoding much match ENC(db) */
- if( meta[4]!=ENC(db) ){
+ if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
" text encoding as main database");
rc = SQLITE_ERROR;
@@ -73725,7 +74934,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
pDb->pSchema->enc = ENC(db);
if( pDb->pSchema->cache_size==0 ){
- size = meta[2];
+ size = meta[BTREE_DEFAULT_CACHE_SIZE-1];
if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
if( size<0 ) size = -size;
pDb->pSchema->cache_size = size;
@@ -73738,7 +74947,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
** file_format==3 Version 3.1.4. // ditto but with non-NULL defaults
** file_format==4 Version 3.3.0. // DESC indices. Boolean constants
*/
- pDb->pSchema->file_format = (u8)meta[1];
+ pDb->pSchema->file_format = (u8)meta[BTREE_FILE_FORMAT-1];
if( pDb->pSchema->file_format==0 ){
pDb->pSchema->file_format = 1;
}
@@ -73753,7 +74962,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
** not downgrade the database and thus invalidate any descending
** indices that the user might have created.
*/
- if( iDb==0 && meta[1]>=4 ){
+ if( iDb==0 && meta[BTREE_FILE_FORMAT-1]>=4 ){
db->flags &= ~SQLITE_LegacyFileFmt;
}
@@ -73909,7 +75118,7 @@ static int schemaIsValid(sqlite3 *db){
memset(curTemp, 0, sqlite3BtreeCursorSize());
rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, curTemp);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
+ rc = sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){
allOk = 0;
}
@@ -73971,12 +75180,22 @@ static int sqlite3Prepare(
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
){
- Parse sParse;
- char *zErrMsg = 0;
- int rc = SQLITE_OK;
- int i;
+ Parse *pParse; /* Parsing context */
+ char *zErrMsg = 0; /* Error message */
+ int rc = SQLITE_OK; /* Result code */
+ int i; /* Loop counter */
- if( sqlite3SafetyOn(db) ) return SQLITE_MISUSE;
+ /* Allocate the parsing context */
+ pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM;
+ goto end_prepare;
+ }
+
+ if( sqlite3SafetyOn(db) ){
+ rc = SQLITE_MISUSE;
+ goto end_prepare;
+ }
assert( ppStmt && *ppStmt==0 );
assert( !db->mallocFailed );
assert( sqlite3_mutex_held(db->mutex) );
@@ -74014,68 +75233,71 @@ static int sqlite3Prepare(
sqlite3Error(db, rc, "database schema is locked: %s", zDb);
(void)sqlite3SafetyOff(db);
testcase( db->flags & SQLITE_ReadUncommitted );
- return sqlite3ApiExit(db, rc);
+ goto end_prepare;
}
}
}
-
- memset(&sParse, 0, sizeof(sParse));
- sParse.db = db;
+
+
+ pParse->db = db;
if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
char *zSqlCopy;
int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
if( nBytes>mxLen ){
sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
(void)sqlite3SafetyOff(db);
- return sqlite3ApiExit(db, SQLITE_TOOBIG);
+ rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
+ goto end_prepare;
}
zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
if( zSqlCopy ){
- sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);
+ sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
sqlite3DbFree(db, zSqlCopy);
- sParse.zTail = &zSql[sParse.zTail-zSqlCopy];
+ pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
}else{
- sParse.zTail = &zSql[nBytes];
+ pParse->zTail = &zSql[nBytes];
}
}else{
- sqlite3RunParser(&sParse, zSql, &zErrMsg);
+ sqlite3RunParser(pParse, zSql, &zErrMsg);
}
if( db->mallocFailed ){
- sParse.rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM;
}
- if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
- if( sParse.checkSchema && !schemaIsValid(db) ){
- sParse.rc = SQLITE_SCHEMA;
+ if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
+ if( pParse->checkSchema && !schemaIsValid(db) ){
+ pParse->rc = SQLITE_SCHEMA;
}
- if( sParse.rc==SQLITE_SCHEMA ){
+ if( pParse->rc==SQLITE_SCHEMA ){
sqlite3ResetInternalSchema(db, 0);
}
if( db->mallocFailed ){
- sParse.rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM;
}
if( pzTail ){
- *pzTail = sParse.zTail;
+ *pzTail = pParse->zTail;
}
- rc = sParse.rc;
+ rc = pParse->rc;
#ifndef SQLITE_OMIT_EXPLAIN
- if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){
- if( sParse.explain==2 ){
- sqlite3VdbeSetNumCols(sParse.pVdbe, 3);
- sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", SQLITE_STATIC);
+ if( rc==SQLITE_OK && pParse->pVdbe && pParse->explain ){
+ static const char * const azColName[] = {
+ "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment",
+ "order", "from", "detail"
+ };
+ int iFirst, mx;
+ if( pParse->explain==2 ){
+ sqlite3VdbeSetNumCols(pParse->pVdbe, 3);
+ iFirst = 8;
+ mx = 11;
}else{
- sqlite3VdbeSetNumCols(sParse.pVdbe, 8);
- sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 5, COLNAME_NAME, "p4", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 6, COLNAME_NAME, "p5", SQLITE_STATIC);
- sqlite3VdbeSetColName(sParse.pVdbe, 7, COLNAME_NAME, "comment", SQLITE_STATIC);
+ sqlite3VdbeSetNumCols(pParse->pVdbe, 8);
+ iFirst = 0;
+ mx = 8;
+ }
+ for(i=iFirst; i<mx; i++){
+ sqlite3VdbeSetColName(pParse->pVdbe, i-iFirst, COLNAME_NAME,
+ azColName[i], SQLITE_STATIC);
}
}
#endif
@@ -74086,14 +75308,14 @@ static int sqlite3Prepare(
assert( db->init.busy==0 || saveSqlFlag==0 );
if( db->init.busy==0 ){
- Vdbe *pVdbe = sParse.pVdbe;
- sqlite3VdbeSetSql(pVdbe, zSql, (int)(sParse.zTail-zSql), saveSqlFlag);
+ Vdbe *pVdbe = pParse->pVdbe;
+ sqlite3VdbeSetSql(pVdbe, zSql, (int)(pParse->zTail-zSql), saveSqlFlag);
}
- if( sParse.pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
- sqlite3VdbeFinalize(sParse.pVdbe);
+ if( pParse->pVdbe && (rc!=SQLITE_OK || db->mallocFailed) ){
+ sqlite3VdbeFinalize(pParse->pVdbe);
assert(!(*ppStmt));
}else{
- *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
+ *ppStmt = (sqlite3_stmt*)pParse->pVdbe;
}
if( zErrMsg ){
@@ -74103,6 +75325,9 @@ static int sqlite3Prepare(
sqlite3Error(db, rc, 0);
}
+end_prepare:
+
+ sqlite3StackFree(db, pParse);
rc = sqlite3ApiExit(db, rc);
assert( (rc&db->errMask)==rc );
return rc;
@@ -74355,7 +75580,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
memset(pNew, 0, sizeof(*pNew));
}
if( pEList==0 ){
- pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0,0,0), 0);
+ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
}
pNew->pEList = pEList;
pNew->pSrc = pSrc;
@@ -74367,6 +75592,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
pNew->op = TK_SELECT;
pNew->pLimit = pLimit;
pNew->pOffset = pOffset;
+ assert( pOffset==0 || pLimit!=0 );
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->addrOpenEphm[2] = -1;
@@ -74409,18 +75635,20 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p
int jointype = 0;
Token *apAll[3];
Token *p;
+ /* 0123456789 123456789 123456789 123 */
+ static const char zKeyText[] = "naturaleftouterightfullinnercross";
static const struct {
- const char zKeyword[8];
- u8 nChar;
- u8 code;
- } keywords[] = {
- { "natural", 7, JT_NATURAL },
- { "left", 4, JT_LEFT|JT_OUTER },
- { "right", 5, JT_RIGHT|JT_OUTER },
- { "full", 4, JT_LEFT|JT_RIGHT|JT_OUTER },
- { "outer", 5, JT_OUTER },
- { "inner", 5, JT_INNER },
- { "cross", 5, JT_INNER|JT_CROSS },
+ u8 i; /* Beginning of keyword text in zKeyText[] */
+ u8 nChar; /* Length of the keyword in characters */
+ u8 code; /* Join type mask */
+ } aKeyword[] = {
+ /* natural */ { 0, 7, JT_NATURAL },
+ /* left */ { 6, 4, JT_LEFT|JT_OUTER },
+ /* outer */ { 10, 5, JT_OUTER },
+ /* right */ { 14, 5, JT_RIGHT|JT_OUTER },
+ /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
+ /* inner */ { 23, 5, JT_INNER },
+ /* cross */ { 28, 5, JT_INNER|JT_CROSS },
};
int i, j;
apAll[0] = pA;
@@ -74428,14 +75656,15 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p
apAll[2] = pC;
for(i=0; i<3 && apAll[i]; i++){
p = apAll[i];
- for(j=0; j<ArraySize(keywords); j++){
- if( p->n==keywords[j].nChar
- && sqlite3StrNICmp((char*)p->z, keywords[j].zKeyword, p->n)==0 ){
- jointype |= keywords[j].code;
+ for(j=0; j<ArraySize(aKeyword); j++){
+ if( p->n==aKeyword[j].nChar
+ && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){
+ jointype |= aKeyword[j].code;
break;
}
}
- if( j>=ArraySize(keywords) ){
+ testcase( j==0 || j==1 || j==2 || j==3 || j==4 || j==5 || j==6 );
+ if( j>=ArraySize(aKeyword) ){
jointype |= JT_ERROR;
break;
}
@@ -74450,7 +75679,8 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p
sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
"%T %T%s%T", pA, pB, zSp, pC);
jointype = JT_INNER;
- }else if( jointype & JT_RIGHT ){
+ }else if( (jointype & JT_OUTER)!=0
+ && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
sqlite3ErrorMsg(pParse,
"RIGHT and FULL OUTER JOINs are not currently supported");
jointype = JT_INNER;
@@ -74471,22 +75701,10 @@ static int columnIndex(Table *pTab, const char *zCol){
}
/*
-** Set the value of a token to a '\000'-terminated string.
-*/
-static void setToken(Token *p, const char *z){
- p->z = (u8*)z;
- p->n = z ? sqlite3Strlen30(z) : 0;
- p->dyn = 0;
- p->quoted = 0;
-}
-
-/*
** Create an expression node for an identifier with the name of zName
*/
SQLITE_PRIVATE Expr *sqlite3CreateIdExpr(Parse *pParse, const char *zName){
- Token dummy;
- setToken(&dummy, zName);
- return sqlite3PExpr(pParse, TK_ID, 0, 0, &dummy);
+ return sqlite3Expr(pParse->db, TK_ID, zName);
}
/*
@@ -74523,7 +75741,9 @@ static void addWhereTerm(
pE = sqlite3PExpr(pParse, TK_EQ, pE1c, pE2c, 0);
if( pE && isOuterJoin ){
ExprSetProperty(pE, EP_FromJoin);
- pE->iRightJoinTable = iRightJoinTable;
+ assert( !ExprHasAnyProperty(pE, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(pE);
+ pE->iRightJoinTable = (i16)iRightJoinTable;
}
*ppExpr = sqlite3ExprAnd(pParse->db,*ppExpr, pE);
}
@@ -74557,7 +75777,9 @@ static void addWhereTerm(
static void setJoinExpr(Expr *p, int iTable){
while( p ){
ExprSetProperty(p, EP_FromJoin);
- p->iRightJoinTable = iTable;
+ assert( !ExprHasAnyProperty(p, EP_TokenOnly|EP_Reduced) );
+ ExprSetIrreducible(p);
+ p->iRightJoinTable = (i16)iTable;
setJoinExpr(p->pLeft, iTable);
p = p->pRight;
}
@@ -74874,6 +76096,8 @@ static void selectInnerLoop(
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite3GetTempReg(pParse);
+ testcase( eDest==SRT_Table );
+ testcase( eDest==SRT_EphemTab );
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
if( pOrderBy ){
pushOntoSorter(pParse, pOrderBy, p, r1);
@@ -74942,6 +76166,8 @@ static void selectInnerLoop(
*/
case SRT_Coroutine:
case SRT_Output: {
+ testcase( eDest==SRT_Coroutine );
+ testcase( eDest==SRT_Output );
if( pOrderBy ){
int r1 = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
@@ -75083,9 +76309,9 @@ static void generateSortTail(
break;
}
#endif
- case SRT_Output:
- case SRT_Coroutine: {
+ default: {
int i;
+ assert( eDest==SRT_Output || eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
testcase( eDest==SRT_Coroutine );
sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid);
@@ -75102,10 +76328,6 @@ static void generateSortTail(
}
break;
}
- default: {
- /* Do nothing */
- break;
- }
}
sqlite3ReleaseTempReg(pParse, regRow);
sqlite3ReleaseTempReg(pParse, regRowid);
@@ -75154,7 +76376,7 @@ static const char *columnType(
char const *zOriginTab = 0;
char const *zOriginCol = 0;
int j;
- if( pExpr==0 || pNC->pSrcList==0 ) return 0;
+ if( NEVER(pExpr==0) || pNC->pSrcList==0 ) return 0;
switch( pExpr->op ){
case TK_AGG_COLUMN:
@@ -75166,6 +76388,8 @@ static const char *columnType(
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++);
@@ -75319,7 +76543,6 @@ static void generateColumnNames(
}
#endif
- assert( v!=0 );
if( pParse->colNamesSet || NEVER(v==0) || db->mallocFailed ) return;
pParse->colNamesSet = 1;
fullNames = (db->flags & SQLITE_FullColNames)!=0;
@@ -75328,7 +76551,7 @@ static void generateColumnNames(
for(i=0; i<pEList->nExpr; i++){
Expr *p;
p = pEList->a[i].pExpr;
- if( p==0 ) continue;
+ if( NEVER(p==0) ) continue;
if( pEList->a[i].zName ){
char *zName = pEList->a[i].zName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
@@ -75350,7 +76573,7 @@ static void generateColumnNames(
}
if( !shortNames && !fullNames ){
sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrNDup(db, (char*)p->span.z, p->span.n), SQLITE_DYNAMIC);
+ sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
}else if( fullNames ){
char *zName = 0;
zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol);
@@ -75360,7 +76583,7 @@ static void generateColumnNames(
}
}else{
sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrNDup(db, (char*)p->span.z, p->span.n), SQLITE_DYNAMIC);
+ sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
}
}
generateColumnTypes(pParse, pTabList, pEList);
@@ -75417,7 +76640,8 @@ static int selectColumnsFromExprList(
/* Get an appropriate name for the column
*/
p = pEList->a[i].pExpr;
- assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 );
+ assert( p->pRight==0 || ExprHasProperty(p->pRight, EP_IntValue)
+ || p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
/* If the column contains an "AS <name>" phrase, use <name> as the name */
zName = sqlite3DbStrDup(db, zName);
@@ -75425,16 +76649,19 @@ static int selectColumnsFromExprList(
Expr *pColExpr = p; /* The expression that is the result column name */
Table *pTab; /* Table associated with this expression */
while( pColExpr->op==TK_DOT ) pColExpr = pColExpr->pRight;
- if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->pTab)!=0 ){
+ if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
+ pTab = pColExpr->pTab;
if( iCol<0 ) iCol = pTab->iPKey;
zName = sqlite3MPrintf(db, "%s",
iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
+ }else if( pColExpr->op==TK_ID ){
+ assert( !ExprHasProperty(pColExpr, EP_IntValue) );
+ zName = sqlite3MPrintf(db, "%s", pColExpr->u.zToken);
}else{
/* Use the original text of the column expression as its name */
- Token *pToken = (pColExpr->span.z?&pColExpr->span:&pColExpr->token);
- zName = sqlite3MPrintf(db, "%T", pToken);
+ zName = sqlite3MPrintf(db, "%s", pEList->a[i].zSpan);
}
}
if( db->mallocFailed ){
@@ -75507,6 +76734,7 @@ static void selectAddColumnTypeAndCollation(
p = a[i].pExpr;
pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p, 0, 0, 0));
pCol->affinity = sqlite3ExprAffinity(p);
+ if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
pColl = sqlite3ExprCollSeq(pParse, p);
if( pColl ){
pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
@@ -75534,7 +76762,10 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
if( pTab==0 ){
return 0;
}
- pTab->dbMem = db->lookaside.bEnabled ? db : 0;
+ /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside
+ ** is disabled, so we might as well hard-code pTab->dbMem to NULL. */
+ assert( db->lookaside.bEnabled==0 );
+ pTab->dbMem = 0;
pTab->nRef = 1;
pTab->zName = 0;
selectColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
@@ -75597,29 +76828,24 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
** no rows.
*/
sqlite3ExprCacheClear(pParse);
+ assert( p->pOffset==0 || p->pLimit!=0 );
if( p->pLimit ){
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
+ if( NEVER(v==0) ) return; /* VDBE should have already been allocated */
sqlite3ExprCode(pParse, p->pLimit, iLimit);
sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
VdbeComment((v, "LIMIT counter"));
sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
- }
- if( p->pOffset ){
- p->iOffset = iOffset = ++pParse->nMem;
- if( p->pLimit ){
+ if( p->pOffset ){
+ p->iOffset = iOffset = ++pParse->nMem;
pParse->nMem++; /* Allocate an extra register for limit+offset */
- }
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) return;
- sqlite3ExprCode(pParse, p->pOffset, iOffset);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
- VdbeComment((v, "OFFSET counter"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
- sqlite3VdbeJumpHere(v, addr1);
- if( p->pLimit ){
+ sqlite3ExprCode(pParse, p->pOffset, iOffset);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
+ VdbeComment((v, "OFFSET counter"));
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
+ sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
VdbeComment((v, "LIMIT+OFFSET"));
addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
@@ -75777,11 +77003,9 @@ static int multiSelect(
VdbeComment((v, "Jump ahead if LIMIT reached"));
}
rc = sqlite3Select(pParse, p, &dest);
+ testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
- if( rc ){
- goto multi_select_end;
- }
if( addr ){
sqlite3VdbeJumpHere(v, addr);
}
@@ -75796,6 +77020,8 @@ static int multiSelect(
int addr;
SelectDest uniondest;
+ testcase( p->op==TK_EXCEPT );
+ testcase( p->op==TK_UNION );
priorOp = SRT_Union;
if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){
/* We can reuse a temporary table generated by a SELECT to our
@@ -75843,6 +77069,7 @@ static int multiSelect(
p->pOffset = 0;
uniondest.eDest = op;
rc = sqlite3Select(pParse, p, &uniondest);
+ testcase( rc!=SQLITE_OK );
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
sqlite3ExprListDelete(db, p->pOrderBy);
@@ -75854,15 +77081,12 @@ static int multiSelect(
p->pOffset = pOffset;
p->iLimit = 0;
p->iOffset = 0;
- if( rc ){
- goto multi_select_end;
- }
-
/* Convert the data in the temporary table into whatever form
** it is that we currently need.
- */
- if( dest.eDest!=priorOp || unionTab!=dest.iParm ){
+ */
+ assert( unionTab==dest.iParm || dest.eDest!=priorOp );
+ if( dest.eDest!=priorOp ){
int iCont, iBreak, iStart;
assert( p->pEList );
if( dest.eDest==SRT_Output ){
@@ -75884,7 +77108,7 @@ static int multiSelect(
}
break;
}
- case TK_INTERSECT: {
+ default: assert( p->op==TK_INTERSECT ); {
int tab1, tab2;
int iCont, iBreak, iStart;
Expr *pLimit, *pOffset;
@@ -75926,14 +77150,12 @@ static int multiSelect(
p->pOffset = 0;
intersectdest.iParm = tab2;
rc = sqlite3Select(pParse, p, &intersectdest);
+ testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
- if( rc ){
- goto multi_select_end;
- }
/* Generate code to take the intersection of the two temporary
** tables.
@@ -76086,6 +77308,8 @@ static int generateOutputSubroutine(
case SRT_EphemTab: {
int r1 = sqlite3GetTempReg(pParse);
int r2 = sqlite3GetTempReg(pParse);
+ testcase( pDest->eDest==SRT_Table );
+ testcase( pDest->eDest==SRT_EphemTab );
sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
@@ -76148,26 +77372,20 @@ static int generateOutputSubroutine(
break;
}
- /* Results are stored in a sequence of registers. Then the
- ** OP_ResultRow opcode is used to cause sqlite3_step() to return
- ** the next row of result.
+ /* If none of the above, then the result destination must be
+ ** SRT_Output. This routine is never called with any other
+ ** destination other than the ones handled above or SRT_Output.
+ **
+ ** For SRT_Output, results are stored in a sequence of registers.
+ ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to
+ ** return the next row of result.
*/
- case SRT_Output: {
+ default: {
+ assert( pDest->eDest==SRT_Output );
sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
break;
}
-
-#if !defined(SQLITE_OMIT_TRIGGER)
- /* Discard the results. This is used for SELECT statements inside
- ** the body of a TRIGGER. The purpose of such selects is to call
- ** user-defined functions that have side effects. We do not care
- ** about the actual results of the select.
- */
- default: {
- break;
- }
-#endif
}
/* Jump to the end of the loop if the LIMIT is reached.
@@ -76316,7 +77534,7 @@ static int multiSelectOrderBy(
assert( pKeyDup==0 ); /* "Managed" code needs this. Ticket #3382. */
db = pParse->db;
v = pParse->pVdbe;
- if( v==0 ) return SQLITE_NOMEM;
+ assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */
labelEnd = sqlite3VdbeMakeLabel(v);
labelCmpr = sqlite3VdbeMakeLabel(v);
@@ -76342,11 +77560,11 @@ static int multiSelectOrderBy(
if( pItem->iCol==i ) break;
}
if( j==nOrderBy ){
- Expr *pNew = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, 0);
+ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
if( pNew==0 ) return SQLITE_NOMEM;
pNew->flags |= EP_IntValue;
- pNew->iTable = i;
- pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew, 0);
+ pNew->u.iValue = i;
+ pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
pOrderBy->a[nOrderBy++].iCol = (u16)i;
}
}
@@ -76631,13 +77849,13 @@ static void substSelect(sqlite3*, Select *, int, ExprList *);
** changes to pExpr so that it refers directly to the source table
** of the subquery rather the result set of the subquery.
*/
-static void substExpr(
+static Expr *substExpr(
sqlite3 *db, /* Report malloc errors to this connection */
Expr *pExpr, /* Expr in which substitution occurs */
int iTable, /* Table to be substituted */
ExprList *pEList /* Substitute expressions */
){
- if( pExpr==0 ) return;
+ if( pExpr==0 ) return 0;
if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
if( pExpr->iColumn<0 ){
pExpr->op = TK_NULL;
@@ -76645,38 +77863,20 @@ static void substExpr(
Expr *pNew;
assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
- pNew = pEList->a[pExpr->iColumn].pExpr;
- assert( pNew!=0 );
- pExpr->op = pNew->op;
- assert( pExpr->pLeft==0 );
- pExpr->pLeft = sqlite3ExprDup(db, pNew->pLeft, 0);
- assert( pExpr->pRight==0 );
- pExpr->pRight = sqlite3ExprDup(db, pNew->pRight, 0);
- pExpr->iTable = pNew->iTable;
- pExpr->pTab = pNew->pTab;
- pExpr->iColumn = pNew->iColumn;
- pExpr->iAgg = pNew->iAgg;
- sqlite3TokenCopy(db, &pExpr->token, &pNew->token);
- sqlite3TokenCopy(db, &pExpr->span, &pNew->span);
- assert( pExpr->x.pList==0 && pExpr->x.pSelect==0 );
- if( ExprHasProperty(pNew, EP_xIsSelect) ){
- pExpr->x.pSelect = sqlite3SelectDup(db, pNew->x.pSelect, 0);
- }else{
- pExpr->x.pList = sqlite3ExprListDup(db, pNew->x.pList, 0);
- }
- pExpr->flags = pNew->flags;
- pExpr->pAggInfo = pNew->pAggInfo;
- pNew->pAggInfo = 0;
+ pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0);
+ sqlite3ExprDelete(db, pExpr);
+ pExpr = pNew;
}
}else{
- substExpr(db, pExpr->pLeft, iTable, pEList);
- substExpr(db, pExpr->pRight, iTable, pEList);
+ pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
+ pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
substSelect(db, pExpr->x.pSelect, iTable, pEList);
}else{
substExprList(db, pExpr->x.pList, iTable, pEList);
}
}
+ return pExpr;
}
static void substExprList(
sqlite3 *db, /* Report malloc errors here */
@@ -76687,7 +77887,7 @@ static void substExprList(
int i;
if( pList==0 ) return;
for(i=0; i<pList->nExpr; i++){
- substExpr(db, pList->a[i].pExpr, iTable, pEList);
+ pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
}
}
static void substSelect(
@@ -76703,8 +77903,8 @@ static void substSelect(
substExprList(db, p->pEList, iTable, pEList);
substExprList(db, p->pGroupBy, iTable, pEList);
substExprList(db, p->pOrderBy, iTable, pEList);
- substExpr(db, p->pHaving, iTable, pEList);
- substExpr(db, p->pWhere, iTable, pEList);
+ p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
+ p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
substSelect(db, p->pPrior, iTable, pEList);
pSrc = p->pSrc;
assert( pSrc ); /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
@@ -76930,9 +78130,11 @@ static int flattenSubquery(
return 0;
}
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 );
if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
|| (pSub1->pPrior && pSub1->op!=TK_ALL)
- || !pSub1->pSrc || pSub1->pSrc->nSrc!=1
+ || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc!=1
){
return 0;
}
@@ -77032,8 +78234,10 @@ static int flattenSubquery(
** subquery until code generation is
** complete, since there may still exist Expr.pTab entries that
** refer to the subquery even after flattening. Ticket #3346.
+ **
+ ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
*/
- if( pSubitem->pTab!=0 ){
+ if( ALWAYS(pSubitem->pTab!=0) ){
Table *pTabToDel = pSubitem->pTab;
if( pTabToDel->nRef==1 ){
pTabToDel->pNextZombie = pParse->pZombieTab;
@@ -77102,6 +78306,7 @@ static int flattenSubquery(
** outer query.
*/
for(i=0; i<nSubSrc; i++){
+ sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
pSrc->a[i+iFrom] = pSubSrc->a[i];
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
@@ -77121,16 +78326,17 @@ static int flattenSubquery(
*/
pList = pParent->pEList;
for(i=0; i<pList->nExpr; i++){
- Expr *pExpr;
- if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
- pList->a[i].zName =
- sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n);
+ if( pList->a[i].zName==0 ){
+ const char *zSpan = pList->a[i].zSpan;
+ if( ALWAYS(zSpan) ){
+ pList->a[i].zName = sqlite3DbStrDup(db, zSpan);
+ }
}
}
substExprList(db, pParent->pEList, iParent, pSub->pEList);
if( isAgg ){
substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
- substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+ pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
}
if( pSub->pOrderBy ){
assert( pParent->pOrderBy==0 );
@@ -77148,13 +78354,13 @@ static int flattenSubquery(
assert( pParent->pHaving==0 );
pParent->pHaving = pParent->pWhere;
pParent->pWhere = pWhere;
- substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+ pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving,
sqlite3ExprDup(db, pSub->pHaving, 0));
assert( pParent->pGroupBy==0 );
pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
}else{
- substExpr(db, pParent->pWhere, iParent, pSub->pEList);
+ pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
}
@@ -77201,14 +78407,15 @@ static u8 minMaxQuery(Select *p){
if( pEList->nExpr!=1 ) return WHERE_ORDERBY_NORMAL;
pExpr = pEList->a[0].pExpr;
- if( ExprHasProperty(pExpr, EP_xIsSelect) ) return 0;
+ if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
+ if( NEVER(ExprHasProperty(pExpr, EP_xIsSelect)) ) return 0;
pEList = pExpr->x.pList;
- if( pExpr->op!=TK_AGG_FUNCTION || pEList==0 || pEList->nExpr!=1 ) return 0;
+ if( pEList==0 || pEList->nExpr!=1 ) return 0;
if( pEList->a[0].pExpr->op!=TK_AGG_COLUMN ) return WHERE_ORDERBY_NORMAL;
- if( pExpr->token.n!=3 ) return WHERE_ORDERBY_NORMAL;
- if( sqlite3StrNICmp((char*)pExpr->token.z,"min",3)==0 ){
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
+ if( sqlite3StrICmp(pExpr->u.zToken,"min")==0 ){
return WHERE_ORDERBY_MIN;
- }else if( sqlite3StrNICmp((char*)pExpr->token.z,"max",3)==0 ){
+ }else if( sqlite3StrICmp(pExpr->u.zToken,"max")==0 ){
return WHERE_ORDERBY_MAX;
}
return WHERE_ORDERBY_NORMAL;
@@ -77308,7 +78515,7 @@ static int selectExpander(Walker *pWalker, Select *p){
if( db->mallocFailed ){
return WRC_Abort;
}
- if( p->pSrc==0 || (p->selFlags & SF_Expanded)!=0 ){
+ if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
return WRC_Prune;
}
p->selFlags |= SF_Expanded;
@@ -77360,16 +78567,9 @@ static int selectExpander(Walker *pWalker, Select *p){
if( pTab->pSelect || IsVirtual(pTab) ){
/* We reach here if the named table is a really a view */
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
-
- /* If pFrom->pSelect!=0 it means we are dealing with a
- ** view within a view. The SELECT structure has already been
- ** copied by the outer view so we can skip the copy step here
- ** in the inner view.
- */
- if( pFrom->pSelect==0 ){
- pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
- sqlite3WalkSelect(pWalker, pFrom->pSelect);
- }
+ assert( pFrom->pSelect==0 );
+ pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+ sqlite3WalkSelect(pWalker, pFrom->pSelect);
}
#endif
}
@@ -77399,8 +78599,9 @@ static int selectExpander(Walker *pWalker, Select *p){
for(k=0; k<pEList->nExpr; k++){
Expr *pE = pEList->a[k].pExpr;
if( pE->op==TK_ALL ) break;
- if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
- && pE->pLeft && pE->pLeft->op==TK_ID ) break;
+ 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_ALL ) break;
}
if( k<pEList->nExpr ){
/*
@@ -77416,30 +78617,34 @@ static int selectExpander(Walker *pWalker, Select *p){
for(k=0; k<pEList->nExpr; k++){
Expr *pE = a[k].pExpr;
- if( pE->op!=TK_ALL &&
- (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
+ assert( pE->op!=TK_DOT || pE->pRight!=0 );
+ if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pE->pRight->op!=TK_ALL) ){
/* This particular expression does not need to be expanded.
*/
- pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr, 0);
+ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
if( pNew ){
pNew->a[pNew->nExpr-1].zName = a[k].zName;
+ pNew->a[pNew->nExpr-1].zSpan = a[k].zSpan;
+ a[k].zName = 0;
+ a[k].zSpan = 0;
}
a[k].pExpr = 0;
- a[k].zName = 0;
}else{
/* This expression is a "*" or a "TABLE.*" and needs to be
** expanded. */
int tableSeen = 0; /* Set to 1 when TABLE matches */
char *zTName; /* text of name of TABLE */
- if( pE->op==TK_DOT && pE->pLeft ){
- zTName = sqlite3NameFromToken(db, &pE->pLeft->token);
+ if( pE->op==TK_DOT ){
+ assert( pE->pLeft!=0 );
+ assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
+ zTName = pE->pLeft->u.zToken;
}else{
zTName = 0;
}
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab;
char *zTabName = pFrom->zAlias;
- if( zTabName==0 || zTabName[0]==0 ){
+ if( zTabName==0 ){
zTabName = pTab->zName;
}
if( db->mallocFailed ) break;
@@ -77450,6 +78655,9 @@ static int selectExpander(Walker *pWalker, Select *p){
for(j=0; j<pTab->nCol; j++){
Expr *pExpr, *pRight;
char *zName = pTab->aCol[j].zName;
+ char *zColname; /* The computed column name */
+ char *zToFree; /* Malloced string that needs to be freed */
+ Token sColname; /* Computed column name as a token */
/* If a column is marked as 'hidden' (currently only possible
** for virtual tables), do not include it in the expanded
@@ -77474,30 +78682,25 @@ static int selectExpander(Walker *pWalker, Select *p){
continue;
}
}
- pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
- if( pRight==0 ) break;
- setToken(&pRight->token, zName);
+ pRight = sqlite3Expr(db, TK_ID, zName);
+ zColname = zName;
+ zToFree = 0;
if( longNames || pTabList->nSrc>1 ){
- Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
+ Expr *pLeft;
+ pLeft = sqlite3Expr(db, TK_ID, zTabName);
pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- if( pExpr==0 ) break;
- setToken(&pLeft->token, zTabName);
- setToken(&pExpr->span,
- sqlite3MPrintf(db, "%s.%s", zTabName, zName));
- pExpr->span.dyn = 1;
- pExpr->token.z = 0;
- pExpr->token.n = 0;
- pExpr->token.dyn = 0;
+ if( longNames ){
+ zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
+ zToFree = zColname;
+ }
}else{
pExpr = pRight;
- pExpr->span = pExpr->token;
- pExpr->span.dyn = 0;
- }
- if( longNames ){
- pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pExpr->span);
- }else{
- pNew = sqlite3ExprListAppend(pParse, pNew, pExpr, &pRight->token);
}
+ pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
+ sColname.z = zColname;
+ sColname.n = sqlite3Strlen30(zColname);
+ sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
+ sqlite3DbFree(db, zToFree);
}
}
if( !tableSeen ){
@@ -77507,7 +78710,6 @@ static int selectExpander(Walker *pWalker, Select *p){
sqlite3ErrorMsg(pParse, "no tables specified");
}
}
- sqlite3DbFree(db, zTName);
}
}
sqlite3ExprListDelete(db, pEList);
@@ -77578,19 +78780,18 @@ static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
struct SrcList_item *pFrom;
assert( p->selFlags & SF_Resolved );
- if( (p->selFlags & SF_HasTypeInfo)==0 ){
- p->selFlags |= SF_HasTypeInfo;
- pParse = pWalker->pParse;
- pTabList = p->pSrc;
- for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
- Table *pTab = pFrom->pTab;
- if( pTab && (pTab->tabFlags & TF_Ephemeral)!=0 ){
- /* A sub-query in the FROM clause of a SELECT */
- Select *pSel = pFrom->pSelect;
- assert( pSel );
- while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
- }
+ assert( (p->selFlags & SF_HasTypeInfo)==0 );
+ p->selFlags |= SF_HasTypeInfo;
+ pParse = pWalker->pParse;
+ pTabList = p->pSrc;
+ for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
+ Table *pTab = pFrom->pTab;
+ if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
+ /* A sub-query in the FROM clause of a SELECT */
+ Select *pSel = pFrom->pSelect;
+ assert( pSel );
+ while( pSel->pPrior ) pSel = pSel->pPrior;
+ selectAddColumnTypeAndCollation(pParse, pTab->nCol, pTab->aCol, pSel);
}
}
return WRC_Continue;
@@ -77634,10 +78835,9 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
NameContext *pOuterNC /* Name context for container */
){
sqlite3 *db;
- if( p==0 ) return;
+ if( NEVER(p==0) ) return;
db = pParse->db;
if( p->selFlags & SF_HasTypeInfo ) return;
- if( pParse->nErr || db->mallocFailed ) return;
sqlite3SelectExpand(pParse, p);
if( pParse->nErr || db->mallocFailed ) return;
sqlite3ResolveSelectNames(pParse, p, pOuterNC);
@@ -77841,38 +79041,24 @@ SQLITE_PRIVATE int sqlite3Select(
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
memset(&sAggInfo, 0, sizeof(sAggInfo));
- pOrderBy = p->pOrderBy;
if( IgnorableOrderby(pDest) ){
- p->pOrderBy = 0;
-
- /* In these cases the DISTINCT operator makes no difference to the
- ** results, so remove it if it were specified.
- */
assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union ||
pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard);
+ /* If ORDER BY makes no difference in the output then neither does
+ ** DISTINCT so it can be removed too. */
+ sqlite3ExprListDelete(db, p->pOrderBy);
+ p->pOrderBy = 0;
p->selFlags &= ~SF_Distinct;
}
sqlite3SelectPrep(pParse, p, 0);
+ pOrderBy = p->pOrderBy;
pTabList = p->pSrc;
pEList = p->pEList;
if( pParse->nErr || db->mallocFailed ){
goto select_end;
}
- p->pOrderBy = pOrderBy;
isAgg = (p->selFlags & SF_Aggregate)!=0;
- if( pEList==0 ) goto select_end;
-
- /*
- ** Do not even attempt to generate any code if we have already seen
- ** errors before this routine starts.
- */
- if( pParse->nErr>0 ) goto select_end;
-
- /* ORDER BY is ignored for some destinations.
- */
- if( IgnorableOrderby(pDest) ){
- pOrderBy = 0;
- }
+ assert( pEList!=0 );
/* Begin generating code.
*/
@@ -77913,7 +79099,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3Select(pParse, pSub, &dest);
pItem->isPopulated = 1;
}
- if( pParse->nErr || db->mallocFailed ){
+ if( /*pParse->nErr ||*/ db->mallocFailed ){
goto select_end;
}
pParse->nHeight -= sqlite3SelectExprHeight(p);
@@ -77964,7 +79150,8 @@ SQLITE_PRIVATE int sqlite3Select(
/* If possible, rewrite the query to use GROUP BY instead of DISTINCT.
** GROUP BY might use an index, DISTINCT never does.
*/
- if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && !p->pGroupBy ){
+ assert( p->pGroupBy==0 || (p->selFlags & SF_Aggregate)!=0 );
+ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ){
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
p->selFlags &= ~SF_Distinct;
@@ -78282,9 +79469,7 @@ SQLITE_PRIVATE int sqlite3Select(
VdbeComment((v, "Groupby result generator entry point"));
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, &sAggInfo);
- if( pHaving ){
- sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
- }
+ sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
distinct, pDest,
addrOutputRow+1, addrSetAbort);
@@ -78297,7 +79482,7 @@ SQLITE_PRIVATE int sqlite3Select(
resetAccumulator(pParse, &sAggInfo);
sqlite3VdbeAddOp1(v, OP_Return, regReset);
- } /* endif pGroupBy */
+ } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
ExprList *pDel = 0;
#ifndef SQLITE_OMIT_BTREECOUNT
@@ -78415,9 +79600,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
pOrderBy = 0;
- if( pHaving ){
- sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
- }
+ sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1,
pDest, addrEnd, addrEnd);
sqlite3ExprListDelete(db, pDel);
@@ -78474,8 +79657,8 @@ select_end:
** or from temporary "printf" statements inserted for debugging.
*/
SQLITE_PRIVATE void sqlite3PrintExpr(Expr *p){
- if( p->token.z && p->token.n>0 ){
- sqlite3DebugPrintf("(%.*s", p->token.n, p->token.z);
+ if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
+ sqlite3DebugPrintf("(%s", p->u.zToken);
}else{
sqlite3DebugPrintf("(%d", p->op);
}
@@ -78779,7 +79962,6 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS
TriggerStep * pTmp = pTriggerStep;
pTriggerStep = pTriggerStep->pNext;
- if( pTmp->target.dyn ) sqlite3DbFree(db, (char*)pTmp->target.z);
sqlite3ExprDelete(db, pTmp->pWhere);
sqlite3ExprListDelete(db, pTmp->pExprList);
sqlite3SelectDelete(db, pTmp->pSelect);
@@ -78792,6 +79974,16 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS
/*
** Given table pTab, return a list of all the triggers attached to
** the table. The list is connected by Trigger.pNext pointers.
+**
+** All of the triggers on pTab that are in the same database as pTab
+** are already attached to pTab->pTrigger. But there might be additional
+** triggers on pTab in the TEMP schema. This routine prepends all
+** TEMP triggers on pTab to the beginning of the pTab->pTrigger list
+** and returns the combined list.
+**
+** To state it another way: This routine returns a list of all triggers
+** that fire off of pTab. The list will include any TEMP triggers on
+** pTab as well as the triggers lised in pTab->pTrigger.
*/
SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
Schema * const pTmpSchema = pParse->db->aDb[1].pSchema;
@@ -78964,7 +80156,6 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
pTrigger->pColumns = sqlite3IdListDup(db, pColumns);
- sqlite3TokenCopy(db, &pTrigger->nameToken,pName);
assert( pParse->pNewTrigger==0 );
pParse->pNewTrigger = pTrigger;
@@ -78994,10 +80185,11 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
sqlite3 *db = pParse->db; /* The database */
DbFixer sFix;
int iDb; /* Database containing the trigger */
+ Token nameToken; /* Trigger name for error reporting */
pTrig = pParse->pNewTrigger;
pParse->pNewTrigger = 0;
- if( pParse->nErr || !pTrig ) goto triggerfinish_cleanup;
+ if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup;
zName = pTrig->name;
iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
pTrig->step_list = pStepList;
@@ -79005,7 +80197,9 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
pStepList->pTrig = pTrig;
pStepList = pStepList->pNext;
}
- if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &pTrig->nameToken)
+ nameToken.z = pTrig->name;
+ nameToken.n = sqlite3Strlen30(nameToken.z);
+ if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken)
&& sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){
goto triggerfinish_cleanup;
}
@@ -79056,43 +80250,6 @@ triggerfinish_cleanup:
}
/*
-** Make a copy of all components of the given trigger step. This has
-** the effect of copying all Expr.token.z values into memory obtained
-** from sqlite3_malloc(). As initially created, the Expr.token.z values
-** all point to the input string that was fed to the parser. But that
-** string is ephemeral - it will go away as soon as the sqlite3_exec()
-** call that started the parser exits. This routine makes a persistent
-** copy of all the Expr.token.z strings so that the TriggerStep structure
-** will be valid even after the sqlite3_exec() call returns.
-*/
-static void sqlitePersistTriggerStep(sqlite3 *db, TriggerStep *p){
- if( p->target.z ){
- p->target.z = (u8*)sqlite3DbStrNDup(db, (char*)p->target.z, p->target.n);
- p->target.dyn = 1;
- }
- if( p->pSelect ){
- Select *pNew = sqlite3SelectDup(db, p->pSelect, 1);
- sqlite3SelectDelete(db, p->pSelect);
- p->pSelect = pNew;
- }
- if( p->pWhere ){
- Expr *pNew = sqlite3ExprDup(db, p->pWhere, EXPRDUP_REDUCE);
- sqlite3ExprDelete(db, p->pWhere);
- p->pWhere = pNew;
- }
- if( p->pExprList ){
- ExprList *pNew = sqlite3ExprListDup(db, p->pExprList, 1);
- sqlite3ExprListDelete(db, p->pExprList);
- p->pExprList = pNew;
- }
- if( p->pIdList ){
- IdList *pNew = sqlite3IdListDup(db, p->pIdList);
- sqlite3IdListDelete(db, p->pIdList);
- p->pIdList = pNew;
- }
-}
-
-/*
** Turn a SELECT statement (that the pSelect parameter points to) into
** a trigger step. Return a pointer to a TriggerStep structure.
**
@@ -79105,12 +80262,33 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelec
sqlite3SelectDelete(db, pSelect);
return 0;
}
-
pTriggerStep->op = TK_SELECT;
pTriggerStep->pSelect = pSelect;
pTriggerStep->orconf = OE_Default;
- sqlitePersistTriggerStep(db, pTriggerStep);
+ return pTriggerStep;
+}
+
+/*
+** Allocate space to hold a new trigger step. The allocated space
+** holds both the TriggerStep object and the TriggerStep.target.z string.
+**
+** If an OOM error occurs, NULL is returned and db->mallocFailed is set.
+*/
+static TriggerStep *triggerStepAllocate(
+ sqlite3 *db, /* Database connection */
+ int op, /* Trigger opcode */
+ Token *pName /* The target name */
+){
+ TriggerStep *pTriggerStep;
+ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
+ if( pTriggerStep ){
+ char *z = (char*)&pTriggerStep[1];
+ memcpy(z, pName->z, pName->n);
+ pTriggerStep->target.z = z;
+ pTriggerStep->target.n = pName->n;
+ pTriggerStep->op = op;
+ }
return pTriggerStep;
}
@@ -79134,20 +80312,17 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
assert(pEList == 0 || pSelect == 0);
assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
+ pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
if( pTriggerStep ){
- pTriggerStep->op = TK_INSERT;
- pTriggerStep->pSelect = pSelect;
- pTriggerStep->target = *pTableName;
+ pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
pTriggerStep->pIdList = pColumn;
- pTriggerStep->pExprList = pEList;
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
pTriggerStep->orconf = orconf;
- sqlitePersistTriggerStep(db, pTriggerStep);
}else{
sqlite3IdListDelete(db, pColumn);
- sqlite3ExprListDelete(db, pEList);
- sqlite3SelectDelete(db, pSelect);
}
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3SelectDelete(db, pSelect);
return pTriggerStep;
}
@@ -79164,20 +80339,16 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
Expr *pWhere, /* The WHERE clause */
int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
){
- TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
- if( pTriggerStep==0 ){
- sqlite3ExprListDelete(db, pEList);
- sqlite3ExprDelete(db, pWhere);
- return 0;
- }
-
- pTriggerStep->op = TK_UPDATE;
- pTriggerStep->target = *pTableName;
- pTriggerStep->pExprList = pEList;
- pTriggerStep->pWhere = pWhere;
- pTriggerStep->orconf = orconf;
- sqlitePersistTriggerStep(db, pTriggerStep);
+ TriggerStep *pTriggerStep;
+ pTriggerStep = triggerStepAllocate(db, TK_UPDATE, pTableName);
+ if( pTriggerStep ){
+ pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = orconf;
+ }
+ sqlite3ExprListDelete(db, pEList);
+ sqlite3ExprDelete(db, pWhere);
return pTriggerStep;
}
@@ -79191,18 +80362,14 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(
Token *pTableName, /* The table from which rows are deleted */
Expr *pWhere /* The WHERE clause */
){
- TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep));
- if( pTriggerStep==0 ){
- sqlite3ExprDelete(db, pWhere);
- return 0;
- }
-
- pTriggerStep->op = TK_DELETE;
- pTriggerStep->target = *pTableName;
- pTriggerStep->pWhere = pWhere;
- pTriggerStep->orconf = OE_Default;
- sqlitePersistTriggerStep(db, pTriggerStep);
+ TriggerStep *pTriggerStep;
+ pTriggerStep = triggerStepAllocate(db, TK_DELETE, pTableName);
+ if( pTriggerStep ){
+ pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
+ pTriggerStep->orconf = OE_Default;
+ }
+ sqlite3ExprDelete(db, pWhere);
return pTriggerStep;
}
@@ -79216,7 +80383,6 @@ SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
sqlite3DbFree(db, pTrigger->table);
sqlite3ExprDelete(db, pTrigger->pWhen);
sqlite3IdListDelete(db, pTrigger->pColumns);
- if( pTrigger->nameToken.dyn ) sqlite3DbFree(db, (char*)pTrigger->nameToken.z);
sqlite3DbFree(db, pTrigger);
}
@@ -79338,7 +80504,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const ch
Hash *pHash = &(db->aDb[iDb].pSchema->trigHash);
Trigger *pTrigger;
pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
- if( pTrigger ){
+ if( ALWAYS(pTrigger) ){
if( pTrigger->pSchema==pTrigger->pTabSchema ){
Table *pTab = tableOfTrigger(pTrigger);
Trigger **pp;
@@ -79359,9 +80525,9 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const ch
** it matches anything so always return true. Return false only
** if there is no match.
*/
-static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
+static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
int e;
- if( !pIdList || !pEList ) return 1;
+ if( pIdList==0 || NEVER(pEList==0) ) return 1;
for(e=0; e<pEList->nExpr; e++){
if( sqlite3IdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
}
@@ -79386,7 +80552,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
Trigger *p;
assert( pList==0 || IsVirtual(pTab)==0 );
for(p=pList; p; p=p->pNext){
- if( p->op==op && checkColumnOverLap(p->pColumns, pChanges) ){
+ if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
mask |= p->tr_tm;
}
}
@@ -79410,19 +80576,19 @@ static SrcList *targetSrcList(
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
- Token sDb; /* Dummy database name token */
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
- iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
- if( iDb==0 || iDb>=2 ){
- assert( iDb<pParse->db->nDb );
- sDb.z = (u8*)pParse->db->aDb[iDb].zName;
- sDb.n = sqlite3Strlen30((char*)sDb.z);
- sDb.quoted = 0;
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &sDb, &pStep->target);
- } else {
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+ pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+ if( pSrc ){
+ assert( pSrc->nSrc>0 );
+ assert( pSrc->a!=0 );
+ iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
+ if( iDb==0 || iDb>=2 ){
+ sqlite3 *db = pParse->db;
+ assert( iDb<pParse->db->nDb );
+ pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
+ }
}
return pSrc;
}
@@ -79450,17 +80616,6 @@ static int codeTriggerProgram(
orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
pParse->trigStack->orconf = orconf;
switch( pTriggerStep->op ){
- case TK_SELECT: {
- Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect, 0);
- if( ss ){
- SelectDest dest;
-
- sqlite3SelectDestInit(&dest, SRT_Discard, 0);
- sqlite3Select(pParse, ss, &dest);
- sqlite3SelectDelete(db, ss);
- }
- break;
- }
case TK_UPDATE: {
SrcList *pSrc;
pSrc = targetSrcList(pParse, pTriggerStep);
@@ -79491,8 +80646,17 @@ static int codeTriggerProgram(
sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0);
break;
}
- default:
- assert(0);
+ default: assert( pTriggerStep->op==TK_SELECT ); {
+ Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect, 0);
+ if( ss ){
+ SelectDest dest;
+
+ sqlite3SelectDestInit(&dest, SRT_Discard, 0);
+ sqlite3Select(pParse, ss, &dest);
+ sqlite3SelectDelete(db, ss);
+ }
+ break;
+ }
}
pTriggerStep = pTriggerStep->pNext;
}
@@ -79558,12 +80722,18 @@ SQLITE_PRIVATE int sqlite3CodeRowTrigger(
for(p=pTrigger; p; p=p->pNext){
int fire_this = 0;
+ /* Sanity checking: The schema for the trigger and for the table are
+ ** always defined. The trigger must be in the same schema as the table
+ ** or else it must be a TEMP trigger. */
+ assert( p->pSchema!=0 );
+ assert( p->pTabSchema!=0 );
+ assert( p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema );
+
/* Determine whether we should code this trigger */
if(
p->op==op &&
p->tr_tm==tr_tm &&
- (p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema) &&
- (op!=TK_UPDATE||!p->pColumns||checkColumnOverLap(p->pColumns,pChanges))
+ checkColumnOverlap(p->pColumns,pChanges)
){
TriggerStack *pS; /* Pointer to trigger-stack entry */
for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){}
@@ -80262,10 +81432,10 @@ static void updateVirtualTable(
** all updated rows.
*/
pEList = sqlite3ExprListAppend(pParse, 0,
- sqlite3CreateIdExpr(pParse, "_rowid_"), 0);
+ sqlite3CreateIdExpr(pParse, "_rowid_"));
if( pRowid ){
pEList = sqlite3ExprListAppend(pParse, pEList,
- sqlite3ExprDup(db, pRowid, 0), 0);
+ sqlite3ExprDup(db, pRowid, 0));
}
assert( pTab->iPKey<0 );
for(i=0; i<pTab->nCol; i++){
@@ -80274,7 +81444,7 @@ static void updateVirtualTable(
}else{
pExpr = sqlite3CreateIdExpr(pParse, pTab->aCol[i].zName);
}
- pEList = sqlite3ExprListAppend(pParse, pEList, pExpr, 0);
+ pEList = sqlite3ExprListAppend(pParse, pEList, pExpr);
}
pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
@@ -80401,14 +81571,13 @@ SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse){
SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
- Pager *pMainPager; /* Pager for database being vacuumed */
Btree *pTemp; /* The temporary database we vacuum into */
char *zSql = 0; /* SQL statements */
int saved_flags; /* Saved value of the db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
Db *pDb = 0; /* Database to detach at end of vacuum */
- int isMemDb; /* True is vacuuming a :memory: database */
+ int isMemDb; /* True if vacuuming a :memory: database */
int nRes;
if( !db->autoCommit ){
@@ -80423,8 +81592,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
pMain = db->aDb[0].pBt;
- pMainPager = sqlite3BtreePager(pMain);
- isMemDb = sqlite3PagerFile(pMainPager)->pMethods==0;
+ isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
** can be set to 'off' for this file, as it is not recovered if a crash
@@ -80561,10 +81729,10 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
** connections to the same database will know to reread the schema.
*/
static const unsigned char aCopy[] = {
- 1, 1, /* Add one to the old schema cookie */
- 3, 0, /* Preserve the default page cache size */
- 5, 0, /* Preserve the default text encoding */
- 6, 0, /* Preserve the user version */
+ BTREE_SCHEMA_VERSION, 1, /* Add one to the old schema cookie */
+ BTREE_DEFAULT_CACHE_SIZE, 0, /* Preserve the default page cache size */
+ BTREE_TEXT_ENCODING, 0, /* Preserve the text encoding */
+ BTREE_USER_VERSION, 0, /* Preserve the user version */
};
assert( 1==sqlite3BtreeIsInTrans(pTemp) );
@@ -80729,11 +81897,14 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){
assert(db);
assert( sqlite3SafetyCheckOk(db) );
if( pVtab->nRef==0 ){
+#ifdef SQLITE_DEBUG
if( db->magic==SQLITE_MAGIC_BUSY ){
(void)sqlite3SafetyOff(db);
pVtab->pModule->xDisconnect(pVtab);
(void)sqlite3SafetyOn(db);
- } else {
+ } else
+#endif
+ {
pVtab->pModule->xDisconnect(pVtab);
}
}
@@ -80810,7 +81981,7 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0);
pTable = pParse->pNewTable;
- if( pTable==0 || pParse->nErr ) return;
+ if( pTable==0 ) return;
assert( 0==pTable->pIndex );
db = pParse->db;
@@ -80843,7 +82014,7 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
** virtual table currently under construction in pParse->pTable.
*/
static void addArgumentToVtab(Parse *pParse){
- if( pParse->sArg.z && pParse->pNewTable ){
+ if( pParse->sArg.z && ALWAYS(pParse->pNewTable) ){
const char *z = (const char*)pParse->sArg.z;
int n = pParse->sArg.n;
sqlite3 *db = pParse->db;
@@ -80999,7 +82170,10 @@ static int vtabCallConstructor(
assert( rc==SQLITE_OK );
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVtab, &zErr);
rc2 = sqlite3SafetyOn(db);
- if( rc==SQLITE_OK && pVtab ){
+ if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
+ /* Justification of ALWAYS(): A correct vtab constructor must allocate
+ ** the sqlite3_vtab object if successful. */
+ if( rc==SQLITE_OK && ALWAYS(pVtab) ){
pVtab->pModule = pMod->pModule;
pVtab->nRef = 1;
pTab->pVtab = pVtab;
@@ -81074,7 +82248,8 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
Module *pMod;
int rc = SQLITE_OK;
- if( !pTab || (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){
+ assert( pTab );
+ if( (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){
return SQLITE_OK;
}
@@ -81150,7 +82325,9 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr);
}
- if( rc==SQLITE_OK && pTab->pVtab ){
+ /* Justification of ALWAYS(): The xConstructor method is required to
+ ** create a valid sqlite3_vtab if it returns SQLITE_OK. */
+ if( rc==SQLITE_OK && ALWAYS(pTab->pVtab) ){
rc = addToVTrans(db, pTab->pVtab);
}
@@ -81163,7 +82340,7 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
** virtual table module.
*/
SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
- Parse sParse;
+ Parse *pParse;
int rc = SQLITE_OK;
Table *pTab;
@@ -81178,33 +82355,37 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
}
assert((pTab->tabFlags & TF_Virtual)!=0 && pTab->nCol==0 && pTab->aCol==0);
- memset(&sParse, 0, sizeof(Parse));
- sParse.declareVtab = 1;
- sParse.db = db;
-
- if(
- SQLITE_OK == sqlite3RunParser(&sParse, zCreateTable, &zErr) &&
- sParse.pNewTable &&
- !sParse.pNewTable->pSelect &&
- (sParse.pNewTable->tabFlags & TF_Virtual)==0
- ){
- pTab->aCol = sParse.pNewTable->aCol;
- pTab->nCol = sParse.pNewTable->nCol;
- sParse.pNewTable->nCol = 0;
- sParse.pNewTable->aCol = 0;
- db->pVTab = 0;
- } else {
- sqlite3Error(db, SQLITE_ERROR, zErr);
- sqlite3DbFree(db, zErr);
- rc = SQLITE_ERROR;
- }
- sParse.declareVtab = 0;
-
- if( sParse.pVdbe ){
- sqlite3VdbeFinalize(sParse.pVdbe);
+ pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
+ if( pParse==0 ){
+ rc = SQLITE_NOMEM;
+ }else{
+ pParse->declareVtab = 1;
+ pParse->db = db;
+
+ if(
+ SQLITE_OK == sqlite3RunParser(pParse, zCreateTable, &zErr) &&
+ pParse->pNewTable &&
+ !pParse->pNewTable->pSelect &&
+ (pParse->pNewTable->tabFlags & TF_Virtual)==0
+ ){
+ pTab->aCol = pParse->pNewTable->aCol;
+ pTab->nCol = pParse->pNewTable->nCol;
+ pParse->pNewTable->nCol = 0;
+ pParse->pNewTable->aCol = 0;
+ db->pVTab = 0;
+ } else {
+ sqlite3Error(db, SQLITE_ERROR, zErr);
+ sqlite3DbFree(db, zErr);
+ rc = SQLITE_ERROR;
+ }
+ pParse->declareVtab = 0;
+
+ if( pParse->pVdbe ){
+ sqlite3VdbeFinalize(pParse->pVdbe);
+ }
+ sqlite3DeleteTable(pParse->pNewTable);
+ sqlite3StackFree(db, pParse);
}
- sqlite3DeleteTable(sParse.pNewTable);
- sParse.pNewTable = 0;
assert( (rc&0xff)==rc );
rc = sqlite3ApiExit(db, rc);
@@ -81219,20 +82400,16 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
**
** This call is a no-op if zTab is not a virtual table.
*/
-SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab)
-{
+SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
int rc = SQLITE_OK;
Table *pTab;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
- assert(pTab);
- if( pTab->pVtab ){
+ if( ALWAYS(pTab!=0 && pTab->pVtab!=0) ){
int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy;
rc = sqlite3SafetyOff(db);
assert( rc==SQLITE_OK );
- if( xDestroy ){
- rc = xDestroy(pTab->pVtab);
- }
+ rc = xDestroy(pTab->pVtab);
(void)sqlite3SafetyOn(db);
if( rc==SQLITE_OK ){
int i;
@@ -81260,9 +82437,11 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
static void callFinaliser(sqlite3 *db, int offset){
int i;
if( db->aVTrans ){
- for(i=0; i<db->nVTrans && db->aVTrans[i]; i++){
+ for(i=0; i<db->nVTrans; i++){
sqlite3_vtab *pVtab = db->aVTrans[i];
int (*x)(sqlite3_vtab *);
+
+ assert( pVtab!=0 );
x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
if( x ) x(pVtab);
sqlite3VtabUnlock(db, pVtab);
@@ -81289,9 +82468,10 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){
rc = sqlite3SafetyOff(db);
db->aVTrans = 0;
- for(i=0; rc==SQLITE_OK && i<db->nVTrans && aVTrans[i]; i++){
+ for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
sqlite3_vtab *pVtab = aVTrans[i];
int (*x)(sqlite3_vtab *);
+ assert( pVtab!=0 );
x = pVtab->pModule->xSync;
if( x ){
rc = x(pVtab);
@@ -81342,7 +82522,7 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
/* Special case: If db->aVTrans is NULL and db->nVTrans is greater
** than zero, then this function is being called from within a
** virtual module xSync() callback. It is illegal to write to
- ** virtual module tables in this case, so return SQLITE_MISUSE.
+ ** virtual module tables in this case, so return SQLITE_LOCKED.
*/
if( sqlite3VtabInSync(db) ){
return SQLITE_LOCKED;
@@ -81357,7 +82537,7 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){
/* If pVtab is already in the aVTrans array, return early */
- for(i=0; (i<db->nVTrans) && 0!=db->aVTrans[i]; i++){
+ for(i=0; i<db->nVTrans; i++){
if( db->aVTrans[i]==pVtab ){
return SQLITE_OK;
}
@@ -81403,10 +82583,10 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
/* Check to see the left operand is a column in a virtual table */
- if( pExpr==0 ) return pDef;
+ if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
pTab = pExpr->pTab;
- if( pTab==0 ) return pDef;
+ if( NEVER(pTab==0) ) return pDef;
if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef;
pVtab = pTab->pVtab;
assert( pVtab!=0 );
@@ -81424,11 +82604,6 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
}
rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
sqlite3DbFree(db, zLowerName);
- if( pVtab->zErrMsg ){
- sqlite3Error(db, rc, "%s", pVtab->zErrMsg);
- sqlite3DbFree(db, pVtab->zErrMsg);
- pVtab->zErrMsg = 0;
- }
}
if( rc==0 ){
return pDef;
@@ -81458,13 +82633,16 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(
*/
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
int i, n;
+ Table **apVtabLock;
+
assert( IsVirtual(pTab) );
for(i=0; i<pParse->nVtabLock; i++){
if( pTab==pParse->apVtabLock[i] ) return;
}
n = (pParse->nVtabLock+1)*sizeof(pParse->apVtabLock[0]);
- pParse->apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
- if( pParse->apVtabLock ){
+ apVtabLock = sqlite3_realloc(pParse->apVtabLock, n);
+ if( apVtabLock ){
+ pParse->apVtabLock = apVtabLock;
pParse->apVtabLock[pParse->nVtabLock++] = pTab;
}else{
pParse->db->mallocFailed = 1;
@@ -81603,11 +82781,16 @@ struct WhereTerm {
struct WhereClause {
Parse *pParse; /* The parser context */
WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
+ Bitmask vmask; /* Bitmask identifying virtual table cursors */
u8 op; /* Split operator. TK_AND or TK_OR */
int nTerm; /* Number of terms */
int nSlot; /* Number of entries in a[] */
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
- WhereTerm aStatic[4]; /* Initial static space for a[] */
+#if defined(SQLITE_SMALL_STACK)
+ WhereTerm aStatic[1]; /* Initial static space for a[] */
+#else
+ WhereTerm aStatic[8]; /* Initial static space for a[] */
+#endif
};
/*
@@ -81730,6 +82913,7 @@ static void whereClauseInit(
pWC->nTerm = 0;
pWC->nSlot = ArraySize(pWC->aStatic);
pWC->a = pWC->aStatic;
+ pWC->vmask = 0;
}
/* Forward reference */
@@ -82102,7 +83286,6 @@ static int isLikeOrGlob(
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 n; /* Length of string z[] */
int cnt; /* Number of non-wildcard prefix characters */
char wc[3]; /* Wildcard characters */
CollSeq *pColl; /* Collating sequence for LHS */
@@ -82125,23 +83308,20 @@ static int isLikeOrGlob(
}
pColl = sqlite3ExprCollSeq(pParse, pLeft);
assert( pColl!=0 || pLeft->iColumn==-1 );
- if( pColl==0 ){
- /* No collation is defined for the ROWID. Use the default. */
- pColl = db->pDfltColl;
- }
+ if( pColl==0 ) return 0;
if( (pColl->type!=SQLITE_COLL_BINARY || *pnoCase) &&
(pColl->type!=SQLITE_COLL_NOCASE || !*pnoCase) ){
return 0;
}
- z = (const char*)pRight->token.z;
+ if( sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ) return 0;
+ z = pRight->u.zToken;
cnt = 0;
- if( z ){
- n = pRight->token.n;
- while( cnt<n && (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
+ if( ALWAYS(z) ){
+ while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
}
}
- if( cnt==0 || 255==(u8)z[cnt-1] ){
+ if( cnt==0 || c==0 || 255==(u8)z[cnt-1] ){
return 0;
}
*pisComplete = z[cnt]==wc[0] && z[cnt+1]==0;
@@ -82167,8 +83347,7 @@ static int isMatchOfColumn(
if( pExpr->op!=TK_FUNCTION ){
return 0;
}
- if( pExpr->token.n!=5 ||
- sqlite3StrNICmp((const char*)pExpr->token.z,"match",5)!=0 ){
+ if( sqlite3StrICmp(pExpr->u.zToken,"match")!=0 ){
return 0;
}
pList = pExpr->x.pList;
@@ -82305,7 +83484,8 @@ static void exprAnalyzeOrTerm(
/*
** Compute the set of tables that might satisfy cases 1 or 2.
*/
- indexable = chngToIN = ~(Bitmask)0;
+ indexable = ~(Bitmask)0;
+ chngToIN = ~(pWC->vmask);
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
WhereAndInfo *pAndInfo;
@@ -82366,6 +83546,22 @@ static void exprAnalyzeOrTerm(
** chngToIN holds a set of tables that *might* satisfy case 1. But
** we have to do some additional checking to see if case 1 really
** is satisfied.
+ **
+ ** chngToIN will hold either 0, 1, or 2 bits. The 0-bit case means
+ ** that there is no possibility of transforming the OR clause into an
+ ** IN operator because one or more terms in the OR clause contain
+ ** something other than == on a column in the single table. The 1-bit
+ ** case means that every term of the OR clause is of the form
+ ** "table.column=expr" for some single table. The one bit that is set
+ ** will correspond to the common table. We still need to check to make
+ ** sure the same column is used on all terms. The 2-bit case is when
+ ** the all terms are of the form "table1.column=table2.column". It
+ ** might be possible to form an IN operator with either table1.column
+ ** or table2.column as the LHS if either is common to every term of
+ ** the OR clause.
+ **
+ ** Note that terms of the form "table.column1=table.column2" (the
+ ** same table on both sizes of the ==) cannot be optimized.
*/
if( chngToIN ){
int okToChngToIN = 0; /* True if the conversion to IN is valid */
@@ -82384,18 +83580,38 @@ static void exprAnalyzeOrTerm(
for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
assert( pOrTerm->eOperator==WO_EQ );
pOrTerm->wtFlags &= ~TERM_OR_OK;
- if( pOrTerm->leftCursor==iColumn ) continue;
- if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ) continue;
+ if( pOrTerm->leftCursor==iCursor ){
+ /* This is the 2-bit case and we are on the second iteration and
+ ** current term is from the first iteration. So skip this term. */
+ assert( j==1 );
+ continue;
+ }
+ if( (chngToIN & getMask(pMaskSet, pOrTerm->leftCursor))==0 ){
+ /* This term must be of the form t1.a==t2.b where t2 is in the
+ ** chngToIN set but t1 is not. This term will be either preceeded
+ ** or follwed by an inverted copy (t2.b==t1.a). Skip this term
+ ** and use its inversion. */
+ testcase( pOrTerm->wtFlags & TERM_COPIED );
+ testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
+ assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
+ continue;
+ }
iColumn = pOrTerm->u.leftColumn;
iCursor = pOrTerm->leftCursor;
break;
}
if( i<0 ){
+ /* No candidate table+column was found. This can only occur
+ ** on the second iteration */
assert( j==1 );
assert( (chngToIN&(chngToIN-1))==0 );
- assert( chngToIN==getMask(pMaskSet, iColumn) );
+ assert( chngToIN==getMask(pMaskSet, iCursor) );
break;
}
+ testcase( j==1 );
+
+ /* We have found a candidate table and column. Check to see if that
+ ** table and column is common to every term in the OR clause */
okToChngToIN = 1;
for(; i>=0 && okToChngToIN; i--, pOrTerm++){
assert( pOrTerm->eOperator==WO_EQ );
@@ -82436,12 +83652,12 @@ static void exprAnalyzeOrTerm(
assert( pOrTerm->leftCursor==iCursor );
assert( pOrTerm->u.leftColumn==iColumn );
pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
- pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0);
+ pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup);
pLeft = pOrTerm->pExpr->pLeft;
}
assert( pLeft!=0 );
pDup = sqlite3ExprDup(db, pLeft, 0);
- pNew = sqlite3Expr(db, TK_IN, pDup, 0, 0);
+ pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0, 0);
if( pNew ){
int idxNew;
transferJoinMarkings(pNew, pExpr);
@@ -82594,7 +83810,8 @@ static void exprAnalyze(
for(i=0; i<2; i++){
Expr *pNewExpr;
int idxNew;
- pNewExpr = sqlite3Expr(db, ops[i], sqlite3ExprDup(db, pExpr->pLeft, 0),
+ pNewExpr = sqlite3PExpr(pParse, ops[i],
+ sqlite3ExprDup(db, pExpr->pLeft, 0),
sqlite3ExprDup(db, pList->a[i].pExpr, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
@@ -82636,19 +83853,22 @@ static void exprAnalyze(
pLeft = pExpr->x.pList->a[1].pExpr;
pRight = pExpr->x.pList->a[0].pExpr;
- pStr1 = sqlite3PExpr(pParse, TK_STRING, 0, 0, 0);
- if( pStr1 ){
- sqlite3TokenCopy(db, &pStr1->token, &pRight->token);
- pStr1->token.n = nPattern;
- }
+ pStr1 = sqlite3Expr(db, TK_STRING, pRight->u.zToken);
+ if( pStr1 ) pStr1->u.zToken[nPattern] = 0;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
if( !db->mallocFailed ){
- u8 c, *pC;
- /* assert( pStr2->token.dyn ); */
- pC = (u8*)&pStr2->token.z[nPattern-1];
+ u8 c, *pC; /* Last character before the first wildcard */
+ pC = (u8*)&pStr2->u.zToken[nPattern-1];
c = *pC;
if( noCase ){
- if( c=='@' ) isComplete = 0;
+ /* The point is to increment the last character before the first
+ ** wildcard. But if we increment '@', that will push it into the
+ ** alphabetic range where case conversions will mess up the
+ ** inequality. To avoid this, make sure to also run the full
+ ** LIKE on all candidate expressions by clearing the isComplete flag
+ */
+ if( c=='A'-1 ) isComplete = 0;
+
c = sqlite3UpperToLower[c];
}
*pC = c + 1;
@@ -82689,7 +83909,8 @@ static void exprAnalyze(
prereqColumn = exprTableUsage(pMaskSet, pLeft);
if( (prereqExpr & prereqColumn)==0 ){
Expr *pNewExpr;
- pNewExpr = sqlite3Expr(db, TK_MATCH, 0, sqlite3ExprDup(db, pRight, 0), 0);
+ pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
+ 0, sqlite3ExprDup(db, pRight, 0), 0);
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );
pNewTerm = &pWC->a[idxNew];
@@ -83317,7 +84538,7 @@ static void bestVirtualIndex(
pCost->rCost = pIdxInfo->estimatedCost;
}
pCost->plan.u.pVtabIdx = pIdxInfo;
- if( pIdxInfo && pIdxInfo->orderByConsumed ){
+ if( pIdxInfo->orderByConsumed ){
pCost->plan.wsFlags |= WHERE_ORDERBY;
}
pCost->plan.nEq = 0;
@@ -83603,7 +84824,7 @@ static void bestBtreeIndex(
cost += cost*estLog(cost);
WHERETRACE(("...... orderby increases cost to %.9g\n", cost));
}
- }else if( pParse->db->flags & SQLITE_ReverseOrder ){
+ }else if( wsFlags!=0 && (pParse->db->flags & SQLITE_ReverseOrder)!=0 ){
/* For application testing, randomly reverse the output order for
** SELECT statements that omit the ORDER BY clause. This will help
** to find cases where
@@ -83769,7 +84990,6 @@ static int codeEqualityTerm(
eType = sqlite3FindInIndex(pParse, pX, 0);
iTab = pX->iTable;
sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
- VdbeComment((v, "%.*s", pX->span.n, pX->span.z));
assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
if( pLevel->u.in.nIn==0 ){
pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
@@ -84350,7 +85570,6 @@ static Bitmask codeOneLoopStart(
WhereTerm *pOrTerm = &pOrWc->a[ii];
if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
-
/* Loop through table entries that match term pOrTerm. */
pSubWInfo = sqlite3WhereBegin(pParse, &oneTab, pOrTerm->pExpr, 0,
WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | WHERE_FORCE_TABLE);
@@ -84642,9 +85861,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
** of the join. Subtracting one from the right table bitmask gives a
** bitmask for all tables to the left of the join. Knowing the bitmask
** for all tables to the left of a left join is important. Ticket #3015.
+ **
+ ** Configure the WhereClause.vmask variable so that bits that correspond
+ ** to virtual table cursors are set. This is used to selectively disable
+ ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful
+ ** with virtual tables.
*/
+ assert( pWC->vmask==0 && pMaskSet->n==0 );
for(i=0; i<pTabList->nSrc; i++){
createMask(pMaskSet, pTabList->a[i].iCursor);
+ if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){
+ pWC->vmask |= ((Bitmask)1 << i);
+ }
}
#ifndef NDEBUG
{
@@ -85017,7 +86245,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** that reference the table and converts them into opcodes that
** reference the index.
*/
- if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 ){
+ if( (pLevel->plan.wsFlags & WHERE_INDEXED)!=0 && !db->mallocFailed){
int k, j, last;
VdbeOp *pOp;
Index *pIdx = pLevel->plan.u.pIdx;
@@ -85063,6 +86291,17 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
/*
+** Disable all error recovery processing in the parser push-down
+** automaton.
+*/
+#define YYNOERRORRECOVERY 1
+
+/*
+** Make yytestcase() the same as testcase()
+*/
+#define yytestcase(X) testcase(X)
+
+/*
** An instance of this structure holds information about the
** LIMIT clause of a SELECT statement.
*/
@@ -85096,6 +86335,68 @@ struct TrigEvent { int a; IdList * b; };
*/
struct AttachKey { int type; Token key; };
+
+ /* 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 *pValue){
+ pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
+ pOut->zStart = pValue->z;
+ pOut->zEnd = &pValue->z[pValue->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(
+ ExprSpan *pOut, /* Write the result here */
+ Parse *pParse, /* The parsing context. Errors accumulate here */
+ int op, /* The binary operation */
+ ExprSpan *pLeft, /* The left operand */
+ ExprSpan *pRight /* The right operand */
+ ){
+ pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
+ pOut->zStart = pLeft->zStart;
+ pOut->zEnd = pRight->zEnd;
+ }
+
+ /* Construct an expression node for a unary postfix operator
+ */
+ static void spanUnaryPostfix(
+ ExprSpan *pOut, /* Write the new expression node here */
+ Parse *pParse, /* Parsing context to record errors */
+ int op, /* The operator */
+ ExprSpan *pOperand, /* The operand */
+ Token *pPostOp /* The operand token for setting the span */
+ ){
+ pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOut->zStart = pOperand->zStart;
+ pOut->zEnd = &pPostOp->z[pPostOp->n];
+ }
+
+ /* 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->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOut->zStart = pPreOp->z;
+ pOut->zEnd = pOperand->zEnd;
+ }
/* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch.
*/
@@ -85145,7 +86446,7 @@ struct AttachKey { int type; Token key; };
** YYERRORSYMBOL is the code number of the error symbol. If not
** defined, then do no error processing.
*/
-#define YYCODETYPE unsigned short int
+#define YYCODETYPE unsigned char
#define YYNOCODE 252
#define YYACTIONTYPE unsigned short int
#define YYWILDCARD 65
@@ -85157,6 +86458,7 @@ typedef union {
TriggerStep* yy145;
ExprList* yy148;
SrcList* yy185;
+ ExprSpan yy190;
int yy194;
Select* yy243;
IdList* yy254;
@@ -85172,8 +86474,8 @@ typedef union {
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 616
-#define YYNRULE 323
+#define YYNSTATE 619
+#define YYNRULE 324
#define YYFALLBACK 1
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
@@ -85183,6 +86485,18 @@ typedef union {
** YYMINORTYPE objects to zero. */
static const YYMINORTYPE yyzerominor = { 0 };
+/* Define the yytestcase() macro to be a no-op if is not already defined
+** otherwise.
+**
+** Applications can choose to define yytestcase() in the %include section
+** to a macro that can assist in verifying code coverage. For production
+** code the yytestcase() macro should be turned off. But it is useful
+** for testing.
+*/
+#ifndef yytestcase
+# define yytestcase(X)
+#endif
+
/* Next are the tables used to determine what action to take based on the
** current state and lookahead token. These tables are used to implement
@@ -85232,156 +86546,157 @@ static const YYMINORTYPE yyzerominor = { 0 };
** yy_default[] Default action for each state.
*/
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 304, 940, 176, 615, 2, 150, 214, 439, 24, 24,
- /* 10 */ 24, 24, 488, 26, 26, 26, 26, 27, 27, 28,
- /* 20 */ 28, 28, 29, 216, 413, 414, 212, 413, 414, 446,
- /* 30 */ 452, 31, 26, 26, 26, 26, 27, 27, 28, 28,
- /* 40 */ 28, 29, 216, 30, 483, 32, 134, 23, 22, 308,
- /* 50 */ 456, 457, 453, 453, 25, 25, 24, 24, 24, 24,
- /* 60 */ 436, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 70 */ 29, 216, 304, 216, 311, 439, 512, 490, 45, 26,
+ /* 0 */ 305, 944, 176, 618, 2, 150, 214, 441, 24, 24,
+ /* 10 */ 24, 24, 490, 26, 26, 26, 26, 27, 27, 28,
+ /* 20 */ 28, 28, 29, 216, 415, 416, 212, 415, 416, 448,
+ /* 30 */ 454, 31, 26, 26, 26, 26, 27, 27, 28, 28,
+ /* 40 */ 28, 29, 216, 30, 485, 32, 134, 23, 22, 311,
+ /* 50 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24,
+ /* 60 */ 438, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 70 */ 29, 216, 305, 216, 314, 441, 514, 492, 45, 26,
/* 80 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 90 */ 413, 414, 416, 417, 156, 416, 417, 360, 363, 364,
- /* 100 */ 311, 446, 452, 385, 514, 21, 186, 495, 365, 27,
- /* 110 */ 27, 28, 28, 28, 29, 216, 413, 414, 415, 23,
- /* 120 */ 22, 308, 456, 457, 453, 453, 25, 25, 24, 24,
- /* 130 */ 24, 24, 555, 26, 26, 26, 26, 27, 27, 28,
- /* 140 */ 28, 28, 29, 216, 304, 228, 504, 135, 468, 218,
- /* 150 */ 548, 145, 132, 256, 358, 261, 359, 153, 416, 417,
- /* 160 */ 241, 598, 331, 30, 265, 32, 134, 439, 596, 597,
- /* 170 */ 230, 228, 490, 446, 452, 57, 506, 328, 132, 256,
- /* 180 */ 358, 261, 359, 153, 416, 417, 435, 78, 408, 405,
- /* 190 */ 265, 23, 22, 308, 456, 457, 453, 453, 25, 25,
- /* 200 */ 24, 24, 24, 24, 342, 26, 26, 26, 26, 27,
- /* 210 */ 27, 28, 28, 28, 29, 216, 304, 214, 534, 547,
- /* 220 */ 307, 127, 489, 595, 30, 331, 32, 134, 345, 387,
- /* 230 */ 429, 63, 331, 355, 415, 439, 507, 331, 415, 535,
- /* 240 */ 328, 215, 193, 594, 593, 446, 452, 328, 18, 435,
- /* 250 */ 85, 16, 328, 183, 190, 556, 435, 78, 309, 463,
- /* 260 */ 464, 435, 85, 23, 22, 308, 456, 457, 453, 453,
- /* 270 */ 25, 25, 24, 24, 24, 24, 436, 26, 26, 26,
- /* 280 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 347,
- /* 290 */ 221, 313, 595, 191, 378, 331, 472, 234, 345, 381,
- /* 300 */ 324, 410, 220, 344, 592, 217, 213, 415, 112, 331,
- /* 310 */ 328, 4, 594, 399, 211, 554, 529, 446, 452, 435,
- /* 320 */ 79, 217, 553, 515, 328, 334, 513, 459, 459, 469,
- /* 330 */ 441, 572, 432, 435, 78, 23, 22, 308, 456, 457,
- /* 340 */ 453, 453, 25, 25, 24, 24, 24, 24, 436, 26,
+ /* 90 */ 415, 416, 418, 419, 156, 418, 419, 362, 365, 366,
+ /* 100 */ 314, 448, 454, 387, 516, 21, 186, 497, 367, 27,
+ /* 110 */ 27, 28, 28, 28, 29, 216, 415, 416, 417, 23,
+ /* 120 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24,
+ /* 130 */ 24, 24, 557, 26, 26, 26, 26, 27, 27, 28,
+ /* 140 */ 28, 28, 29, 216, 305, 228, 506, 135, 470, 218,
+ /* 150 */ 550, 145, 132, 256, 360, 261, 361, 153, 418, 419,
+ /* 160 */ 241, 600, 333, 30, 265, 32, 134, 441, 598, 599,
+ /* 170 */ 230, 228, 492, 448, 454, 57, 508, 330, 132, 256,
+ /* 180 */ 360, 261, 361, 153, 418, 419, 437, 78, 410, 407,
+ /* 190 */ 265, 23, 22, 311, 458, 459, 455, 455, 25, 25,
+ /* 200 */ 24, 24, 24, 24, 344, 26, 26, 26, 26, 27,
+ /* 210 */ 27, 28, 28, 28, 29, 216, 305, 214, 536, 549,
+ /* 220 */ 308, 127, 491, 597, 30, 333, 32, 134, 347, 389,
+ /* 230 */ 431, 63, 333, 357, 417, 441, 509, 333, 417, 537,
+ /* 240 */ 330, 215, 193, 596, 595, 448, 454, 330, 18, 437,
+ /* 250 */ 85, 16, 330, 183, 190, 558, 437, 78, 312, 465,
+ /* 260 */ 466, 437, 85, 23, 22, 311, 458, 459, 455, 455,
+ /* 270 */ 25, 25, 24, 24, 24, 24, 438, 26, 26, 26,
+ /* 280 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 349,
+ /* 290 */ 221, 316, 597, 191, 380, 333, 474, 234, 347, 383,
+ /* 300 */ 326, 412, 220, 346, 594, 217, 213, 417, 112, 333,
+ /* 310 */ 330, 4, 596, 401, 211, 556, 531, 448, 454, 437,
+ /* 320 */ 79, 217, 555, 517, 330, 336, 515, 461, 461, 471,
+ /* 330 */ 443, 574, 434, 437, 78, 23, 22, 311, 458, 459,
+ /* 340 */ 455, 455, 25, 25, 24, 24, 24, 24, 438, 26,
/* 350 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 360 */ 304, 443, 443, 443, 156, 468, 218, 360, 363, 364,
- /* 370 */ 331, 247, 395, 398, 217, 349, 331, 30, 365, 32,
- /* 380 */ 134, 388, 282, 281, 39, 328, 41, 430, 545, 446,
- /* 390 */ 452, 328, 214, 531, 435, 93, 542, 601, 1, 404,
- /* 400 */ 435, 93, 413, 414, 495, 40, 536, 23, 22, 308,
- /* 410 */ 456, 457, 453, 453, 25, 25, 24, 24, 24, 24,
- /* 420 */ 573, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 430 */ 29, 216, 304, 276, 331, 179, 508, 490, 210, 547,
- /* 440 */ 319, 413, 414, 222, 192, 385, 320, 240, 415, 328,
- /* 450 */ 557, 63, 413, 414, 415, 616, 408, 405, 435, 71,
- /* 460 */ 415, 446, 452, 611, 572, 28, 28, 28, 29, 216,
- /* 470 */ 416, 417, 436, 336, 463, 464, 401, 43, 436, 23,
- /* 480 */ 22, 308, 456, 457, 453, 453, 25, 25, 24, 24,
- /* 490 */ 24, 24, 495, 26, 26, 26, 26, 27, 27, 28,
- /* 500 */ 28, 28, 29, 216, 304, 612, 209, 135, 511, 416,
- /* 510 */ 417, 431, 233, 64, 388, 282, 281, 439, 66, 542,
- /* 520 */ 416, 417, 413, 414, 156, 214, 403, 360, 363, 364,
- /* 530 */ 547, 252, 490, 446, 452, 491, 217, 8, 365, 495,
- /* 540 */ 436, 606, 63, 537, 299, 415, 492, 470, 546, 200,
- /* 550 */ 196, 23, 22, 308, 456, 457, 453, 453, 25, 25,
- /* 560 */ 24, 24, 24, 24, 386, 26, 26, 26, 26, 27,
- /* 570 */ 27, 28, 28, 28, 29, 216, 304, 477, 254, 354,
- /* 580 */ 528, 60, 517, 518, 436, 439, 389, 331, 356, 7,
- /* 590 */ 416, 417, 331, 478, 328, 208, 197, 137, 460, 499,
- /* 600 */ 447, 448, 328, 435, 9, 446, 452, 328, 479, 485,
- /* 610 */ 519, 435, 72, 567, 415, 434, 435, 67, 486, 433,
- /* 620 */ 520, 450, 451, 23, 22, 308, 456, 457, 453, 453,
- /* 630 */ 25, 25, 24, 24, 24, 24, 331, 26, 26, 26,
- /* 640 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 331,
- /* 650 */ 449, 328, 268, 390, 461, 331, 65, 331, 368, 434,
- /* 660 */ 435, 76, 310, 433, 328, 150, 427, 439, 473, 331,
- /* 670 */ 328, 499, 328, 435, 97, 29, 216, 446, 452, 435,
- /* 680 */ 96, 435, 101, 353, 328, 372, 415, 334, 154, 459,
- /* 690 */ 459, 352, 569, 435, 99, 23, 22, 308, 456, 457,
- /* 700 */ 453, 453, 25, 25, 24, 24, 24, 24, 331, 26,
+ /* 360 */ 305, 445, 445, 445, 156, 470, 218, 362, 365, 366,
+ /* 370 */ 333, 247, 397, 400, 217, 351, 333, 30, 367, 32,
+ /* 380 */ 134, 390, 282, 281, 39, 330, 41, 432, 547, 448,
+ /* 390 */ 454, 330, 214, 533, 437, 93, 544, 603, 1, 406,
+ /* 400 */ 437, 93, 415, 416, 497, 40, 538, 23, 22, 311,
+ /* 410 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24,
+ /* 420 */ 575, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 430 */ 29, 216, 305, 276, 333, 179, 510, 492, 210, 549,
+ /* 440 */ 322, 415, 416, 222, 192, 387, 323, 240, 417, 330,
+ /* 450 */ 559, 63, 415, 416, 417, 619, 410, 407, 437, 71,
+ /* 460 */ 417, 448, 454, 539, 574, 28, 28, 28, 29, 216,
+ /* 470 */ 418, 419, 438, 338, 465, 466, 403, 43, 438, 23,
+ /* 480 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24,
+ /* 490 */ 24, 24, 497, 26, 26, 26, 26, 27, 27, 28,
+ /* 500 */ 28, 28, 29, 216, 305, 429, 209, 135, 513, 418,
+ /* 510 */ 419, 433, 233, 64, 390, 282, 281, 441, 66, 544,
+ /* 520 */ 418, 419, 415, 416, 156, 214, 405, 362, 365, 366,
+ /* 530 */ 549, 252, 492, 448, 454, 493, 217, 8, 367, 497,
+ /* 540 */ 438, 608, 63, 208, 299, 417, 494, 472, 548, 200,
+ /* 550 */ 196, 23, 22, 311, 458, 459, 455, 455, 25, 25,
+ /* 560 */ 24, 24, 24, 24, 388, 26, 26, 26, 26, 27,
+ /* 570 */ 27, 28, 28, 28, 29, 216, 305, 479, 254, 356,
+ /* 580 */ 530, 60, 519, 520, 438, 441, 391, 333, 358, 7,
+ /* 590 */ 418, 419, 333, 480, 330, 374, 197, 137, 462, 501,
+ /* 600 */ 449, 450, 330, 437, 9, 448, 454, 330, 481, 487,
+ /* 610 */ 521, 437, 72, 569, 417, 436, 437, 67, 488, 435,
+ /* 620 */ 522, 452, 453, 23, 22, 311, 458, 459, 455, 455,
+ /* 630 */ 25, 25, 24, 24, 24, 24, 333, 26, 26, 26,
+ /* 640 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 333,
+ /* 650 */ 451, 330, 268, 392, 463, 333, 65, 333, 370, 436,
+ /* 660 */ 437, 76, 313, 435, 330, 150, 185, 441, 475, 333,
+ /* 670 */ 330, 501, 330, 437, 97, 29, 216, 448, 454, 437,
+ /* 680 */ 96, 437, 101, 355, 330, 242, 417, 336, 154, 461,
+ /* 690 */ 461, 354, 571, 437, 99, 23, 22, 311, 458, 459,
+ /* 700 */ 455, 455, 25, 25, 24, 24, 24, 24, 333, 26,
/* 710 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 720 */ 304, 331, 248, 328, 264, 56, 334, 331, 459, 459,
- /* 730 */ 861, 333, 435, 104, 376, 439, 328, 415, 331, 415,
- /* 740 */ 565, 331, 328, 306, 564, 435, 105, 185, 265, 446,
- /* 750 */ 452, 435, 126, 328, 570, 518, 328, 334, 377, 459,
- /* 760 */ 459, 314, 435, 128, 194, 435, 59, 23, 22, 308,
- /* 770 */ 456, 457, 453, 453, 25, 25, 24, 24, 24, 24,
- /* 780 */ 331, 26, 26, 26, 26, 27, 27, 28, 28, 28,
- /* 790 */ 29, 216, 304, 331, 136, 328, 242, 477, 436, 331,
- /* 800 */ 350, 331, 609, 303, 435, 102, 201, 137, 328, 415,
- /* 810 */ 454, 178, 331, 478, 328, 415, 328, 435, 77, 440,
- /* 820 */ 249, 446, 452, 435, 100, 435, 68, 328, 479, 465,
- /* 830 */ 341, 613, 931, 484, 931, 415, 435, 98, 467, 23,
- /* 840 */ 22, 308, 456, 457, 453, 453, 25, 25, 24, 24,
- /* 850 */ 24, 24, 331, 26, 26, 26, 26, 27, 27, 28,
- /* 860 */ 28, 28, 29, 216, 304, 331, 397, 328, 164, 264,
- /* 870 */ 205, 331, 264, 332, 610, 339, 435, 129, 407, 2,
- /* 880 */ 328, 322, 175, 331, 415, 214, 328, 415, 415, 435,
- /* 890 */ 130, 466, 466, 446, 452, 435, 131, 396, 328, 257,
- /* 900 */ 334, 487, 459, 459, 436, 154, 229, 435, 69, 315,
- /* 910 */ 258, 23, 33, 308, 456, 457, 453, 453, 25, 25,
- /* 920 */ 24, 24, 24, 24, 331, 26, 26, 26, 26, 27,
- /* 930 */ 27, 28, 28, 28, 29, 216, 304, 331, 497, 328,
- /* 940 */ 151, 264, 412, 331, 264, 470, 337, 200, 435, 80,
- /* 950 */ 250, 155, 328, 523, 524, 331, 415, 415, 328, 415,
- /* 960 */ 306, 435, 81, 533, 532, 446, 452, 435, 70, 47,
- /* 970 */ 328, 613, 930, 259, 930, 418, 419, 420, 316, 435,
- /* 980 */ 82, 317, 206, 539, 22, 308, 456, 457, 453, 453,
- /* 990 */ 25, 25, 24, 24, 24, 24, 331, 26, 26, 26,
- /* 1000 */ 26, 27, 27, 28, 28, 28, 29, 216, 304, 331,
- /* 1010 */ 209, 328, 529, 540, 610, 331, 436, 563, 375, 563,
- /* 1020 */ 435, 83, 362, 538, 328, 155, 541, 331, 499, 526,
- /* 1030 */ 328, 331, 575, 435, 84, 424, 543, 446, 452, 435,
- /* 1040 */ 86, 290, 328, 415, 436, 267, 328, 155, 394, 141,
- /* 1050 */ 415, 435, 87, 588, 411, 435, 88, 308, 456, 457,
- /* 1060 */ 453, 453, 25, 25, 24, 24, 24, 24, 386, 26,
+ /* 720 */ 305, 333, 248, 330, 264, 56, 336, 333, 461, 461,
+ /* 730 */ 864, 335, 437, 104, 378, 441, 330, 417, 333, 417,
+ /* 740 */ 567, 333, 330, 307, 566, 437, 105, 442, 265, 448,
+ /* 750 */ 454, 437, 126, 330, 572, 520, 330, 336, 379, 461,
+ /* 760 */ 461, 317, 437, 128, 194, 437, 59, 23, 22, 311,
+ /* 770 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24,
+ /* 780 */ 333, 26, 26, 26, 26, 27, 27, 28, 28, 28,
+ /* 790 */ 29, 216, 305, 333, 136, 330, 467, 479, 438, 333,
+ /* 800 */ 352, 333, 611, 303, 437, 102, 201, 137, 330, 417,
+ /* 810 */ 456, 178, 333, 480, 330, 417, 330, 437, 77, 486,
+ /* 820 */ 249, 448, 454, 437, 100, 437, 68, 330, 481, 469,
+ /* 830 */ 343, 616, 934, 341, 934, 417, 437, 98, 489, 23,
+ /* 840 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24,
+ /* 850 */ 24, 24, 333, 26, 26, 26, 26, 27, 27, 28,
+ /* 860 */ 28, 28, 29, 216, 305, 333, 399, 330, 164, 264,
+ /* 870 */ 205, 333, 264, 334, 612, 250, 437, 129, 409, 2,
+ /* 880 */ 330, 325, 175, 333, 417, 214, 330, 417, 417, 437,
+ /* 890 */ 130, 468, 468, 448, 454, 437, 131, 398, 330, 257,
+ /* 900 */ 336, 259, 461, 461, 438, 154, 229, 437, 69, 318,
+ /* 910 */ 258, 23, 33, 311, 458, 459, 455, 455, 25, 25,
+ /* 920 */ 24, 24, 24, 24, 333, 26, 26, 26, 26, 27,
+ /* 930 */ 27, 28, 28, 28, 29, 216, 305, 333, 155, 330,
+ /* 940 */ 531, 264, 414, 333, 264, 472, 339, 200, 437, 80,
+ /* 950 */ 542, 499, 330, 151, 541, 333, 417, 417, 330, 417,
+ /* 960 */ 307, 437, 81, 535, 534, 448, 454, 437, 70, 47,
+ /* 970 */ 330, 616, 933, 543, 933, 420, 421, 422, 319, 437,
+ /* 980 */ 82, 320, 304, 613, 22, 311, 458, 459, 455, 455,
+ /* 990 */ 25, 25, 24, 24, 24, 24, 333, 26, 26, 26,
+ /* 1000 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 333,
+ /* 1010 */ 209, 330, 364, 206, 612, 333, 528, 565, 377, 565,
+ /* 1020 */ 437, 83, 525, 526, 330, 615, 545, 333, 501, 577,
+ /* 1030 */ 330, 333, 290, 437, 84, 426, 396, 448, 454, 437,
+ /* 1040 */ 86, 590, 330, 417, 438, 141, 330, 438, 413, 423,
+ /* 1050 */ 417, 437, 87, 424, 327, 437, 88, 311, 458, 459,
+ /* 1060 */ 455, 455, 25, 25, 24, 24, 24, 24, 388, 26,
/* 1070 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216,
- /* 1080 */ 35, 338, 286, 3, 331, 270, 331, 327, 414, 421,
- /* 1090 */ 382, 318, 276, 422, 325, 35, 338, 335, 3, 328,
- /* 1100 */ 423, 328, 327, 414, 142, 144, 276, 415, 435, 73,
- /* 1110 */ 435, 74, 335, 331, 6, 340, 425, 331, 326, 331,
- /* 1120 */ 367, 415, 155, 437, 289, 472, 287, 274, 328, 272,
- /* 1130 */ 340, 415, 328, 47, 328, 277, 276, 435, 89, 348,
- /* 1140 */ 472, 435, 90, 435, 91, 38, 37, 243, 331, 582,
- /* 1150 */ 244, 415, 426, 276, 36, 329, 330, 46, 245, 441,
- /* 1160 */ 38, 37, 505, 328, 202, 203, 204, 415, 415, 36,
- /* 1170 */ 329, 330, 435, 92, 441, 198, 568, 214, 155, 584,
- /* 1180 */ 235, 236, 237, 143, 239, 346, 133, 581, 438, 246,
- /* 1190 */ 443, 443, 443, 444, 445, 10, 585, 276, 20, 42,
- /* 1200 */ 172, 415, 294, 331, 288, 443, 443, 443, 444, 445,
- /* 1210 */ 10, 295, 415, 35, 338, 219, 3, 149, 328, 482,
- /* 1220 */ 327, 414, 331, 170, 276, 572, 48, 435, 75, 169,
- /* 1230 */ 335, 19, 171, 251, 442, 413, 414, 328, 331, 415,
- /* 1240 */ 586, 343, 276, 177, 351, 496, 435, 17, 340, 415,
- /* 1250 */ 481, 253, 255, 328, 276, 502, 415, 415, 472, 331,
- /* 1260 */ 503, 357, 435, 94, 576, 415, 151, 231, 312, 415,
- /* 1270 */ 577, 516, 54, 472, 328, 393, 291, 281, 38, 37,
- /* 1280 */ 494, 305, 521, 435, 95, 232, 214, 36, 329, 330,
- /* 1290 */ 526, 498, 441, 188, 189, 415, 500, 292, 522, 262,
- /* 1300 */ 530, 260, 263, 513, 549, 269, 415, 441, 589, 400,
- /* 1310 */ 54, 415, 525, 527, 415, 415, 271, 415, 273, 415,
- /* 1320 */ 415, 275, 280, 443, 443, 443, 444, 445, 10, 107,
- /* 1330 */ 380, 415, 383, 415, 384, 283, 415, 415, 443, 443,
- /* 1340 */ 443, 284, 285, 580, 300, 415, 591, 415, 293, 415,
- /* 1350 */ 415, 296, 297, 605, 226, 550, 415, 415, 415, 225,
- /* 1360 */ 608, 415, 302, 415, 551, 227, 415, 415, 415, 301,
- /* 1370 */ 544, 552, 369, 158, 373, 558, 159, 278, 371, 160,
- /* 1380 */ 51, 207, 560, 561, 161, 140, 379, 117, 571, 163,
- /* 1390 */ 391, 392, 181, 180, 321, 602, 578, 118, 119, 120,
- /* 1400 */ 121, 123, 55, 587, 58, 603, 604, 607, 62, 174,
- /* 1410 */ 103, 224, 111, 409, 238, 428, 199, 323, 657, 658,
- /* 1420 */ 659, 146, 147, 455, 458, 34, 474, 462, 471, 182,
- /* 1430 */ 195, 148, 475, 476, 480, 5, 12, 493, 44, 11,
- /* 1440 */ 106, 138, 509, 510, 501, 223, 49, 361, 108, 109,
- /* 1450 */ 152, 266, 50, 110, 157, 258, 370, 184, 559, 139,
- /* 1460 */ 151, 113, 279, 162, 115, 374, 15, 574, 116, 165,
- /* 1470 */ 52, 13, 366, 579, 53, 167, 168, 166, 583, 124,
- /* 1480 */ 114, 122, 562, 566, 14, 61, 599, 600, 125, 173,
- /* 1490 */ 298, 590, 187, 406, 941, 614, 941, 402,
+ /* 1080 */ 35, 340, 286, 3, 333, 270, 333, 329, 416, 142,
+ /* 1090 */ 384, 321, 276, 425, 144, 35, 340, 337, 3, 330,
+ /* 1100 */ 6, 330, 329, 416, 304, 614, 276, 417, 437, 73,
+ /* 1110 */ 437, 74, 337, 333, 328, 342, 427, 333, 439, 333,
+ /* 1120 */ 540, 417, 155, 47, 289, 474, 287, 274, 330, 272,
+ /* 1130 */ 342, 417, 330, 350, 330, 277, 276, 437, 89, 243,
+ /* 1140 */ 474, 437, 90, 437, 91, 38, 37, 615, 333, 584,
+ /* 1150 */ 244, 417, 428, 276, 36, 331, 332, 46, 245, 443,
+ /* 1160 */ 38, 37, 507, 330, 202, 203, 204, 417, 417, 36,
+ /* 1170 */ 331, 332, 437, 92, 443, 198, 267, 214, 155, 586,
+ /* 1180 */ 235, 236, 237, 143, 239, 348, 133, 583, 440, 246,
+ /* 1190 */ 445, 445, 445, 446, 447, 10, 587, 276, 20, 42,
+ /* 1200 */ 172, 417, 294, 333, 288, 445, 445, 445, 446, 447,
+ /* 1210 */ 10, 295, 417, 35, 340, 219, 3, 149, 330, 484,
+ /* 1220 */ 329, 416, 333, 170, 276, 574, 48, 437, 75, 169,
+ /* 1230 */ 337, 19, 171, 251, 444, 415, 416, 330, 333, 417,
+ /* 1240 */ 588, 345, 276, 177, 353, 498, 437, 17, 342, 417,
+ /* 1250 */ 483, 253, 255, 330, 276, 496, 417, 417, 474, 333,
+ /* 1260 */ 504, 505, 437, 94, 369, 417, 155, 231, 359, 417,
+ /* 1270 */ 417, 518, 523, 474, 330, 395, 291, 281, 38, 37,
+ /* 1280 */ 500, 306, 315, 437, 95, 232, 214, 36, 331, 332,
+ /* 1290 */ 524, 502, 443, 188, 189, 417, 262, 292, 532, 263,
+ /* 1300 */ 551, 260, 269, 515, 271, 273, 417, 443, 570, 402,
+ /* 1310 */ 155, 417, 527, 417, 417, 417, 275, 417, 280, 417,
+ /* 1320 */ 417, 382, 385, 445, 445, 445, 446, 447, 10, 528,
+ /* 1330 */ 386, 417, 283, 417, 284, 285, 417, 417, 445, 445,
+ /* 1340 */ 445, 582, 593, 293, 107, 417, 296, 417, 297, 417,
+ /* 1350 */ 417, 607, 578, 529, 151, 300, 417, 417, 417, 226,
+ /* 1360 */ 579, 417, 54, 417, 158, 591, 417, 54, 225, 610,
+ /* 1370 */ 227, 302, 546, 552, 301, 553, 554, 371, 560, 159,
+ /* 1380 */ 375, 373, 207, 160, 51, 562, 563, 161, 117, 278,
+ /* 1390 */ 381, 140, 573, 163, 181, 393, 394, 118, 119, 120,
+ /* 1400 */ 180, 580, 121, 123, 324, 605, 604, 606, 55, 609,
+ /* 1410 */ 589, 309, 224, 62, 58, 103, 411, 111, 238, 430,
+ /* 1420 */ 199, 174, 660, 661, 662, 146, 147, 460, 310, 457,
+ /* 1430 */ 34, 476, 464, 473, 182, 195, 148, 477, 5, 478,
+ /* 1440 */ 482, 12, 138, 44, 11, 106, 495, 511, 512, 503,
+ /* 1450 */ 223, 49, 363, 108, 109, 152, 266, 50, 110, 157,
+ /* 1460 */ 258, 372, 184, 561, 139, 113, 151, 162, 279, 115,
+ /* 1470 */ 376, 15, 576, 116, 165, 52, 13, 368, 581, 53,
+ /* 1480 */ 167, 166, 585, 122, 124, 114, 592, 564, 568, 168,
+ /* 1490 */ 14, 61, 601, 602, 173, 298, 125, 408, 187, 617,
+ /* 1500 */ 945, 945, 404,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 19, 142, 143, 144, 145, 24, 116, 26, 75, 76,
@@ -85430,75 +86745,75 @@ static const YYCODETYPE yy_lookahead[] = {
/* 430 */ 89, 90, 19, 150, 150, 23, 23, 25, 160, 150,
/* 440 */ 220, 26, 27, 205, 160, 150, 220, 158, 165, 165,
/* 450 */ 161, 162, 26, 27, 165, 0, 1, 2, 174, 175,
- /* 460 */ 165, 48, 49, 23, 55, 86, 87, 88, 89, 90,
+ /* 460 */ 165, 48, 49, 183, 55, 86, 87, 88, 89, 90,
/* 470 */ 94, 95, 194, 169, 170, 171, 193, 136, 194, 66,
/* 480 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 490 */ 77, 78, 166, 80, 81, 82, 83, 84, 85, 86,
- /* 500 */ 87, 88, 89, 90, 19, 65, 160, 95, 23, 94,
+ /* 500 */ 87, 88, 89, 90, 19, 153, 160, 95, 23, 94,
/* 510 */ 95, 173, 217, 22, 105, 106, 107, 26, 22, 181,
/* 520 */ 94, 95, 26, 27, 96, 116, 243, 99, 100, 101,
/* 530 */ 150, 205, 120, 48, 49, 120, 232, 22, 110, 166,
- /* 540 */ 194, 161, 162, 183, 163, 165, 120, 166, 167, 168,
+ /* 540 */ 194, 161, 162, 236, 163, 165, 120, 166, 167, 168,
/* 550 */ 160, 66, 67, 68, 69, 70, 71, 72, 73, 74,
/* 560 */ 75, 76, 77, 78, 218, 80, 81, 82, 83, 84,
/* 570 */ 85, 86, 87, 88, 89, 90, 19, 12, 205, 150,
/* 580 */ 23, 235, 190, 191, 194, 94, 240, 150, 86, 74,
- /* 590 */ 94, 95, 150, 28, 165, 236, 206, 207, 23, 150,
+ /* 590 */ 94, 95, 150, 28, 165, 237, 206, 207, 23, 150,
/* 600 */ 48, 49, 165, 174, 175, 48, 49, 165, 43, 31,
/* 610 */ 45, 174, 175, 21, 165, 113, 174, 175, 40, 117,
/* 620 */ 55, 69, 70, 66, 67, 68, 69, 70, 71, 72,
/* 630 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
/* 640 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
/* 650 */ 98, 165, 23, 61, 23, 150, 25, 150, 19, 113,
- /* 660 */ 174, 175, 213, 117, 165, 24, 153, 26, 23, 150,
+ /* 660 */ 174, 175, 213, 117, 165, 24, 196, 26, 23, 150,
/* 670 */ 165, 150, 165, 174, 175, 89, 90, 48, 49, 174,
- /* 680 */ 175, 174, 175, 19, 165, 237, 165, 112, 49, 114,
+ /* 680 */ 175, 174, 175, 19, 165, 198, 165, 112, 49, 114,
/* 690 */ 115, 27, 100, 174, 175, 66, 67, 68, 69, 70,
/* 700 */ 71, 72, 73, 74, 75, 76, 77, 78, 150, 80,
/* 710 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 720 */ 19, 150, 150, 165, 150, 24, 112, 150, 114, 115,
/* 730 */ 138, 19, 174, 175, 213, 94, 165, 165, 150, 165,
- /* 740 */ 29, 150, 165, 104, 33, 174, 175, 196, 109, 48,
+ /* 740 */ 29, 150, 165, 104, 33, 174, 175, 166, 109, 48,
/* 750 */ 49, 174, 175, 165, 190, 191, 165, 112, 47, 114,
/* 760 */ 115, 187, 174, 175, 160, 174, 175, 66, 67, 68,
/* 770 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 780 */ 150, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 790 */ 89, 90, 19, 150, 150, 165, 198, 12, 194, 150,
+ /* 790 */ 89, 90, 19, 150, 150, 165, 233, 12, 194, 150,
/* 800 */ 150, 150, 248, 249, 174, 175, 206, 207, 165, 165,
- /* 810 */ 98, 23, 150, 28, 165, 165, 165, 174, 175, 166,
+ /* 810 */ 98, 23, 150, 28, 165, 165, 165, 174, 175, 177,
/* 820 */ 150, 48, 49, 174, 175, 174, 175, 165, 43, 233,
- /* 830 */ 45, 22, 23, 177, 25, 165, 174, 175, 233, 66,
+ /* 830 */ 45, 22, 23, 228, 25, 165, 174, 175, 177, 66,
/* 840 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 850 */ 77, 78, 150, 80, 81, 82, 83, 84, 85, 86,
/* 860 */ 87, 88, 89, 90, 19, 150, 97, 165, 25, 150,
- /* 870 */ 160, 150, 150, 150, 65, 228, 174, 175, 144, 145,
+ /* 870 */ 160, 150, 150, 150, 65, 209, 174, 175, 144, 145,
/* 880 */ 165, 246, 247, 150, 165, 116, 165, 165, 165, 174,
/* 890 */ 175, 129, 130, 48, 49, 174, 175, 128, 165, 98,
/* 900 */ 112, 177, 114, 115, 194, 49, 187, 174, 175, 187,
/* 910 */ 109, 66, 67, 68, 69, 70, 71, 72, 73, 74,
/* 920 */ 75, 76, 77, 78, 150, 80, 81, 82, 83, 84,
- /* 930 */ 85, 86, 87, 88, 89, 90, 19, 150, 23, 165,
- /* 940 */ 25, 150, 150, 150, 150, 166, 167, 168, 174, 175,
- /* 950 */ 209, 25, 165, 7, 8, 150, 165, 165, 165, 165,
+ /* 930 */ 85, 86, 87, 88, 89, 90, 19, 150, 25, 165,
+ /* 940 */ 182, 150, 150, 150, 150, 166, 167, 168, 174, 175,
+ /* 950 */ 166, 23, 165, 25, 177, 150, 165, 165, 165, 165,
/* 960 */ 104, 174, 175, 97, 98, 48, 49, 174, 175, 126,
/* 970 */ 165, 22, 23, 177, 25, 7, 8, 9, 187, 174,
- /* 980 */ 175, 187, 160, 177, 67, 68, 69, 70, 71, 72,
+ /* 980 */ 175, 187, 22, 23, 67, 68, 69, 70, 71, 72,
/* 990 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82,
/* 1000 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150,
- /* 1010 */ 160, 165, 182, 166, 65, 150, 194, 105, 106, 107,
- /* 1020 */ 174, 175, 178, 23, 165, 25, 177, 150, 150, 103,
- /* 1030 */ 165, 150, 199, 174, 175, 150, 166, 48, 49, 174,
- /* 1040 */ 175, 209, 165, 165, 194, 23, 165, 25, 209, 6,
- /* 1050 */ 165, 174, 175, 199, 149, 174, 175, 68, 69, 70,
+ /* 1010 */ 160, 165, 178, 160, 65, 150, 103, 105, 106, 107,
+ /* 1020 */ 174, 175, 7, 8, 165, 65, 166, 150, 150, 199,
+ /* 1030 */ 165, 150, 209, 174, 175, 150, 209, 48, 49, 174,
+ /* 1040 */ 175, 199, 165, 165, 194, 6, 165, 194, 149, 149,
+ /* 1050 */ 165, 174, 175, 149, 149, 174, 175, 68, 69, 70,
/* 1060 */ 71, 72, 73, 74, 75, 76, 77, 78, 218, 80,
/* 1070 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
- /* 1080 */ 19, 20, 16, 22, 150, 16, 150, 26, 27, 149,
- /* 1090 */ 240, 213, 150, 149, 149, 19, 20, 36, 22, 165,
- /* 1100 */ 13, 165, 26, 27, 151, 151, 150, 165, 174, 175,
- /* 1110 */ 174, 175, 36, 150, 25, 54, 150, 150, 159, 150,
- /* 1120 */ 23, 165, 25, 194, 58, 64, 60, 58, 165, 60,
- /* 1130 */ 54, 165, 165, 126, 165, 193, 150, 174, 175, 123,
- /* 1140 */ 64, 174, 175, 174, 175, 84, 85, 199, 150, 193,
+ /* 1080 */ 19, 20, 16, 22, 150, 16, 150, 26, 27, 151,
+ /* 1090 */ 240, 213, 150, 13, 151, 19, 20, 36, 22, 165,
+ /* 1100 */ 25, 165, 26, 27, 22, 23, 150, 165, 174, 175,
+ /* 1110 */ 174, 175, 36, 150, 159, 54, 150, 150, 194, 150,
+ /* 1120 */ 23, 165, 25, 126, 58, 64, 60, 58, 165, 60,
+ /* 1130 */ 54, 165, 165, 123, 165, 193, 150, 174, 175, 199,
+ /* 1140 */ 64, 174, 175, 174, 175, 84, 85, 65, 150, 193,
/* 1150 */ 200, 165, 150, 150, 93, 94, 95, 124, 201, 98,
/* 1160 */ 84, 85, 86, 165, 105, 106, 107, 165, 165, 93,
/* 1170 */ 94, 95, 174, 175, 98, 5, 23, 116, 25, 193,
@@ -85509,34 +86824,35 @@ static const YYCODETYPE yy_lookahead[] = {
/* 1220 */ 26, 27, 150, 53, 150, 55, 104, 174, 175, 59,
/* 1230 */ 36, 22, 62, 210, 150, 26, 27, 165, 150, 165,
/* 1240 */ 193, 150, 150, 157, 121, 211, 174, 175, 54, 165,
- /* 1250 */ 150, 210, 210, 165, 150, 211, 165, 165, 64, 150,
- /* 1260 */ 211, 104, 174, 175, 23, 165, 25, 193, 46, 165,
- /* 1270 */ 23, 176, 25, 64, 165, 105, 106, 107, 84, 85,
- /* 1280 */ 150, 111, 176, 174, 175, 193, 116, 93, 94, 95,
- /* 1290 */ 103, 150, 98, 84, 85, 165, 150, 193, 184, 150,
+ /* 1250 */ 150, 210, 210, 165, 150, 150, 165, 165, 64, 150,
+ /* 1260 */ 211, 211, 174, 175, 23, 165, 25, 193, 104, 165,
+ /* 1270 */ 165, 176, 176, 64, 165, 105, 106, 107, 84, 85,
+ /* 1280 */ 150, 111, 46, 174, 175, 193, 116, 93, 94, 95,
+ /* 1290 */ 184, 150, 98, 84, 85, 165, 150, 193, 150, 150,
/* 1300 */ 150, 176, 150, 94, 150, 150, 165, 98, 23, 139,
- /* 1310 */ 25, 165, 178, 176, 165, 165, 150, 165, 150, 165,
- /* 1320 */ 165, 150, 150, 129, 130, 131, 132, 133, 134, 22,
+ /* 1310 */ 25, 165, 178, 165, 165, 165, 150, 165, 150, 165,
+ /* 1320 */ 165, 150, 150, 129, 130, 131, 132, 133, 134, 103,
/* 1330 */ 150, 165, 150, 165, 150, 150, 165, 165, 129, 130,
- /* 1340 */ 131, 150, 150, 150, 179, 165, 150, 165, 150, 165,
- /* 1350 */ 165, 150, 150, 150, 90, 176, 165, 165, 165, 230,
- /* 1360 */ 23, 165, 25, 165, 176, 230, 165, 165, 165, 179,
- /* 1370 */ 184, 176, 18, 156, 44, 157, 156, 238, 157, 156,
- /* 1380 */ 135, 157, 157, 239, 156, 66, 157, 22, 189, 189,
- /* 1390 */ 157, 18, 219, 219, 157, 39, 199, 192, 192, 192,
- /* 1400 */ 192, 189, 241, 199, 241, 157, 157, 37, 244, 247,
- /* 1410 */ 164, 180, 180, 1, 15, 23, 22, 250, 118, 118,
- /* 1420 */ 118, 118, 118, 98, 113, 22, 11, 23, 23, 22,
- /* 1430 */ 22, 25, 23, 23, 23, 34, 34, 120, 25, 25,
- /* 1440 */ 22, 118, 23, 23, 27, 50, 22, 50, 22, 22,
- /* 1450 */ 34, 23, 22, 22, 102, 109, 19, 24, 20, 38,
- /* 1460 */ 25, 104, 138, 104, 22, 42, 5, 1, 108, 127,
- /* 1470 */ 74, 22, 50, 1, 74, 16, 121, 119, 20, 108,
- /* 1480 */ 51, 119, 57, 51, 22, 16, 23, 23, 127, 15,
- /* 1490 */ 140, 128, 22, 3, 251, 4, 251, 63,
+ /* 1340 */ 131, 150, 150, 150, 22, 165, 150, 165, 150, 165,
+ /* 1350 */ 165, 150, 23, 176, 25, 179, 165, 165, 165, 90,
+ /* 1360 */ 23, 165, 25, 165, 156, 23, 165, 25, 230, 23,
+ /* 1370 */ 230, 25, 184, 176, 179, 176, 176, 18, 157, 156,
+ /* 1380 */ 44, 157, 157, 156, 135, 157, 239, 156, 22, 238,
+ /* 1390 */ 157, 66, 189, 189, 219, 157, 18, 192, 192, 192,
+ /* 1400 */ 219, 199, 192, 189, 157, 157, 39, 157, 241, 37,
+ /* 1410 */ 199, 250, 180, 244, 241, 164, 1, 180, 15, 23,
+ /* 1420 */ 22, 247, 118, 118, 118, 118, 118, 113, 250, 98,
+ /* 1430 */ 22, 11, 23, 23, 22, 22, 25, 23, 34, 23,
+ /* 1440 */ 23, 34, 118, 25, 25, 22, 120, 23, 23, 27,
+ /* 1450 */ 50, 22, 50, 22, 22, 34, 23, 22, 22, 102,
+ /* 1460 */ 109, 19, 24, 20, 38, 104, 25, 104, 138, 22,
+ /* 1470 */ 42, 5, 1, 108, 127, 74, 22, 50, 1, 74,
+ /* 1480 */ 16, 119, 20, 119, 108, 51, 128, 57, 51, 121,
+ /* 1490 */ 22, 16, 23, 23, 15, 140, 127, 3, 22, 4,
+ /* 1500 */ 251, 251, 63,
};
#define YY_SHIFT_USE_DFLT (-111)
-#define YY_SHIFT_MAX 406
+#define YY_SHIFT_MAX 408
static const short yy_shift_ofst[] = {
/* 0 */ 187, 1061, 1170, 1061, 1194, 1194, -2, 64, 64, -19,
/* 10 */ 1194, 1194, 1194, 1194, 1194, 276, 1, 125, 1076, 1194,
@@ -85560,28 +86876,28 @@ static const short yy_shift_ofst[] = {
/* 190 */ 268, 428, 213, 575, 645, 785, 788, 412, 968, 502,
/* 200 */ 491, 52, 183, 183, 183, 614, 614, 711, 912, 614,
/* 210 */ 614, 614, 614, 229, 546, -13, 141, 762, 762, 249,
- /* 220 */ 578, 578, 664, 578, 856, 578, 141, 578, 141, 926,
- /* 230 */ 843, 664, 664, 843, 1043, 1043, 1043, 1043, 1087, 1087,
- /* 240 */ 1089, -110, 1007, 1016, 1033, 1063, 1073, 1064, 1099, 1099,
- /* 250 */ 1122, 1123, 1122, 1123, 1122, 1123, 1157, 1157, 1222, 1157,
- /* 260 */ 1187, 1157, 1307, 1264, 1264, 1222, 1157, 1157, 1157, 1307,
- /* 270 */ 1354, 1099, 1354, 1099, 1354, 1099, 1099, 1330, 1245, 1354,
- /* 280 */ 1099, 1319, 1319, 1365, 1007, 1099, 1373, 1373, 1373, 1373,
- /* 290 */ 1007, 1319, 1365, 1099, 1356, 1356, 1099, 1099, 1370, -111,
- /* 300 */ -111, -111, -111, -111, 552, 1066, 1059, 1069, 712, 631,
- /* 310 */ 915, 801, 946, 866, 1000, 1022, 1097, 1153, 1241, 1247,
- /* 320 */ 1285, 515, 1337, 440, 1412, 1399, 1392, 1394, 1300, 1301,
- /* 330 */ 1302, 1303, 1304, 1325, 1311, 1403, 1404, 1405, 1407, 1415,
- /* 340 */ 1408, 1409, 1406, 1410, 1411, 1413, 1401, 1414, 1402, 1413,
- /* 350 */ 1317, 1418, 1416, 1417, 1323, 1419, 1420, 1421, 1395, 1424,
- /* 360 */ 1397, 1426, 1428, 1427, 1430, 1422, 1431, 1352, 1346, 1437,
- /* 370 */ 1438, 1433, 1357, 1423, 1425, 1429, 1435, 1432, 1324, 1359,
- /* 380 */ 1442, 1461, 1466, 1360, 1396, 1400, 1342, 1449, 1358, 1472,
- /* 390 */ 1459, 1355, 1458, 1362, 1371, 1361, 1462, 1363, 1463, 1464,
- /* 400 */ 1469, 1434, 1474, 1350, 1470, 1490, 1491,
+ /* 220 */ 578, 578, 664, 578, 856, 578, 141, 578, 141, 913,
+ /* 230 */ 843, 664, 664, 843, 1039, 1039, 1039, 1039, 1080, 1080,
+ /* 240 */ 1075, -110, 997, 1010, 1033, 1063, 1073, 1064, 1099, 1099,
+ /* 250 */ 1122, 1123, 1122, 1123, 1122, 1123, 1164, 1164, 1236, 1164,
+ /* 260 */ 1226, 1164, 1322, 1269, 1269, 1236, 1164, 1164, 1164, 1322,
+ /* 270 */ 1359, 1099, 1359, 1099, 1359, 1099, 1099, 1336, 1249, 1359,
+ /* 280 */ 1099, 1325, 1325, 1366, 997, 1099, 1378, 1378, 1378, 1378,
+ /* 290 */ 997, 1325, 1366, 1099, 1367, 1367, 1099, 1099, 1372, -111,
+ /* 300 */ -111, -111, -111, -111, -111, 552, 1066, 1059, 1069, 960,
+ /* 310 */ 1082, 712, 631, 928, 801, 1015, 866, 1097, 1153, 1241,
+ /* 320 */ 1285, 1329, 1337, 1342, 515, 1346, 1415, 1403, 1396, 1398,
+ /* 330 */ 1304, 1305, 1306, 1307, 1308, 1331, 1314, 1408, 1409, 1410,
+ /* 340 */ 1412, 1420, 1413, 1414, 1411, 1416, 1417, 1418, 1404, 1419,
+ /* 350 */ 1407, 1418, 1326, 1423, 1421, 1422, 1324, 1424, 1425, 1426,
+ /* 360 */ 1400, 1429, 1402, 1431, 1433, 1432, 1435, 1427, 1436, 1357,
+ /* 370 */ 1351, 1442, 1443, 1438, 1361, 1428, 1430, 1434, 1441, 1437,
+ /* 380 */ 1330, 1363, 1447, 1466, 1471, 1365, 1401, 1405, 1347, 1454,
+ /* 390 */ 1362, 1477, 1464, 1368, 1462, 1364, 1376, 1369, 1468, 1358,
+ /* 400 */ 1469, 1470, 1475, 1439, 1479, 1355, 1476, 1494, 1495,
};
#define YY_REDUCE_USE_DFLT (-180)
-#define YY_REDUCE_MAX 303
+#define YY_REDUCE_MAX 304
static const short yy_reduce_ofst[] = {
/* 0 */ -141, 82, 154, 284, 12, 75, 69, 73, 142, -59,
/* 10 */ 145, 87, 159, 220, 226, 346, 289, 155, 429, 437,
@@ -85598,86 +86914,86 @@ static const short yy_reduce_ofst[] = {
/* 120 */ 1003, 1047, 1074, 1092, 295, 1104, 2, 779, 2, 2,
/* 130 */ 2, 2, 158, 338, 572, 644, 650, 670, 723, 392,
/* 140 */ 564, 792, 885, 966, 1002, 1036, 723, 1084, 1091, 1100,
- /* 150 */ 1130, 1141, 1146, 1149, 1150, 1152, 1154, 1155, 1166, 1168,
- /* 160 */ 1171, 1172, 1180, 1182, 1184, 1185, 1191, 1192, 1193, 1196,
- /* 170 */ 1198, 1201, 1202, 1203, 554, 554, 734, 238, 326, 373,
- /* 180 */ -134, 278, 604, 710, 822, 44, 600, 635, -98, -70,
+ /* 150 */ 1105, 1130, 1141, 1146, 1148, 1149, 1150, 1152, 1154, 1155,
+ /* 160 */ 1166, 1168, 1171, 1172, 1180, 1182, 1184, 1185, 1191, 1192,
+ /* 170 */ 1193, 1196, 1198, 1201, 554, 554, 734, 238, 326, 373,
+ /* 180 */ -134, 278, 604, 710, 853, 44, 600, 635, -98, -70,
/* 190 */ -54, -36, -35, -35, -35, 13, -35, 14, 149, 115,
- /* 200 */ 163, 14, 210, 223, 360, -35, -35, 359, 448, -35,
- /* 210 */ -35, -35, -35, 513, 551, 598, 653, 596, 605, 647,
- /* 220 */ 656, 724, 741, 796, 830, 806, 847, 849, 870, 844,
- /* 230 */ 833, 832, 839, 854, 905, 940, 944, 945, 953, 954,
- /* 240 */ 959, 929, 948, 950, 957, 987, 985, 988, 1062, 1086,
- /* 250 */ 1023, 1034, 1041, 1044, 1042, 1049, 1095, 1106, 1114, 1125,
- /* 260 */ 1134, 1137, 1165, 1129, 1135, 1186, 1179, 1188, 1195, 1190,
- /* 270 */ 1217, 1218, 1220, 1221, 1223, 1224, 1225, 1139, 1144, 1228,
- /* 280 */ 1229, 1199, 1200, 1173, 1197, 1233, 1205, 1206, 1207, 1208,
- /* 290 */ 1204, 1212, 1174, 1237, 1161, 1163, 1248, 1249, 1164, 1246,
- /* 300 */ 1231, 1232, 1162, 1167,
+ /* 200 */ 163, 14, 210, 223, 280, -35, -35, 307, 358, -35,
+ /* 210 */ -35, -35, -35, 352, 470, 487, 581, 563, 596, 605,
+ /* 220 */ 642, 661, 666, 724, 758, 777, 784, 796, 860, 834,
+ /* 230 */ 830, 823, 827, 842, 899, 900, 904, 905, 938, 943,
+ /* 240 */ 955, 924, 940, 950, 957, 987, 985, 988, 1062, 1086,
+ /* 250 */ 1023, 1034, 1041, 1049, 1042, 1050, 1095, 1096, 1106, 1125,
+ /* 260 */ 1134, 1177, 1176, 1138, 1140, 1188, 1197, 1199, 1200, 1195,
+ /* 270 */ 1208, 1221, 1223, 1224, 1227, 1225, 1228, 1151, 1147, 1231,
+ /* 280 */ 1233, 1203, 1204, 1175, 1202, 1238, 1205, 1206, 1207, 1210,
+ /* 290 */ 1211, 1214, 1181, 1247, 1167, 1173, 1248, 1250, 1169, 1251,
+ /* 300 */ 1232, 1237, 1174, 1161, 1178,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 621, 856, 939, 939, 856, 939, 939, 885, 885, 744,
- /* 10 */ 854, 939, 939, 939, 939, 939, 939, 914, 939, 939,
- /* 20 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 30 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 40 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 50 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 828,
- /* 60 */ 939, 939, 939, 660, 885, 885, 748, 779, 939, 939,
- /* 70 */ 939, 939, 939, 939, 939, 939, 780, 939, 858, 853,
- /* 80 */ 849, 851, 850, 857, 781, 770, 777, 784, 759, 898,
- /* 90 */ 786, 787, 793, 794, 915, 913, 816, 815, 834, 818,
- /* 100 */ 840, 817, 827, 652, 819, 820, 939, 939, 939, 939,
- /* 110 */ 939, 713, 647, 939, 939, 939, 939, 939, 939, 939,
- /* 120 */ 939, 939, 939, 939, 939, 939, 821, 939, 822, 835,
- /* 130 */ 836, 837, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 140 */ 939, 627, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 150 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 160 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 869,
- /* 170 */ 939, 918, 920, 939, 939, 939, 621, 744, 744, 744,
- /* 180 */ 939, 939, 939, 939, 939, 738, 748, 932, 939, 939,
- /* 190 */ 704, 939, 939, 939, 939, 939, 939, 939, 629, 736,
- /* 200 */ 662, 746, 939, 939, 939, 649, 725, 891, 939, 905,
- /* 210 */ 903, 727, 789, 939, 736, 745, 939, 939, 939, 852,
- /* 220 */ 773, 773, 761, 773, 683, 773, 939, 773, 939, 686,
- /* 230 */ 783, 761, 761, 783, 626, 626, 626, 626, 637, 637,
- /* 240 */ 703, 939, 783, 774, 776, 766, 778, 939, 752, 752,
- /* 250 */ 760, 765, 760, 765, 760, 765, 715, 715, 700, 715,
- /* 260 */ 686, 715, 862, 866, 866, 700, 715, 715, 715, 862,
- /* 270 */ 644, 752, 644, 752, 644, 752, 752, 895, 897, 644,
- /* 280 */ 752, 717, 717, 795, 783, 752, 724, 724, 724, 724,
- /* 290 */ 783, 717, 795, 752, 917, 917, 752, 752, 925, 670,
- /* 300 */ 688, 688, 932, 937, 939, 939, 939, 939, 939, 939,
- /* 310 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 320 */ 939, 871, 939, 939, 939, 635, 939, 654, 802, 807,
- /* 330 */ 803, 939, 804, 939, 730, 939, 939, 939, 939, 939,
- /* 340 */ 939, 939, 939, 939, 939, 855, 939, 767, 939, 775,
- /* 350 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 360 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 370 */ 939, 939, 939, 939, 939, 893, 894, 939, 939, 939,
- /* 380 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 390 */ 939, 939, 939, 939, 939, 939, 939, 939, 939, 939,
- /* 400 */ 939, 924, 939, 939, 927, 622, 939, 617, 619, 620,
- /* 410 */ 624, 625, 628, 654, 655, 657, 658, 659, 630, 631,
- /* 420 */ 632, 633, 634, 636, 640, 638, 639, 641, 648, 650,
- /* 430 */ 669, 671, 673, 734, 735, 799, 728, 729, 733, 656,
- /* 440 */ 810, 801, 805, 806, 808, 809, 823, 824, 826, 832,
- /* 450 */ 839, 842, 825, 830, 831, 833, 838, 841, 731, 732,
- /* 460 */ 845, 663, 664, 667, 668, 881, 883, 882, 884, 666,
- /* 470 */ 665, 811, 814, 847, 848, 906, 907, 908, 909, 910,
- /* 480 */ 843, 753, 846, 829, 768, 771, 772, 769, 737, 747,
- /* 490 */ 755, 756, 757, 758, 742, 743, 749, 764, 797, 798,
- /* 500 */ 762, 763, 750, 751, 739, 740, 741, 844, 800, 812,
- /* 510 */ 813, 674, 675, 807, 676, 677, 678, 716, 719, 720,
- /* 520 */ 721, 679, 698, 701, 702, 680, 687, 681, 682, 689,
- /* 530 */ 690, 691, 694, 695, 696, 697, 692, 693, 863, 864,
- /* 540 */ 867, 865, 684, 685, 699, 672, 661, 653, 705, 708,
- /* 550 */ 709, 710, 711, 712, 714, 706, 707, 651, 642, 645,
- /* 560 */ 754, 887, 896, 892, 888, 889, 890, 646, 859, 860,
- /* 570 */ 718, 791, 792, 886, 899, 901, 796, 902, 904, 900,
- /* 580 */ 929, 643, 722, 723, 726, 868, 911, 782, 785, 788,
- /* 590 */ 790, 870, 872, 874, 876, 877, 878, 879, 880, 873,
- /* 600 */ 875, 912, 916, 919, 921, 922, 923, 926, 928, 933,
- /* 610 */ 934, 935, 938, 936, 623, 618,
+ /* 0 */ 624, 859, 943, 943, 859, 943, 943, 888, 888, 747,
+ /* 10 */ 857, 943, 943, 943, 943, 943, 943, 917, 943, 943,
+ /* 20 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 30 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 40 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 50 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 831,
+ /* 60 */ 943, 943, 943, 663, 888, 888, 751, 782, 943, 943,
+ /* 70 */ 943, 943, 943, 943, 943, 943, 783, 943, 861, 856,
+ /* 80 */ 852, 854, 853, 860, 784, 773, 780, 787, 762, 901,
+ /* 90 */ 789, 790, 796, 797, 918, 916, 819, 818, 837, 821,
+ /* 100 */ 843, 820, 830, 655, 822, 823, 943, 943, 943, 943,
+ /* 110 */ 943, 716, 650, 943, 943, 943, 943, 943, 943, 943,
+ /* 120 */ 943, 943, 943, 943, 943, 943, 824, 943, 825, 838,
+ /* 130 */ 839, 840, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 140 */ 943, 630, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 150 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 160 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 872,
+ /* 170 */ 943, 921, 923, 943, 943, 943, 624, 747, 747, 747,
+ /* 180 */ 943, 943, 943, 943, 943, 741, 751, 935, 943, 943,
+ /* 190 */ 707, 943, 943, 943, 943, 943, 943, 943, 632, 739,
+ /* 200 */ 665, 749, 943, 943, 943, 652, 728, 894, 943, 908,
+ /* 210 */ 906, 730, 792, 943, 739, 748, 943, 943, 943, 855,
+ /* 220 */ 776, 776, 764, 776, 686, 776, 943, 776, 943, 689,
+ /* 230 */ 786, 764, 764, 786, 629, 629, 629, 629, 640, 640,
+ /* 240 */ 706, 943, 786, 777, 779, 769, 781, 943, 755, 755,
+ /* 250 */ 763, 768, 763, 768, 763, 768, 718, 718, 703, 718,
+ /* 260 */ 689, 718, 865, 869, 869, 703, 718, 718, 718, 865,
+ /* 270 */ 647, 755, 647, 755, 647, 755, 755, 898, 900, 647,
+ /* 280 */ 755, 720, 720, 798, 786, 755, 727, 727, 727, 727,
+ /* 290 */ 786, 720, 798, 755, 920, 920, 755, 755, 928, 673,
+ /* 300 */ 691, 691, 935, 940, 940, 943, 943, 943, 943, 943,
+ /* 310 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 320 */ 943, 943, 943, 943, 874, 943, 943, 638, 943, 657,
+ /* 330 */ 805, 810, 806, 943, 807, 943, 733, 943, 943, 943,
+ /* 340 */ 943, 943, 943, 943, 943, 943, 943, 858, 943, 770,
+ /* 350 */ 943, 778, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 360 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 370 */ 943, 943, 943, 943, 943, 943, 943, 896, 897, 943,
+ /* 380 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 390 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943,
+ /* 400 */ 943, 943, 943, 927, 943, 943, 930, 625, 943, 620,
+ /* 410 */ 622, 623, 627, 628, 631, 657, 658, 660, 661, 662,
+ /* 420 */ 633, 634, 635, 636, 637, 639, 643, 641, 642, 644,
+ /* 430 */ 651, 653, 672, 674, 676, 737, 738, 802, 731, 732,
+ /* 440 */ 736, 659, 813, 804, 808, 809, 811, 812, 826, 827,
+ /* 450 */ 829, 835, 842, 845, 828, 833, 834, 836, 841, 844,
+ /* 460 */ 734, 735, 848, 666, 667, 670, 671, 884, 886, 885,
+ /* 470 */ 887, 669, 668, 814, 817, 850, 851, 909, 910, 911,
+ /* 480 */ 912, 913, 846, 756, 849, 832, 771, 774, 775, 772,
+ /* 490 */ 740, 750, 758, 759, 760, 761, 745, 746, 752, 767,
+ /* 500 */ 800, 801, 765, 766, 753, 754, 742, 743, 744, 847,
+ /* 510 */ 803, 815, 816, 677, 678, 810, 679, 680, 681, 719,
+ /* 520 */ 722, 723, 724, 682, 701, 704, 705, 683, 690, 684,
+ /* 530 */ 685, 692, 693, 694, 697, 698, 699, 700, 695, 696,
+ /* 540 */ 866, 867, 870, 868, 687, 688, 702, 675, 664, 656,
+ /* 550 */ 708, 711, 712, 713, 714, 715, 717, 709, 710, 654,
+ /* 560 */ 645, 648, 757, 890, 899, 895, 891, 892, 893, 649,
+ /* 570 */ 862, 863, 721, 794, 795, 889, 902, 904, 799, 905,
+ /* 580 */ 907, 903, 932, 646, 725, 726, 729, 871, 914, 785,
+ /* 590 */ 788, 791, 793, 873, 875, 877, 879, 880, 881, 882,
+ /* 600 */ 883, 876, 878, 915, 919, 922, 924, 925, 926, 929,
+ /* 610 */ 931, 936, 937, 938, 941, 942, 939, 626, 621,
};
#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
@@ -85758,82 +87074,6 @@ static const YYCODETYPE yyFallback[] = {
26, /* REINDEX => ID */
26, /* RENAME => ID */
26, /* CTIME_KW => ID */
- 0, /* ANY => nothing */
- 0, /* OR => nothing */
- 0, /* AND => nothing */
- 0, /* IS => nothing */
- 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, /* BITAND => nothing */
- 0, /* BITOR => nothing */
- 0, /* LSHIFT => nothing */
- 0, /* RSHIFT => nothing */
- 0, /* PLUS => nothing */
- 0, /* MINUS => nothing */
- 0, /* STAR => nothing */
- 0, /* SLASH => nothing */
- 0, /* REM => nothing */
- 0, /* CONCAT => nothing */
- 0, /* COLLATE => nothing */
- 0, /* UMINUS => nothing */
- 0, /* UPLUS => nothing */
- 0, /* BITNOT => nothing */
- 0, /* STRING => nothing */
- 0, /* JOIN_KW => nothing */
- 0, /* CONSTRAINT => nothing */
- 0, /* DEFAULT => nothing */
- 0, /* NULL => nothing */
- 0, /* PRIMARY => nothing */
- 0, /* UNIQUE => nothing */
- 0, /* CHECK => nothing */
- 0, /* REFERENCES => nothing */
- 0, /* AUTOINCR => nothing */
- 0, /* ON => nothing */
- 0, /* DELETE => nothing */
- 0, /* UPDATE => nothing */
- 0, /* INSERT => nothing */
- 0, /* SET => nothing */
- 0, /* DEFERRABLE => nothing */
- 0, /* FOREIGN => nothing */
- 0, /* DROP => nothing */
- 0, /* UNION => nothing */
- 0, /* ALL => nothing */
- 0, /* EXCEPT => nothing */
- 0, /* INTERSECT => nothing */
- 0, /* SELECT => nothing */
- 0, /* DISTINCT => nothing */
- 0, /* DOT => nothing */
- 0, /* FROM => nothing */
- 0, /* JOIN => nothing */
- 0, /* USING => nothing */
- 0, /* ORDER => nothing */
- 0, /* GROUP => nothing */
- 0, /* HAVING => nothing */
- 0, /* LIMIT => nothing */
- 0, /* WHERE => nothing */
- 0, /* INTO => nothing */
- 0, /* VALUES => nothing */
- 0, /* INTEGER => nothing */
- 0, /* FLOAT => nothing */
- 0, /* BLOB => nothing */
- 0, /* REGISTER => nothing */
- 0, /* VARIABLE => nothing */
- 0, /* CASE => nothing */
- 0, /* WHEN => nothing */
- 0, /* THEN => nothing */
- 0, /* ELSE => nothing */
- 0, /* INDEX => nothing */
- 0, /* ALTER => nothing */
- 0, /* ADD => nothing */
};
#endif /* YYFALLBACK */
@@ -86303,7 +87543,8 @@ static const char *const yyRuleName[] = {
/* 319 */ "vtabargtoken ::= lp anylist RP",
/* 320 */ "lp ::= LP",
/* 321 */ "anylist ::=",
- /* 322 */ "anylist ::= anylist ANY",
+ /* 322 */ "anylist ::= anylist LP anylist RP",
+ /* 323 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
@@ -86390,17 +87631,9 @@ sqlite3SelectDelete(pParse->db, (yypminor->yy243));
break;
case 174: /* term */
case 175: /* expr */
- case 199: /* where_opt */
- case 201: /* having_opt */
- case 210: /* on_opt */
- case 215: /* sortitem */
case 223: /* escape */
- case 226: /* case_operand */
- case 228: /* case_else */
- case 239: /* when_clause */
- case 242: /* key_opt */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy72));
+sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr);
}
break;
case 179: /* idxlist_opt */
@@ -86427,6 +87660,18 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy148));
sqlite3SrcListDelete(pParse->db, (yypminor->yy185));
}
break;
+ case 199: /* where_opt */
+ case 201: /* having_opt */
+ case 210: /* on_opt */
+ case 215: /* sortitem */
+ case 226: /* case_operand */
+ case 228: /* case_else */
+ case 239: /* when_clause */
+ case 242: /* key_opt */
+{
+sqlite3ExprDelete(pParse->db, (yypminor->yy72));
+}
+ break;
case 211: /* using_opt */
case 213: /* inscollist */
case 219: /* inscollist_opt */
@@ -86997,6 +88242,7 @@ static const struct {
{ 248, 3 },
{ 249, 1 },
{ 250, 0 },
+ { 250, 4 },
{ 250, 2 },
};
@@ -87052,46 +88298,6 @@ static void yy_reduce(
** #line <lineno> <thisfile>
** break;
*/
- case 0: /* input ::= cmdlist */
- case 1: /* cmdlist ::= cmdlist ecmd */
- case 2: /* cmdlist ::= ecmd */
- case 3: /* ecmd ::= SEMI */
- case 4: /* ecmd ::= explain cmdx SEMI */
- case 10: /* trans_opt ::= */
- case 11: /* trans_opt ::= TRANSACTION */
- case 12: /* trans_opt ::= TRANSACTION nm */
- case 20: /* savepoint_opt ::= SAVEPOINT */
- case 21: /* savepoint_opt ::= */
- case 25: /* cmd ::= create_table create_table_args */
- case 34: /* columnlist ::= columnlist COMMA column */
- case 35: /* columnlist ::= column */
- case 44: /* type ::= */
- case 51: /* signed ::= plus_num */
- case 52: /* signed ::= minus_num */
- case 53: /* carglist ::= carglist carg */
- case 54: /* carglist ::= */
- case 55: /* carg ::= CONSTRAINT nm ccons */
- case 56: /* carg ::= ccons */
- case 62: /* ccons ::= NULL onconf */
- case 89: /* conslist ::= conslist COMMA tcons */
- case 90: /* conslist ::= conslist tcons */
- case 91: /* conslist ::= tcons */
- case 92: /* tcons ::= CONSTRAINT nm */
- case 268: /* plus_opt ::= PLUS */
- case 269: /* plus_opt ::= */
- case 279: /* foreach_clause ::= */
- case 280: /* foreach_clause ::= FOR EACH ROW */
- case 300: /* database_kw_opt ::= DATABASE */
- case 301: /* database_kw_opt ::= */
- case 309: /* kwcolumn_opt ::= */
- case 310: /* kwcolumn_opt ::= COLUMNKW */
- case 314: /* vtabarglist ::= vtabarg */
- case 315: /* vtabarglist ::= vtabarglist COMMA vtabarg */
- case 317: /* vtabarg ::= vtabarg vtabargtoken */
- case 321: /* anylist ::= */
-{
-}
- break;
case 5: /* explain ::= */
{ sqlite3BeginParse(pParse, 0); }
break;
@@ -87111,14 +88317,14 @@ static void yy_reduce(
{yygotominor.yy194 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
- case 15: /* transtype ::= IMMEDIATE */
- case 16: /* transtype ::= EXCLUSIVE */
- case 114: /* multiselect_op ::= UNION */
- case 116: /* multiselect_op ::= EXCEPT|INTERSECT */
+ case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
+ case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
+ case 114: /* multiselect_op ::= UNION */ yytestcase(yyruleno==114);
+ case 116: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==116);
{yygotominor.yy194 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
- case 18: /* cmd ::= END trans_opt */
+ case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
{sqlite3CommitTransaction(pParse);}
break;
case 19: /* cmd ::= ROLLBACK trans_opt */
@@ -87151,26 +88357,26 @@ static void yy_reduce(
}
break;
case 28: /* ifnotexists ::= */
- case 31: /* temp ::= */
- case 70: /* autoinc ::= */
- case 84: /* init_deferred_pred_opt ::= */
- case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
- case 97: /* defer_subclause_opt ::= */
- case 108: /* ifexists ::= */
- case 119: /* distinct ::= ALL */
- case 120: /* distinct ::= */
- case 222: /* between_op ::= BETWEEN */
- case 225: /* in_op ::= IN */
+ case 31: /* temp ::= */ yytestcase(yyruleno==31);
+ case 70: /* autoinc ::= */ yytestcase(yyruleno==70);
+ case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
+ case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
+ case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97);
+ case 108: /* ifexists ::= */ yytestcase(yyruleno==108);
+ case 119: /* distinct ::= ALL */ yytestcase(yyruleno==119);
+ case 120: /* distinct ::= */ yytestcase(yyruleno==120);
+ case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222);
+ case 225: /* in_op ::= IN */ yytestcase(yyruleno==225);
{yygotominor.yy194 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
- case 30: /* temp ::= TEMP */
- case 71: /* autoinc ::= AUTOINCR */
- case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
- case 107: /* ifexists ::= IF EXISTS */
- case 118: /* distinct ::= DISTINCT */
- case 223: /* between_op ::= NOT BETWEEN */
- case 226: /* in_op ::= NOT IN */
+ case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
+ case 71: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==71);
+ case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
+ case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107);
+ case 118: /* distinct ::= DISTINCT */ yytestcase(yyruleno==118);
+ case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223);
+ case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226);
{yygotominor.yy194 = 1;}
break;
case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
@@ -87188,8 +88394,6 @@ static void yy_reduce(
{
yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
- yygotominor.yy0.quoted = 0;
- yygotominor.yy0.dyn = 0;
}
break;
case 37: /* columnid ::= nm */
@@ -87199,26 +88403,26 @@ static void yy_reduce(
}
break;
case 38: /* id ::= ID */
- case 39: /* id ::= INDEXED */
- case 40: /* ids ::= ID|STRING */
- case 41: /* nm ::= id */
- case 42: /* nm ::= STRING */
- case 43: /* nm ::= JOIN_KW */
- case 46: /* typetoken ::= typename */
- case 49: /* typename ::= ids */
- case 126: /* as ::= AS nm */
- case 127: /* as ::= ids */
- case 137: /* dbnm ::= DOT nm */
- case 146: /* indexed_opt ::= INDEXED BY nm */
- case 251: /* collate ::= COLLATE ids */
- case 260: /* nmnum ::= plus_num */
- case 261: /* nmnum ::= nm */
- case 262: /* nmnum ::= ON */
- case 263: /* nmnum ::= DELETE */
- case 264: /* nmnum ::= DEFAULT */
- case 265: /* plus_num ::= plus_opt number */
- case 266: /* minus_num ::= MINUS number */
- case 267: /* number ::= INTEGER|FLOAT */
+ case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
+ case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
+ case 41: /* nm ::= id */ yytestcase(yyruleno==41);
+ case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
+ case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
+ case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
+ case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
+ case 126: /* as ::= AS nm */ yytestcase(yyruleno==126);
+ case 127: /* as ::= ids */ yytestcase(yyruleno==127);
+ case 137: /* dbnm ::= DOT nm */ yytestcase(yyruleno==137);
+ case 146: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==146);
+ case 251: /* collate ::= COLLATE ids */ yytestcase(yyruleno==251);
+ case 260: /* nmnum ::= plus_num */ yytestcase(yyruleno==260);
+ case 261: /* nmnum ::= nm */ yytestcase(yyruleno==261);
+ case 262: /* nmnum ::= ON */ yytestcase(yyruleno==262);
+ case 263: /* nmnum ::= DELETE */ yytestcase(yyruleno==263);
+ case 264: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==264);
+ case 265: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==265);
+ case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266);
+ case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
case 45: /* type ::= typetoken */
@@ -87240,23 +88444,26 @@ static void yy_reduce(
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
case 57: /* ccons ::= DEFAULT term */
- case 59: /* ccons ::= DEFAULT PLUS term */
-{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy72);}
+ case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59);
+{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);}
break;
case 58: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy72);}
+{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);}
break;
case 60: /* ccons ::= DEFAULT MINUS term */
{
- Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(p,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
- sqlite3AddDefaultValue(pParse,p);
+ ExprSpan v;
+ v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0, 0);
+ v.zStart = yymsp[-1].minor.yy0.z;
+ v.zEnd = yymsp[0].minor.yy190.zEnd;
+ sqlite3AddDefaultValue(pParse,&v);
}
break;
case 61: /* ccons ::= DEFAULT id */
{
- Expr *p = sqlite3PExpr(pParse, TK_STRING, 0, 0, &yymsp[0].minor.yy0);
- sqlite3AddDefaultValue(pParse,p);
+ ExprSpan v;
+ spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
+ sqlite3AddDefaultValue(pParse,&v);
}
break;
case 63: /* ccons ::= NOT NULL onconf */
@@ -87269,7 +88476,7 @@ static void yy_reduce(
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0);}
break;
case 66: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy72);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);}
break;
case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);}
@@ -87311,12 +88518,12 @@ static void yy_reduce(
{ yygotominor.yy194 = OE_Restrict; }
break;
case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
- case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 98: /* defer_subclause_opt ::= defer_subclause */
- case 100: /* onconf ::= ON CONFLICT resolvetype */
- case 102: /* orconf ::= OR resolvetype */
- case 103: /* resolvetype ::= raisetype */
- case 175: /* insert_cmd ::= INSERT orconf */
+ case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83);
+ case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98);
+ case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100);
+ case 102: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==102);
+ case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103);
+ case 175: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==175);
{yygotominor.yy194 = yymsp[0].minor.yy194;}
break;
case 87: /* conslist_opt ::= */
@@ -87332,7 +88539,7 @@ static void yy_reduce(
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0);}
break;
case 95: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy72);}
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);}
break;
case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
{
@@ -87341,14 +88548,14 @@ static void yy_reduce(
}
break;
case 99: /* onconf ::= */
- case 101: /* orconf ::= */
+ case 101: /* orconf ::= */ yytestcase(yyruleno==101);
{yygotominor.yy194 = OE_Default;}
break;
case 104: /* resolvetype ::= IGNORE */
{yygotominor.yy194 = OE_Ignore;}
break;
case 105: /* resolvetype ::= REPLACE */
- case 176: /* insert_cmd ::= REPLACE */
+ case 176: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==176);
{yygotominor.yy194 = OE_Replace;}
break;
case 106: /* cmd ::= DROP TABLE ifexists fullname */
@@ -87396,25 +88603,27 @@ static void yy_reduce(
}
break;
case 121: /* sclp ::= selcollist COMMA */
- case 247: /* idxlist_opt ::= LP idxlist RP */
+ case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247);
{yygotominor.yy148 = yymsp[-1].minor.yy148;}
break;
case 122: /* sclp ::= */
- case 150: /* orderby_opt ::= */
- case 158: /* groupby_opt ::= */
- case 240: /* exprlist ::= */
- case 246: /* idxlist_opt ::= */
+ case 150: /* orderby_opt ::= */ yytestcase(yyruleno==150);
+ case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158);
+ case 240: /* exprlist ::= */ yytestcase(yyruleno==240);
+ case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246);
{yygotominor.yy148 = 0;}
break;
case 123: /* selcollist ::= sclp expr as */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[-1].minor.yy72,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yygotominor.yy148,&yymsp[-1].minor.yy190);
}
break;
case 124: /* selcollist ::= sclp STAR */
{
- Expr *p = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p, 0);
+ Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p);
}
break;
case 125: /* selcollist ::= sclp nm DOT STAR */
@@ -87422,7 +88631,7 @@ static void yy_reduce(
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot);
}
break;
case 128: /* as ::= */
@@ -87440,7 +88649,7 @@ static void yy_reduce(
case 131: /* stl_prefix ::= seltablist joinop */
{
yygotominor.yy185 = yymsp[-1].minor.yy185;
- if( yygotominor.yy185 && yygotominor.yy185->nSrc>0 ) yygotominor.yy185->a[yygotominor.yy185->nSrc-1].jointype = (u8)yymsp[0].minor.yy194;
+ if( ALWAYS(yygotominor.yy185 && yygotominor.yy185->nSrc>0) ) yygotominor.yy185->a[yygotominor.yy185->nSrc-1].jointype = (u8)yymsp[0].minor.yy194;
}
break;
case 132: /* stl_prefix ::= */
@@ -87459,7 +88668,9 @@ static void yy_reduce(
break;
case 135: /* 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 ){
+ if( yymsp[-6].minor.yy185==0 ){
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72);
+ sqlite3IdListDelete(pParse->db, yymsp[0].minor.yy254);
yygotominor.yy185 = yymsp[-4].minor.yy185;
}else{
Select *pSubquery;
@@ -87470,7 +88681,7 @@ static void yy_reduce(
}
break;
case 136: /* dbnm ::= */
- case 145: /* indexed_opt ::= */
+ case 145: /* indexed_opt ::= */ yytestcase(yyruleno==145);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
case 138: /* fullname ::= nm dbnm */
@@ -87489,53 +88700,50 @@ static void yy_reduce(
{ yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
break;
case 143: /* on_opt ::= ON expr */
- case 154: /* sortitem ::= expr */
- case 161: /* having_opt ::= HAVING expr */
- case 168: /* where_opt ::= WHERE expr */
- case 183: /* expr ::= term */
- case 211: /* escape ::= ESCAPE expr */
- case 235: /* case_else ::= ELSE expr */
- case 237: /* case_operand ::= expr */
-{yygotominor.yy72 = yymsp[0].minor.yy72;}
+ case 154: /* sortitem ::= expr */ yytestcase(yyruleno==154);
+ case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161);
+ case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168);
+ case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235);
+ case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237);
+{yygotominor.yy72 = yymsp[0].minor.yy190.pExpr;}
break;
case 144: /* on_opt ::= */
- case 160: /* having_opt ::= */
- case 167: /* where_opt ::= */
- case 212: /* escape ::= */
- case 236: /* case_else ::= */
- case 238: /* case_operand ::= */
+ case 160: /* having_opt ::= */ yytestcase(yyruleno==160);
+ case 167: /* where_opt ::= */ yytestcase(yyruleno==167);
+ case 236: /* case_else ::= */ yytestcase(yyruleno==236);
+ case 238: /* case_operand ::= */ yytestcase(yyruleno==238);
{yygotominor.yy72 = 0;}
break;
case 147: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
case 148: /* using_opt ::= USING LP inscollist RP */
- case 180: /* inscollist_opt ::= LP inscollist RP */
+ case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180);
{yygotominor.yy254 = yymsp[-1].minor.yy254;}
break;
case 149: /* using_opt ::= */
- case 179: /* inscollist_opt ::= */
+ case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
{yygotominor.yy254 = 0;}
break;
case 151: /* orderby_opt ::= ORDER BY sortlist */
- case 159: /* groupby_opt ::= GROUP BY nexprlist */
- case 239: /* exprlist ::= nexprlist */
+ case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159);
+ case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239);
{yygotominor.yy148 = yymsp[0].minor.yy148;}
break;
case 152: /* sortlist ::= sortlist COMMA sortitem sortorder */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy72,0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy72);
if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
}
break;
case 153: /* sortlist ::= sortitem sortorder */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy72,0);
- if( yygotominor.yy148 && yygotominor.yy148->a ) yygotominor.yy148->a[0].sortOrder = (u8)yymsp[0].minor.yy194;
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy72);
+ if( yygotominor.yy148 && ALWAYS(yygotominor.yy148->a) ) yygotominor.yy148->a[0].sortOrder = (u8)yymsp[0].minor.yy194;
}
break;
case 155: /* sortorder ::= ASC */
- case 157: /* sortorder ::= */
+ case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
{yygotominor.yy194 = SQLITE_SO_ASC;}
break;
case 156: /* sortorder ::= DESC */
@@ -87545,13 +88753,13 @@ static void yy_reduce(
{yygotominor.yy354.pLimit = 0; yygotominor.yy354.pOffset = 0;}
break;
case 163: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy354.pLimit = yymsp[0].minor.yy72; yygotominor.yy354.pOffset = 0;}
+{yygotominor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yygotominor.yy354.pOffset = 0;}
break;
case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy354.pLimit = yymsp[-2].minor.yy72; yygotominor.yy354.pOffset = yymsp[0].minor.yy72;}
+{yygotominor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yygotominor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;}
break;
case 165: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy354.pOffset = yymsp[-2].minor.yy72; yygotominor.yy354.pLimit = yymsp[0].minor.yy72;}
+{yygotominor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yygotominor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;}
break;
case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
{
@@ -87567,10 +88775,16 @@ static void yy_reduce(
}
break;
case 170: /* setlist ::= setlist COMMA nm EQ expr */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148,yymsp[0].minor.yy72,&yymsp[-2].minor.yy0);}
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1);
+}
break;
case 171: /* setlist ::= nm EQ expr */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy72,&yymsp[-2].minor.yy0);}
+{
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1);
+}
break;
case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
{sqlite3Insert(pParse, yymsp[-5].minor.yy185, yymsp[-1].minor.yy148, 0, yymsp[-4].minor.yy254, yymsp[-7].minor.yy194);}
@@ -87582,12 +88796,12 @@ static void yy_reduce(
{sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);}
break;
case 177: /* itemlist ::= itemlist COMMA expr */
- case 241: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy72,0);}
+ case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241);
+{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);}
break;
case 178: /* itemlist ::= expr */
- case 242: /* nexprlist ::= expr */
-{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy72,0);}
+ case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242);
+{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr);}
break;
case 181: /* inscollist ::= inscollist COMMA nm */
{yygotominor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);}
@@ -87595,23 +88809,28 @@ static void yy_reduce(
case 182: /* inscollist ::= nm */
{yygotominor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
+ case 183: /* expr ::= term */
+ case 211: /* escape ::= ESCAPE expr */ yytestcase(yyruleno==211);
+{yygotominor.yy190 = yymsp[0].minor.yy190;}
+ break;
case 184: /* expr ::= LP expr RP */
-{yygotominor.yy72 = yymsp[-1].minor.yy72; sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+{yygotominor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr; spanSet(&yygotominor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 185: /* term ::= NULL */
- case 190: /* term ::= INTEGER|FLOAT|BLOB */
- case 191: /* term ::= STRING */
-{yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
+ case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
+ case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
+{spanExpr(&yygotominor.yy190, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
case 186: /* expr ::= id */
- case 187: /* expr ::= JOIN_KW */
-{yygotominor.yy72 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+ case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
+{spanExpr(&yygotominor.yy190, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
case 188: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ spanSet(&yygotominor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 189: /* expr ::= nm DOT nm DOT nm */
@@ -87620,238 +88839,243 @@ static void yy_reduce(
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ spanSet(&yygotominor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 192: /* expr ::= REGISTER */
-{yygotominor.yy72 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
+{
+ /* 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. */
+ if( pParse->nested==0 ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = 0;
+ }else{
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
+ if( yygotominor.yy190.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy190.pExpr->iTable);
+ }
+ spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+}
break;
case 193: /* expr ::= VARIABLE */
{
- Token *pToken = &yymsp[0].minor.yy0;
- Expr *pExpr = yygotominor.yy72 = sqlite3PExpr(pParse, TK_VARIABLE, 0, 0, pToken);
- sqlite3ExprAssignVarNumber(pParse, pExpr);
+ spanExpr(&yygotominor.yy190, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yygotominor.yy190.pExpr);
+ spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 194: /* expr ::= expr COLLATE ids */
{
- yygotominor.yy72 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy72, &yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0);
+ yygotominor.yy190.zStart = yymsp[-2].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 195: /* expr ::= CAST LP expr AS typetoken RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy72, 0, &yymsp[-1].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0);
+ spanSet(&yygotominor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 196: /* expr ::= ID LP distinct exprlist RP */
{
- if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>SQLITE_MAX_FUNCTION_ARG ){
+ if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
- yygotominor.yy72 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy194 && yygotominor.yy72 ){
- yygotominor.yy72->flags |= EP_Distinct;
+ yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0);
+ spanSet(&yygotominor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ if( yymsp[-2].minor.yy194 && yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->flags |= EP_Distinct;
}
}
break;
case 197: /* expr ::= ID LP STAR RP */
{
- yygotominor.yy72 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+ spanSet(&yygotominor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 198: /* term ::= CTIME_KW */
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
- yygotominor.yy72 = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->op = TK_CONST_FUNC;
- yygotominor.yy72->span = yymsp[0].minor.yy0;
+ yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->op = TK_CONST_FUNC;
}
+ spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 199: /* expr ::= expr AND expr */
- case 200: /* expr ::= expr OR expr */
- case 201: /* expr ::= expr LT|GT|GE|LE expr */
- case 202: /* expr ::= expr EQ|NE expr */
- case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
- case 204: /* expr ::= expr PLUS|MINUS expr */
- case 205: /* expr ::= expr STAR|SLASH|REM expr */
- case 206: /* expr ::= expr CONCAT expr */
-{yygotominor.yy72 = sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy72,yymsp[0].minor.yy72,0);}
+ case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
+ case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
+ case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
+ case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
+ case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
+ case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
+ case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
+{spanBinaryExpr(&yygotominor.yy190,pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);}
break;
case 207: /* likeop ::= LIKE_KW */
- case 209: /* likeop ::= MATCH */
+ case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 0;}
break;
case 208: /* likeop ::= NOT LIKE_KW */
- case 210: /* likeop ::= NOT MATCH */
+ case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210);
{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 1;}
break;
+ case 212: /* escape ::= */
+{memset(&yygotominor.yy190,0,sizeof(yygotominor.yy190));}
+ break;
case 213: /* expr ::= expr likeop expr escape */
{
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy72, 0);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy72, 0);
- if( yymsp[0].minor.yy72 ){
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy72, 0);
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy190.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy190.pExpr);
+ if( yymsp[0].minor.yy190.pExpr ){
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
}
- yygotominor.yy72 = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy392.eOperator);
- if( yymsp[-2].minor.yy392.not ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-3].minor.yy72->span, &yymsp[-1].minor.yy72->span);
- if( yygotominor.yy72 ) yygotominor.yy72->flags |= EP_InfixFunc;
+ yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy392.eOperator);
+ if( yymsp[-2].minor.yy392.not ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = yymsp[-1].minor.yy190.zEnd;
+ if( yygotominor.yy190.pExpr ) yygotominor.yy190.pExpr->flags |= EP_InfixFunc;
}
break;
case 214: /* expr ::= expr ISNULL|NOTNULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[0].major, yymsp[-1].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{spanUnaryPostfix(&yygotominor.yy190,pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);}
break;
case 215: /* expr ::= expr IS NULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_ISNULL, yymsp[-2].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_ISNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
break;
case 216: /* expr ::= expr NOT NULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-2].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);}
break;
case 217: /* expr ::= expr IS NOT NULL */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOTNULL, yymsp[-3].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy72->span,&yymsp[0].minor.yy0);
-}
+{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_NOTNULL,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy0);}
break;
case 218: /* expr ::= NOT expr */
- case 219: /* expr ::= BITNOT expr */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
-}
+ case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219);
+{spanUnaryPrefix(&yygotominor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);}
break;
case 220: /* expr ::= MINUS expr */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
-}
+{spanUnaryPrefix(&yygotominor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);}
break;
case 221: /* expr ::= PLUS expr */
-{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_UPLUS, yymsp[0].minor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy72->span);
-}
+{spanUnaryPrefix(&yygotominor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);}
break;
case 224: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy72, 0);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy72, 0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy72->span);
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = yymsp[0].minor.yy190.zEnd;
}
break;
case 227: /* expr ::= expr in_op LP exprlist RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pList = yymsp[-1].minor.yy148;
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148);
}
- if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy0);
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 228: /* expr ::= LP select RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pSelect = yymsp[-1].minor.yy243;
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pSelect = yymsp[-1].minor.yy243;
+ ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
}
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy190.zStart = yymsp[-2].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 229: /* expr ::= expr in_op LP select RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pSelect = yymsp[-1].minor.yy243;
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pSelect = yymsp[-1].minor.yy243;
+ ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
}
- if( yymsp[-3].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-4].minor.yy72->span,&yymsp[0].minor.yy0);
+ if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 230: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy72, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy190.pExpr, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+ ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- if( yymsp[-2].minor.yy194 ) yygotominor.yy72 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy72, 0, 0);
- sqlite3ExprSpan(yygotominor.yy72,&yymsp[-3].minor.yy72->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
+ if( yymsp[-2].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0);
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy190.zStart;
+ yygotominor.yy190.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
case 231: /* expr ::= EXISTS LP select RP */
{
- Expr *p = yygotominor.yy72 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ Expr *p = yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = yymsp[-1].minor.yy243;
- ExprSetProperty(yygotominor.yy72, EP_xIsSelect);
- sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ ExprSetProperty(p, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243);
}
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 232: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->x.pList = yymsp[-2].minor.yy148;
- sqlite3ExprSetHeight(pParse, yygotominor.yy72);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->x.pList = yymsp[-2].minor.yy148;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148);
}
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+ yygotominor.yy190.zStart = yymsp[-4].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy72, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy72, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
case 234: /* case_exprlist ::= WHEN expr THEN expr */
{
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy72, 0);
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy72, 0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy190.pExpr);
}
break;
case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
@@ -87862,7 +89086,7 @@ static void yy_reduce(
}
break;
case 244: /* uniqueflag ::= UNIQUE */
- case 293: /* raisetype ::= ABORT */
+ case 293: /* raisetype ::= ABORT */ yytestcase(yyruleno==293);
{yygotominor.yy194 = OE_Abort;}
break;
case 245: /* uniqueflag ::= */
@@ -87872,10 +89096,11 @@ static void yy_reduce(
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
- p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
+ p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
}
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, p, &yymsp[-2].minor.yy0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, p);
+ sqlite3ExprListSetName(pParse,yygotominor.yy148,&yymsp[-2].minor.yy0,1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index");
if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
}
@@ -87887,7 +89112,8 @@ static void yy_reduce(
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
}
- yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy0);
+ yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, p);
+ sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index");
if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194;
}
@@ -87899,7 +89125,7 @@ static void yy_reduce(
{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
break;
case 253: /* cmd ::= VACUUM */
- case 254: /* cmd ::= VACUUM nm */
+ case 254: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==254);
{sqlite3Vacuum(pParse);}
break;
case 255: /* cmd ::= PRAGMA nm dbnm */
@@ -87932,7 +89158,7 @@ static void yy_reduce(
}
break;
case 272: /* trigger_time ::= BEFORE */
- case 275: /* trigger_time ::= */
+ case 275: /* trigger_time ::= */ yytestcase(yyruleno==275);
{ yygotominor.yy194 = TK_BEFORE; }
break;
case 273: /* trigger_time ::= AFTER */
@@ -87942,29 +89168,22 @@ static void yy_reduce(
{ yygotominor.yy194 = TK_INSTEAD;}
break;
case 276: /* trigger_event ::= DELETE|INSERT */
- case 277: /* trigger_event ::= UPDATE */
+ case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277);
{yygotominor.yy332.a = yymsp[0].major; yygotominor.yy332.b = 0;}
break;
case 278: /* trigger_event ::= UPDATE OF inscollist */
{yygotominor.yy332.a = TK_UPDATE; yygotominor.yy332.b = yymsp[0].minor.yy254;}
break;
case 281: /* when_clause ::= */
- case 298: /* key_opt ::= */
+ case 298: /* key_opt ::= */ yytestcase(yyruleno==298);
{ yygotominor.yy72 = 0; }
break;
case 282: /* when_clause ::= WHEN expr */
- case 299: /* key_opt ::= KEY expr */
-{ yygotominor.yy72 = yymsp[0].minor.yy72; }
+ case 299: /* key_opt ::= KEY expr */ yytestcase(yyruleno==299);
+{ yygotominor.yy72 = yymsp[0].minor.yy190.pExpr; }
break;
case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
-/*
- if( yymsp[-2].minor.yy145 ){
- yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145;
- }else{
- yymsp[-2].minor.yy145 = yymsp[-1].minor.yy145;
- }
-*/
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;
@@ -87973,7 +89192,6 @@ static void yy_reduce(
break;
case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- /* if( yymsp[-1].minor.yy145 ) */
assert( yymsp[-1].minor.yy145!=0 );
yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145;
yygotominor.yy145 = yymsp[-1].minor.yy145;
@@ -87996,20 +89214,22 @@ static void yy_reduce(
break;
case 290: /* expr ::= RAISE LP IGNORE RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy72 ){
- yygotominor.yy72->affinity = OE_Ignore;
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ if( yygotominor.yy190.pExpr ){
+ yygotominor.yy190.pExpr->affinity = OE_Ignore;
}
+ yygotominor.yy190.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 291: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- yygotominor.yy72 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy72 ) {
- yygotominor.yy72->affinity = (char)yymsp[-3].minor.yy194;
- sqlite3ExprSpan(yygotominor.yy72, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+ yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ if( yygotominor.yy190.pExpr ) {
+ yygotominor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194;
}
+ yygotominor.yy190.zStart = yymsp[-5].minor.yy0.z;
+ yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 292: /* raisetype ::= ROLLBACK */
@@ -88025,12 +89245,12 @@ static void yy_reduce(
break;
case 296: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, yymsp[0].minor.yy72);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72);
}
break;
case 297: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy72);
+ sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr);
}
break;
case 302: /* cmd ::= REINDEX */
@@ -88076,11 +89296,51 @@ static void yy_reduce(
{sqlite3VtabArgInit(pParse);}
break;
case 318: /* vtabargtoken ::= ANY */
- case 319: /* vtabargtoken ::= lp anylist RP */
- case 320: /* lp ::= LP */
- case 322: /* anylist ::= anylist ANY */
+ case 319: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==319);
+ case 320: /* lp ::= LP */ yytestcase(yyruleno==320);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
+ default:
+ /* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
+ /* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
+ /* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
+ /* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
+ /* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
+ /* (10) trans_opt ::= */ yytestcase(yyruleno==10);
+ /* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
+ /* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
+ /* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
+ /* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
+ /* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
+ /* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
+ /* (35) columnlist ::= column */ yytestcase(yyruleno==35);
+ /* (44) type ::= */ yytestcase(yyruleno==44);
+ /* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
+ /* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
+ /* (53) carglist ::= carglist carg */ yytestcase(yyruleno==53);
+ /* (54) carglist ::= */ yytestcase(yyruleno==54);
+ /* (55) carg ::= CONSTRAINT nm ccons */ yytestcase(yyruleno==55);
+ /* (56) carg ::= ccons */ yytestcase(yyruleno==56);
+ /* (62) ccons ::= NULL onconf */ yytestcase(yyruleno==62);
+ /* (89) conslist ::= conslist COMMA tcons */ yytestcase(yyruleno==89);
+ /* (90) conslist ::= conslist tcons */ yytestcase(yyruleno==90);
+ /* (91) conslist ::= tcons */ yytestcase(yyruleno==91);
+ /* (92) tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92);
+ /* (268) plus_opt ::= PLUS */ yytestcase(yyruleno==268);
+ /* (269) plus_opt ::= */ yytestcase(yyruleno==269);
+ /* (279) foreach_clause ::= */ yytestcase(yyruleno==279);
+ /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280);
+ /* (300) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==300);
+ /* (301) database_kw_opt ::= */ yytestcase(yyruleno==301);
+ /* (309) kwcolumn_opt ::= */ yytestcase(yyruleno==309);
+ /* (310) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==310);
+ /* (314) vtabarglist ::= vtabarg */ yytestcase(yyruleno==314);
+ /* (315) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==315);
+ /* (317) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==317);
+ /* (321) anylist ::= */ yytestcase(yyruleno==321);
+ /* (322) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==322);
+ /* (323) anylist ::= anylist ANY */ yytestcase(yyruleno==323);
+ break;
};
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
@@ -88112,6 +89372,7 @@ static void yy_reduce(
/*
** The following code executes when the parse fails
*/
+#ifndef YYNOERRORRECOVERY
static void yy_parse_failed(
yyParser *yypParser /* The parser */
){
@@ -88126,6 +89387,7 @@ static void yy_parse_failed(
** parser fails */
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
+#endif /* YYNOERRORRECOVERY */
/*
** The following code executes when a syntax error first occurs.
@@ -88296,6 +89558,18 @@ SQLITE_PRIVATE void sqlite3Parser(
}
yypParser->yyerrcnt = 3;
yyerrorhit = 1;
+#elif defined(YYNOERRORRECOVERY)
+ /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
+ ** do any kind of error recovery. Instead, simply invoke the syntax
+ ** error routine and continue going as if nothing had happened.
+ **
+ ** Applications can set this macro (for example inside %include) if
+ ** they intend to abandon the parse upon the first syntax error seen.
+ */
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+
#else /* YYERRORSYMBOL is not defined */
/* This is what we do if the grammar does not define ERROR:
**
@@ -88528,125 +89802,125 @@ static int keywordCode(const char *z, int n){
n) % 127;
for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){
if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){
- testcase( i==0 ); /* TK_REINDEX */
- testcase( i==1 ); /* TK_INDEXED */
- testcase( i==2 ); /* TK_INDEX */
- testcase( i==3 ); /* TK_DESC */
- testcase( i==4 ); /* TK_ESCAPE */
- testcase( i==5 ); /* TK_EACH */
- testcase( i==6 ); /* TK_CHECK */
- testcase( i==7 ); /* TK_KEY */
- testcase( i==8 ); /* TK_BEFORE */
- testcase( i==9 ); /* TK_FOREIGN */
- testcase( i==10 ); /* TK_FOR */
- testcase( i==11 ); /* TK_IGNORE */
- testcase( i==12 ); /* TK_LIKE_KW */
- testcase( i==13 ); /* TK_EXPLAIN */
- testcase( i==14 ); /* TK_INSTEAD */
- testcase( i==15 ); /* TK_ADD */
- testcase( i==16 ); /* TK_DATABASE */
- testcase( i==17 ); /* TK_AS */
- testcase( i==18 ); /* TK_SELECT */
- testcase( i==19 ); /* TK_TABLE */
- testcase( i==20 ); /* TK_JOIN_KW */
- testcase( i==21 ); /* TK_THEN */
- testcase( i==22 ); /* TK_END */
- testcase( i==23 ); /* TK_DEFERRABLE */
- testcase( i==24 ); /* TK_ELSE */
- testcase( i==25 ); /* TK_EXCEPT */
- testcase( i==26 ); /* TK_TRANSACTION */
- testcase( i==27 ); /* TK_ON */
- testcase( i==28 ); /* TK_JOIN_KW */
- testcase( i==29 ); /* TK_ALTER */
- testcase( i==30 ); /* TK_RAISE */
- testcase( i==31 ); /* TK_EXCLUSIVE */
- testcase( i==32 ); /* TK_EXISTS */
- testcase( i==33 ); /* TK_SAVEPOINT */
- testcase( i==34 ); /* TK_INTERSECT */
- testcase( i==35 ); /* TK_TRIGGER */
- testcase( i==36 ); /* TK_REFERENCES */
- testcase( i==37 ); /* TK_CONSTRAINT */
- testcase( i==38 ); /* TK_INTO */
- testcase( i==39 ); /* TK_OFFSET */
- testcase( i==40 ); /* TK_OF */
- testcase( i==41 ); /* TK_SET */
- testcase( i==42 ); /* TK_TEMP */
- testcase( i==43 ); /* TK_TEMP */
- testcase( i==44 ); /* TK_OR */
- testcase( i==45 ); /* TK_UNIQUE */
- testcase( i==46 ); /* TK_QUERY */
- testcase( i==47 ); /* TK_ATTACH */
- testcase( i==48 ); /* TK_HAVING */
- testcase( i==49 ); /* TK_GROUP */
- testcase( i==50 ); /* TK_UPDATE */
- testcase( i==51 ); /* TK_BEGIN */
- testcase( i==52 ); /* TK_JOIN_KW */
- testcase( i==53 ); /* TK_RELEASE */
- testcase( i==54 ); /* TK_BETWEEN */
- testcase( i==55 ); /* TK_NOTNULL */
- testcase( i==56 ); /* TK_NOT */
- testcase( i==57 ); /* TK_NULL */
- testcase( i==58 ); /* TK_LIKE_KW */
- testcase( i==59 ); /* TK_CASCADE */
- testcase( i==60 ); /* TK_ASC */
- testcase( i==61 ); /* TK_DELETE */
- testcase( i==62 ); /* TK_CASE */
- testcase( i==63 ); /* TK_COLLATE */
- testcase( i==64 ); /* TK_CREATE */
- testcase( i==65 ); /* TK_CTIME_KW */
- testcase( i==66 ); /* TK_DETACH */
- testcase( i==67 ); /* TK_IMMEDIATE */
- testcase( i==68 ); /* TK_JOIN */
- testcase( i==69 ); /* TK_INSERT */
- testcase( i==70 ); /* TK_MATCH */
- testcase( i==71 ); /* TK_PLAN */
- testcase( i==72 ); /* TK_ANALYZE */
- testcase( i==73 ); /* TK_PRAGMA */
- testcase( i==74 ); /* TK_ABORT */
- testcase( i==75 ); /* TK_VALUES */
- testcase( i==76 ); /* TK_VIRTUAL */
- testcase( i==77 ); /* TK_LIMIT */
- testcase( i==78 ); /* TK_WHEN */
- testcase( i==79 ); /* TK_WHERE */
- testcase( i==80 ); /* TK_RENAME */
- testcase( i==81 ); /* TK_AFTER */
- testcase( i==82 ); /* TK_REPLACE */
- testcase( i==83 ); /* TK_AND */
- testcase( i==84 ); /* TK_DEFAULT */
- testcase( i==85 ); /* TK_AUTOINCR */
- testcase( i==86 ); /* TK_TO */
- testcase( i==87 ); /* TK_IN */
- testcase( i==88 ); /* TK_CAST */
- testcase( i==89 ); /* TK_COLUMNKW */
- testcase( i==90 ); /* TK_COMMIT */
- testcase( i==91 ); /* TK_CONFLICT */
- testcase( i==92 ); /* TK_JOIN_KW */
- testcase( i==93 ); /* TK_CTIME_KW */
- testcase( i==94 ); /* TK_CTIME_KW */
- testcase( i==95 ); /* TK_PRIMARY */
- testcase( i==96 ); /* TK_DEFERRED */
- testcase( i==97 ); /* TK_DISTINCT */
- testcase( i==98 ); /* TK_IS */
- testcase( i==99 ); /* TK_DROP */
- testcase( i==100 ); /* TK_FAIL */
- testcase( i==101 ); /* TK_FROM */
- testcase( i==102 ); /* TK_JOIN_KW */
- testcase( i==103 ); /* TK_LIKE_KW */
- testcase( i==104 ); /* TK_BY */
- testcase( i==105 ); /* TK_IF */
- testcase( i==106 ); /* TK_ISNULL */
- testcase( i==107 ); /* TK_ORDER */
- testcase( i==108 ); /* TK_RESTRICT */
- testcase( i==109 ); /* TK_JOIN_KW */
- testcase( i==110 ); /* TK_JOIN_KW */
- testcase( i==111 ); /* TK_ROLLBACK */
- testcase( i==112 ); /* TK_ROW */
- testcase( i==113 ); /* TK_UNION */
- testcase( i==114 ); /* TK_USING */
- testcase( i==115 ); /* TK_VACUUM */
- testcase( i==116 ); /* TK_VIEW */
- testcase( i==117 ); /* TK_INITIALLY */
- testcase( i==118 ); /* TK_ALL */
+ testcase( i==0 ); /* REINDEX */
+ testcase( i==1 ); /* INDEXED */
+ testcase( i==2 ); /* INDEX */
+ testcase( i==3 ); /* DESC */
+ testcase( i==4 ); /* ESCAPE */
+ testcase( i==5 ); /* EACH */
+ testcase( i==6 ); /* CHECK */
+ testcase( i==7 ); /* KEY */
+ testcase( i==8 ); /* BEFORE */
+ testcase( i==9 ); /* FOREIGN */
+ testcase( i==10 ); /* FOR */
+ testcase( i==11 ); /* IGNORE */
+ testcase( i==12 ); /* REGEXP */
+ testcase( i==13 ); /* EXPLAIN */
+ testcase( i==14 ); /* INSTEAD */
+ testcase( i==15 ); /* ADD */
+ testcase( i==16 ); /* DATABASE */
+ testcase( i==17 ); /* AS */
+ testcase( i==18 ); /* SELECT */
+ testcase( i==19 ); /* TABLE */
+ testcase( i==20 ); /* LEFT */
+ testcase( i==21 ); /* THEN */
+ testcase( i==22 ); /* END */
+ testcase( i==23 ); /* DEFERRABLE */
+ testcase( i==24 ); /* ELSE */
+ testcase( i==25 ); /* EXCEPT */
+ testcase( i==26 ); /* TRANSACTION */
+ testcase( i==27 ); /* ON */
+ testcase( i==28 ); /* NATURAL */
+ testcase( i==29 ); /* ALTER */
+ testcase( i==30 ); /* RAISE */
+ testcase( i==31 ); /* EXCLUSIVE */
+ testcase( i==32 ); /* EXISTS */
+ testcase( i==33 ); /* SAVEPOINT */
+ testcase( i==34 ); /* INTERSECT */
+ testcase( i==35 ); /* TRIGGER */
+ testcase( i==36 ); /* REFERENCES */
+ testcase( i==37 ); /* CONSTRAINT */
+ testcase( i==38 ); /* INTO */
+ testcase( i==39 ); /* OFFSET */
+ testcase( i==40 ); /* OF */
+ testcase( i==41 ); /* SET */
+ testcase( i==42 ); /* TEMP */
+ testcase( i==43 ); /* TEMPORARY */
+ testcase( i==44 ); /* OR */
+ testcase( i==45 ); /* UNIQUE */
+ testcase( i==46 ); /* QUERY */
+ testcase( i==47 ); /* ATTACH */
+ testcase( i==48 ); /* HAVING */
+ testcase( i==49 ); /* GROUP */
+ testcase( i==50 ); /* UPDATE */
+ testcase( i==51 ); /* BEGIN */
+ testcase( i==52 ); /* INNER */
+ testcase( i==53 ); /* RELEASE */
+ testcase( i==54 ); /* BETWEEN */
+ testcase( i==55 ); /* NOTNULL */
+ testcase( i==56 ); /* NOT */
+ testcase( i==57 ); /* NULL */
+ testcase( i==58 ); /* LIKE */
+ testcase( i==59 ); /* CASCADE */
+ testcase( i==60 ); /* ASC */
+ testcase( i==61 ); /* DELETE */
+ testcase( i==62 ); /* CASE */
+ testcase( i==63 ); /* COLLATE */
+ testcase( i==64 ); /* CREATE */
+ testcase( i==65 ); /* CURRENT_DATE */
+ testcase( i==66 ); /* DETACH */
+ testcase( i==67 ); /* IMMEDIATE */
+ testcase( i==68 ); /* JOIN */
+ testcase( i==69 ); /* INSERT */
+ testcase( i==70 ); /* MATCH */
+ testcase( i==71 ); /* PLAN */
+ testcase( i==72 ); /* ANALYZE */
+ testcase( i==73 ); /* PRAGMA */
+ testcase( i==74 ); /* ABORT */
+ testcase( i==75 ); /* VALUES */
+ testcase( i==76 ); /* VIRTUAL */
+ testcase( i==77 ); /* LIMIT */
+ testcase( i==78 ); /* WHEN */
+ testcase( i==79 ); /* WHERE */
+ testcase( i==80 ); /* RENAME */
+ testcase( i==81 ); /* AFTER */
+ testcase( i==82 ); /* REPLACE */
+ testcase( i==83 ); /* AND */
+ testcase( i==84 ); /* DEFAULT */
+ testcase( i==85 ); /* AUTOINCREMENT */
+ testcase( i==86 ); /* TO */
+ testcase( i==87 ); /* IN */
+ testcase( i==88 ); /* CAST */
+ testcase( i==89 ); /* COLUMN */
+ testcase( i==90 ); /* COMMIT */
+ testcase( i==91 ); /* CONFLICT */
+ testcase( i==92 ); /* CROSS */
+ testcase( i==93 ); /* CURRENT_TIMESTAMP */
+ testcase( i==94 ); /* CURRENT_TIME */
+ testcase( i==95 ); /* PRIMARY */
+ testcase( i==96 ); /* DEFERRED */
+ testcase( i==97 ); /* DISTINCT */
+ testcase( i==98 ); /* IS */
+ testcase( i==99 ); /* DROP */
+ testcase( i==100 ); /* FAIL */
+ testcase( i==101 ); /* FROM */
+ testcase( i==102 ); /* FULL */
+ testcase( i==103 ); /* GLOB */
+ testcase( i==104 ); /* BY */
+ testcase( i==105 ); /* IF */
+ testcase( i==106 ); /* ISNULL */
+ testcase( i==107 ); /* ORDER */
+ testcase( i==108 ); /* RESTRICT */
+ testcase( i==109 ); /* OUTER */
+ testcase( i==110 ); /* RIGHT */
+ testcase( i==111 ); /* ROLLBACK */
+ testcase( i==112 ); /* ROW */
+ testcase( i==113 ); /* UNION */
+ testcase( i==114 ); /* USING */
+ testcase( i==115 ); /* VACUUM */
+ testcase( i==116 ); /* VIEW */
+ testcase( i==117 ); /* INITIALLY */
+ testcase( i==118 ); /* ALL */
return aCode[i];
}
}
@@ -88716,6 +89990,11 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
int i, c;
switch( *z ){
case ' ': case '\t': case '\n': case '\f': case '\r': {
+ testcase( z[0]==' ' );
+ testcase( z[0]=='\t' );
+ testcase( z[0]=='\n' );
+ testcase( z[0]=='\f' );
+ testcase( z[0]=='\r' );
for(i=1; sqlite3Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
@@ -88828,6 +90107,9 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
case '\'':
case '"': {
int delim = z[0];
+ testcase( delim=='`' );
+ testcase( delim=='\'' );
+ testcase( delim=='"' );
for(i=1; (c=z[i])!=0; i++){
if( c==delim ){
if( z[i+1]==delim ){
@@ -88861,6 +90143,10 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
+ testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' );
+ testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' );
+ testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' );
+ testcase( z[0]=='9' );
*tokenType = TK_INTEGER;
for(i=0; sqlite3Isdigit(z[i]); i++){}
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -88912,6 +90198,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
case '@': /* For compatibility with MS SQL Server */
case ':': {
int n = 0;
+ testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' );
*tokenType = TK_VARIABLE;
for(i=1; (c=z[i])!=0; i++){
if( IdChar(c) ){
@@ -88939,6 +90226,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
}
#ifndef SQLITE_OMIT_BLOB_LITERAL
case 'x': case 'X': {
+ testcase( z[0]=='x' ); testcase( z[0]=='X' );
if( z[1]=='\'' ){
*tokenType = TK_BLOB;
for(i=2; (c=z[i])!=0 && c!='\''; i++){
@@ -88997,7 +90285,6 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
db->mallocFailed = 1;
return SQLITE_NOMEM;
}
- assert( pParse->sLastToken.dyn==0 );
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
@@ -89006,12 +90293,9 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
assert( pParse->apVarExpr==0 );
enableLookaside = db->lookaside.bEnabled;
if( db->lookaside.pStart ) db->lookaside.bEnabled = 1;
- pParse->sLastToken.quoted = 1;
while( !db->mallocFailed && zSql[i]!=0 ){
assert( i>=0 );
- pParse->sLastToken.z = (u8*)&zSql[i];
- assert( pParse->sLastToken.dyn==0 );
- assert( pParse->sLastToken.quoted );
+ pParse->sLastToken.z = &zSql[i];
pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType);
i += pParse->sLastToken.n;
if( i>mxSqlLen ){
@@ -89021,8 +90305,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
switch( tokenType ){
case TK_SPACE: {
if( db->u1.isInterrupted ){
+ sqlite3ErrorMsg(pParse, "interrupt");
pParse->rc = SQLITE_INTERRUPT;
- sqlite3SetString(pzErrMsg, db, "interrupt");
goto abort_parse;
}
break;
@@ -89069,12 +90353,9 @@ abort_parse:
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
}
+ assert( pzErrMsg!=0 );
if( pParse->zErrMsg ){
- if( *pzErrMsg==0 ){
- *pzErrMsg = pParse->zErrMsg;
- }else{
- sqlite3DbFree(db, pParse->zErrMsg);
- }
+ *pzErrMsg = pParse->zErrMsg;
pParse->zErrMsg = 0;
nErr++;
}
@@ -89795,7 +91076,7 @@ SQLITE_API int sqlite3_config(int op, ...){
break;
}
case SQLITE_CONFIG_PAGECACHE: {
- /* Designate a buffer for scratch memory space */
+ /* Designate a buffer for page cache memory space */
sqlite3GlobalConfig.pPage = va_arg(ap, void*);
sqlite3GlobalConfig.szPage = va_arg(ap, int);
sqlite3GlobalConfig.nPage = va_arg(ap, int);
@@ -89803,7 +91084,7 @@ SQLITE_API int sqlite3_config(int op, ...){
}
case SQLITE_CONFIG_PCACHE: {
- /* Specify an alternative malloc implementation */
+ /* Specify an alternative page cache implementation */
sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*);
break;
}
@@ -89834,7 +91115,6 @@ SQLITE_API int sqlite3_config(int op, ...){
/* The heap pointer is not NULL, then install one of the
** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
** ENABLE_MEMSYS5 is defined, return an error.
- ** the default case and return an error.
*/
#ifdef SQLITE_ENABLE_MEMSYS3
sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
@@ -90416,8 +91696,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
(!xFunc && (!xFinal && xStep)) ||
(nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
(255<(nName = sqlite3Strlen30( zFunctionName))) ){
- sqlite3Error(db, SQLITE_ERROR, "bad parameters");
- return SQLITE_ERROR;
+ return SQLITE_MISUSE;
}
#ifndef SQLITE_OMIT_UTF16
@@ -90678,7 +91957,8 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
#endif
#if SQLITE_TEMP_STORE==3
return 1;
-#else
+#endif
+#if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
return 0;
#endif
}
@@ -90847,7 +92127,7 @@ static int createCollation(
){
CollSeq *pColl;
int enc2;
- int nName;
+ int nName = sqlite3Strlen30(zName);
assert( sqlite3_mutex_held(db->mutex) );
@@ -90869,8 +92149,7 @@ static int createCollation(
** sequence. If so, and there are active VMs, return busy. If there
** are no active VMs, invalidate any pre-compiled statements.
*/
- nName = sqlite3Strlen30(zName);
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 0);
+ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
if( pColl && pColl->xCmp ){
if( db->activeVdbeCnt ){
sqlite3Error(db, SQLITE_BUSY,
@@ -90900,7 +92179,7 @@ static int createCollation(
}
}
- pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 1);
+ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
if( pColl ){
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
@@ -91022,8 +92301,16 @@ static int openDatabase(
isThreadsafe = sqlite3GlobalConfig.bFullMutex;
}
- /* Remove harmful bits from the flags parameter */
+ /* Remove harmful bits from the flags parameter
+ **
+ ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
+ ** dealt with in the previous code block. Besides these, the only
+ ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
+ ** SQLITE_OPEN_READWRITE, and SQLITE_OPEN_CREATE. Silently mask
+ ** off all other flags.
+ */
flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
+ SQLITE_OPEN_EXCLUSIVE |
SQLITE_OPEN_MAIN_DB |
SQLITE_OPEN_TEMP_DB |
SQLITE_OPEN_TRANSIENT_DB |
@@ -91089,7 +92376,7 @@ static int openDatabase(
if( db->mallocFailed ){
goto opendb_out;
}
- db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0);
+ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
assert( db->pDfltColl!=0 );
/* Also add a UTF-8 case-insensitive collation sequence. */
@@ -91097,7 +92384,7 @@ static int openDatabase(
/* Set flags on the built-in collating sequences */
db->pDfltColl->type = SQLITE_COLL_BINARY;
- pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 6, 0);
+ pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 0);
if( pColl ){
pColl->type = SQLITE_COLL_NOCASE;
}
@@ -91143,8 +92430,9 @@ static int openDatabase(
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
*/
- (void)sqlite3AutoLoadExtensions(db);
- if( sqlite3_errcode(db)!=SQLITE_OK ){
+ sqlite3AutoLoadExtensions(db);
+ rc = sqlite3_errcode(db);
+ if( rc!=SQLITE_OK ){
goto opendb_out;
}
@@ -91662,7 +92950,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
}
/*
- ** sqlite3_test_control(PENDING_BYTE, unsigned int X)
+ ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X)
**
** Set the PENDING byte to the value in the argument, if X>0.
** Make no changes if X==0. Return the value of the pending byte
@@ -91679,6 +92967,58 @@ SQLITE_API int sqlite3_test_control(int op, ...){
if( newVal ) sqlite3PendingByte = newVal;
break;
}
+
+ /*
+ ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X)
+ **
+ ** This action provides a run-time test to see whether or not
+ ** assert() was enabled at compile-time. If X is true and assert()
+ ** is enabled, then the return value is true. If X is true and
+ ** assert() is disabled, then the return value is zero. If X is
+ ** false and assert() is enabled, then the assertion fires and the
+ ** process aborts. If X is false and assert() is disabled, then the
+ ** return value is zero.
+ */
+ case SQLITE_TESTCTRL_ASSERT: {
+ volatile int x = 0;
+ assert( (x = va_arg(ap,int))!=0 );
+ rc = x;
+ break;
+ }
+
+
+ /*
+ ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X)
+ **
+ ** 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 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
+ ** default setting. If the return value is 1, then ALWAYS() is either
+ ** hard-coded to true or else it asserts if its argument is false.
+ ** The first behavior (hard-coded to true) is the case if
+ ** SQLITE_TESTCTRL_ASSERT shows that assert() is disabled and the second
+ ** behavior (assert if the argument to ALWAYS() is false) is the case if
+ ** SQLITE_TESTCTRL_ASSERT shows that assert() is enabled.
+ **
+ ** The run-time test procedure might look something like this:
+ **
+ ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){
+ ** // ALWAYS() and NEVER() are no-op pass-through macros
+ ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){
+ ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false.
+ ** }else{
+ ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0.
+ ** }
+ */
+ case SQLITE_TESTCTRL_ALWAYS: {
+ int x = va_arg(ap,int);
+ rc = ALWAYS(x);
+ break;
+ }
}
va_end(ap);
#endif /* SQLITE_OMIT_BUILTIN_TEST */
diff --git a/ext/sqlite3/libsqlite/sqlite3.h b/ext/sqlite3/libsqlite/sqlite3.h
index 025cc9f2a9..8554281ff5 100644
--- a/ext/sqlite3/libsqlite/sqlite3.h
+++ b/ext/sqlite3/libsqlite/sqlite3.h
@@ -99,8 +99,8 @@ extern "C" {
**
** Requirements: [H10011] [H10014]
*/
-#define SQLITE_VERSION "3.6.14.2"
-#define SQLITE_VERSION_NUMBER 3006014
+#define SQLITE_VERSION "3.6.15"
+#define SQLITE_VERSION_NUMBER 3006015
/*
** CAPI3REF: Run-Time Library Version Numbers {H10020} <S60100>
@@ -392,20 +392,20 @@ int sqlite3_exec(
** in the 4th parameter to the xOpen method of the
** [sqlite3_vfs] object.
*/
-#define SQLITE_OPEN_READONLY 0x00000001
-#define SQLITE_OPEN_READWRITE 0x00000002
-#define SQLITE_OPEN_CREATE 0x00000004
-#define SQLITE_OPEN_DELETEONCLOSE 0x00000008
-#define SQLITE_OPEN_EXCLUSIVE 0x00000010
-#define SQLITE_OPEN_MAIN_DB 0x00000100
-#define SQLITE_OPEN_TEMP_DB 0x00000200
-#define SQLITE_OPEN_TRANSIENT_DB 0x00000400
-#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800
-#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000
-#define SQLITE_OPEN_SUBJOURNAL 0x00002000
-#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000
-#define SQLITE_OPEN_NOMUTEX 0x00008000
-#define SQLITE_OPEN_FULLMUTEX 0x00010000
+#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
+#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
+#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
+#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
+#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
+#define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */
+#define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */
+#define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */
+#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
+#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
/*
** CAPI3REF: Device Characteristics {H10240} <H11120>
@@ -702,9 +702,14 @@ typedef struct sqlite3_mutex sqlite3_mutex;
** deleted when it is closed. The [SQLITE_OPEN_DELETEONCLOSE]
** will be set for TEMP databases, journals and for subjournals.
**
-** The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
-** for exclusive access. This flag is set for all files except
-** for the main database file.
+** The [SQLITE_OPEN_EXCLUSIVE] flag is always used in conjunction
+** with the [SQLITE_OPEN_CREATE] flag, which are both directly
+** analogous to the O_EXCL and O_CREAT flags of the POSIX open()
+** API. The SQLITE_OPEN_EXCLUSIVE flag, when paired with the
+** SQLITE_OPEN_CREATE, is used to indicate that file should always
+** be created, and that it is an error if it already exists.
+** It is <i>not</i> used to indicate the file should be opened
+** for exclusive access.
**
** At least szOsFile bytes of memory are allocated by SQLite
** to hold the [sqlite3_file] structure passed as the third
@@ -1031,12 +1036,14 @@ struct sqlite3_mem_methods {
**
** <dt>SQLITE_CONFIG_SCRATCH</dt>
** <dd>This option specifies a static memory buffer that SQLite can use for
-** scratch memory. There are three arguments: A pointer to the memory, the
-** size of each scratch buffer (sz), and the number of buffers (N). The sz
+** scratch memory. There are three arguments: A pointer an 8-byte
+** aligned memory buffer from which the scrach allocations will be
+** drawn, the size of each scratch allocation (sz),
+** and the maximum number of scratch allocations (N). The sz
** argument must be a multiple of 16. The sz parameter should be a few bytes
-** larger than the actual scratch space required due internal overhead.
-** The first
-** argument should point to an allocation of at least sz*N bytes of memory.
+** larger than the actual scratch space required due to internal overhead.
+** The first argument should pointer to an 8-byte aligned buffer
+** of at least sz*N bytes of memory.
** SQLite will use no more than one scratch buffer at once per thread, so
** N should be set to the expected maximum number of threads. The sz
** parameter should be 6 times the size of the largest database page size.
@@ -1050,29 +1057,37 @@ struct sqlite3_mem_methods {
** the database page cache with the default page cache implemenation.
** This configuration should not be used if an application-define page
** cache implementation is loaded using the SQLITE_CONFIG_PCACHE option.
-** There are three arguments to this option: A pointer to the
+** There are three arguments to this option: A pointer to 8-byte aligned
** memory, the size of each page buffer (sz), and the number of pages (N).
-** The sz argument must be a power of two between 512 and 32768. The first
+** The sz argument should be the size of the largest database page
+** (a power of two between 512 and 32768) plus a little extra for each
+** page header. The page header size is 20 to 40 bytes depending on
+** the host architecture. It is harmless, apart from the wasted memory,
+** to make sz a little too large. The first
** argument should point to an allocation of at least sz*N bytes of memory.
** SQLite will use the memory provided by the first argument to satisfy its
** memory needs for the first N pages that it adds to cache. If additional
** page cache memory is needed beyond what is provided by this option, then
** SQLite goes to [sqlite3_malloc()] for the additional storage space.
** The implementation might use one or more of the N buffers to hold
-** memory accounting information. </dd>
+** memory accounting information. The pointer in the first argument must
+** be aligned to an 8-byte boundary or subsequent behavior of SQLite
+** will be undefined.</dd>
**
** <dt>SQLITE_CONFIG_HEAP</dt>
** <dd>This 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].
-** There are three arguments: A pointer to the memory, the number of
-** bytes in the memory buffer, and the minimum allocation size. If
-** the first pointer (the memory pointer) is NULL, then SQLite reverts
+** There are three arguments: An 8-byte aligned pointer to the memory,
+** the number of bytes in the memory buffer, and the minimum allocation size.
+** If the first pointer (the memory pointer) is NULL, then SQLite reverts
** to using its default memory allocator (the system malloc() implementation),
** undoing any prior invocation of [SQLITE_CONFIG_MALLOC]. If the
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
-** allocator is engaged to handle all of SQLites memory allocation needs.</dd>
+** allocator is engaged to handle all of SQLites memory allocation needs.
+** The first pointer (the memory pointer) must be aligned to an 8-byte
+** boundary or subsequent behavior of SQLite will be undefined.</dd>
**
** <dt>SQLITE_CONFIG_MUTEX</dt>
** <dd>This option takes a single argument which is a pointer to an
@@ -1143,9 +1158,9 @@ struct sqlite3_mem_methods {
** <dd>This option takes three additional arguments that determine the
** [lookaside memory allocator] configuration for the [database connection].
** The first argument (the third parameter to [sqlite3_db_config()] is a
-** pointer to a memory buffer to use for lookaside memory. The first
-** argument may be NULL in which case SQLite will allocate the lookaside
-** buffer itself using [sqlite3_malloc()]. The second argument is the
+** pointer to an 8-byte aligned memory buffer to use for lookaside memory.
+** The first argument may be NULL in which case SQLite will allocate the
+** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the
** size of each lookaside buffer slot and the third argument is the number of
** slots. The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.</dd>
@@ -1277,9 +1292,9 @@ int sqlite3_changes(sqlite3*);
** [CREATE TRIGGER | trigger] contexts. However,
** the count does not include changes used to implement [REPLACE] constraints,
** do rollbacks or ABORT processing, or [DROP TABLE] processing. The
-** count does not rows of views that fire an [INSTEAD OF trigger], though if
-** the INSTEAD OF trigger makes changes of its own, those changes are
-** counted.
+** count does not include rows of views that fire an [INSTEAD OF trigger],
+** though if the INSTEAD OF trigger makes changes of its own, those changes
+** are counted.
** The changes are counted as soon as the statement that makes them is
** completed (when the statement handle is passed to [sqlite3_reset()] or
** [sqlite3_finalize()]).
@@ -3069,8 +3084,11 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
**
** The third parameter (nArg)
** is the number of arguments that the SQL function or
-** aggregate takes. If this parameter is negative, then the SQL function or
-** aggregate may take any number of arguments.
+** aggregate takes. If this parameter is -1, then the SQL function or
+** aggregate may take any number of arguments between 0 and the limit
+** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third
+** parameter is less than -1 or greater than 127 then the behavior is
+** undefined.
**
** The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
@@ -3121,7 +3139,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt);
** statement in which the function is running.
**
** Requirements:
-** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16124] [H16127]
+** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16127]
** [H16130] [H16133] [H16136] [H16139] [H16142]
*/
int sqlite3_create_function(
@@ -3736,11 +3754,11 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} <S60400>
**
** The sqlite3_commit_hook() interface registers a callback
-** function to be invoked whenever a transaction is committed.
+** function to be invoked whenever a transaction is [COMMIT | committed].
** Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** The sqlite3_rollback_hook() interface registers a callback
-** function to be invoked whenever a transaction is committed.
+** function to be invoked whenever a transaction is [ROLLBACK | rolled back].
** Any callback set by a previous call to sqlite3_commit_hook()
** for the same database connection is overridden.
** The pArg argument is passed through to the callback.
@@ -3760,6 +3778,12 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
**
** Registering a NULL function disables the callback.
**
+** When the commit hook callback routine returns zero, the [COMMIT]
+** operation is allowed to continue normally. If the commit hook
+** returns non-zero, then the [COMMIT] is converted into a [ROLLBACK].
+** The rollback hook is invoked on a rollback that results from a commit
+** hook returning non-zero, just as it would be with any other rollback.
+**
** For the purposes of this API, a transaction is said to have been
** rolled back if an explicit "ROLLBACK" statement is executed, or
** an error or constraint causes an implicit rollback to occur.
@@ -3769,6 +3793,8 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
** rolled back because a commit callback returned non-zero.
** <todo> Check on this </todo>
**
+** See also the [sqlite3_update_hook()] interface.
+**
** Requirements:
** [H12951] [H12952] [H12953] [H12954] [H12955]
** [H12961] [H12962] [H12963] [H12964]
@@ -3800,6 +3826,13 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** The update hook is not invoked when internal system tables are
** modified (i.e. sqlite_master and sqlite_sequence).
**
+** In the current implementation, the update hook
+** is not invoked when duplication rows are deleted because of an
+** [ON CONFLICT | ON CONFLICT REPLACE] clause. Nor is the update hook
+** invoked when rows are deleted using the [truncate optimization].
+** The exceptions defined in this paragraph might change in a future
+** release of SQLite.
+**
** The update hook implementation must not do anything that will modify
** the database connection that invoked the update hook. Any actions
** to modify the database connection must be deferred until after the
@@ -3810,6 +3843,9 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
** If another function was previously registered, its pArg value
** is returned. Otherwise NULL is returned.
**
+** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
+** interfaces.
+**
** Requirements:
** [H12971] [H12973] [H12975] [H12977] [H12979] [H12981] [H12983] [H12986]
*/
@@ -4379,7 +4415,7 @@ typedef struct sqlite3_blob sqlite3_blob;
** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
** </pre> {END}
**
-** If the flags parameter is non-zero, the the BLOB is opened for read
+** If the flags parameter is non-zero, then the BLOB is opened for read
** and write access. If it is zero, the BLOB is opened for read access.
**
** Note that the database name is not the filename that contains
@@ -4389,10 +4425,13 @@ typedef struct sqlite3_blob sqlite3_blob;
** For TEMP tables, the database name is "temp".
**
** On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and any value written
-** to *ppBlob should not be used by the caller.
+** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
+** to be a null pointer.
** This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()].
+** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
+** functions. Note that the *ppBlob variable is always initialized in a
+** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
+** regardless of the success or failure of this routine.
**
** If the row that a BLOB handle points to is modified by an
** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -4405,6 +4444,19 @@ typedef struct sqlite3_blob sqlite3_blob;
** rollback by the expiration of the BLOB. Such changes will eventually
** commit if the transaction continues to completion.
**
+** Use the [sqlite3_blob_bytes()] interface to determine the size of
+** the opened blob. The size of a blob may not be changed by this
+** underface. Use the [UPDATE] SQL command to change the size of a
+** blob.
+**
+** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
+** and the built-in [zeroblob] SQL function can be used, if desired,
+** to create an empty, zero-filled blob in which to read or write using
+** this interface.
+**
+** To avoid a resource leak, every open [BLOB handle] should eventually
+** be released by a call to [sqlite3_blob_close()].
+**
** Requirements:
** [H17813] [H17814] [H17816] [H17819] [H17821] [H17824]
*/
@@ -4427,16 +4479,19 @@ int sqlite3_blob_open(
** if there are no other BLOBs, no pending prepared statements, and the
** database connection is in [autocommit mode].
** If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit. {END}
+** until the close operation if they will fit.
**
** Closing the BLOB often forces the changes
** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed. {H17833} Any errors that occur during
+** at the time when the BLOB is closed. Any errors that occur during
** closing are reported as a non-zero return value.
**
** The BLOB is closed unconditionally. Even if this routine returns
** an error code, the BLOB is still closed.
**
+** Calling this routine with a null pointer (which as would be returned
+** by failed call to [sqlite3_blob_open()]) is a harmless no-op.
+**
** Requirements:
** [H17833] [H17836] [H17839]
*/
@@ -4445,8 +4500,15 @@ int sqlite3_blob_close(sqlite3_blob *);
/*
** CAPI3REF: Return The Size Of An Open BLOB {H17840} <S30230>
**
-** Returns the size in bytes of the BLOB accessible via the open
-** []BLOB handle] in its only argument.
+** Returns the size in bytes of the BLOB accessible via the
+** successfully opened [BLOB handle] in its only argument. The
+** incremental blob I/O routines can only read or overwriting existing
+** blob content; they cannot change the size of a blob.
+**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
**
** Requirements:
** [H17843]
@@ -4463,6 +4525,8 @@ int sqlite3_blob_bytes(sqlite3_blob *);
** If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is read. If N or iOffset is
** less than zero, [SQLITE_ERROR] is returned and no data is read.
+** The size of the blob (and hence the maximum value of N+iOffset)
+** can be determined using the [sqlite3_blob_bytes()] interface.
**
** An attempt to read from an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT].
@@ -4470,6 +4534,13 @@ int sqlite3_blob_bytes(sqlite3_blob *);
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_write()].
+**
** Requirements:
** [H17853] [H17856] [H17859] [H17862] [H17863] [H17865] [H17868]
*/
@@ -4491,6 +4562,8 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** If offset iOffset is less than N bytes from the end of the BLOB,
** [SQLITE_ERROR] is returned and no data is written. If N is
** less than zero [SQLITE_ERROR] is returned and no data is written.
+** The size of the BLOB (and hence the maximum value of N+iOffset)
+** can be determined using the [sqlite3_blob_bytes()] interface.
**
** An attempt to write to an expired [BLOB handle] fails with an
** error code of [SQLITE_ABORT]. Writes to the BLOB that occurred
@@ -4502,6 +4575,13 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
** On success, SQLITE_OK is returned.
** Otherwise, an [error code] or an [extended error code] is returned.
**
+** This routine only works on a [BLOB handle] which has been created
+** by a prior successful call to [sqlite3_blob_open()] and which has not
+** been closed by [sqlite3_blob_close()]. Passing any other pointer in
+** to this routine results in undefined and probably undesirable behavior.
+**
+** See also: [sqlite3_blob_read()].
+**
** Requirements:
** [H17873] [H17874] [H17875] [H17876] [H17877] [H17879] [H17882] [H17885]
** [H17888]
@@ -4852,6 +4932,8 @@ int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
#define SQLITE_TESTCTRL_PENDING_BYTE 11
+#define SQLITE_TESTCTRL_ASSERT 12
+#define SQLITE_TESTCTRL_ALWAYS 13
/*
** CAPI3REF: SQLite Runtime Status {H17200} <S60200>